# Compiling, linking, using Shared Library

**URL:** <https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196>\
**Category:** Help\
**Created:** [February 10, 2025, 6:33pm UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196 "2025-02-10T18:33:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![skav](https://avatars.discourse-cdn.com/v4/letter/s/df705f/32.png) [@skav](https://fortran-lang.discourse.group/u/skav)\
**Post date:** [February 10, 2025, 6:33pm UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196/1 "2025-02-10T18:33:47Z")

</div>

Hello everyone! I am using Debian 12 (amd64) with gfortran 12.2 and gmake. I want to be able to create a shared library and then be able to link to this library to a new fortran program which is located in a directory elsewhere. I have been able to create the shared library and associated modules but I am having trouble calling the library’s subroutines and functions from the new program. Here are the steps I followed:

1. Create and Compile Shared Library  
One of the files in this library is constants.f03:

```auto
module dnx_constants
   use iso_fortran_env, only: sp => real32, dp => real64
   implicit none
   real(dp), parameter :: dnx_pi=3.14159265358979323846d0
end module dnx_constants

```

Another file is vector.f03 and it is basically a module which contains a few subroutines:

```auto
module dnx_vector
   use dnx_constants
   implicit none
   public :: dnx_vprint

contains

   subroutine dnx_vprint(v, vname)
      implicit none
      integer :: i, n
      real(dp), intent(in), dimension(:) :: v
      character(len=8), intent(in) :: vname

      n= size(v)
      write(*,*)
      write(*,*) vname
      do i=1,n,1
         print*, v(i)
      end do
      write(*,*)

   end subroutine dnx_vprint
end module dnx_vector ! [EDIT] added missing line

```

I compiled the library as follows:

```auto
gfortran -c -std=f2008 -fPIC constants.f03 vector.f03
gfortran -shared constants.o vector.o -o libdnx.so

```

Compiles fine with no issues. Generates the .so as well as a couple .mod files.

1. Creating and compiling a new program which uses the library (main.f03):

```auto
program main
   use dnx_constants
   use dnx_vector
   implicit none
   print*, dnx_pi
   ! call dnx_vprint((/1.d0, 1.d0, dnx_pi/),"v= ")
end program main    

```

Compilation and linking are as follows

```auto
LIBDIR= /path/to/library
gfortran -L$(LIBDIR) -I$(LIBDIR) -ldnx main.f03 -o main.run

```

LD\_LIBRARY\_PATH environmental variable points to LIBDIR. Program compiles fine and it prints out the value of dnx\_pi to the screen. Uncommenting the call to dnx\_vprint gives me this error during compilation however:

```auto
/usr/bin/ld: /tmp/ccPeSQlf.o: in function `MAIN__':
main.f03:(.text+0x101): undefined reference to `__dnx_vector_MOD_dnx_vprint'

```

Any help would be appreciated.

---

<div class="post-metadata">

**Author:** ![wspector](https://avatars.discourse-cdn.com/v4/letter/w/47e85d/32.png) [@wspector](https://fortran-lang.discourse.group/u/wspector)\
**Post date:** [February 10, 2025, 9:22pm UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196/3 "2025-02-10T21:22:47Z")

</div>

Obtaining the value of pi was done at compile time - so doesn’t depend on finding the shared library at run time. However calling the procedure does require access to the shared lib. So somehow you’ve probably lost your LD\_LIBRARY\_PATH environment variable.

What happens when you type ‘`ldd main.run`’? It should list where it is looking for the various shared libs.

Note that you can hard code the path to the shared lib into the main program at link time. Use the -Wl,-rpath option. Then you don’t have to worry about setting LD\_LIBRARY\_PATH at run time.

---

<div class="post-metadata">

**Author:** ![nbehrnd](https://avatars.discourse-cdn.com/v4/letter/n/e0b2c6/32.png) [@nbehrnd](https://fortran-lang.discourse.group/u/nbehrnd)\
**Post date:** [February 10, 2025, 10:12pm UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196/4 "2025-02-10T22:12:45Z")

</div>

Two/three comments:

- Your source code is about Fortran in _free form_ syntax. Regardless if you adopt the standard of Fortran 90, or newer, the general recommendation is to use `.f90` as file extension.  
On the contrary, `.f` typically is used for the _fixed format_ of FORTRAN77 (comments indicated by `C`; instructions (except labels and continuation signs ) constrained to anything between char 7 and 72 per line, etc.). A compiler like gfortran for instance assumes `example.f` is the elder format, equivalent to the explicit `-std=legacy`, or `-ffixed-form` compiler flag. Capitalization of the file extension (`.F90`, or `.F`) conventionally indicates the source code shall pass a pre-processor prior to compilation (and linking).

- The representation of `vector.f03` is incomplete; without the closing line `end module dnx_vector` (or at least an `end module`) gfortran’s work doesn’t complete.

- On occasion, I see the approximation of of \pi in lines of

---

<div class="post-metadata">

**Author:** ![skav](https://avatars.discourse-cdn.com/v4/letter/s/df705f/32.png) [@skav](https://fortran-lang.discourse.group/u/skav)\
**Post date:** [February 11, 2025, 1:57am UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196/5 "2025-02-11T01:57:07Z")

</div>

I am now compiling using -Wl,-rpath /link/to/library

LDD Gives me the following:

```auto
$ ldd main.run 
	linux-vdso.so.1 (0x00007ffc28790000)
	libgfortran.so.5 => /lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007f8491600000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f849141f000)
	libquadmath.so.0 => /lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f849196d000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8491340000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f849194d000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f84919d2000)

```

Still getting the same error when I uncomment the call to dnx\_vector:

```auto
main.f90:(.text+0x101): undefined reference to `__dnx_vector_MOD_dnx_vprint'

```

Note that I can link with the shared lib and call the subroutine just fine if it is NOT contained inside of a module and its just sitting by itself outside of a module. Perhaps the feature I am looking for does not exist in GCC?

Any other thoughts?

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [February 11, 2025, 3:15am UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196/6 "2025-02-11T03:15:47Z")

</div>

It may be useful to place the link part after `main.f03`, i.e., instead of

> [@skav](#):
>
> `gfortran -L$(LIBDIR) -I$(LIBDIR) -ldnx main.f03 -o main.run`

put `-ldnx` after main.f03:

```auto
gfortran -L$(LIBDIR) -I$(LIBDIR) main.f03 -ldnx -o main.run

```

Indeed, the order of libraries seems to matter for GCC according to the following pages:

- [linker - Why does the order in which libraries are linked sometimes cause errors in GCC? - Stack Overflow](https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc)
- [Order of libraries in gcc command line is important? (Reddit)](https://www.reddit.com/r/opengl/comments/qfhbax/order_of_libraries_in_gcc_command_line_is/?rdt=39622)

But the result may depend on OS / platforms, so maybe try… (Also, any order of libraries may be OK for other compilers).

---

<div class="post-metadata">

**Author:** ![wspector](https://avatars.discourse-cdn.com/v4/letter/w/47e85d/32.png) [@wspector](https://fortran-lang.discourse.group/u/wspector)\
**Post date:** [February 11, 2025, 4:09am UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196/7 "2025-02-11T04:09:36Z")

</div>

> [@skav](#):
>
> I am now compiling using `-Wl,-rpath /link/to/library`

Replace the blank character with a comma. E.g., `-Wl,-rpath,/link/to/library`

And yes, you should place the -ldnx after the main.f03. So in your makefile, it would look like:

` gfortran -I$(LIBDIR) -L$(LIBDIR) main.f03 -ldnx -o main.run -Wl,-rpath,$(LIBDIR)`

If you then do a `ldd main.run`, you should see something like:

```auto
$ ldd main.run
	linux-vdso.so.1 (0x00007ffca5d6c000)
	libdnx.so => /link/to/library/libdnx.so (0x00007f31deffc000)
	libgfortran.so.5 => /lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007f31ded1e000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f31debcf000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f31debb4000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f31de9c2000)
	libquadmath.so.0 => /lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f31de978000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f31df003000)

```

---

<div class="post-metadata">

**Author:** ![skav](https://avatars.discourse-cdn.com/v4/letter/s/df705f/32.png) [@skav](https://fortran-lang.discourse.group/u/skav)\
**Post date:** [February 11, 2025, 11:50pm UTC](https://fortran-lang.discourse.group/t/compiling-linking-using-shared-library/9196/8 "2025-02-11T23:50:47Z")

</div>

wspector, septc

Worked perfectly! The flag `-ldnx` goes AFTER main.f03 (order matters) and `-Wl,-rpath,` to point to the library location.

Thanks!
