MantisBT - CMake
View Issue Details
0015804CMakeModulespublic2015-10-20 05:322016-06-10 14:31
Sam Thursfield 
Kitware Robot 
normalminoralways
closedmoved 
CMake 3.3.2 
 
0015804: FindPkgConfig pkg_check_modules command should return full path to shared libraries in _LIBRARIES variable
CMake seems to encourage using absolute paths to shared libraries.

From link_directories() documentation:

       Note that this command is rarely necessary. Library locations returned
       by find_package() and find_library() are absolute paths. Pass these
       absolute library file paths directly to the target_link_libraries()
       command. CMake will ensure the linker finds them.

However, the FindPkgConfig module doesn't follow this, and instead returns just the names of libraries, plus a linker path. Since CMake makes it awkward to propagate the linker path, so the end result is that if you have a package installed in a non-standard library path, things break.
An example pkg-config file:

  cmake_minimum_required(VERSION 3.3.2)

  find_package(PkgConfig REQUIRED)

  pkg_check_modules(ZLIB zlib REQUIRED)

  message("ZLIB_LIBRARIES: ${ZLIB_LIBRARIES}")
  message("ZLIB_LIBRARY_DIRS: ${ZLIB_LIBRARY_DIRS}")

Output:

  ZLIB_LIBRARIES: z
  ZLIB_LIBRARY_DIRS: /usr/lib64

Expected output:

  ZLIB_LIBRARIES: /usr/lib64/libz.so
I'm aware that in the case of Zlib there is a FindZLib module, and /usr/lib64 is in my library search path in any case. This is just an example. The painful case is where I had to build a library from source myself and then install it into a non-standard prefix.
No tags attached.
related to 0015805closed Ben Boeckel pkg_get_variable from FindPkgConfig should honour search path from CMAKE_PREFIX_PATH 
patch cmake-pkg-config-absolute-paths.patch (2,189) 2015-10-20 17:59
https://public.kitware.com/Bug/file/5555/cmake-pkg-config-absolute-paths.patch
patch cmake-pkg-import-module.patch (5,839) 2016-01-12 12:58
https://public.kitware.com/Bug/file/5608/cmake-pkg-import-module.patch
Issue History
2015-10-20 05:32Sam ThursfieldNew Issue
2015-10-20 17:59Sam ThursfieldFile Added: cmake-pkg-config-absolute-paths.patch
2015-10-20 18:04Sam ThursfieldNote Added: 0039663
2015-10-20 18:10Sam ThursfieldNote Added: 0039664
2015-10-20 18:14Sam ThursfieldNote Added: 0039665
2015-10-21 08:27Brad KingNote Added: 0039666
2015-10-21 08:28Brad KingRelationship addedrelated to 0015805
2016-01-12 12:58Sam ThursfieldFile Added: cmake-pkg-import-module.patch
2016-01-12 12:59Sam ThursfieldNote Added: 0040207
2016-06-10 14:29Kitware RobotNote Added: 0042863
2016-06-10 14:29Kitware RobotStatusnew => 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
(0039663)
Sam Thursfield   
2015-10-20 18:04   
Attached is a patch to implement this behaviour.

I'm not sure if this can be merged without breaking backwards compatibility... it may need either a new policy, or a new variable to be used instead of changing the meaning of xx_LIBRARIES. (Maybe xx_LIBRARY_PATHS ?)

That said, I think other Findxx modules already return absolute paths in xx_LIBRARIES, and the only breakage I can imagine in practice would involve manually constructing a linker commandline from xx_LIBRARIES using ${CMAKE_LINK_LIBRARY_FLAG}... which seems quite broken already.

I'm happy to rework the patch, anyway.
(0039664)
Sam Thursfield   
2015-10-20 18:10   
Some related bugs that could, I think, be closed if this was fixed:

https://cmake.org/Bug/view.php?id=14345 [^] (pkg_check_modules does not honor link command given by pkg-config: leaves out -L flag)
https://cmake.org/Bug/view.php?id=12317 [^] (pkg_check_modules produces output incompatible with other cmake variables)

and possibly:

https://cmake.org/Bug/view.php?id=8644 [^] (Imcompatible output of pkg_check_modules for flags)
(0039665)
Sam Thursfield   
2015-10-20 18:14   
Just thought of another possible way to solve this -- FindPkgConfig could generate an imported target for the different modules, with the full library path set. It seems like this is the current "best practice" of referencing external libraries, and it would not interfere with existing operation. On the other hand, it would take a bit longer to implement, and all existing users would need to manually update their CMakeLists to get the new behaviour.

What would be the best approach?
(0039666)
Brad King   
2015-10-21 08:27   
IIRC the original intention of FindPkgConfig was just to report what pkg-config reports. Then the results can be used by other find modules to provide the actual _LIBRARIES variable, imported targets, etc.

We could provide this more complete functionality in a compatible way by providing a separate interface or option to enable it. It would be nice to be able to ask for an imported target encoding the results.

This design discussion is perhaps better held on the cmake dev mailing list.
(0040207)
Sam Thursfield   
2016-01-12 12:59   
I've not had time to start a design discussion, but attached is a patch that shows how I have solved this locally.

It adds a pkg_import_module() command, which generates an imported target for a given pkg-config module.

The approach seems to work for us. The function currently only works for shared libraries, I'm sure how to allow the user to get imported static targets instead.
(0042863)
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.