Browse Source

Merge topic 'FindPkgConfig-isystem' into release-3.17

e9d93c3731 Help: Add 3.17 release note for FindPkgConfig '-isystem' fix
dfaaae67a3 Merge branch 'backport-3.16-FindPkgConfig-isystem'
4d446c68d1 FindPkgConfig: also handle "-isystem" prefixes for include directories

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4693
Brad King 5 years ago
parent
commit
6ccbf6ba71

+ 9 - 0
Help/release/3.17.rst

@@ -333,3 +333,12 @@ Changes made since CMake 3.17.0 include the following.
 * CMake 3.17.0 updated the :cpack_gen:`CPack NSIS Generator` with changes
   that require NSIS 3.0 or later.  CMake 3.17.1 now enforces the use
   of a sufficiently new version.
+
+3.17.3
+------
+
+* The :module:`FindPkgConfig` module now extracts include directories
+  prefixed with ``-isystem`` into the ``*_INCLUDE_DIRS`` variables and
+  :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target properties.
+  Previously they would be places in ``*_CFLAGS_OTHER`` variables and
+  :prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties.

+ 42 - 8
Modules/FindPkgConfig.cmake

@@ -364,6 +364,36 @@ macro(_pkg_restore_path_internal)
   unset(_pkgconfig_path_old)
 endmacro()
 
+# pkg-config returns -isystem include directories in --cflags-only-other,
+# depending on the version and if there is a space between -isystem and
+# the actual path
+function(_pkgconfig_extract_isystem _prefix)
+  set(cflags "${${_prefix}_CFLAGS_OTHER}")
+  set(outflags "")
+  set(incdirs "${${_prefix}_INCLUDE_DIRS}")
+
+  set(next_is_isystem FALSE)
+  foreach (THING IN LISTS cflags)
+    # This may filter "-isystem -isystem". That would not work anyway,
+    # so let it happen.
+    if (THING STREQUAL "-isystem")
+      set(next_is_isystem TRUE)
+      continue()
+    endif ()
+    if (next_is_isystem)
+      set(next_is_isystem FALSE)
+      list(APPEND incdirs "${THING}")
+    elseif (THING MATCHES "^-isystem")
+      string(SUBSTRING "${THING}" 8 -1 THING)
+      list(APPEND incdirs "${THING}")
+    else ()
+      list(APPEND outflags "${THING}")
+    endif ()
+  endforeach ()
+  set(${_prefix}_CFLAGS_OTHER "${outflags}" PARENT_SCOPE)
+  set(${_prefix}_INCLUDE_DIRS "${incdirs}" PARENT_SCOPE)
+endfunction()
+
 ###
 macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _prefix)
   _pkgconfig_unset(${_prefix}_FOUND)
@@ -497,14 +527,18 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
       endforeach()
 
       # set variables which are combined for multiple modules
-      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARIES           "(^| )-l" --libs-only-l )
-      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARY_DIRS        "(^| )-L" --libs-only-L )
-      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS             ""        --libs )
-      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER       ""        --libs-only-other )
-
-      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS        "(^| )-I" --cflags-only-I )
-      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS              ""        --cflags )
-      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER        ""        --cflags-only-other )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARIES     "(^| )-l"             --libs-only-l )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARY_DIRS  "(^| )-L"             --libs-only-L )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS       ""                    --libs )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER ""                    --libs-only-other )
+
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS  "(^| )(-I|-isystem ?)" --cflags-only-I )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS        ""                    --cflags )
+      _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER  ""                    --cflags-only-other )
+
+      if (${_prefix}_CFLAGS_OTHER MATCHES "-isystem")
+        _pkgconfig_extract_isystem("${_prefix}")
+      endif ()
 
       _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global})
     endif()

+ 21 - 1
Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake

@@ -99,6 +99,7 @@ file(WRITE ${fakePkgDir}/lib/pkgconfig/${pname}.pc
 Description: Dummy package for FindPkgConfig IMPORTED_TARGET INTERFACE_LINK_OPTIONS test
 Version: 1.2.3
 Libs: -e dummy_main
+Cflags: -I/special -isystem /other -isystem/more -DA-isystem/foo
 ")
 
 set(expected_link_options -e dummy_main)
@@ -109,7 +110,26 @@ endif()
 get_target_property(link_options PkgConfig::FakeLinkOptionsPackage INTERFACE_LINK_OPTIONS)
 if (NOT link_options STREQUAL expected_link_options)
   message(FATAL_ERROR
-    "Additional link options not present in INTERFACE_LINK_OPTIONS property"
+    "Additional link options not present in INTERFACE_LINK_OPTIONS property\n"
     "expected: \"${expected_link_options}\", but got \"${link_options}\""
   )
 endif()
+
+get_target_property(inc_dirs PkgConfig::FakeLinkOptionsPackage INTERFACE_INCLUDE_DIRECTORIES)
+set(expected_inc_dirs "/special" "/other" "/more")
+
+if (NOT inc_dirs STREQUAL expected_inc_dirs)
+  message(FATAL_ERROR
+    "Additional include directories not correctly present in INTERFACE_INCLUDE_DIRECTORIES property\n"
+    "expected: \"${expected_inc_dirs}\", got \"${inc_dirs}\""
+  )
+endif ()
+
+get_target_property(c_opts PkgConfig::FakeLinkOptionsPackage INTERFACE_COMPILE_OPTIONS)
+set(expected_c_opts "-DA-isystem/foo") # this is an invalid option, but a good testcase
+if (NOT c_opts STREQUAL expected_c_opts)
+    message(FATAL_ERROR
+      "Additional compile options not present in INTERFACE_COMPILE_OPTIONS property\n"
+      "expected: \"${expected_c_opts}\", got \"${c_opts}\""
+    )
+endif ()