| From 35d3e00e4e9b138dec1d1a646766fc342d04b8f5 Mon Sep 17 00:00:00 2001 |
| From: Christopher Degawa <ccom@randomderp.com> |
| Date: Fri, 11 Jun 2021 15:17:39 -0500 |
| Subject: [PATCH] FindPkgConfig: split args if loaded from environment |
| |
| It's common for some people to use the PKG_CONFIG environment variable |
| to not only load a custom pkg-config/pkgconf but also to load some |
| default arguments such as `--static` or `--keep-system-libs` which often |
| worked since shell scripts would call `$PKG_CONFIG --libs pkg` without |
| quotes, but this breaks FindPkgConfig since it uses the full string as |
| `argv[0]` and might try looking for a binary called `pkgconf --static`, |
| instead of looking for `pkgconf` and adding `--static` as the `argv[1]` |
| |
| Additionally adds RunCMake.FindPkgConfig ARGN test case |
| |
| Fixes: #22305 |
| Signed-off-by: Christopher Degawa <ccom@randomderp.com> |
| --- |
| .../dev/FindPkgConfig-PKG_CONFIG-args.rst | 5 +++ |
| Modules/FindPkgConfig.cmake | 39 ++++++++++++++++--- |
| .../FindPkgConfig_GET_MATCHING_ARGN.cmake | 17 ++++++++ |
| .../RunCMake/FindPkgConfig/RunCMakeTest.cmake | 1 + |
| .../FindPkgConfig/dummy-pkg-config.bat | 17 ++++++++ |
| .../FindPkgConfig/dummy-pkg-config.sh | 19 +++++++++ |
| 6 files changed, 93 insertions(+), 5 deletions(-) |
| create mode 100644 Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst |
| create mode 100644 Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake |
| |
| diff --git a/Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst b/Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst |
| new file mode 100644 |
| index 0000000000..44c26b544f |
| --- /dev/null |
| +++ b/Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst |
| @@ -0,0 +1,5 @@ |
| +FindPkgConfig-PKG_CONFIG-args |
| +----------------------------- |
| + |
| +* The :module:`FindPkgConfig` module gained a :variable:`PKG_CONFIG_ARGN` |
| + variable to specify arguments to ``pkg-config`` calls. |
| diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake |
| index 3bc9dba167..bd54fd9dbc 100644 |
| --- a/Modules/FindPkgConfig.cmake |
| +++ b/Modules/FindPkgConfig.cmake |
| @@ -15,6 +15,8 @@ following variables will also be set: |
| if pkg-config executable was found |
| ``PKG_CONFIG_EXECUTABLE`` |
| pathname of the pkg-config program |
| +``PKG_CONFIG_ARGN`` |
| + list of arguments to pass to pkg-config |
| ``PKG_CONFIG_VERSION_STRING`` |
| version of pkg-config (since CMake 2.8.8) |
| |
| @@ -29,7 +31,15 @@ set(PKG_CONFIG_VERSION 1) |
| |
| # find pkg-config, use PKG_CONFIG if set |
| if((NOT PKG_CONFIG_EXECUTABLE) AND (NOT "$ENV{PKG_CONFIG}" STREQUAL "")) |
| - set(PKG_CONFIG_EXECUTABLE "$ENV{PKG_CONFIG}" CACHE FILEPATH "pkg-config executable") |
| + separate_arguments(PKG_CONFIG_FROM_ENV_SPLIT NATIVE_COMMAND PROGRAM SEPARATE_ARGS "$ENV{PKG_CONFIG}") |
| + list(LENGTH PKG_CONFIG_FROM_ENV_SPLIT PKG_CONFIG_FROM_ENV_SPLIT_ARGC) |
| + if(PKG_CONFIG_FROM_ENV_SPLIT_ARGC GREATER 0) |
| + list(GET PKG_CONFIG_FROM_ENV_SPLIT 0 PKG_CONFIG_FROM_ENV_ARGV0) |
| + if(PKG_CONFIG_FROM_ENV_SPLIT_ARGC GREATER 1) |
| + list(SUBLIST PKG_CONFIG_FROM_ENV_SPLIT 1 -1 PKG_CONFIG_ARGN) |
| + endif() |
| + set(PKG_CONFIG_EXECUTABLE "${PKG_CONFIG_FROM_ENV_ARGV0}" CACHE FILEPATH "pkg-config executable") |
| + endif() |
| endif() |
| |
| set(PKG_CONFIG_NAMES "pkg-config") |
| @@ -43,9 +53,12 @@ find_program(PKG_CONFIG_EXECUTABLE |
| DOC "pkg-config executable") |
| mark_as_advanced(PKG_CONFIG_EXECUTABLE) |
| |
| +set(PKG_CONFIG_ARGN "${PKG_CONFIG_ARGN}" CACHE STRING "Arguments to supply to pkg-config") |
| +mark_as_advanced(PKG_CONFIG_ARGN) |
| + |
| set(_PKG_CONFIG_FAILURE_MESSAGE "") |
| if (PKG_CONFIG_EXECUTABLE) |
| - execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --version |
| + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} --version |
| OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE |
| ERROR_VARIABLE _PKG_CONFIG_VERSION_ERROR ERROR_STRIP_TRAILING_WHITESPACE |
| RESULT_VARIABLE _PKG_CONFIG_VERSION_RESULT |
| @@ -53,14 +66,18 @@ if (PKG_CONFIG_EXECUTABLE) |
| |
| if (NOT _PKG_CONFIG_VERSION_RESULT EQUAL 0) |
| string(REPLACE "\n" "\n " _PKG_CONFIG_VERSION_ERROR " ${_PKG_CONFIG_VERSION_ERROR}") |
| + if(PKG_CONFIG_ARGN) |
| + string(REPLACE ";" " " PKG_CONFIG_ARGN " ${PKG_CONFIG_ARGN}") |
| + endif() |
| string(APPEND _PKG_CONFIG_FAILURE_MESSAGE |
| "The command\n" |
| - " \"${PKG_CONFIG_EXECUTABLE}\" --version\n" |
| + " \"${PKG_CONFIG_EXECUTABLE}\"${PKG_CONFIG_ARGN} --version\n" |
| " failed with output:\n${PKG_CONFIG_VERSION_STRING}\n" |
| " stderr: \n${_PKG_CONFIG_VERSION_ERROR}\n" |
| " result: \n${_PKG_CONFIG_VERSION_RESULT}" |
| ) |
| set(PKG_CONFIG_EXECUTABLE "") |
| + set(PKG_CONFIG_ARGN "") |
| unset(PKG_CONFIG_VERSION_STRING) |
| endif () |
| unset(_PKG_CONFIG_VERSION_RESULT) |
| @@ -91,7 +108,7 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp) |
| set(_pkgconfig_invoke_result) |
| |
| execute_process( |
| - COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist} |
| + COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} ${ARGN} ${_pkglist} |
| OUTPUT_VARIABLE _pkgconfig_invoke_result |
| RESULT_VARIABLE _pkgconfig_failed |
| OUTPUT_STRIP_TRAILING_WHITESPACE) |
| @@ -533,7 +550,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma |
| |
| # execute the query |
| execute_process( |
| - COMMAND ${PKG_CONFIG_EXECUTABLE} ${_pkg_check_modules_exist_query} |
| + COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} ${_pkg_check_modules_exist_query} |
| RESULT_VARIABLE _pkgconfig_retval |
| ERROR_VARIABLE _pkgconfig_error |
| ERROR_STRIP_TRAILING_WHITESPACE) |
| @@ -892,6 +909,18 @@ Variables Affecting Behavior |
| .. versionadded:: 3.1 |
| The ``PKG_CONFIG`` environment variable can be used as a hint. |
| |
| +.. variable:: PKG_CONFIG_ARGN |
| + |
| + .. versionadded:: 3.22 |
| + |
| + This can be set to a list of arguments to additionally pass to pkg-config |
| + if needed. If not provided, it will be an empty string, however, if the |
| + environment variable ``PKG_CONFIG`` is provided, this will be set to the |
| + result of splitting the variable. |
| + |
| + The ``PKG_CONFIG`` environment variable can be used to provide both |
| + ``PKG_CONFIG_EXECUTABLE`` and ``PKG_CONFIG_ARGN`` |
| + |
| .. variable:: PKG_CONFIG_USE_CMAKE_PREFIX_PATH |
| |
| .. versionadded:: 3.1 |
| diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake |
| new file mode 100644 |
| index 0000000000..e49ff22f6b |
| --- /dev/null |
| +++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake |
| @@ -0,0 +1,17 @@ |
| +if(WIN32) |
| + set(ENV{PKG_CONFIG} "\"${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat\" --static --print-errors") |
| +else() |
| + set(ENV{PKG_CONFIG} "\"${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh\" --static --print-errors") |
| +endif() |
| + |
| +find_package(PkgConfig REQUIRED) |
| + |
| +if(NOT PKG_CONFIG_ARGN STREQUAL "--static;--print-errors") |
| + message(SEND_ERROR "PKG_CONFIG_ARGN has wrong value '${PKG_CONFIG_ARGN}'") |
| +endif() |
| + |
| +_pkgconfig_invoke("none" "prefix" "output" "") |
| + |
| +if(NOT prefix_output STREQUAL "Received;--static;Received;--print-errors") |
| + message(SEND_ERROR "prefix_output has wrong value '${prefix_output}'") |
| +endif() |
| diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake |
| index e7f008ca53..17e046a2b8 100644 |
| --- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake |
| +++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake |
| @@ -12,6 +12,7 @@ run_cmake(FindPkgConfig_PKGCONFIG_PATH) |
| run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH) |
| run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH) |
| run_cmake(FindPkgConfig_extract_frameworks) |
| +run_cmake(FindPkgConfig_GET_MATCHING_ARGN) |
| |
| if(APPLE) |
| run_cmake(FindPkgConfig_extract_frameworks_target) |
| diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat |
| index b03837030c..c91713b257 100755 |
| --- a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat |
| +++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat |
| @@ -1,5 +1,10 @@ |
| @ECHO OFF |
| |
| +rem variables to get around `--static --version` printing the received |
| +rem message and then version |
| +set static=false |
| +set print_errors=false |
| + |
| :LOOP |
| |
| IF "%1"=="" ( |
| @@ -21,7 +26,19 @@ IF "%1"=="--exists" ( |
| EXIT /B 0 |
| ) |
| ) |
| +IF "%1"=="--static" ( |
| + set static=true |
| +) |
| +IF "%1"=="--print-errors" ( |
| + set print_errors=true |
| +) |
| SHIFT |
| IF NOT "%~1"=="" GOTO LOOP |
| |
| +IF "%static%"=="true" ECHO Received --static |
| +IF "%print_errors%"=="true" ECHO Received --print-errors |
| + |
| +IF "%static%"=="true" GOTO :EOF |
| +IF "%print_errors%"=="true" GOTO :EOF |
| + |
| EXIT /B 255 |
| diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh |
| index 56bba30dd4..4021bf7a6f 100755 |
| --- a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh |
| +++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh |
| @@ -4,6 +4,11 @@ |
| # to the --exists argument with the PKG_CONFIG_PATH environment variable |
| # and returns 1 if they are different. |
| |
| +# variables to get around `--static --version` printing the received |
| +# message and then version |
| +static=false |
| +print_errors=false |
| + |
| while [ $# -gt 0 ]; do |
| case $1 in |
| --version) |
| @@ -17,7 +22,21 @@ while [ $# -gt 0 ]; do |
| echo "Found: ${PKG_CONFIG_PATH}" |
| [ "${last}" = "${PKG_CONFIG_PATH}" ] && exit 0 || exit 1 |
| ;; |
| + --static) |
| + static=true |
| + ;; |
| + --print-errors) |
| + print_errors=true |
| + ;; |
| esac |
| shift |
| done |
| + |
| +$static && echo "Received --static" |
| +$print_errors && echo "Received --print-errors" |
| + |
| +if $static || $print_errors; then |
| + exit 0 |
| +fi |
| + |
| exit 255 |
| -- |
| GitLab |
| |