Reputation: 137
I'm trying to compile some fortran code and I'm running into some confusing linking errors. I have some code that I compile and place into a static library:
>gfortran -c -I../../inc -o bdout.o bdout.F
>ar rv libgeo.a bdout.o
I then try to compile against that library with some simple test code and get the following:
>gfortran -o mytest -L -lgeo mytest.F
/tmp/cc4uvcsj.o: In function `MAIN__':
mytest.F:(.text+0xb0): undefined reference to `ncwrite1_'
collect2: ld returned 1 exit status
It's not in the object naming because everything looks fine:
>nm -u libgeo.a
bdout.o:
U _gfortran_exit_i4
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character
U _gfortran_transfer_integer
U ncobjcl_
U ncobjwrp_
U ncopencr_
U ncopenshcr_
U ncopenwr_
U ncwrite1_
U ncwrite2_
U ncwrite3_
U ncwrite4_
U ncwritev_
I can check the original object file too:
>nm -u bdout.o
U _gfortran_exit_i4
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character
U _gfortran_transfer_integer
U ncobjcl_
U ncobjwrp_
U ncopencr_
U ncopenshcr_
U ncopenwr_
U ncwrite1_
U ncwrite2_
U ncwrite3_
U ncwrite4_
U ncwritev_
The test code simply contains a single call to a function defined in bdout.o:
program hello
print *,"Hello World!"
call ncwrite1( istat, f, ix2, ix3, ix4, ix5, ih )
end program hello
I can't figure out what the problem is. Does anyone have any suggestions? Maybe even just a way to track the problem down?
Cheers.
Upvotes: 2
Views: 1529
Reputation: 137
First, thanks to everyone who answered. I'm posting to put an official end to this thread. It turns out that the person who wrote the library (libgeo.a) had placed several #ifdef statements in the code that were turned on using compiler flag macros -D(macro). These #ifdef's would then be used to expand the function names with specific parameters. Without supplying the appropriate macros to the compiler the function names were left unexpanded, and The symbols were thus undefined. Grrrr...
Upvotes: 0
Reputation: 137557
The problem is that you're not linking against the library that contains that function. There are two possible reasons for this:
ncwrite1
function isn't defined in the libraries that you are linking against. Use nm
to verify that this is (or is not) the case.If we assume that the geo library has the function you're after (check that!) then you should build and link like this:
gfortran -o mytest -L. mytest.F -lgeo
Upvotes: 1
Reputation: 37188
Don't know if this helps this particular issue, but generally, always put the linker commands AFTER the object files. Secondly, if libgeo.a is in the current directory, you need to add that explicitly, an empty -L AFAIK does nothing. I.e.
gfortran -o mytest mytest.F -L. -lgeo
EDIT: Also note that the "U" in the nm output means that the symbol is undefined. I.e. that the .o file references said symbol, but the symbol is actually in some other file. I.e. you might need to explicitly link in the library that defines the ncwrite1_ symbol.
Upvotes: 1
Reputation: 78316
The problem may be that the call to ncwrite1 does not match the signature of the library definition of the subroutine and what the error message is really trying to tell you is that it can't find a version of ncwrite1 with a signature to match the call. Your program doesn't seem to use an explicit interface to ncwrite1 so type errors like this won't be caught at compile-time.
Upvotes: 0