CMake version 3.5.0

When exporting from a project (with install(EXPORT ...)),
the<PROJECT>Targets.cmake file contains logic for computing the
_IMPORT_PREFIX. This _IMPORT_PREFIX is then used in the
<PROJECT>Targets-<configuration>.cmake file to generate the
IMPORTED_LOCATION_<uppercase-configuration>. The generation appears to
be accomplished by unconditionally appending a "/" to _IMPORT_PREFIX
before appending the rest of the path. If _IMPORT_PREFIX is "/", then
the IMPORTED_LOCATION_<uppercase-configuration> properties all start
with exactly two leading slashes ("//").

Exactly two leading slashes is apparently a special case in POSIX file
paths, such that its interpretation is left up to the implementation.
This means that changing the path prefix from "/" to "//" should not
be allowed.

A result of this is that when importing a library installed to
/usr/lib, the IMPORTED_LOCATION_DEBUG ends up being
"//usr/lib/libmylib.so". At this point in the project, CMake doesn't
contract the two leading slashes (as it apparently shouldn't), so
executables linking against the mylib target end up with "//usr/lib"
in their RPATH. This works fine with the Linux dynamic linker, but if
a program uses dladdr() to get the location of the shared library, the
leading "//" is still present. Manipulation of this path within the
program (e.g. with boost::filesystem) then fails to work as expected,
if the manipulation code is sensitive to the leading "//".

Example of generated cmake code when CPACK_PACKAGING_INSTALL_PREFIX is
"/" and <PROJECT>Targets.cmake is installed via the INSTALL() command
with DESTINATION "usr/lib/<PROJECT>/cmake":

[ -- From <PROJECT>Targets.cmake -- ]
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)

[ -- From <PROJECT>Targets-<configuration>.cmake -- ]

IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/usr/lib/libmylib.so"


The workaround we are using for this currently is to compile a
modified version of cmake that appends the following cmake code below
the get_filename_component stanza in <PROJECTS>Targets.cmake:

if("${_IMPORT_PREFIX}" STREQUAL "/")
  set(_IMPORT_PREFIX "")
endif()
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to