0

Based on this SO post I want to create software with gcc which uses mixed language source code, e.g. C and Fortran. While the linking of the generated object files works fine, the linker gives me the following error if I use a static or shared library instead of the object file:

/usr/bin/ld: /tmp/ccdqJ6hY.o: in function `MAIN__':
hello.f90:(.text+0x76): undefined reference to `fun'
collect2: error: ld returned 1 exit status

This is my C library source code file fun.c:

#include <stdio.h>
void fun(void) {
  printf("Hello from C function.\n");
}

This is my Fortran source code hello.f90:

program hello
  print *, "Hello from Fortran program."
  call fun()
end

This is my build script:

#! /bin/sh
#
gcc -c fun.c                     # Create object file of C library
ar r libfun.a fun.o              # Create static C library 
gcc -shared -o libfun.so fun.o   # Create shared/dynamic linked C library
#
gfortran -fno-underscoring -o hello1 fun.o hello.f90                      # This works.
#
gfortran -fno-underscoring -o hello2 -L. -Wl,-rpath=`pwd` -lfun hello.f90 # This fails.
#
gfortran -fno-underscoring -o hello3 -L. libfun.a hello.f90               # This fails.

The symbol name fun is fine in the libraries as indicated by nm:

$ nm libfun.a

fun.o:
0000000000000000 T fun

I'm using gcc version gcc (Debian 10.2.1-6) 10.2.1 20210110 on Debian GNU/Linux 11 (bullseye).

I suppose that something with my gcc configuration might be broken, but I have no glue, what. Could you give me any advice, please?

CKE
  • 1,533
  • 19
  • 18
  • 29
  • You'll be much better off in the longer term using the [Fortran-C interoperability](https://stackoverflow.com/tags/fortran-iso-c-binding/info) which has been standardized for nearly two decades now, instead of using non-portable and non-standard compiler-level hacks. Is there a particular reason you wish to resort to the latter here? – francescalus Jun 25 '22 at 12:36
  • If I work on Windows, then I follow the standardized Fortran-C interoperability. Now I'm just curious how this works on Linux. I thought that it's much more comfortable as `gcc` supports all my desired programming languages. Reading related posts on SO, as [this one](https://stackoverflow.com/q/44591695/9222996) underline my expectation. But unfortunately something is going wrong during linking on my machine:(. – CKE Jun 25 '22 at 12:45
  • What do you mean by "the standardized Fortran-C interoperability" in particular? Just use `bind(C, name="")`. There is no problem on either operating system. `-fno-underscoring` is just a hack and an ugly one. – Vladimir F Героям слава Jun 25 '22 at 12:57
  • GCC has supported Fortran 2003's interoperability for a very long time (and recent versions support most of Fortran 2018's), Linux and elsewhere. There doesn't seem to be much point using non-portable, compiler-specific options when the standard exists so that the same thing that you have working on one systems works in exactly the same way somewhere else? – francescalus Jun 25 '22 at 12:58
  • These are all valid points. Thanks for your comments. Nevertheless I'm afraid that they will fix my linker problem on `gcc`. – CKE Jun 25 '22 at 13:12
  • I would really appreciate if someone could take my code snippets, just try them on his or her machine and post any feedback as "is working/not working", gcc version, Linux version as well as hints where I can check the proper installation and configuration of `gcc`. Thanks. – CKE Jun 25 '22 at 14:02
  • 3
    You have deviated from the linked example by using a static instead of a shared library. With static libraries the order in which the various objects are listed on the command line is much more significant than with shared (as detailed in the linked post and several related ones): put `hello.f90` before the library. – francescalus Jun 25 '22 at 14:28
  • This works:) Thanks a lot, Frau Doktor. So the order of the source and library files matters for the `gcc` linker. The dependent files must be placed before the independent ones. Therefore 2 lines of my build script have to be changed to this: `gfortran -fno-underscoring -o hello2 <...> hello.f90 -lfun # This works.` and `gfortran -fno-underscoring -o hello3 -L. hello.f90 libfun.a # This works.`. Thanks again. – CKE Jun 26 '22 at 05:17

0 Answers0