# Exporting subroutine symbol in library from fpm

**URL:** <https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321>\
**Category:** fpm\
**Created:** [July 8, 2024, 4:13pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321 "2024-07-08T16:13:01Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![general\_rishkin](https://avatars.discourse-cdn.com/v4/letter/g/a9a28c/32.png) [@general\_rishkin](https://fortran-lang.discourse.group/u/general_rishkin)\
**Post date:** [July 8, 2024, 4:13pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/1 "2024-07-08T16:13:01Z")

</div>

Do you have to do something special to export a subroutine as a symbol in the library created by fpm?

For example, just running `fpm build` on the scaffolded project from `fpm new test_lib_symbol` and looking at the symbols in `libtest_lib_symbol.a` in the build directory with:

> nm -gD build/gfortran\_xxxxxxxxx/test\_lib\_symbol/test\_lib\_symbol.a

produces no symbols for the customary `say_hello` subroutine.

I did also set

> library = true

in fpm.toml.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [July 8, 2024, 6:37pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/2 "2024-07-08T18:37:45Z")

</div>

The scaffold project puts the subroutine in a module. Module procedure’s do not have predictable symbols in the produced libraries/object files (or at least their names are compiler specific). If you want to make use of procedure in a module, you should `use` that module to make the name available. This is best practice in modern Fortran. I.e.

```fortran
module example_mod
contains
  subroutine example_sub
    print *, "Hello, World!"
  end subroutine
end module

program example
use example_mod, only: example_sub
call example_sub
end program

```

---

<div class="post-metadata">

**Author:** ![general\_rishkin](https://avatars.discourse-cdn.com/v4/letter/g/a9a28c/32.png) [@general\_rishkin](https://fortran-lang.discourse.group/u/general_rishkin)\
**Post date:** [July 8, 2024, 7:16pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/3 "2024-07-08T19:16:32Z")

</div>

Thanks @everythingfunctional .

The reason I was looking for the symbol in the generated (static) library, which I converted to a shared library is because I would like to call the subroutine (e.g., your example\_sub) from another programming language.

However, I kept getting symbol not defined error so I checked for it with `nm -gD library_name`. and `objdump -TC library_name`. Both showed no symbols defined.

So, I was wondering if `fpm` was not generating the library correctly or maybe I am failing to do something on my end.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [July 8, 2024, 7:26pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/4 "2024-07-08T19:26:49Z")

</div>

> [@general\_rishkin](#):
>
> I would like to call the subroutine (e.g., your example\_sub) from another programming language.

In that case, use the C-interoperability features of the language and give the procedure the `bind(C)` attribute. I.e.

```auto
module example_mod
contains
  subroutine example_sub() bind(C, name="example_sub")
    print *, "Hello from Fortran!"
  end subroutine
end module

```

```C
void example_sub();
int main(int argv, char* argc) {
  example_sub();
  return 0;
}

```

---

<div class="post-metadata">

**Author:** ![general\_rishkin](https://avatars.discourse-cdn.com/v4/letter/g/a9a28c/32.png) [@general\_rishkin](https://fortran-lang.discourse.group/u/general_rishkin)\
**Post date:** [July 8, 2024, 7:32pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/5 "2024-07-08T19:32:46Z")

</div>

This works perfectly standalone, i.e., if I take your code and create a shared library from it but when I use fpm to generate a library because I use other dependencies like odepack, etc, the final generated library through fpm does not work.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [July 8, 2024, 9:32pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/6 "2024-07-08T21:32:27Z")

</div>

Do you have a specific code example and error message you can share?

---

<div class="post-metadata">

**Author:** ![general\_rishkin](https://avatars.discourse-cdn.com/v4/letter/g/a9a28c/32.png) [@general\_rishkin](https://fortran-lang.discourse.group/u/general_rishkin)\
**Post date:** [July 9, 2024, 8:46am UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/7 "2024-07-09T08:46:08Z")

</div>

This can be done from any project.

1. Generate any new project with **fpm new A**.
2. Set library = true in fpm.toml so that it builds a library.
3. Then **fpm build** or **fpm run**.
4. Search for the generated library.
5. Then **nm -gD library\_name** or **objdump -TC library\_name**. You could also convert the generated static library (\*.a) to a shared one (.so) first with  
_gfortran -shared -fPIC -o new\_shared\_library.so -lgenerated\_static\_library_

We are looking for the _ **say\_hello** _ subroutine in the symbol list, which comes with the scaffolded project. If it is there, it can be called from another language but if it is not, then you will always get symbol not found or unable to find entry point when you compile and run from the other language.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [July 9, 2024, 2:09pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/9 "2024-07-09T14:09:57Z")

</div>

Correct, but it seems to work fine for me, so I’m not sure what you’re doing differently. I.e.

```plaintext
$ fpm new --lib callable_library               
 + mkdir -p callable_library
 + cd callable_library
 + mkdir -p callable_library/src
 + git config --get user.name > /tmp/file1fm3vp
 + git config --get user.email > /tmp/fileugTyij
 + git config --get user.name > /tmp/fileupi3He
 + git init callable_library
Initialized empty Git repository in /home/brad/scratch/callable_library/.git/
$ cd callable_library 
$ vim src/callable_library.f90
$ cat src/callable_library.f90
module callable_library
  implicit none
  private

  public :: say_hello
contains
  subroutine say_hello() bind(c)
    print *, "Hello, callable_library!"
  end subroutine say_hello
end module callable_library
$ fpm build
callable_library.f90 done.
libcallable_library.a done.
[100%] Project compiled successfully.
$ nm `find build -name libcallable_library.a`

src_callable_library.f90.o:
                 U _gfortran_st_write
                 U _gfortran_st_write_done
                 U _gfortran_transfer_character_write
0000000000000000 T say_hello
                 U __stack_chk_fail

```

As I mentioned upthread, note that I added the `bind(c)` attribute to the subroutine. You must use the C interoperability features to make it valid to call Fortran procedures from other languages.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 9, 2024, 4:04pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/10 "2024-07-09T16:04:51Z")

</div>

> [@everythingfunctional](#):
>
> `subroutine say_hello() bind(c)`

It is the bind clause that does the trick. I think in this case it is just a compiler convention that the the external symbol is “say\_hello” in lower case. If the fortran code had been written as “SAY\_HELLO” or “Say\_Hello” or any other case combination, the same external symbol would have been generated with that compiler. Another compiler might generate the upper case symbol, or it might use some other mixed-case convention. To fully specify the external name and to be independent of compiler, loader, and OS conventions, the `name='say_hello'` argument should be added to the bind clause. **[edit: this paragraph is incorrect, there is a defined convention. See below.]**

Having said all that, i must admit that I am often faced with several choices for how interfaces are defined and/or specified when using C interop features. Some of this is because the C language itself treats array references and pointer references equivalently, so there is nothing that fortran can do to eliminate that aspect. Is there a good online reference, or even a tutorial, on how best to use the C interop features of fortran?

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [July 9, 2024, 4:53pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/11 "2024-07-09T16:53:04Z")

</div>

> [@RonShepard](#):
>
> I think in this case it is just a compiler convention that the the external symbol is “say\_hello” in lower case.

The standard actually says, in Sec. 18.10.2 Binding labels for procedures,

> If a procedure has the BIND attribute with no NAME= specifier, and the procedure is not a dummy procedure, internal procedure, or procedure pointer, then the binding label of the procedure is the same as the name of the procedure using lower case letters.

In the old days yes, it was compiler specific what the symbol for an external procedure was. Some did all lower case, some did all upper case, some appended a single `_`, some didn’t, etc. With the `bind` attribute, the standard says what it is by default, and the user can dictate if they want something different.

> [@RonShepard](#):
>
> Is there a good online reference, or even a tutorial, on how best to use the C interop features of fortran?

I’ve generally pieced it together as I’ve gone. I think I’ve seen one or two people say they were putting something together, but I don’t remember if or where those got posted. If there’s enough interest from NERSC users I could do a training session on the topic.

---

<div class="post-metadata">

**Author:** ![general\_rishkin](https://avatars.discourse-cdn.com/v4/letter/g/a9a28c/32.png) [@general\_rishkin](https://fortran-lang.discourse.group/u/general_rishkin)\
**Post date:** [July 9, 2024, 6:10pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/12 "2024-07-09T18:10:13Z")

</div>

Thanks @everythingfunctional and @FedericoPerini . It works now following your examples.

The only problem I have now is on the non-Fortran side with “undefined symbol: \_gfortran\_cfi\_desc\_to\_gfc\_desc” but that is probably due to allocations on the Fortran side. So, I have to finally learn FFI with C descriptors.

@everythingfunctional: If you do a training session, could you make it a hybrid session so I and others could join online.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [July 9, 2024, 6:28pm UTC](https://fortran-lang.discourse.group/t/exporting-subroutine-symbol-in-library-from-fpm/8321/13 "2024-07-09T18:28:35Z")

</div>

> [@general\_rishkin](#):
>
> The only problem I have now is on the non-Fortran side with “undefined symbol: \_gfortran\_cfi\_desc\_to\_gfc\_desc” but that is probably due to allocations on the Fortran side. So, I have to finally learn FFI with C descriptors.

You may also need a `-lgfortran` flag if you’re not using gfortran for linking the executable.

> [@general\_rishkin](#):
>
> @everythingfunctional: If you do a training session, could you make it a hybrid session so I and others could join online.

NERSC training sessions are usually virtual these days, but are typically restricted to DOE computing facility users for attendance. That said, they’re pretty much always recorded and posted publicly on [NERSC’s YouTube channel](https://www.youtube.com/@theRealNERSC).
