Skip to content

Commit b083efd

Browse files
eli-schwartzmikeb01
authored andcommitted
pkg-config file: fix handling of variable-relative paths
In order to handle cross compilation and other concerns, pkg-config files support defining includedir/libdir relative to prefix and perform deferred expansion. For this reason, the expected value of each is: ${prefix}/lib ${prefix}/include or similar. This may or may not work depending on how the standard directories are installed: - autotools all directory variables must be specified by absolute path. However, those variables use the same format as pkg-config to do expansions, so it is possible to pass --libdir='${prefix}/lib' and generate correct pkg-config files - meson all directory variables can be specified by either relative or absolute path. For absolute paths, if they fit inside prefix they are converted to relative paths. There is also a builtin `join_paths` function that correctly handles path joining for both relative and absolute paths. The builtin pkg-config generator always generates correct pkg-config files no matter how you specify directory variables, and it is possible to manually define paths as: join_paths('${prefix}', get_option('libdir')) - cmake all directory variables can be specified by either relative or absolute path. No post-processing is done, so CMAKE_INSTALL_LIBDIR may be relative or absolute, but CMAKE_INSTALL_FULL_LIBDIR is always absolute. If you must have a relative path, you cannot get one. Unfortunately, cmake has neither of the coping mechanisms of meson or autotools. So some manual work is needed in order to generate correct pkg-config files. The following assumption must be made: - this will only be correct if the user configures cmake using relative paths We also need a shared third-party function to reimplement join_paths semantics, available from: https://github.com/jtojnar/cmake-snips#concatenating-paths-when-building-pkg-config-files Using this we can guarantee that directory variables are always expanded to one of two things: - a "technically incorrect" full path such as `/usr/lib` if the user configured with full paths - a spec compliant path such as `${prefix}/lib` if the user configured with relative paths Although this isn't always perfect, it allows -- like autotools -- having fully correct pkg-config files as long as the user configures the build system the "correct" way (relative paths), and in the event that a sub-optimal configuration is used (full paths) a working but sub-optimal pkg-config file is generated. This fixes the case where previously, if a user configured with full paths the generated pkg-config file ended up with directory variables such as: prefix=/usr libdir=${prefix}/usr/lib includedir=${prefix}/usr/include Using a proper join_paths() function guarantees that if the CMAKE_INSTALL_* variables are absolute paths already, the `${prefix}` is not prepended to them.
1 parent 298cc53 commit b083efd

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ project(hdr_histogram
66
DESCRIPTION "C port of the HdrHistogram"
77
HOMEPAGE_URL "http://hdrhistogram.github.io/HdrHistogram/")
88

9+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
10+
911
include(GNUInstallDirs)
1012
include(CMakePackageConfigHelpers)
1113

@@ -94,6 +96,11 @@ install(
9496
set(CPACK_GENERATOR "TGZ")
9597
include(CPack)
9698

99+
include(JoinPaths)
100+
101+
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
102+
join_paths(libdir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
103+
97104
if(${ZLIB_FOUND})
98105
set(PC_REQUIRES_PRIVATE_ZLIB "zlib")
99106
else()

cmake/JoinPaths.cmake

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This module provides function for joining paths
2+
# known from most languages
3+
#
4+
# SPDX-License-Identifier: (MIT OR CC0-1.0)
5+
# Copyright 2020 Jan Tojnar
6+
# https://github.com/jtojnar/cmake-snips
7+
#
8+
# Modelled after Python’s os.path.join
9+
# https://docs.python.org/3.7/library/os.path.html#os.path.join
10+
# Windows not supported
11+
function(join_paths joined_path first_path_segment)
12+
set(temp_path "${first_path_segment}")
13+
foreach(current_segment IN LISTS ARGN)
14+
if(NOT ("${current_segment}" STREQUAL ""))
15+
if(IS_ABSOLUTE "${current_segment}")
16+
set(temp_path "${current_segment}")
17+
else()
18+
set(temp_path "${temp_path}/${current_segment}")
19+
endif()
20+
endif()
21+
endforeach()
22+
set(${joined_path} "${temp_path}" PARENT_SCOPE)
23+
endfunction()

hdr_histogram.pc.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
prefix=@CMAKE_INSTALL_PREFIX@
2-
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
3-
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
2+
libdir=@libdir_for_pc_file@
3+
includedir=@includedir_for_pc_file@
44

55
Name: @PROJECT_NAME@
66
Description: @CMAKE_PROJECT_DESCRIPTION@

0 commit comments

Comments
 (0)