[vcpkg-scripts] Fix rpath fixup; add test (#37964)

Fix fixup for debug tools,
https://github.com/microsoft/vcpkg/pull/37736#issuecomment-2035415913.
Fix fixup for paths with regex chars,
https://github.com/microsoft/vcpkg/issues/37984.
This commit is contained in:
Kai Pastor 2024-04-23 21:09:16 +02:00 committed by GitHub
parent 43586b1aa0
commit a59ba45e60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 157 additions and 27 deletions

View File

@ -4,49 +4,47 @@ function(z_vcpkg_calculate_corrected_rpath)
"ELF_FILE_DIR;ORG_RPATH;OUT_NEW_RPATH_VAR"
"")
set(elf_file_dir "${arg_ELF_FILE_DIR}")
set(org_rpath "${arg_ORG_RPATH}")
set(current_prefix "${CURRENT_PACKAGES_DIR}")
set(current_installed_prefix "${CURRENT_INSTALLED_DIR}")
if(elf_file_dir MATCHES "debug/")
file(RELATIVE_PATH relative_from_packages "${CURRENT_PACKAGES_DIR}" "${arg_ELF_FILE_DIR}")
if("${relative_from_packages}/" MATCHES "^debug/|^(manual-tools|tools)/[^/]*/debug/")
set(current_prefix "${CURRENT_PACKAGES_DIR}/debug")
set(current_installed_prefix "${CURRENT_INSTALLED_DIR}/debug")
endif()
# compute path relative to lib
file(RELATIVE_PATH relative_to_lib "${elf_file_dir}" "${current_prefix}/lib")
file(RELATIVE_PATH relative_to_lib "${arg_ELF_FILE_DIR}" "${current_prefix}/lib")
# compute path relative to prefix
file(RELATIVE_PATH relative_to_prefix "${elf_file_dir}" "${current_prefix}")
file(RELATIVE_PATH relative_to_prefix "${arg_ELF_FILE_DIR}" "${current_prefix}")
set(rpath_norm "")
if(NOT org_rpath STREQUAL "")
cmake_path(CONVERT "${org_rpath}" TO_CMAKE_PATH_LIST rpath_norm)
list(TRANSFORM rpath_norm REPLACE "${elf_file_dir}" "\$ORIGIN")
if(NOT "${arg_ORG_RPATH}" STREQUAL "")
cmake_path(CONVERT "${arg_ORG_RPATH}" TO_CMAKE_PATH_LIST rpath_norm)
# pattern matching helpers
list(TRANSFORM rpath_norm PREPEND "::")
list(TRANSFORM rpath_norm APPEND "/")
string(REPLACE "::${arg_ELF_FILE_DIR}/" "::\$ORIGIN/" rpath_norm "${rpath_norm}")
# Remove unnecessary up/down ; don't use normalize $ORIGIN/../ will be removed otherwise
list(TRANSFORM rpath_norm REPLACE "/lib/pkgconfig/../.." "")
string(REPLACE "/lib/pkgconfig/../../" "/" rpath_norm "${rpath_norm}")
# lib relative corrections
list(TRANSFORM rpath_norm REPLACE "${current_prefix}/lib/?" "\$ORIGIN/${relative_to_lib}/")
list(TRANSFORM rpath_norm REPLACE "${current_installed_prefix}/lib/?" "\$ORIGIN/${relative_to_lib}/")
list(TRANSFORM rpath_norm REPLACE "${current_prefix}/lib/?" "\$ORIGIN/${relative_to_lib}/")
list(TRANSFORM rpath_norm REPLACE "${current_installed_prefix}/lib/?" "\$ORIGIN/${relative_to_lib}/")
string(REPLACE "::${current_prefix}/lib/" "::\$ORIGIN/${relative_to_lib}/" rpath_norm "${rpath_norm}")
string(REPLACE "::${current_installed_prefix}/lib/" "::\$ORIGIN/${relative_to_lib}/" rpath_norm "${rpath_norm}")
# prefix relativ
list(TRANSFORM rpath_norm REPLACE "${current_prefix}" "\$ORIGIN/${relative_to_prefix}/")
list(TRANSFORM rpath_norm REPLACE "${current_installed_prefix}" "\$ORIGIN/${relative_to_prefix}/")
list(TRANSFORM rpath_norm REPLACE "${current_prefix}" "\$ORIGIN/${relative_to_prefix}/")
list(TRANSFORM rpath_norm REPLACE "${current_installed_prefix}" "\$ORIGIN/${relative_to_prefix}/")
string(REPLACE "::${current_prefix}/" "::\$ORIGIN/${relative_to_prefix}/" rpath_norm "${rpath_norm}")
string(REPLACE "::${current_installed_prefix}/" "::\$ORIGIN/${relative_to_prefix}/" rpath_norm "${rpath_norm}")
if(NOT X_VCPKG_RPATH_KEEP_SYSTEM_PATHS)
list(FILTER rpath_norm INCLUDE REGEX "::\\\$ORIGIN.+") # Only keep paths relativ to ORIGIN
endif()
# Path normalization
list(TRANSFORM rpath_norm REPLACE "/+" "/")
list(TRANSFORM rpath_norm REPLACE "/^" "")
# duplication removal
list(REMOVE_ITEM rpath_norm "\$ORIGIN")
list(REMOVE_ITEM rpath_norm "\$ORIGIN/${relative_to_lib}")
if(NOT X_VCPKG_RPATH_KEEP_SYSTEM_PATHS)
list(FILTER rpath_norm INCLUDE REGEX "\\\$ORIGIN.+") # Only keep paths relativ to ORIGIN
endif()
# remove pattern matching helpers
list(TRANSFORM rpath_norm REPLACE "^::" "")
list(TRANSFORM rpath_norm REPLACE "/\$" "")
endif()
if(NOT relative_to_lib STREQUAL "")
@ -110,7 +108,7 @@ function(z_vcpkg_fixup_rpath_in_dir)
get_filename_component(elf_file_dir "${elf_file}" DIRECTORY)
Z_vcpkg_calculate_corrected_rpath(
z_vcpkg_calculate_corrected_rpath(
ELF_FILE_DIR "${elf_file_dir}"
ORG_RPATH "${readelf_output}"
OUT_NEW_RPATH_VAR new_rpath

View File

@ -188,6 +188,9 @@ endif()
if("fixup-pkgconfig" IN_LIST FEATURES)
include("${CMAKE_CURRENT_LIST_DIR}/test-vcpkg_fixup_pkgconfig.cmake")
endif()
if("fixup-rpath" IN_LIST FEATURES)
include("${CMAKE_CURRENT_LIST_DIR}/test-z_vcpkg_calculate_corrected_rpath.cmake")
endif()
if(Z_VCPKG_UNIT_TEST_HAS_ERROR)
_message(FATAL_ERROR "At least one test failed")

View File

@ -0,0 +1,121 @@
# z_vcpkg_calculate_corrected_rpath(...)
block(SCOPE_FOR VARIABLES)
set(CURRENT_PACKAGES_DIR "/P")
set(CURRENT_INSTALLED_DIR "/I")
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/lib")
]] out [[$ORIGIN]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/plugins/group")
]] out [[$ORIGIN:$ORIGIN/../../lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/debug/lib")
]] out [[$ORIGIN]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/debug/plugins/group")
]] out [[$ORIGIN:$ORIGIN/../../lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/tools/port")
]] out [[$ORIGIN:$ORIGIN/../../lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/tools/port/bin")
]] out [[$ORIGIN:$ORIGIN/../../../lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/tools/port/debug")
]] out [[$ORIGIN:$ORIGIN/../../../debug/lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/tools/port/debug/bin")
]] out [[$ORIGIN:$ORIGIN/../../../../debug/lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/manual-tools/port")
]] out [[$ORIGIN:$ORIGIN/../../lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/manual-tools/port/bin")
]] out [[$ORIGIN:$ORIGIN/../../../lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/manual-tools/port/debug")
]] out [[$ORIGIN:$ORIGIN/../../../debug/lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "" ELF_FILE_DIR "/P/manual-tools/port/debug/bin")
]] out [[$ORIGIN:$ORIGIN/../../../../debug/lib]])
# ORG_RPATH
set(X_VCPKG_RPATH_KEEP_SYSTEM_PATHS 1)
set(CURRENT_PACKAGES_DIR "/cxx/P")
set(CURRENT_INSTALLED_DIR "/cxx/I")
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/opt/lib:/usr/local/lib" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN:/opt/lib:/usr/local/lib]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/cxx/I/lib" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/cxx/P/lib" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/cxx/I/foo/lib/pkgconfig/../../bar" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
set(X_VCPKG_RPATH_KEEP_SYSTEM_PATHS 0)
set(CURRENT_PACKAGES_DIR "/cxx/P")
set(CURRENT_INSTALLED_DIR "/cxx/I")
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/opt/lib:/usr/local/lib" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/cxx/I/foo/bar" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/cxx/P/foo/bar" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/cxx/I/foo/lib/pkgconfig/../../bar" ELF_FILE_DIR "/cxx/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
# https://github.com/microsoft/vcpkg/issues/37984
set(CURRENT_PACKAGES_DIR "/c++/P")
set(CURRENT_INSTALLED_DIR "/c++/I")
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/c++/I/foo/bar" ELF_FILE_DIR "/c++/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/c++/P/foo/bar" ELF_FILE_DIR "/c++/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
set(CURRENT_PACKAGES_DIR "/(c)/P")
set(CURRENT_INSTALLED_DIR "/(c)/I")
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/(c)/I/foo/bar" ELF_FILE_DIR "/(c)/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
unit_test_check_variable_equal([[
z_vcpkg_calculate_corrected_rpath(OUT_NEW_RPATH_VAR "out" ORG_RPATH "/(c)/P/foo/bar" ELF_FILE_DIR "/(c)/P/lib")
]] out [[$ORIGIN:$ORIGIN/../foo/bar]])
endblock()

View File

@ -7,6 +7,10 @@
"default-features": [
"backup-restore-env-vars",
"fixup-pkgconfig",
{
"name": "fixup-rpath",
"platform": "!windows"
},
"function-arguments",
"host-path-list",
"list",
@ -21,6 +25,10 @@
"fixup-pkgconfig": {
"description": "Test the vcpkg_fixup_pkgconfig function"
},
"fixup-rpath": {
"description": "Test the rpath fixup function",
"supports": "!windows"
},
"function-arguments": {
"description": "Test the z_vcpkg_function_arguments function"
},