[vcpkg_fixup_pkgconfig] Handle spaces in path, do not validate individual libraries (#13126)

This commit is contained in:
ras0219 2020-12-07 18:17:19 -08:00 committed by GitHub
parent ced334b24d
commit dd4421808c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 150 additions and 279 deletions

View File

@ -7,8 +7,6 @@ Fix common paths in *.pc files and make everything relativ to $(prefix)
vcpkg_fixup_pkgconfig(
[RELEASE_FILES <PATHS>...]
[DEBUG_FILES <PATHS>...]
[SYSTEM_LIBRARIES <NAMES>...]
[IGNORE_FLAGS <FLAGS>]
[SKIP_CHECK]
)
```
@ -22,21 +20,24 @@ Defaults to every *.pc file in the folder ${CURRENT_PACKAGES_DIR} without ${CURR
Specifies a list of files to apply the fixes for debug paths.
Defaults to every *.pc file in the folder ${CURRENT_PACKAGES_DIR}/debug/
### SYSTEM_LIBRARIES
If the *.pc file contains system libraries outside vcpkg these need to be listed here.
VCPKG checks every -l flag for the existence of the required library within vcpkg.
### IGNORE_FLAGS
If the *.pc file contains flags in the lib field which are not libraries. These can be listed here
### SKIP_CHECK
Skips the library checks in vcpkg_fixup_pkgconfig. Only use if the script itself has unhandled cases.
Skips the library checks in vcpkg_fixup_pkgconfig. Only use if the script itself has unhandled cases.
### SYSTEM_PACKAGES (deprecated)
This argument has been deprecated and has no effect.
### SYSTEM_LIBRARIES (deprecated)
This argument has been deprecated and has no effect.
### IGNORE_FLAGS (deprecated)
This argument has been deprecated and has no effect.
## Notes
Still work in progress. If there are more cases which can be handled here feel free to add them
## Examples
Just call `vcpkg_fixup_pkgconfig()` after any install step which installs *.pc files.
* [brotli](https://github.com/Microsoft/vcpkg/blob/master/ports/brotli/portfile.cmake)
## Source
[scripts/cmake/vcpkg_fixup_pkgconfig.cmake](https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_fixup_pkgconfig.cmake)

View File

@ -41,6 +41,8 @@ vcpkg_configure_cmake(
-DBUILD_BENCHMARKS=OFF
-DBUILD_EXAMPLES=OFF
-DBUILD_TESTING=OFF
-DBUILD_BENCHMARKS=OFF
-DPROVIDE_UNINSTALL_TARGET=OFF
-DMSVC_USE_STATIC_CRT=${MSVC_USE_STATIC_CRT_VALUE}
-DLIB_SUFFIX=${LIB_SUFFIX}
)

View File

@ -1,5 +1,5 @@
Source: libbson
Version: 1.16.1
Port-Version: 1
Port-Version: 2
Description: libbson is a library providing useful routines related to building, parsing, and iterating BSON documents.
Homepage: https://github.com/mongodb/libbson

View File

@ -20,6 +20,8 @@ file(READ ${CMAKE_CURRENT_LIST_DIR}/CONTROL _contents)
string(REGEX MATCH "\nVersion:[ ]*[^ \n]+" _contents "${_contents}")
string(REGEX REPLACE ".+Version:[ ]*([\\.0-9]+).*" "\\1" BUILD_VERSION "${_contents}")
file(WRITE "${BUILD_VERSION}" ${SOURCE_PATH}/VERSION_CURRENT)
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
@ -31,6 +33,7 @@ vcpkg_configure_cmake(
-DENABLE_EXAMPLES=OFF
-DENABLE_STATIC=${ENABLE_STATIC}
-DBUILD_VERSION=${BUILD_VERSION}
-DCMAKE_DISABLE_FIND_PACKAGE_PythonInterp=ON
)
vcpkg_install_cmake()
@ -44,6 +47,7 @@ if (VCPKG_LIBRARY_LINKAGE STREQUAL static)
else()
vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/libbson-${PORT_POSTFIX} TARGET_PATH share/bson-${PORT_POSTFIX})
endif()
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share)
file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/share/mongo-c-driver)

View File

@ -1,6 +1,6 @@
Source: mongo-c-driver
Version: 1.16.1-1
Port-Version: 1
Version: 1.16.1
Port-Version: 3
Build-Depends: libbson, openssl (!windows), zlib
Description: Client library written in C for MongoDB.
Homepage: https://github.com/mongodb/mongo-c-driver

View File

@ -40,6 +40,8 @@ file(READ ${CMAKE_CURRENT_LIST_DIR}/CONTROL _contents)
string(REGEX MATCH "\nVersion:[ ]*[^ \n]+" _contents "${_contents}")
string(REGEX REPLACE ".+Version:[ ]*([\\.0-9]+).*" "\\1" BUILD_VERSION "${_contents}")
file(WRITE "${BUILD_VERSION}" ${SOURCE_PATH}/VERSION_CURRENT)
vcpkg_configure_cmake(
SOURCE_PATH ${SOURCE_PATH}
PREFER_NINJA
@ -55,6 +57,7 @@ vcpkg_configure_cmake(
-DENABLE_ZLIB=SYSTEM
-DENABLE_STATIC=${ENABLE_STATIC}
-DBUILD_VERSION=${BUILD_VERSION}
-DCMAKE_DISABLE_FIND_PACKAGE_PythonInterp=ON
${FEATURE_OPTIONS}
)

View File

@ -1,6 +1,6 @@
Source: nettle
Version: 3.5.1
Port-Version: 4
Port-Version: 5
Homepage: https://git.lysator.liu.se/nettle/nettle
Description: Nettle is a low-level cryptographic library that is designed to fit easily in more or less any context: In crypto toolkits for object-oriented languages (C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in kernel space.
Build-Depends: gmp, vs-yasm (windows), yasm-tool-helper (windows)

View File

@ -84,7 +84,7 @@ if(VCPKG_TARGET_IS_WINDOWS)
set(exec_prefix "\${prefix}")
set(libdir "\${prefix}/lib")
set(includedir "\${prefix}/include")
set(LIBS -lnettle -lgmp)
set(LIBS "-lnettle -lgmp")
configure_file("${SOURCE_PATH}/nettle.pc.in" "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/nettle.pc" @ONLY)
set(HOGWEED -lhogweed)
set(LIBS -lnettle)
@ -93,7 +93,7 @@ if(VCPKG_TARGET_IS_WINDOWS)
set(exec_prefix "\${prefix}")
set(libdir "\${prefix}/lib")
set(includedir "\${prefix}/../include")
set(LIBS -lnettled -lgmpd)
set(LIBS "-lnettled -lgmpd")
configure_file("${SOURCE_PATH}/nettle.pc.in" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/nettle.pc" @ONLY)
set(LIBS -lnettled)
set(HOGWEED -lhogweedd)

View File

@ -1,5 +1,5 @@
Source: x265
Version: 3.4
Port-Version: 1
Port-Version: 2
Homepage: https://github.com/videolan/x265
Description: x265 is a H.265 / HEVC video encoder application library, designed to encode video or images into an H.265 / HEVC encoded bitstream.

View File

@ -63,6 +63,17 @@ if(VCPKG_TARGET_IS_MINGW AND ENABLE_SHARED)
endif()
if(UNIX)
foreach(FILE "${CURRENT_PACKAGES_DIR}/lib/pkgconfig/x265.pc" "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/x265.pc")
if(EXISTS "${FILE}")
file(READ "${FILE}" _contents)
string(REPLACE " -lstdc++" "" _contents "${_contents}")
string(REPLACE " -lc++" "" _contents "${_contents}")
string(REPLACE " -lgcc_s" "" _contents "${_contents}")
string(REPLACE " -lgcc" "" _contents "${_contents}")
string(REPLACE " -lrt" "" _contents "${_contents}")
file(WRITE "${FILE}" "${_contents}")
endif()
endforeach()
vcpkg_fixup_pkgconfig(SYSTEM_LIBRARIES numa)
else()
vcpkg_fixup_pkgconfig()

View File

@ -91,6 +91,18 @@ function Run-Vcpkg {
./vcpkg @testArgs
}
##### Test spaces in the path
Refresh-TestRoot
$CurrentTest = "zlib with spaces in path"
Write-Host $CurrentTest
./vcpkg install zlib "--triplet" $Triplet `
"--no-binarycaching" `
"--x-buildtrees-root=$TestingRoot/build Trees" `
"--x-install-root=$TestingRoot/instalL ed" `
"--x-packages-root=$TestingRoot/packaG es"
Throw-IfFailed
##### Binary caching tests
if (-not $IsLinux -and -not $IsMacOS) {
Refresh-TestRoot
# Test msbuild props and targets

View File

@ -8,8 +8,6 @@ Fix common paths in *.pc files and make everything relativ to $(prefix)
vcpkg_fixup_pkgconfig(
[RELEASE_FILES <PATHS>...]
[DEBUG_FILES <PATHS>...]
[SYSTEM_LIBRARIES <NAMES>...]
[IGNORE_FLAGS <FLAGS>]
[SKIP_CHECK]
)
```
@ -23,37 +21,40 @@ Defaults to every *.pc file in the folder ${CURRENT_PACKAGES_DIR} without ${CURR
Specifies a list of files to apply the fixes for debug paths.
Defaults to every *.pc file in the folder ${CURRENT_PACKAGES_DIR}/debug/
### SYSTEM_LIBRARIES
If the *.pc file contains system libraries outside vcpkg these need to be listed here.
VCPKG checks every -l flag for the existence of the required library within vcpkg.
### IGNORE_FLAGS
If the *.pc file contains flags in the lib field which are not libraries. These can be listed here
### SKIP_CHECK
Skips the library checks in vcpkg_fixup_pkgconfig. Only use if the script itself has unhandled cases.
Skips the library checks in vcpkg_fixup_pkgconfig. Only use if the script itself has unhandled cases.
### SYSTEM_PACKAGES (deprecated)
This argument has been deprecated and has no effect.
### SYSTEM_LIBRARIES (deprecated)
This argument has been deprecated and has no effect.
### IGNORE_FLAGS (deprecated)
This argument has been deprecated and has no effect.
## Notes
Still work in progress. If there are more cases which can be handled here feel free to add them
## Examples
Just call `vcpkg_fixup_pkgconfig()` after any install step which installs *.pc files.
* [brotli](https://github.com/Microsoft/vcpkg/blob/master/ports/brotli/portfile.cmake)
#]===]
include(vcpkg_internal_escape_regex_control_characters)
function(vcpkg_fixup_pkgconfig_check_files pkg_cfg_cmd _file _config _system_libs _ignore_flags)
# Setup pkg-config paths
set(_VCPKG_INSTALLED_PKGCONF "${CURRENT_INSTALLED_DIR}")
set(_VCPKG_PACKAGES_PKGCONF "${CURRENT_PACKAGES_DIR}")
function(vcpkg_fixup_pkgconfig_check_files pkg_cfg_cmd _file _config)
set(PATH_SUFFIX_DEBUG /debug)
set(PKGCONFIG_INSTALLED_DIR "${_VCPKG_INSTALLED_PKGCONF}${PATH_SUFFIX_${_config}}/lib/pkgconfig")
set(PKGCONFIG_INSTALLED_SHARE_DIR "${_VCPKG_INSTALLED_PKGCONF}/share/pkgconfig")
set(PKGCONFIG_PACKAGES_DIR "${_VCPKG_PACKAGES_PKGCONF}${PATH_SUFFIX_${_config}}/lib/pkgconfig")
set(PKGCONFIG_PACKAGES_SHARE_DIR "${_VCPKG_PACKAGES_PKGCONF}/share/pkgconfig")
set(PATH_SUFFIX_RELEASE)
set(PKGCONFIG_INSTALLED_DIR "${CURRENT_INSTALLED_DIR}${PATH_SUFFIX_${_config}}/lib/pkgconfig")
set(PKGCONFIG_INSTALLED_SHARE_DIR "${CURRENT_INSTALLED_DIR}/share/pkgconfig")
set(PKGCONFIG_PACKAGES_DIR "${CURRENT_PACKAGES_DIR}${PATH_SUFFIX_${_config}}/lib/pkgconfig")
set(PKGCONFIG_PACKAGES_SHARE_DIR "${CURRENT_PACKAGES_DIR}/share/pkgconfig")
if(ENV{PKG_CONFIG_PATH})
set(BACKUP_ENV_PKG_CONFIG_PATH_${_config} $ENV{PKG_CONFIG_PATH})
if(DEFINED ENV{PKG_CONFIG_PATH})
set(BACKUP_ENV_PKG_CONFIG_PATH "$ENV{PKG_CONFIG_PATH}")
else()
unset(BACKUP_ENV_PKG_CONFIG_PATH)
endif()
if(DEFINED ENV{PKG_CONFIG_PATH} AND NOT ENV{PKG_CONFIG_PATH} STREQUAL "")
set(ENV{PKG_CONFIG_PATH} "${PKGCONFIG_INSTALLED_DIR}${VCPKG_HOST_PATH_SEPARATOR}${PKGCONFIG_INSTALLED_SHARE_DIR}${VCPKG_HOST_PATH_SEPARATOR}${PKGCONFIG_PACKAGES_DIR}${VCPKG_HOST_PATH_SEPARATOR}${PKGCONFIG_PACKAGES_SHARE_DIR}${VCPKG_HOST_PATH_SEPARATOR}$ENV{PKG_CONFIG_PATH}")
else()
set(ENV{PKG_CONFIG_PATH} "${PKGCONFIG_INSTALLED_DIR}${VCPKG_HOST_PATH_SEPARATOR}${PKGCONFIG_INSTALLED_SHARE_DIR}${VCPKG_HOST_PATH_SEPARATOR}${PKGCONFIG_PACKAGES_DIR}${VCPKG_HOST_PATH_SEPARATOR}${PKGCONFIG_PACKAGES_SHARE_DIR}")
@ -81,194 +82,31 @@ function(vcpkg_fixup_pkgconfig_check_files pkg_cfg_cmd _file _config _system_lib
debug_message("pkg-config output:${_pkg_output}")
debug_message("pkg-config error output:${_pkg_error_out}")
endif()
# Get all required libs. --static means we get all libraries required for static linkage
# which is the worst case and includes the case without --static
# This retests already tested *.pc files since pkg-config will recursivly search for
# required packages and add there link flags to the one being tested
# as such NOT_STATIC_PKGCONFIG might be used to deactivate the --static arg to pkg-config
execute_process(COMMAND "${pkg_cfg_cmd}" --print-errors ${PKGCONFIG_STATIC} --libs ${_package_name}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}"
RESULT_VARIABLE _pkg_error_var
OUTPUT_VARIABLE _pkg_libs_output
ERROR_VARIABLE _pkg_error_out
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
if(NOT _pkg_error_var EQUAL 0)
message(STATUS "pkg_cfg_cmd call with:${pkg_cfg_cmd} --libs ${_package_name} failed")
message(STATUS "pkg-config call failed with error code:${_pkg_error_var}")
message(STATUS "pkg-config output:${_pkg_libs_output}")
message(FATAL_ERROR "pkg-config error output:${_pkg_error_out}")
if(DEFINED BACKUP_ENV_PKG_CONFIG_PATH)
set(ENV{PKG_CONFIG_PATH} "${BACKUP_ENV_PKG_CONFIG_PATH}")
else()
debug_message("pkg-config returned:${_pkg_error_var}")
debug_message("pkg-config output:${_pkg_libs_output}")
debug_message("pkg-config error output:${_pkg_error_out}")
unset(ENV{PKG_CONFIG_PATH})
endif()
execute_process(COMMAND "${pkg_cfg_cmd}" --print-errors --static --libs-only-L ${_package_name}
WORKING_DIRECTORY "${CURRENT_BUILDTREES_DIR}"
RESULT_VARIABLE _pkg_error_var
OUTPUT_VARIABLE _pkg_lib_paths_output
ERROR_VARIABLE _pkg_error_out
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
if(NOT _pkg_error_var EQUAL 0)
message(STATUS "pkg_cfg_cmd call with:${pkg_cfg_cmd} --libs-only-L ${_package_name} failed")
message(STATUS "pkg-config call failed with error code:${_pkg_error_var}")
message(STATUS "pkg-config output:${_pkg_lib_paths_output}")
message(FATAL_ERROR "pkg-config error output:${_pkg_error_out}")
else()
debug_message("pkg-config returned:${_pkg_error_var}")
debug_message("pkg-config output:${_pkg_lib_paths_output}")
debug_message("pkg-config error output:${_pkg_error_out}")
endif()
string(REPLACE "\\ " "##" _pkg_lib_paths_output "${_pkg_lib_paths_output}") # Whitespace path protection
string(REGEX REPLACE "(^[\t ]*|[\t ]+)-L" ";" _pkg_lib_paths_output "${_pkg_lib_paths_output}")
debug_message("-L LIST TRANSFORMATION:'${_pkg_lib_paths_output}'")
string(REGEX REPLACE "^[\t ]*;" "" _pkg_lib_paths_output "${_pkg_lib_paths_output}")
string(REPLACE "##" "\\ " _pkg_lib_paths_output "${_pkg_lib_paths_output}")
list(REMOVE_DUPLICATES _pkg_lib_paths_output) # We don't care about linker order and repeats
## Remove search paths from LIBS
foreach(_search_path IN LISTS _pkg_lib_paths_output)
debug_message("REMOVING:'${_search_path}'")
debug_message("FROM:'${_pkg_libs_output}'")
vcpkg_internal_escape_regex_control_characters(_search_path "${_search_path}")
string(REGEX REPLACE "(^[\t ]*|[\t ]+|;[\t ]*)-L${_search_path}([\t ]+|[\t ]*$)" ";" _pkg_libs_output "${_pkg_libs_output}") # Remove search paths from libs
endforeach()
debug_message("LIBS AFTER -L<path> REMOVAL:'${_pkg_libs_output}'")
#Make the remaining libs a proper CMake List
string(REPLACE "\\ " "##" _pkg_libs_output "${_pkg_libs_output}") # Whitespace path protection
string(REGEX REPLACE "(^[\t ]*|[\t ]+)-l" ";-l" _pkg_libs_output "${_pkg_libs_output}")
string(REGEX REPLACE "[\t ]*(-pthreads?)" ";\\1" _pkg_libs_output "${_pkg_libs_output}") # handle pthread without -l here (makes a lot of problems otherwise)
string(REGEX REPLACE "^[\t ]*;[\t ]*" "" _pkg_libs_output "${_pkg_libs_output}")
string(REPLACE "##" "\\ " _pkg_libs_output "${_pkg_libs_output}")
#Windows path transformations
if(CMAKE_HOST_WIN32)
string(REGEX REPLACE "(^|;)/([a-zA-Z])/" "\\1\\2:/" _pkg_lib_paths_output "${_pkg_lib_paths_output}")
string(REGEX REPLACE " /([a-zA-Z])/" ";\\1:/" _pkg_libs_output "${_pkg_libs_output}")
string(REGEX REPLACE "-l/([a-zA-Z])/" "-l\\1:/" _pkg_libs_output "${_pkg_libs_output}")
debug_message("pkg-config output lib paths after replacement (cmake style):${_pkg_lib_paths_output}")
debug_message("pkg-config output lib after replacement (cmake style):${_pkg_libs_output}")
endif()
if("${_config}" STREQUAL "DEBUG")
set(lib_suffixes d _d _debug -s -sd _s _sd -static -staticd _static _staticd)
elseif("${_config}" STREQUAL "RELEASE")
set(lib_suffixes -s _s -static _static)
else()
message(FATAL_ERROR "Unknown configuration in vcpkg_fixup_pkgconfig_check_libraries!")
endif()
debug_message("IGNORED FLAGS:'${_ignore_flags}'")
debug_message("BEFORE IGNORE FLAGS REMOVAL: ${_pkg_libs_output}")
foreach(_ignore IN LISTS _ignore_flags) # Remove ignore with whitespace
debug_message("REMOVING FLAG:'${_ignore}'")
vcpkg_internal_escape_regex_control_characters(_ignore "${_ignore}")
string(REGEX REPLACE "(^[\t ]*|;[\t ]*|[\t ]+)${_ignore}([\t ]+|[\t ]*;|[\t ]*$)" "\\2" _pkg_libs_output "${_pkg_libs_output}")
debug_message("AFTER REMOVAL: ${_pkg_libs_output}")
endforeach()
string(REGEX REPLACE ";?[\t ]*;[\t ]*" ";" _pkg_libs_output "${_pkg_libs_output}") # Double ;; and Whitespace before/after ; removal
debug_message("SYSTEM LIBRARIES:'${_system_libs}'")
debug_message("LIBRARIES in PC:'${_pkg_libs_output}'")
foreach(_system_lib IN LISTS _system_libs) # Remove system libs with whitespace
debug_message("REMOVING:'${_system_lib}'")
debug_message("FROM:'${_pkg_libs_output}'")
string(REGEX REPLACE "(^[\t ]*|;[\t ]*|[\t ]+)(-l?)${_system_lib}([\t ]+|[\t ]*;|[\t ]*$)" "\\3" _pkg_libs_output "${_pkg_libs_output}")
string(REGEX REPLACE "(^[\t ]*|;[\t ]*|[\t ]+)${_system_lib}([\t ]+|[\t ]*;|[\t ]*$)" "\\2" _pkg_libs_output "${_pkg_libs_output}")
string(TOLOWER "${_system_lib}" _system_lib_lower)
string(REGEX REPLACE "(^[\t ]*|;[\t ]*|[\t ]+)(-l?)${_system_lib_lower}([\t ]+|[\t ]*;|[\t ]*$)" "\\3" _pkg_libs_output "${_pkg_libs_output}")
string(REGEX REPLACE "(^[\t ]*|;[\t ]*|[\t ]+)${_system_lib_lower}([\t ]+|[\t ]*;|[\t ]*$)" "\\2" _pkg_libs_output "${_pkg_libs_output}")
debug_message("AFTER REMOVAL:'${_pkg_libs_output}'")
endforeach()
list(REMOVE_DUPLICATES _pkg_libs_output) # We don't care about linker order and repeats
string(REGEX REPLACE ";?[\t ]*;[\t ]*" ";" _pkg_libs_output "${_pkg_libs_output}") # Double ;; and Whitespace before/after ; removal
debug_message("Library search paths:${_pkg_lib_paths_output}")
debug_message("Libraries to search:${_pkg_libs_output}")
set(CMAKE_FIND_LIBRARY_SUFFIXES_BACKUP ${CMAKE_FIND_LIBRARY_SUFFIXES})
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll.a .a)
foreach(_lib IN LISTS _pkg_libs_output)
if(EXISTS "${_lib}" OR "x${_lib}x" STREQUAL "xx" ) # eat; all ok _lib is a fullpath to a library or empty
continue()
elseif (_lib MATCHES "^-l(.+)$")
debug_message("Library match: CMAKE_MATCH_1:${CMAKE_MATCH_1}")
set(_libname "${CMAKE_MATCH_1}")
if(EXISTS "${_libname}")
debug_message("${_libname} detected as an existing full path!")
continue() # fullpath in -l argument and exists; all ok
endif()
debug_message("CHECK_LIB_${_libname}_${_config} before: ${CHECK_LIB_${_libname}_${_config}}")
find_library(CHECK_LIB_${_libname}_${_config} NAMES ${_libname} PATHS ${_pkg_lib_paths_output} "${CURRENT_INSTALLED_DIR}${PATH_SUFFIX_${_config}}/lib" NO_DEFAULT_PATH)
debug_message("CHECK_LIB_${_libname}_${_config} after: ${CHECK_LIB_${_libname}_${_config}}")
if(CHECK_LIB_${_libname}_${_config})
unset(CHECK_LIB_${_libname}_${_config} CACHE) # need to unset or else other configurations will not check correctly
debug_message("CHECK_LIB_${_libname}_${_config} after unset: ${CHECK_LIB_${_libname}_${_config}}")
continue() # found library; all ok
endif()
debug_message("Searching with additional suffixes: '${lib_suffixes}'")
foreach(_lib_suffix IN LISTS lib_suffixes)
string(REPLACE ".dll.a|.a|.lib|.so" "" _name_without_extension "${_libname}")
set(search_name ${_name_without_extension}${_lib_suffix})
debug_message("Search name: '${search_name}'")
debug_message("CHECK_LIB_${search_name}_${_config} before: ${CHECK_LIB_${search_name}_${_config}}")
debug_message("Search paths:'${_pkg_lib_paths_output}' '${CURRENT_INSTALLED_DIR}${PATH_SUFFIX_${_config}}/lib'")
find_library(CHECK_LIB_${search_name}_${_config} NAMES ${search_name} PATHS ${_pkg_lib_paths_output} "${CURRENT_INSTALLED_DIR}${PATH_SUFFIX_${_config}}/lib" NO_DEFAULT_PATH)
debug_message("CHECK_LIB_${search_name}_${_config} after: ${CHECK_LIB_${search_name}_${_config}}")
if(CHECK_LIB_${search_name}_${_config})
message(FATAL_ERROR "Found ${CHECK_LIB_${search_name}_${_config}} with additional '${_lib_suffix}' suffix! Please correct the *.pc file!")
unset(CHECK_LIB_${search_name}_${_config} CACHE) # need to unset or else other configurations will not check correctly
endif()
endforeach()
# Reaching here means error!
message(STATUS "CHECK_LIB_${_libname}_${_config}:${CHECK_LIB_${_libname}_${_config}}")
message(FATAL_ERROR "Library \"${_libname}\" was not found! If it is a system library use the SYSTEM_LIBRARIES parameter for the vcpkg_fixup_pkgconfig call! Otherwise, correct the *.pc file")
else ()
message(FATAL_ERROR "Unhandled string \"${_lib}\" was found! If it is a system library use the SYSTEM_LIBRARIES parameter for the vcpkg_fixup_pkgconfig call! Otherwise, correct the *.pc file or add the case to vcpkg_fixup_pkgconfig")
endif()
endforeach()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BACKUP})
endfunction()
function(vcpkg_fixup_pkgconfig)
# parse parameters such that semicolons in options arguments to COMMAND don't get erased
cmake_parse_arguments(PARSE_ARGV 0 _vfpkg "SKIP_CHECK;NOT_STATIC_PKGCONFIG" "" "RELEASE_FILES;DEBUG_FILES;SYSTEM_LIBRARIES;SYSTEM_PACKAGES;IGNORE_FLAGS")
cmake_parse_arguments(PARSE_ARGV 0 _vfpkg "SKIP_CHECK" "" "RELEASE_FILES;DEBUG_FILES;SYSTEM_LIBRARIES;SYSTEM_PACKAGES;IGNORE_FLAGS")
# Note about SYSTEM_PACKAGES: pkg-config requires all packages mentioned in pc files to exists. Otherwise pkg-config will fail to find the pkg.
# As such naming any SYSTEM_PACKAGES is damned to fail which is why it is not mentioned in the docs at the beginning.
if(VCPKG_SYSTEM_LIBRARIES)
list(APPEND _vfpkg_SYSTEM_LIBRARIES ${VCPKG_SYSTEM_LIBRARIES})
endif()
if(_vfpkg_NOT_STATIC_PKGCONFIG)
set(PKGCONFIG_STATIC)
else()
set(PKGCONFIG_STATIC --static)
endif()
if(_vfpkg_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "vcpkg_fixup_pkgconfig was passed extra arguments: ${_vfct_UNPARSED_ARGUMENTS}")
message(FATAL_ERROR "vcpkg_fixup_pkgconfig() was passed extra arguments: ${_vfct_UNPARSED_ARGUMENTS}")
endif()
vcpkg_internal_escape_regex_control_characters(_vfpkg_ESCAPED_CURRENT_PACKAGES_DIR "${CURRENT_PACKAGES_DIR}")
if(NOT _vfpkg_RELEASE_FILES)
if((DEFINED _vfpkg_RELEASE_FILES AND NOT DEFINED _vfpkg_DEBUG_FILES) OR (NOT DEFINED _vfpkg_RELEASE_FILES AND DEFINED _vfpkg_DEBUG_FILES))
message(FATAL_ERROR "vcpkg_fixup_pkgconfig() requires both or neither of DEBUG_FILES and RELEASE_FILES")
endif()
if(NOT DEFINED _vfpkg_RELEASE_FILES)
file(GLOB_RECURSE _vfpkg_RELEASE_FILES "${CURRENT_PACKAGES_DIR}/**/*.pc")
list(FILTER _vfpkg_RELEASE_FILES EXCLUDE REGEX "${_vfpkg_ESCAPED_CURRENT_PACKAGES_DIR}/debug/")
endif()
if(NOT _vfpkg_DEBUG_FILES)
file(GLOB_RECURSE _vfpkg_DEBUG_FILES "${CURRENT_PACKAGES_DIR}/debug/**/*.pc")
if(_vfpkg_DEBUG_FILES)
list(REMOVE_ITEM _vfpkg_RELEASE_FILES ${_vfpkg_DEBUG_FILES})
endif()
endif()
vcpkg_find_acquire_program(PKGCONFIG)
@ -278,60 +116,71 @@ function(vcpkg_fixup_pkgconfig)
string(REGEX REPLACE "([a-zA-Z]):/" "/\\1/" _VCPKG_PACKAGES_DIR "${CURRENT_PACKAGES_DIR}")
string(REGEX REPLACE "([a-zA-Z]):/" "/\\1/" _VCPKG_INSTALLED_DIR "${CURRENT_INSTALLED_DIR}")
debug_message("Release Files: ${_vfpkg_RELEASE_FILES}")
foreach(_file ${_vfpkg_RELEASE_FILES})
message(STATUS "Fixing pkgconfig file: ${_file}")
get_filename_component(PKG_LIB_SEARCH_PATH "${_file}" DIRECTORY)
file(RELATIVE_PATH RELATIVE_PC_PATH "${PKG_LIB_SEARCH_PATH}" "${CURRENT_PACKAGES_DIR}")
string(REGEX REPLACE "/$" "" RELATIVE_PC_PATH "${RELATIVE_PC_PATH}")
#Correct *.pc file
file(READ "${_file}" _contents)
string(REPLACE "${CURRENT_PACKAGES_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${CURRENT_INSTALLED_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${_VCPKG_PACKAGES_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${_VCPKG_INSTALLED_DIR}" "\${prefix}" _contents "${_contents}")
string(REGEX REPLACE "^prefix[\t ]*=[^\n]*" "" _contents "${_contents}")
string(REGEX REPLACE "[\n]prefix[\t ]*=[^\n]*" "" _contents "${_contents}")
file(WRITE "${_file}" "prefix=\${pcfiledir}/${RELATIVE_PC_PATH}\n${_contents}")
unset(PKG_LIB_SEARCH_PATH)
endforeach()
if(NOT _vfpkg_SKIP_CHECK) # The check can only run after all files have been corrected!
foreach(_file ${_vfpkg_RELEASE_FILES})
vcpkg_fixup_pkgconfig_check_files("${PKGCONFIG}" "${_file}" "RELEASE" "${_vfpkg_SYSTEM_LIBRARIES}" "${_vfpkg_IGNORE_FLAGS}")
foreach(CONFIG RELEASE DEBUG)
debug_message("${CONFIG} Files: ${_vfpkg_${CONFIG}_FILES}")
if(VCPKG_BUILD_TYPE STREQUAL "debug" AND CONFIG STREQUAL "RELEASE")
continue()
endif()
if(VCPKG_BUILD_TYPE STREQUAL "release" AND CONFIG STREQUAL "DEBUG")
continue()
endif()
foreach(_file ${_vfpkg_${CONFIG}_FILES})
message(STATUS "Fixing pkgconfig file: ${_file}")
get_filename_component(PKG_LIB_SEARCH_PATH "${_file}" DIRECTORY)
if(CONFIG STREQUAL "DEBUG")
file(RELATIVE_PATH RELATIVE_PC_PATH "${PKG_LIB_SEARCH_PATH}" "${CURRENT_PACKAGES_DIR}/debug/")
else()
file(RELATIVE_PATH RELATIVE_PC_PATH "${PKG_LIB_SEARCH_PATH}" "${CURRENT_PACKAGES_DIR}")
endif()
# strip trailing slash
string(REGEX REPLACE "/$" "" RELATIVE_PC_PATH "${RELATIVE_PC_PATH}")
#Correct *.pc file
file(READ "${_file}" _contents)
string(REPLACE "${CURRENT_PACKAGES_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${CURRENT_INSTALLED_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${_VCPKG_PACKAGES_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${_VCPKG_INSTALLED_DIR}" "\${prefix}" _contents "${_contents}")
string(REGEX REPLACE "(^|\n)prefix[\t ]*=[^\n]*" "" _contents "${_contents}")
if(CONFIG STREQUAL "DEBUG")
string(REPLACE "}/debug" "}" _contents "${_contents}")
# Prefix points at the debug subfolder
string(REPLACE "\${prefix}/include" "\${prefix}/../include" _contents "${_contents}")
string(REPLACE "\${prefix}/share" "\${prefix}/../share" _contents "${_contents}")
endif()
string(REGEX REPLACE " -L(\\\${[^}]*}[^ \n\t]*)" " -L\"\\1\"" _contents "${_contents}")
string(REGEX REPLACE " -I(\\\${[^}]*}[^ \n\t]*)" " -I\"\\1\"" _contents "${_contents}")
string(REGEX REPLACE " -l(\\\${[^}]*}[^ \n\t]*)" " -l\"\\1\"" _contents "${_contents}")
# This section fuses XYZ.private and XYZ according to VCPKG_LIBRARY_LINKAGE
#
# Pkgconfig searches Requires.private transitively for Cflags in the dynamic case,
# which prevents us from removing it.
#
# Once this transformation is complete, users of vcpkg should never need to pass
# --static.
if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
# Libs comes before Libs.private
string(REGEX REPLACE "(^|\n)(Libs: [^\n]*)(.*)\nLibs.private:( [^\n]*)" "\\1\\2\\4\\3" _contents "${_contents}")
# Libs.private comes before Libs
string(REGEX REPLACE "(^|\n)Libs.private:( [^\n]*)(.*\nLibs: [^\n]*)" "\\3\\2" _contents "${_contents}")
# Only Libs.private
string(REGEX REPLACE "(^|\n)Libs.private: " "\\1Libs: " _contents "${_contents}")
# Requires comes before Requires.private
string(REGEX REPLACE "(^|\n)(Requires: [^\n]*)(.*)\nRequires.private:( [^\n]*)" "\\1\\2\\4\\3" _contents "${_contents}")
# Requires.private comes before Requires
string(REGEX REPLACE "(^|\n)Requires.private:( [^\n]*)(.*\nRequires: [^\n]*)" "\\3\\2" _contents "${_contents}")
# Only Requires.private
string(REGEX REPLACE "(^|\n)Requires.private: " "\\1Requires: " _contents "${_contents}")
endif()
file(WRITE "${_file}" "prefix=\${pcfiledir}/${RELATIVE_PC_PATH}\n${_contents}")
unset(PKG_LIB_SEARCH_PATH)
endforeach()
endif()
debug_message("Debug Files: ${_vfpkg_DEBUG_FILES}")
foreach(_file ${_vfpkg_DEBUG_FILES})
message(STATUS "Fixing pkgconfig file: ${_file}")
get_filename_component(PKG_LIB_SEARCH_PATH "${_file}" DIRECTORY)
file(RELATIVE_PATH RELATIVE_PC_PATH "${PKG_LIB_SEARCH_PATH}" "${CURRENT_PACKAGES_DIR}/debug/")
string(REGEX REPLACE "/$" "" RELATIVE_PC_PATH "${RELATIVE_PC_PATH}")
string(REGEX REPLACE "/pkgconfig/?" "" PKG_LIB_SEARCH_PATH "${PKG_LIB_SEARCH_PATH}")
#Correct *.pc file
file(READ "${_file}" _contents)
string(REPLACE "${CURRENT_PACKAGES_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${CURRENT_INSTALLED_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${_VCPKG_PACKAGES_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "${_VCPKG_INSTALLED_DIR}" "\${prefix}" _contents "${_contents}")
string(REPLACE "debug/include" "../include" _contents "${_contents}")
string(REPLACE "\${prefix}/include" "\${prefix}/../include" _contents "${_contents}")
string(REPLACE "debug/share" "../share" _contents "${_contents}")
string(REPLACE "\${prefix}/share" "\${prefix}/../share" _contents "${_contents}")
string(REPLACE "debug/lib" "lib" _contents "${_contents}") # the prefix will contain the debug keyword
string(REGEX REPLACE "^prefix[\t ]*=[^\n]*" "" _contents "${_contents}") # make pc file relocatable
string(REGEX REPLACE "[\n]prefix[\t ]*=[^\n]*" "" _contents "${_contents}") # make pc file relocatable
string(REPLACE "\${prefix}/debug" "\${prefix}" _contents "${_contents}") # replace remaining debug paths if they exist.
file(WRITE "${_file}" "prefix=\${pcfiledir}/${RELATIVE_PC_PATH}\n${_contents}")
unset(PKG_LIB_SEARCH_PATH)
if(NOT _vfpkg_SKIP_CHECK) # The check can only run after all files have been corrected!
foreach(_file ${_vfpkg_${CONFIG}_FILES})
vcpkg_fixup_pkgconfig_check_files("${PKGCONFIG}" "${_file}" "${CONFIG}")
endforeach()
endif()
endforeach()
if(NOT _vfpkg_SKIP_CHECK) # The check can only run after all files have been corrected!
foreach(_file ${_vfpkg_DEBUG_FILES})
vcpkg_fixup_pkgconfig_check_files("${PKGCONFIG}" "${_file}" "DEBUG" "${_vfpkg_SYSTEM_LIBRARIES}" "${_vfpkg_IGNORE_FLAGS}")
endforeach()
endif()
debug_message("Fixing pkgconfig --- finished")
set(VCPKG_FIXUP_PKGCONFIG_CALLED TRUE CACHE INTERNAL "See below" FORCE)
@ -340,14 +189,3 @@ function(vcpkg_fixup_pkgconfig)
# or check if this function has been called if *.pc files are detected.
# The same is true for vcpkg_fixup_cmake_targets
endfunction()
# script to test the function locally without running vcpkg. Uncomment fix filepaths and use cmake -P vcpkg_fixup_pkgconfig
# set(_file "G:\\xlinux\\packages\\xlib_x64-windows\\lib\\pkgconfig\\x11.pc")
# include(${CMAKE_CURRENT_LIST_DIR}/vcpkg_common_definitions.cmake)
# file(READ "${_file}" _contents)
# set(CURRENT_INSTALLED_DIR "G:/xlinux/installed/x64-windows")
# set(CURRENT_PACKAGES_DIR "G:/xlinux/packages/xlib_x64-windows")
# set(_vfpkg_SYSTEM_LIBRARIES "blu\\ ub")
# set(_vfpkg_SYSTEM_PACKAGES "szip")
# vcpkg_fixup_pkgconfig_check_libraries("RELEASE" _contents "${_vfpkg_SYSTEM_LIBRARIES}" "${_vfpkg_SYSTEM_PACKAGES}")