diff options
author | Christopher Degawa <ccom@randomderp.com> | 2021-06-11 15:17:39 -0500 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2021-06-18 11:10:12 -0400 |
commit | 35d3e00e4e9b138dec1d1a646766fc342d04b8f5 (patch) | |
tree | a27895e2748c4ab00ce77d30f2dbb6191ac86027 | |
parent | 11695f5985e9cbd7a5206908fe6d2ea7e77865e9 (diff) | |
download | cmake-35d3e00e4e9b138dec1d1a646766fc342d04b8f5.tar.gz |
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>
-rw-r--r-- | Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst | 5 | ||||
-rw-r--r-- | Modules/FindPkgConfig.cmake | 39 | ||||
-rw-r--r-- | Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake | 17 | ||||
-rw-r--r-- | Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake | 1 | ||||
-rwxr-xr-x | Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat | 17 | ||||
-rwxr-xr-x | Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh | 19 |
6 files changed, 93 insertions, 5 deletions
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 |