I made a minor refactoring change to a large code project and suddenly, BOOM, tons of link errors. After spending a lot of time trying to debug, I've concluded this is a linker/module problem. I think I've seen the problem discussed online years ago, but I couldn't find any good references.
With a simple, data-only module with no default initializers, linking on Mac OS X fails if the object file for the module is in a static library. Consider two separate source files:
module.f90:
module mod implicit none real(8) :: array(1000) contains subroutine Init() array(:) = 0 end subroutine end module
main.f90:
program main use mod array(2) = 1 print *, array(1:2) end program
Compiling together works fine:
$ ifort module.f90 main.f90
$ ./a.out
0.000000000000000E+000 1.00000000000000
Compiling and linking separately also works fine:
$ ifort -c module.f90 main.f90
$ ifort main.o module.o
$ ./a.out
0.000000000000000E+000 1.00000000000000
But if the module is in a library, BOOM:
$ libtool -static -o libmod.a module.o
$ ifort main.o libmod.a
Undefined symbols for architecture x86_64:
"_mod_mp_array_", referenced from:
_MAIN__ in main.o
ld: symbol(s) not found for architecture x86_64
If the module is changed to have a default initializer, (i.e. real(8) :: array(1000) = 0) then linking through a static library works. Similarly, if the main routine is changed to call the module procedure Init(), then linking also works.
It appears that the system linker on Mac OS X ignores any static library objects that won't invoke executable code.
Is there a good way to guard against this problem in the future (other than remembering)?
Link Copied
It's not "executable code", but rather the initializer. As you found out, the Apple linker won't pull in an object from a library if the only reference is to an uninitialized global variable. The Apple linker has some other quirks as well that give Fortran users headaches.
Thanks Steve. That's what I suspected but just couldn't find the old posts to confirm. When it happens in a large project, it can be hard to pin down.
For more complete information about compiler optimizations, see our Optimization Notice.