Skip to content

Commit

Permalink
[vcpkg-scripts] Fix rpath fixup; add test (#37964)
Browse files Browse the repository at this point in the history
Fix fixup for debug tools,
#37736 (comment).
Fix fixup for paths with regex chars,
#37984.
  • Loading branch information
dg0yt authored Apr 23, 2024
1 parent 43586b1 commit a59ba45
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 27 deletions.
52 changes: 25 additions & 27 deletions scripts/cmake/z_vcpkg_fixup_rpath.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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 "")
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions scripts/test_ports/unit-test-cmake/portfile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
8 changes: 8 additions & 0 deletions scripts/test_ports/unit-test-cmake/vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"default-features": [
"backup-restore-env-vars",
"fixup-pkgconfig",
{
"name": "fixup-rpath",
"platform": "!windows"
},
"function-arguments",
"host-path-list",
"list",
Expand All @@ -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"
},
Expand Down

0 comments on commit a59ba45

Please sign in to comment.