MantisBT - CMake
View Issue Details
0014647CMakeCMakepublic2013-12-13 17:112016-06-10 14:31
Sean Patrick Santos 
Kitware Robot 
normalminoralways
closedmoved 
CMake 2.8.11.1 
 
0014647: Inconsistency in the way shared libraries are passed to Fortran vs C linker
When "target_link_libraries" is called with the full path to a shared file (at least in my case, which is a .so on a Linux system), the behavior is different depending on whether a Fortran or a C compiler is being used for the actual linking step.

For a C compiler, the full path "/usr/lib64/libm.so", gets translated to a simple "-lm" option.

For the Fortran compiler, though, the full path is retained.

In most cases, I haven't even noticed this, because ultimately both end up working. But I've found encountered bugs due to compiler wrappers that behave differently in the two cases. For this reason, I wanted to suggest that this inconsistency should be resolved one way or the other, unless there's a specific reason why the two cases need to be treated differently.
No tags attached.
Issue History
2013-12-13 17:11Sean Patrick SantosNew Issue
2013-12-18 11:13Brad KingNote Added: 0034786
2013-12-18 12:56Sean Patrick SantosNote Added: 0034793
2013-12-18 15:10Brad KingNote Added: 0034799
2013-12-18 15:16Sean Patrick SantosNote Added: 0034800
2013-12-18 15:36Brad KingNote Added: 0034802
2013-12-18 15:40Brad KingNote Added: 0034804
2013-12-18 16:04Sean Patrick SantosNote Added: 0034809
2013-12-19 14:18Brad KingNote Added: 0034829
2013-12-19 14:18Brad KingStatusnew => backlog
2016-06-10 14:29Kitware RobotNote Added: 0042447
2016-06-10 14:29Kitware RobotStatusbacklog => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:29Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0034786)
Brad King   
2013-12-18 11:13   
As explained here:

 http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/8795/focus=8812 [^]

CMake converts libraries in implicit linker search paths to the "-lm" form.

The difference you see must be due to which directories are detected as implicitly passed to the linker by the compiler front-end. Look under the CMakeFiles/2.8.11.1 directory at the top of the build tree for "CMake*Compiler.cmake" files. Inside there are variables like CMAKE_C_IMPLICIT_LINK_DIRECTORIES. What are they for C and Fortran?
(0034793)
Sean Patrick Santos   
2013-12-18 12:56   
Here are the IMPLICIT_LINK variables for a system where I found the same effect with 2.8.10.2.

This is not the same as the system where I originally found the issue, but this machine has simpler settings. Note that I'm working on HPC systems where these paths can be quite long.

set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "netcdf_c++;netcdff;netcdf;mpi;dl;pthread;rt;c")
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/glade/apps/el6/usr/lib;/glade/apps/el6/usr/lib64;/glade/apps/opt/ncl/6.1.2/gnu/4.4.6/lib;/glade/apps/opt/netcdf/4.3.0/gnu/4.7.2/lib;/opt/ibmhpc/pecurrent/mpich2/gnu/lib64;/glade/u/apps/opt/gnu/4.7.2/lib/gcc/x86_64-unknown-linux-gnu/4.7.2;/glade/u/apps/opt/gnu/4.7.2/lib64;/lib64;/usr/lib64;/glade/u/apps/opt/gnu/4.7.2/lib")

set(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES "netcdf_c++;netcdff;netcdf;gfortran;m;quadmath;m;c")
set(CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES "/glade/apps/el6/usr/lib;/glade/apps/el6/usr/lib64;/glade/apps/opt/ncl/6.1.2/gnu/4.4.6/lib;/glade/apps/opt/netcdf/4.3.0/gnu/4.7.2/lib;/glade/u/apps/opt/gnu/4.7.2/lib/gcc/x86_64-unknown-linux-gnu/4.7.2;/glade/u/apps/opt/gnu/4.7.2/lib64;/lib64;/usr/lib64;/glade/u/apps/opt/gnu/4.7.2/lib")


Note that this actually shows up for multiple compilers, and even for a BlueGene system that I've checked, which was why I was inclined to think that there's something that's explicitly treating C and Fortran differently.

But in fact there are differences between some static libraries too, so I was wrong in thinking that this was a shared library issue originally.
(0034799)
Brad King   
2013-12-18 15:10   
Re 0014647:0034793: Both the C and Fortran values you report list "/usr/lib64" so I would expect "/usr/lib64/libm.so" to become "-lm" in both cases. Does the difference occur in the build tree where you got these values?
(0034800)
Sean Patrick Santos   
2013-12-18 15:16   
Yes, they are the same build tree. And in fact I see the same conditions repeating on other systems and with other libraries besides libm.

As far as I can tell, CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES does not cause *any* absolute library paths to be converted to "-l" options when linking with the Fortran compiler, at least in CMake 2.8.10 and 2.8.11. So maybe that is the real bug here.
(0034802)
Brad King   
2013-12-18 15:36   
It looks like conversion never occurs for Fortran. The conversion takes place in cmComputeLinkInformation::CheckImplicitDirItem here:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmComputeLinkInformation.cxx;hb=v2.8.12.1#l1176 [^]

but only if LinkTypeEnabled is true. That is set here:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmComputeLinkInformation.cxx;hb=v2.8.12.1#l808 [^]

by looking up the CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS value for the current target type and linker language. Those values are set in the Modules/Platform/*.cmake files for C. For CXX they are copied from C here:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeCXXInformation.cmake;hb=v2.8.12.1#l184 [^]

There is no equivalent in Modules/CMakeFortranInformation.cmake, and that bug propagates back through all the above steps to result in not converting library linking in implicit directories.
(0034804)
Brad King   
2013-12-18 15:40   
To test my hypothesis in 0014647:0034802, add this to your project code:

 foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
  set(CMAKE_${type}_LINK_STATIC_Fortran_FLAGS "-Wl,-Bstatic")
  set(CMAKE_${type}_LINK_DYNAMIC_Fortran_FLAGS "-Wl,-Bdynamic")
 endforeach()

(with whatever are the proper flags). Does it make Fortran linking use the "-lm" form?
(0034809)
Sean Patrick Santos   
2013-12-18 16:04   
Yes, that did the trick.
(0034829)
Brad King   
2013-12-19 14:18   
Unfortunately I think there are several Fortran compilers that do not recognize the same options their C compiler uses (like -Wl,-Bstatic) for specifying the library search path. The flag mapping for this language will have to be added to the information file for each compiler/platform combo.

Moving to backlog for now.
(0042447)
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.