From 892dea3b82208654cc9f57ffc4ef555d0d934cf5 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Mon, 13 Apr 2020 16:16:11 +0200 Subject: [PATCH] build: Produce correct pc file with absolute libdir The CMAKE_INSTALL_INCLUDEDIR and CMAKE_INSTALL_LIBDIR variables can be absolute paths so simply appending them to \${prefix} might not work. Unfortunately, CMake does not have simple function for joining paths [1] so I had to write my own suboptimal one. It somewhat handles the following cases - prefix absolute + libdir relative - prefix absolute + libdir absolute but not under prefix but for - prefix absolute + libdir absolute & under prefix we would want to strip the prefix and make the libdir relative so we can make it relative to the pkg-config variables. Basically, we want the equivalent of the following Python function: import os.path from pathlib import PurePath if os.path.isabs(libdir) and os.path.commonpath([libdir, prefix]) == str(PurePath(prefix)): # Convert path to be relative to prefix skip = len(prefix) + 1 libdir = libdir[skip:] return os.path.join('${prefix}', libdir) This would be non-trivial to replicate in CMake scripts as far as I can tell. [1]: https://gitlab.kitware.com/cmake/cmake/issues/19568 --- CMakeScripts/JoinPaths.cmake | 23 +++++++++++++++++++++++ zzip/CMakeLists.txt | 9 +++++++-- zzipwrap/CMakeLists.txt | 9 +++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 CMakeScripts/JoinPaths.cmake diff --git a/CMakeScripts/JoinPaths.cmake b/CMakeScripts/JoinPaths.cmake new file mode 100644 index 0000000..10d5ba6 --- /dev/null +++ b/CMakeScripts/JoinPaths.cmake @@ -0,0 +1,23 @@ +# This module provides function for joining paths +# known from 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 +# Windows not supported +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/zzip/CMakeLists.txt b/zzip/CMakeLists.txt index c7f92e0..28ce35b 100644 --- a/zzip/CMakeLists.txt +++ b/zzip/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required (VERSION 3.1) project(zziplib VERSION "0.13.69" LANGUAGES C) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeScripts") + # generate _config.h include ( CheckIncludeFiles ) include ( CheckFunctionExists ) @@ -8,6 +10,7 @@ include ( CheckSymbolExists ) include ( CheckTypeSize ) include ( TestBigEndian ) include ( GNUInstallDirs ) +include ( JoinPaths ) # options ########################################################### option(BUILD_SHARED_LIBS "Build a shared library" ON) @@ -212,10 +215,12 @@ add_custom_target(compat ALL DEPENDS compat/zzip.h) endif() if(UNIX) +join_paths(libdir "\${prefix}" "${CMAKE_INSTALL_LIBDIR}") +join_paths(includedir "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") add_custom_command(OUTPUT zziplib.pc COMMAND ${BASH} -c "echo 'prefix=${CMAKE_INSTALL_PREFIX}' > zziplib.pc" - COMMAND ${BASH} -c "echo 'libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}' >> zziplib.pc" - COMMAND ${BASH} -c "echo 'includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}' >> zziplib.pc" + COMMAND ${BASH} -c "echo 'libdir=${libdir}' >> zziplib.pc" + COMMAND ${BASH} -c "echo 'includedir=${includedir}' >> zziplib.pc" COMMAND ${BASH} -c "echo '' >> zziplib.pc" COMMAND ${BASH} -c "echo 'Name: ${PROJECT_NAME}' >> zziplib.pc" COMMAND ${BASH} -c "echo 'Description: ZZipLib - libZ-based ZIP-access Library with an Easy-to-Use API' >> zziplib.c" diff --git a/zzipwrap/CMakeLists.txt b/zzipwrap/CMakeLists.txt index 5ac2682..68b9b47 100644 --- a/zzipwrap/CMakeLists.txt +++ b/zzipwrap/CMakeLists.txt @@ -1,9 +1,12 @@ cmake_minimum_required (VERSION 3.1) project(zzipwrap VERSION "0.13.69" LANGUAGES C) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeScripts") + include ( CheckIncludeFiles ) include ( GNUInstallDirs ) include ( FindPkgConfig ) +include ( JoinPaths ) # options ######################################################## option(BUILD_SHARED_LIBS "Build a shared library" ON) @@ -46,10 +49,12 @@ target_link_libraries(zzipwrap libzzipwrap ) target_include_directories(zzipwrap PRIVATE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") if(UNIX) +join_paths(libdir "\${prefix}" "${CMAKE_INSTALL_LIBDIR}") +join_paths(includedir "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") add_custom_command(OUTPUT zzipwrap.pc COMMAND ${BASH} -c "echo 'prefix=${CMAKE_INSTALL_PREFIX}' > zzipwrap.pc" - COMMAND ${BASH} -c "echo 'libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}' >> zzipwrap.pc" - COMMAND ${BASH} -c "echo 'includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}' >> zzipwrap.pc" + COMMAND ${BASH} -c "echo 'libdir=${libdir}' >> zzipwrap.pc" + COMMAND ${BASH} -c "echo 'includedir=${includedir}' >> zzipwrap.pc" COMMAND ${BASH} -c "echo '' >> zzipwrap.pc" COMMAND ${BASH} -c "echo 'Name: ${PROJECT_NAME}' >> zzipwrap.pc" COMMAND ${BASH} -c "echo 'Description: Callback Wrappers for ZZipLib' >> zzipwrap.c" -- 2.40.0