MantisBT - CMake
View Issue Details
0014870CMakeCMakepublic2014-04-09 16:222014-10-06 10:33
Melven Roehrig-Zoellner 
Brad King 
normalmajoralways
closedfixed 
x86_64LinuxopenSUSE 13.1
CMake 2.8.12 
CMake 3.0CMake 3.0 
0014870: FindMPI.cmake returns 32-bit libraries on 64-bit systems for Fortran-only projects
Linker errors for pure Fortran projects using MPI because find_package(MPI)
adds a 32-bit library to MPI_Fortran_LIBRARIES.
This occurs with the PGI-Compilers, but could also affect other compilers/MPI-versions.

This affects at least CMake 2.8.11 and 2.8.12
Minimal CMakeLists-example:

project(test Fortran)
find_package(MPI REQUIRED)
message(STATUS ${MPI_Fortran_LIBRARIES})

For PGI-Fortran-Compilers:
This shows: [...]/usr/lib/librt.so
But must be: [...]/usr/lib64/librt.so
So Linking with MPI_Fortran_LIBRARIES produces linker errors.

In FindMPI.cmake system libraries are searched in /usr/lib and not in /usr/lib64. One can circumvent this bug through enabling C/C++, but this is not always an option (I only have a PGI Fortran License)
Possible bugfix:
In FindMPI.cmake replace:
        # add the compiler implicit directories because some compilers
        # such as the intel compiler have libraries that show up
        # in the showme list that can only be found in the implicit
        # link directories of the compiler. Do this for C++ and C
        # compilers if the implicit link directories are defined.
        if (DEFINED CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES)
          set(MPI_LINK_PATH
            "${MPI_LINK_PATH};${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}")
        endif ()

        if (DEFINED CMAKE_C_IMPLICIT_LINK_DIRECTORIES)
          set(MPI_LINK_PATH
            "${MPI_LINK_PATH};${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
        endif ()
by the respective language-specific variant:
        # add the compiler implicit directories because some compilers
        # such as the intel compiler have libraries that show up
        # in the showme list that can only be found in the implicit
        # link directories of the compiler.
        if (DEFINED CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES)
          set(MPI_LINK_PATH
            "${MPI_LINK_PATH};${CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES}")
        endif ()
No tags attached.
related to 0010119closed Brad King 64-bit libraries not found with Fortran project 
? FindMPI.cmake (29,702) 2014-04-09 16:22
https://public.kitware.com/Bug/file/5126/FindMPI.cmake
Issue History
2014-04-09 16:22Melven Roehrig-ZoellnerNew Issue
2014-04-09 16:22Melven Roehrig-ZoellnerFile Added: FindMPI.cmake
2014-04-10 10:26Brad KingRelationship addedrelated to 0010119
2014-04-10 10:33Brad KingNote Added: 0035666
2014-04-10 12:10Melven Roehrig-ZoellnerNote Added: 0035667
2014-04-10 12:10Melven Roehrig-ZoellnerNote Edited: 0035667bug_revision_view_page.php?bugnote_id=35667#r1444
2014-04-10 12:11Melven Roehrig-ZoellnerNote Edited: 0035667bug_revision_view_page.php?bugnote_id=35667#r1445
2014-04-10 12:40Brad KingNote Added: 0035668
2014-04-10 12:40Brad KingNote Edited: 0035668bug_revision_view_page.php?bugnote_id=35668#r1447
2014-04-10 15:09Melven Roehrig-ZoellnerNote Added: 0035673
2014-04-11 08:48Brad KingNote Added: 0035674
2014-04-11 09:16Brad KingNote Added: 0035676
2014-04-11 10:01Brad KingNote Added: 0035677
2014-04-12 05:02Melven Roehrig-ZoellnerNote Added: 0035678
2014-04-14 08:55Brad KingNote Added: 0035688
2014-04-14 08:55Brad KingAssigned To => Brad King
2014-04-14 08:55Brad KingStatusnew => resolved
2014-04-14 08:55Brad KingResolutionopen => fixed
2014-04-14 08:55Brad KingFixed in Version => CMake 3.0
2014-04-14 08:55Brad KingTarget Version => CMake 3.0
2014-10-06 10:33Robert MaynardNote Added: 0036970
2014-10-06 10:33Robert MaynardStatusresolved => closed

Notes
(0035666)
Brad King   
2014-04-10 10:33   
As discussed in 0010119, the real problem is that CMake is not detecting that this compiler targets a 64-bit architecture. For C and C++ a simple test of sizeof(void*) is sufficient:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeCompilerABI.h;hb=v3.0.0-rc3 [^]

For Fortran there is no "pointer" type to test so we have to rely on knowledge of preprocessor definitions provided by compilers for 64-bit architectures:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeFortranCompilerABI.F;hb=v3.0.0-rc3 [^]

Does this compiler provide a 64-bit-only preprocessor definition we could test there?
(0035667)
Melven Roehrig-Zoellner   
2014-04-10 12:10   
(edited on: 2014-04-10 12:11)
I don't know how (and if) cmake detects that the PGI compiler targets a 64-bit arch here, but the bugfix above works.
CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES contains here with PGI: /opt/pgi/linux86-64/14.1/lib;/usr/lib64;/usr/lib64/gcc/x86_64-suse-linux/4.8

The CMakeFortranCompilerABI.F doesn't detect the target arch here with PGI.

But at least recent GNU-, PGI- and Intel-Fortran compilers support the iso_c_binding intrinsic module and the non-standard extension cloc, which allows us to calculate the size of C void pointers:
  module ctest_mod
    implicit none
  contains
    subroutine ctest(cptr) bind(C)
      use, intrinsic :: iso_c_binding, only: C_PTR, c_loc
      type(C_PTR), target :: cptr(2)
      ! the c_loc from iso_c_binding does possible not allow pointer arithmetic,
      ! loc is a non-standard extension in at least GNU , PGI and Intel Fortran compilers
      write(*,*) loc(cptr(2)) - loc(cptr(1))
    end subroutine ctest
  end module ctest_mod

  program test
    use, intrinsic :: iso_c_binding, only: C_PTR, C_NULL_PTR
    use ctest_mod
    type(C_PTR), target :: cptr(2) = C_NULL_PTR

    call ctest(cptr)

  end program test

(0035668)
Brad King   
2014-04-10 12:40   
Re 0014870:0035667: The proposed patch is a hack that will only work for FindMPI and only if it happens to be installed where the compiler looks. All other Find modules will have the same problem. The correct fix is to get CMake to detect that the compiler is targeting a 64-bit architecture. It cannot depend on *running* a small test program built with the compiler, at most on compiling one.

Please try the patch below:

diff --git a/Modules/CMakeFortranCompilerABI.F b/Modules/CMakeFortranCompilerABI.F
index 21ca7ff..15fc60a 100644
--- a/Modules/CMakeFortranCompilerABI.F
+++ b/Modules/CMakeFortranCompilerABI.F
@@ -10,6 +10,8 @@
         PRINT *, 'INFO:sizeof_dptr[8]'
 #elif defined(_M_AMD64)
         PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(__x86_64__)
+        PRINT *, 'INFO:sizeof_dptr[8]'
 
 #elif defined(_ILP32)
         PRINT *, 'INFO:sizeof_dptr[4]'


(0035673)
Melven Roehrig-Zoellner   
2014-04-10 15:09   
The patch in 0014870:0035668 works fine!
This also solves the original problem.


Concerning my proposed changes in 0014870:
The current code in FindMPI.cmake still seems strange to me: why for Fortran consider CMAKE_C_IMPLICIT_LINK_DIRECTORIES and CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES and not CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES?
(0035674)
Brad King   
2014-04-11 08:48   
Re 0014870:0035673: Sorry, I didn't realize the module was already using CMAKE_(C|CXX)_IMPLICIT_LINK_DIRECTORIES and that you were simply proposing to use CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES instead. I see the existing use was added here:

 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2f9ad7c6 [^]

Yes, changing to ${lang} is a reasonable proposal.
(0035676)
Brad King   
2014-04-11 09:16   
Meanwhile I've applied the pointer size patch:

 Fortran: Detect pointer size on Intel archs with PGI
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=eb8cb2c6 [^]
(0035677)
Brad King   
2014-04-11 10:01   
I've applied the proposed implicit link dir change:

 FindMPI: Use compiler implicit link dirs for matching language
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=856bfe23 [^]
(0035678)
Melven Roehrig-Zoellner   
2014-04-12 05:02   
The last nightly build (973b3e7d) works fine, as expected. Thanks!
So this issue can be closed...
(0035688)
Brad King   
2014-04-14 08:55   
The change from 0014870:0035676 will be in v3.0.0-rc4.
(0036970)
Robert Maynard   
2014-10-06 10:33   
Closing resolved issues that have not been updated in more than 4 months.