From 4283fc6918531e55dbb93fd77298a45d59d7fe9d Mon Sep 17 00:00:00 2001 From: Ben Wolsieffer Date: Tue, 30 Aug 2022 20:06:48 -0400 Subject: [PATCH] Don't assume `CMAKE_INSTALL_*DIR` variables are relative (#305) * Don't assume CMAKE_INSTALL_*DIR variables are relative The CMAKE_INSTALL_*DIR variables are allowed to be absolute paths, so they cannot be simply appended to CMAKE_INSTALL_PREFIX. When an absolute path is needed, CMAKE_INSTALL_FULL_*DIR must be used. Additionally, pkgconfig files should use ${prefix} relative paths if CMAKE_INSTALL_*DIR are relative, but otherwise use absolute paths. This is handled by the custom join_paths() function. Note that CMake 3.20 provides cmake_path(APPEND) which implements the same functionality as join_paths(), but this CMake version is not available in all supported distros yet (notably Ubuntu older than 22.04). Signed-off-by: Ben Wolsieffer Co-authored-by: Jose Luis Rivero --- CMakeLists.txt | 12 ++++++++++-- cmake/IgnPackaging.cmake | 14 +++++++++----- cmake/JoinPaths.cmake | 22 ++++++++++++++++++++++ cmake/pkgconfig/ignition-component.pc.in | 4 ++-- cmake/pkgconfig/ignition.pc.in | 4 ++-- config/ignition-cmake.pc.in | 2 +- 6 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 cmake/JoinPaths.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 1db04c76..c2683370 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,7 @@ set(ign_version_output "${PROJECT_NAME_LOWER}-config-version.cmake") set(ign_config_install_dir "${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME_LOWER}") set(ign_pkgconfig_input "${CMAKE_CURRENT_SOURCE_DIR}/config/ignition-cmake.pc.in") set(ign_pkgconfig_output "${CMAKE_BINARY_DIR}/ignition-cmake${PROJECT_VERSION_MAJOR}.pc") -set(ign_pkgconfig_install_dir "${IGN_LIB_INSTALL_DIR}/pkgconfig") +set(ign_pkgconfig_install_dir "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig") set(ign_utilities_target ${PROJECT_EXPORT_NAME}-utilities) set(ign_utilities_import_target_name ${PROJECT_EXPORT_NAME}::${ign_utilities_target}) set(ign_utilities_target_output_filename "${ign_utilities_target}-targets.cmake") @@ -96,9 +96,17 @@ install( # Configure and install the pkgconfig file (needed for utilities headers) file(RELATIVE_PATH IGN_PC_CONFIG_RELATIVE_PATH_TO_PREFIX - "${CMAKE_INSTALL_PREFIX}/${ign_pkgconfig_install_dir}" + "${ign_pkgconfig_install_dir}" "${CMAKE_INSTALL_PREFIX}" ) + +# TODO(jrivero): CMake 3.20 provides cmake_path(APPEND) which implements the +# same functionality as join_paths(). Remove JoinPaths in the next major version +# if all the supported platforms are in 3.20 version. +include(JoinPaths) +join_paths(IGN_PC_LIBDIR "\${prefix}" "${CMAKE_INSTALL_LIBDIR}") +join_paths(IGN_PC_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}" "${IGN_INCLUDE_INSTALL_DIR_POSTFIX}") + configure_file(${ign_pkgconfig_input} ${ign_pkgconfig_output} @ONLY) install( diff --git a/cmake/IgnPackaging.cmake b/cmake/IgnPackaging.cmake index c8b2f2e8..9606f7d0 100644 --- a/cmake/IgnPackaging.cmake +++ b/cmake/IgnPackaging.cmake @@ -121,16 +121,16 @@ macro(ign_setup_packages) # (but later on when installing) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${IGN_LIB_INSTALL_DIR}") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") # add the automatically determined parts of the RPATH # which point to directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # the RPATH to be used when installing, but only if its not a system directory - list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${IGN_LIB_INSTALL_DIR}" isSystemDir) + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" isSystemDir) if("${isSystemDir}" STREQUAL "-1") - set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${IGN_LIB_INSTALL_DIR}") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") endif("${isSystemDir}" STREQUAL "-1") endif() @@ -198,13 +198,17 @@ function(_ign_create_pkgconfig) endif() set(pkgconfig_output "${CMAKE_BINARY_DIR}/cmake/pkgconfig/${target_name}.pc") - set(pkgconfig_install_dir "${IGN_LIB_INSTALL_DIR}/pkgconfig") + set(pkgconfig_install_dir "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig") file(RELATIVE_PATH PC_CONFIG_RELATIVE_PATH_TO_PREFIX - "${CMAKE_INSTALL_PREFIX}/${pkgconfig_install_dir}" + "${pkgconfig_install_dir}" "${CMAKE_INSTALL_PREFIX}" ) + include("${IGNITION_CMAKE_DIR}/JoinPaths.cmake") + join_paths(PC_LIBDIR "\${prefix}" "${CMAKE_INSTALL_LIBDIR}") + join_paths(PC_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}" "${IGN_INCLUDE_INSTALL_DIR_POSTFIX}") + configure_file(${pkgconfig_input} ${pkgconfig_output} @ONLY) install( diff --git a/cmake/JoinPaths.cmake b/cmake/JoinPaths.cmake new file mode 100644 index 00000000..3fcbce43 --- /dev/null +++ b/cmake/JoinPaths.cmake @@ -0,0 +1,22 @@ +# This module provides function for joining paths +# known from most languages +# +# SPDX-License-Identifier: (MIT OR CC0-1.0) +# Copyright 2020 Jan Tojnar +# https://github.com/jtojnar/cmake-snips +# +# Modelled after Python’s os.path.join +# https://docs.python.org/3.7/library/os.path.html#os.path.join +function(join_paths joined_path first_path_segment) + set(temp_path "${first_path_segment}") + foreach(current_segment IN LISTS ARGN) + if(NOT ("${current_segment}" STREQUAL "")) + if(IS_ABSOLUTE "${current_segment}") + set(temp_path "${current_segment}") + else() + set(temp_path "${temp_path}/${current_segment}") + endif() + endif() + endforeach() + set(${joined_path} "${temp_path}" PARENT_SCOPE) +endfunction() diff --git a/cmake/pkgconfig/ignition-component.pc.in b/cmake/pkgconfig/ignition-component.pc.in index 3d749398..fd1a00f5 100644 --- a/cmake/pkgconfig/ignition-component.pc.in +++ b/cmake/pkgconfig/ignition-component.pc.in @@ -1,6 +1,6 @@ prefix=${pcfiledir}/@PC_CONFIG_RELATIVE_PATH_TO_PREFIX@ -libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@IGN_INCLUDE_INSTALL_DIR_POSTFIX@ +libdir=@PC_LIBDIR@ +includedir=@PC_INCLUDEDIR@ Name: Ignition @GZ_DESIGNATION@ @component_name@ Description: A set of @GZ_DESIGNATION@ @component_name@ classes for robot applications diff --git a/cmake/pkgconfig/ignition.pc.in b/cmake/pkgconfig/ignition.pc.in index be64e5ed..6d44ce0c 100644 --- a/cmake/pkgconfig/ignition.pc.in +++ b/cmake/pkgconfig/ignition.pc.in @@ -1,6 +1,6 @@ prefix=${pcfiledir}/@PC_CONFIG_RELATIVE_PATH_TO_PREFIX@ -libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@IGN_INCLUDE_INSTALL_DIR_POSTFIX@ +libdir=@PC_LIBDIR@ +includedir=@PC_INCLUDEDIR@ Name: Ignition @GZ_DESIGNATION@ Description: A set of @GZ_DESIGNATION@ classes for robot applications diff --git a/config/ignition-cmake.pc.in b/config/ignition-cmake.pc.in index d2e92f71..e30858d5 100644 --- a/config/ignition-cmake.pc.in +++ b/config/ignition-cmake.pc.in @@ -1,5 +1,5 @@ prefix=${pcfiledir}/@IGN_PC_CONFIG_RELATIVE_PATH_TO_PREFIX@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@IGN_INCLUDE_INSTALL_DIR_POSTFIX@ +includedir=@IGN_PC_INCLUDEDIR@ Name: Ignition @GZ_DESIGNATION@ Description: Build system package for the ignition libraries