ResolveCompilerPaths bug

Issue #151 resolved
Nico Schlömer created an issue

When FindPETSc.cmake calls resolve_compiler_path, it converts

PETSC_LIB: -L/opt/petsc/dev//lib -lpetsc

to

PETSC_LIBRARIES: /usr/lib/libpetsc.so

Both are indeed installed, but really you'd expect to get /opt/petsc/lib/libpetsc.so.

Comments (26)

  1. Nico Schlömer reporter

    I was able to resolve this by adding the NO_CMAKE_PATH keyword to the find_library call in ./cmake/modules/ResolveCompilerPaths.cmake. According to CMake's documentation (http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:find_library), by default find_library searches "paths specified in cmake-specific cache variables." The way I interpret the code in ./cmake/modules/ResolveCompilerPaths.cmake, I suppose the original author intended for HINTS to take precedence of everything else.

    I'm not entirely sure what the purpose of ResolveCompilerPaths is anyhow. Shouldn't finding out about the correct link line be CMake's job?

  2. Nico Schlömer reporter

    I see that there's some similar hacking for Boost, specifically set(Boost_NO_SYSTEM_PATHS on) which "disable[s] searching in locations not specified by the[se] hint variables."

    The issue described above is a different one though since it only concerns ResolveCompilerPaths.cmake (used in FindPETSc.cmake, FindSLEPc.cmake, FindTAO.cmake only).

  3. Johannes Ring

    You can also run cmake with -DPETSC_LIBRARIES:STRING=/opt/petsc/lib/libpetsc.so as a workaround.

  4. Johannes Ring

    Sorry, setting PETSC_LIBRARIES does not work since it will be overwritten in FindPETSc.cmake. It only worked for me because I had already applied Nico's fix in ResolveCompilerPaths.cmake. However, the fix is not enough to find the correct libslepc.so. I had to use -DSLEPC_LIBRARY:FILEPATH=/path/to/libslepc.so.

  5. Nico Schlömer reporter

    @johannes_ring Can't reproduce this. With the fix above and not further adjustments, I get -- SLEPC_DIR is /opt/slepc/dev.

  6. Johannes Ring

    @nschloe - yes, SLEPC_DIR is correct for me too but SLEPC_LIBRARIES in CMakeCache.txt points to /usr/lib/libslepc.so, not the locally installed library. Is your SLEPC_LIBRARIES in CMakeCache.txt correct? If so, do you also have libslepc.so in /usr/lib?

  7. Nico Schlömer reporter

    Gah!

    $ grep SLEPC_LIBRARIES CMakeCache.txt
    SLEPC_LIBRARIES:STRING=/path/to/libslepc.so
    

    This isn't too good at all. I'll check FindSLEPC.cmake for obvious blunders later.

  8. Nico Schlömer reporter

    Okay so, things are pretty simple: The find_package call in cmake/modules/FindSLEPc.cmake is missing a NO_CMAKE_PATH as well. Add it and SLEPc will be found alright.

  9. Johannes Ring

    Is this something that has been changed in CMake recently? Do we need to add NO_CMAKE_PATH to every find_library call now?

  10. Nico Schlömer reporter

    @johannes_ring The attribute NO_CMAKE_PATH is around since at least CMake 2.6 (http://www.cmake.org/Wiki/CMake_2.6.0_Docs), i.e., 2008. The bug seems be due to a misunderstanding of the HINTS attribute, thinking that it takes precedence over the CMake path. Consequently, I suppose only the find_package calls that contain HINTS would need to be looked at.

  11. Johannes Ring

    We have a solution - just not sure it is the correct fix.

    diff --git a/cmake/modules/FindSLEPc.cmake b/cmake/modules/FindSLEPc.cmake
    index ced7b6a..214b5d7 100644
    --- a/cmake/modules/FindSLEPc.cmake
    +++ b/cmake/modules/FindSLEPc.cmake
    @@ -87,6 +87,7 @@ if (SLEPC_DIR)
       find_library(SLEPC_LIBRARY
         NAMES slepc
         HINTS ${SLEPC_DIR}/lib $ENV{SLEPC_DIR}/lib  ${SLEPC_DIR}/${PETSC_ARCH}/lib $ENV{SLEPC_DIR}/$ENV{PETSC_ARCH}/lib 
    +    NO_CMAKE_PATH
         DOC "The SLEPc library"
         )
       mark_as_advanced(SLEPC_LIBRARY)
    diff --git a/cmake/modules/ResolveCompilerPaths.cmake b/cmake/modules/ResolveCompilerPaths.cmake
    index 644a738..edc3d09 100644
    --- a/cmake/modules/ResolveCompilerPaths.cmake
    +++ b/cmake/modules/ResolveCompilerPaths.cmake
    @@ -68,7 +68,7 @@ macro (RESOLVE_LIBRARIES LIBS LINK_LINE)
             set (token ${libname})
           endif (token MATCHES "^/")
           set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
    -      find_library (_lib ${token} HINTS ${_directory_list} ${_root})
    +      find_library (_lib ${token} HINTS ${_directory_list} ${_root} NO_CMAKE_PATH)
           if (_lib)
            string (REPLACE "//" "/" _lib ${_lib})
             list (APPEND _libs_found ${_lib})
    
  12. Jan Blechta

    Does the issue apply (and will be solved) for other dependencies? I experience something similar with SCOTCH.

  13. Nico Schlömer reporter

    @blechta ResolveCompilerPaths.cmake gets called by a number of 3rd party libraries, so chances are that SCOTCH finding is also fixed by this. grep -ir "find_library(" * in the DOLFIN tree reveals a number of places where this fix could be applied to.

  14. Jan Blechta

    @nschloe Yes, find_library() call is involved in FindSCOTCH.cmake. Will you fix all those calls?

  15. Prof Garth Wells

    Improve find_library calls for custom library paths

    Many of DOLFIN's find_library() calls provide HINT paths which were allegedly assumed to take precedence over CMake's default paths. This is not true, cf. http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:find_library. It is recommended http://www.cmake.org/pipermail/cmake/2013-December/056635.html to call find_library() twice, once with HINTS and NO_DEFAULT_PATH, then once more without those options. The second call will only be executed if the first find_library() was not successful.

    Fixes issue #151.

    → <<cset 8c714a50b227>>

  16. Jan Blechta

    There are more find_library calls missing NO_DEFAUTL_PATH, for example in FindLAPACK.cmake, FindBLAS.cmake, FindPaStiX.cmake. Is it ok?

  17. Log in to comment