From 0a75474f2940440e263a52c311fd4b60226e5b88 Mon Sep 17 00:00:00 2001
From: Christophe Marin <christophe@krop.fr>
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 "\\$<INSTALL_INTERFACE:([^,>]+)>" "\\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 "\\$<INSTALL_INTERFACE:([^,>]+)>" "\\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

