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 mod implicit none real(8) :: array(1000) contains subroutine Init() array(:) = 0 end subroutine end module
program main use mod array(2) = 1 print *, array(1:2) end program
Compiling together works fine:
$ ifort module.f90 main.f90
Compiling and linking separately also works fine:
$ ifort -c module.f90 main.f90
$ ifort main.o module.o
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)?
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.