Wed, 22 Apr 2009
At work I've been promoting the use of pkg-config and modules to solve the problems of avoiding hard-coded paths and an environment where we've multiple compilers. In summary, "module load intel-cc" to load the intel compiler, "module load netcdf-intel" to, which among other things appends /ichec/packages/netcdf/4.0-intel/pkgconfig to $PKG_CONFIG_PATH, and then:
NCDF_INCS := `pkg-config netcdf --cflags` NCDF_LIBS := `pkg-config netcdf --libs`in the application code. Replace "intel-cc" and "netcdf-intel" with "gcc" and "netcdf-gcc", and it builds with gcc.
This would work better if upstream supplied .pc files, which means the next stage in world domination is to send patches to do just that. But it's not that easy, apparently.
netcdf (for example) supplies two libraries, libnetcdf.so and libnetcff.so, with the second including code only needed for Fortran. So, for gcc I have the following netcdf file:
prefix=/ichec/packages/netcdf/4.0-gcc
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: netcdf
Description: netCDF libraries, include files and development tools (gcc version)
Version: 4.0
Libs: -L${libdir} -Wl,--as-needed -lnetcdf -lnetcdff
Cflags: -I${includedir}
While for Intel I have:
prefix=/ichec/packages/netcdf/4.0-intel
# Add fortran libs
forlibs=/ichec/packages/intel/fce/11.0.081/lib/intel64
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: netcdf
Description: netCDF libraries, include files and development tools
Version: 4.0
Libs: -L${libdir} -lnetcdf -L${forlibs} -lnetcdff -lifcore
Cflags: -I${includedir}
The main problem is that --as-needed is not understood by non GNU-ld linkers, and must be conditionally removed somehow. Any ideas ? (There is a second wrinkle of needing to add additional libraries for Intel Fortran here, but I'm sure I can remove that with the addition of more .pc files.).
A second issue is that --as-needed can break otherwise working pkg-config usages. Thanks to galtgendo at PhP Bugs for this example:
alastair@ailm:~$ cc -o testx -Wl,--as-needed `pkg-config glib-2.0 --cflags` test.c `pkg-config glib-2.0 --libs`works, but:
alastair@ailm:~$ cc -o testx -Wl,--as-needed `pkg-config glib-2.0 --cflags` `pkg-config glib-2.0 --libs` test.c /tmp/ccsUEwtk.o: In function `main': test.c:(.text+0x20): undefined reference to `g_print' collect2: ld returned 1 exit statusThe problem being that --as-needed removes libraries as unnecessary before the linker sees the test.o code.