From 0a75474f2940440e263a52c311fd4b60226e5b88 Mon Sep 17 00:00:00 2001 From: Christophe Marin Date: Thu, 28 Nov 2024 16:18:53 +0100 Subject: [PATCH] EGPF: Handle case where INTERFACE_INCLUDE_DIRECTORIES is empty Issue mentioned privately by Dariusz Pelowski. Thanks! Amends: 85aa50ba81 BUG: 496781 FIXED-IN: 6.9.0 --- modules/ECMGeneratePkgConfigFile.cmake | 43 ++++++++++--------- tests/ECMGeneratePkgConfigFile/CMakeLists.txt | 1 + .../CMakeLists.txt | 39 +++++++++++++++++ .../EGPF_no_interface_include_directories.pc | 13 ++++++ .../test_no_interface_include_dirs/main.cpp | 4 ++ 5 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/CMakeLists.txt create mode 100644 tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/EGPF_no_interface_include_directories.pc create mode 100644 tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/main.cpp diff --git a/modules/ECMGeneratePkgConfigFile.cmake b/modules/ECMGeneratePkgConfigFile.cmake index a5c2d9bc..77ab8ae1 100644 --- a/modules/ECMGeneratePkgConfigFile.cmake +++ b/modules/ECMGeneratePkgConfigFile.cmake @@ -168,26 +168,29 @@ function(ECM_GENERATE_PKGCONFIG_FILE) if(TARGET ${EGPF_LIB_NAME}) # Generator expression cannot be evaluated when creating the pkgconfig file, we need to convert the public include directories # into something pkgconfig can understand - get_target_property(_EGPF_TARGET_INCLUDE_DIRS ${EGPF_LIB_NAME} INTERFACE_INCLUDE_DIRECTORIES) - - # INTERFACE_INCLUDE_DIRS can contain semicolon separated locations. Since CMake still doesn't accept different separators, - # We need to convert _EGPF_TARGET_INCLUDE_DIRS to a string, extract the locations and convert it back to a list - string(REPLACE ";" "|" _EGPF_TARGET_INCLUDE_DIRS "${_EGPF_TARGET_INCLUDE_DIRS}") - list(TRANSFORM _EGPF_TARGET_INCLUDE_DIRS REPLACE "\\$]+)>" "\\1") - string(REPLACE "|" ";" _EGPF_TARGET_INCLUDE_DIRS "${_EGPF_TARGET_INCLUDE_DIRS}") - - # Remove any other generator expression. - string(GENEX_STRIP "${_EGPF_TARGET_INCLUDE_DIRS}" _EGPF_TARGET_INCLUDE_DIRS) - - # Remove possible duplicate entries a first time - list(REMOVE_DUPLICATES _EGPF_TARGET_INCLUDE_DIRS) - - foreach(EGPF_INCLUDE_DIR IN LISTS _EGPF_TARGET_INCLUDE_DIRS) - # if the path is not absolute (that would be the case for KDEInstallDirs variables), append \${prefix} before each entry - if(NOT IS_ABSOLUTE "${EGPF_INCLUDE_DIR}") - list(TRANSFORM _EGPF_TARGET_INCLUDE_DIRS REPLACE "${EGPF_INCLUDE_DIR}" "\${prefix}/${EGPF_INCLUDE_DIR}") - endif() - endforeach() + get_target_property(__EGPF_TARGET_INCLUDE_DIRS ${EGPF_LIB_NAME} INTERFACE_INCLUDE_DIRECTORIES) + + if(__EGPF_TARGET_INCLUDE_DIRS) + set(_EGPF_TARGET_INCLUDE_DIRS "${__EGPF_TARGET_INCLUDE_DIRS}") + # INTERFACE_INCLUDE_DIRS can contain semicolon separated locations. Since CMake still doesn't accept different separators, + # We need to convert _EGPF_TARGET_INCLUDE_DIRS to a string, extract the locations and convert it back to a list + string(REPLACE ";" "|" _EGPF_TARGET_INCLUDE_DIRS "${_EGPF_TARGET_INCLUDE_DIRS}") + list(TRANSFORM _EGPF_TARGET_INCLUDE_DIRS REPLACE "\\$]+)>" "\\1") + string(REPLACE "|" ";" _EGPF_TARGET_INCLUDE_DIRS "${_EGPF_TARGET_INCLUDE_DIRS}") + + # Remove any other generator expression. + string(GENEX_STRIP "${_EGPF_TARGET_INCLUDE_DIRS}" _EGPF_TARGET_INCLUDE_DIRS) + + # Remove possible duplicate entries a first time + list(REMOVE_DUPLICATES _EGPF_TARGET_INCLUDE_DIRS) + + foreach(EGPF_INCLUDE_DIR IN LISTS _EGPF_TARGET_INCLUDE_DIRS) + # if the path is not absolute (that would be the case for KDEInstallDirs variables), append \${prefix} before each entry + if(NOT IS_ABSOLUTE "${EGPF_INCLUDE_DIR}") + list(TRANSFORM _EGPF_TARGET_INCLUDE_DIRS REPLACE "${EGPF_INCLUDE_DIR}" "\${prefix}/${EGPF_INCLUDE_DIR}") + endif() + endforeach() + endif() endif() if(IS_ABSOLUTE "${EGPF_INCLUDE_INSTALL_DIR}") diff --git a/tests/ECMGeneratePkgConfigFile/CMakeLists.txt b/tests/ECMGeneratePkgConfigFile/CMakeLists.txt index c2382106..755476b0 100644 --- a/tests/ECMGeneratePkgConfigFile/CMakeLists.txt +++ b/tests/ECMGeneratePkgConfigFile/CMakeLists.txt @@ -6,3 +6,4 @@ add_test( COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/run_test.cmake") add_subdirectory(test_imported_targets) +add_subdirectory(test_no_interface_include_dirs) diff --git a/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/CMakeLists.txt b/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/CMakeLists.txt new file mode 100644 index 00000000..ecd8c546 --- /dev/null +++ b/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.16) +project(ECMGeneratePkgConfigFile_no_interface_include_directories VERSION 0.1) + +set(ECM_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../modules") +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../modules;${CMAKE_CURRENT_SOURCE_DIR}/../../../kde-modules") + +enable_language(CXX) + +include(ECMGeneratePkgConfigFile) +include(ECMSetupVersion) + +# KDEInstallDirs can't be used +set(EGPF_KDE_INSTALL_INCLUDEDIR_KF "include/KF6") + +set(InputFile "${CMAKE_CURRENT_SOURCE_DIR}/EGPF_no_interface_include_directories.pc") + +set(CMAKE_INSTALL_PREFIX "/usr") +set(CMAKE_INSTALL_LIBDIR "lib") + +ecm_setup_version(0.1 VARIABLE_PREFIX EGPF_lib_without_interface + SOVERSION 0) + +add_library(EGPF_lib_without_interface) +target_sources(EGPF_lib_without_interface PRIVATE main.cpp) +set_target_properties(EGPF_lib_without_interface PROPERTIES + VERSION 0.1 + SOVERSION 0 +) + +ecm_generate_pkgconfig_file(BASE_NAME EGPF_lib_without_interface + DESCRIPTION "Testing generated pkgconfig file without interface_include_directories" + INCLUDE_INSTALL_DIR ${EGPF_KDE_INSTALL_INCLUDEDIR_KF} + FILENAME_VAR OutputFile + ) + +add_test( + NAME ECMGeneratePkgConfigFileTest.no_interface_include_directories + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol "${InputFile}" "${OutputFile}" + ) diff --git a/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/EGPF_no_interface_include_directories.pc b/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/EGPF_no_interface_include_directories.pc new file mode 100644 index 00000000..7123c9b7 --- /dev/null +++ b/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/EGPF_no_interface_include_directories.pc @@ -0,0 +1,13 @@ + +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include/KF6 + +Name: EGPF_lib_without_interface +Description: Testing generated pkgconfig file without interface_include_directories +URL: https://www.kde.org/ +Version: 0.1 +Libs: -L${prefix}/lib -lEGPF_lib_without_interface +Cflags: -I${prefix}/include/KF6 +Requires: diff --git a/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/main.cpp b/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/main.cpp new file mode 100644 index 00000000..0f45ea60 --- /dev/null +++ b/tests/ECMGeneratePkgConfigFile/test_no_interface_include_dirs/main.cpp @@ -0,0 +1,4 @@ +int main(int, char**) +{ + return 0; +} -- GitLab