Static linking and linker search paths

All, Conor's problems on OSX with libiconv reminds me of something I've been thinking about for a little while. So the problem is that the semantics of static linking does not at all match what we really want. We can easily accidentally "interpose" a wrong library in place of the one we wanted. In the iconv case people have hit recently we've got this situation: libHSbase-4.2.0.0.a contains references to _iconv_open, _iconv, _iconv_close ${system}/libiconv.a ${macports}/libiconv.a When the code for libHSbase was built, it was against the header files for the standard system version of iconv on OSX. Thus it is intended that we link against the system version of iconv. No suppose by default that the system is set up such that only the system iconv is found by default. So I am assuming there is no LD_LIBRARY_PATH or similar set. Then when we link something then we correctly resolve the references in base to the system iconv lib. When we call gcc to link we're doing something like: -L${ghclibdir} -lHSbase-4.2.0.0.a -liconv Now suppose we build some FFI package (libHSfoo-1.0.a) that provides a binding to a C lib installed via macports (libfoo.a). When we link a program that depends indirectly on this FFI package then the gcc linker line is like: -L${ghclibdir} -L/opt/local/lib -lHSfoo-1.0.a -lfoo -lHSbase-4.2.0.0.a -liconv and now it all breaks. We're asking the linker to look in /opt/local/lib first for *all the remaining libraries* and that includes iconv, so we pick up the wrong iconv. Our intention was just to look for -lfoo using /opt/local/lib, but we cannot express that to the linker. The problem is that our notion of library dependencies is hierarchical but for the system linker it is linear. We know that package foo-1.0 needs the C library libfoo.a and that it should be found by looking in /opt/local/lib. But we end up asking the linker to look there first for all other libs too, including for the -liconv needed by the base package. The registration for the base package never mentioned /opt/local/lib of course. What we'd really like to say is something like: link HSfoo-1.0.a push search path /opt/local/lib link foo pop search path If we think we know enough about the behaviour of the system linker and its search path then we could do just: -L${ghclibdir} -lHSfoo-1.0.a /opt/local/lib/libfoo.a -lHSbase-4.2.0.0.a -liconv that is, specify the .a file exactly by fully resolved path and not add anything to the linker search path. (Actually we'd do it for the libHS*.a ones too since we know precisely where they live) The possible danger is that how we search for the library and how the system linker searches for it might not match exactly and we could end up sowing confusion. Worth thinking about anyway. Note that some of this is different for shared libs. Duncan
participants (1)
-
Duncan Coutts