From 144021a43b16b2c6cb9c0ec20b4595b1b9629efe Mon Sep 17 00:00:00 2001 From: Gleb Popov <6yearold@gmail.com> Date: Thu, 18 Jun 2026 20:58:29 +0300 Subject: [PATCH 1/2] file(GET_RUNTIME_DEPENDENCIES): Implement command for FreeBSD Closes: #25305 --- Help/command/file.rst | 8 +++++- .../dev/freebsd-get-runtime-dependencies.rst | 5 ++++ Source/cmLDConfigLDConfigTool.cxx | 27 ++++++++++++++++++- Source/cmRuntimeDependencyArchive.cxx | 12 ++++++--- .../RunCMakeTest.cmake | 2 +- .../file-filter-all-check.cmake | 2 +- .../file-filter.cmake | 2 +- 7 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 Help/release/dev/freebsd-get-runtime-dependencies.rst diff --git a/Help/command/file.rst b/Help/command/file.rst index 0b9fe56296..5ddf4dacbb 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -1487,7 +1487,13 @@ Handling Runtime Binaries for. This could be one of several values: * ``linux+elf`` + + * ``freebsd+elf`` + + .. versionadded:: 4.5 + * ``windows+pe`` + * ``macos+macho`` If this variable is not specified, it is determined automatically by system @@ -1502,7 +1508,7 @@ Handling Runtime Binaries ================================================= ============================================= ``CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM`` ``CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL`` ================================================= ============================================= - ``linux+elf`` ``objdump`` + ``linux+elf``, ``freebsd+elf`` ``objdump`` ``windows+pe`` ``objdump`` or ``dumpbin`` ``macos+macho`` ``otool`` ================================================= ============================================= diff --git a/Help/release/dev/freebsd-get-runtime-dependencies.rst b/Help/release/dev/freebsd-get-runtime-dependencies.rst new file mode 100644 index 0000000000..5f7d2a1436 --- /dev/null +++ b/Help/release/dev/freebsd-get-runtime-dependencies.rst @@ -0,0 +1,5 @@ +freebsd-get-runtime-dependencies +-------------------------------- + +* The :command:`file(GET_RUNTIME_DEPENDENCIES)` command is now implemented + on FreeBSD. diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx index 4afdce3f6b..d062f1b632 100644 --- a/Source/cmLDConfigLDConfigTool.cxx +++ b/Source/cmLDConfigLDConfigTool.cxx @@ -36,9 +36,13 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector& paths) } cmList ldConfigCommand{ ldConfigPath }; +#ifdef __FreeBSD__ + ldConfigCommand.emplace_back("-r"); // List directories +#else ldConfigCommand.emplace_back("-v"); ldConfigCommand.emplace_back("-N"); // Don't rebuild the cache. ldConfigCommand.emplace_back("-X"); // Don't update links. +#endif cmUVProcessChainBuilder builder; builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) @@ -50,14 +54,35 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector& paths) } std::string line; - static cmsys::RegularExpression const regex("^([^\t:]*):"); cmUVIStream output(process.OutputStream()); +#ifdef __FreeBSD__ + // FreeBSD ldconfig output: + // /var/run/ld-elf.so.hints: + // search directories: /lib:/usr/lib:... + // Extract everything after "search directories: " and split by ':' + static cmsys::RegularExpression regex("search directories: (.*)$"); + while (std::getline(output, line)) { + cmsys::RegularExpressionMatch match; + if (!regex.find(line.c_str(), match)) + continue; + auto allPaths = std::stringstream(match.match(1)); + std::string path; + while (std::getline(allPaths, path, ':')) + if (!path.empty()) + paths.push_back(path); + } +#else + // Linux ldconfig output: + // /lib64: (from :0) + // Extract the "/lib64" part + static cmsys::RegularExpression const regex("^([^\t:]*):"); while (std::getline(output, line)) { cmsys::RegularExpressionMatch match; if (regex.find(line.c_str(), match)) { paths.push_back(match.match(1)); } } +#endif if (!process.Wait()) { this->Archive->SetError("Failed to wait on ldconfig process"); diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx index a837b72634..82fbdde8d4 100644 --- a/Source/cmRuntimeDependencyArchive.cxx +++ b/Source/cmRuntimeDependencyArchive.cxx @@ -153,9 +153,11 @@ bool cmRuntimeDependencyArchive::Prepare() platform = "macos+macho"; } else if (systemName == "Linux") { platform = "linux+elf"; + } else if (systemName == "FreeBSD") { + platform = "freebsd+elf"; } } - if (platform == "linux+elf") { + if (platform == "linux+elf" || platform == "freebsd+elf") { this->Linker = cm::make_unique(this); } else if (platform == "windows+pe") { this->Linker = cm::make_unique(this); @@ -403,7 +405,11 @@ cmRuntimeDependencyArchive::GetRPaths() const bool cmRuntimeDependencyArchive::PlatformSupportsRuntimeDependencies( std::string const& platform) { - static std::set const supportedPlatforms = { "Windows", "Linux", - "Darwin" }; + static std::set const supportedPlatforms = { + "Windows", + "Linux", + "Darwin", + "FreeBSD", + }; return supportedPlatforms.count(platform); } diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake index 88ed1bb648..37948240de 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake @@ -60,7 +60,7 @@ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") run_cmake(project) run_cmake(badargs1) run_cmake(badargs2) -elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD") if(DEFINED ENV{LDFLAGS}) # Some setups prebake disable-new-dtags into LDFLAGS string(REPLACE "-Wl,--disable-new-dtags" "" new_ldflags "$ENV{LDFLAGS}") diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter-all-check.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter-all-check.cmake index 9622f877ca..c9edf4a367 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter-all-check.cmake +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter-all-check.cmake @@ -1,4 +1,4 @@ -if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD") set(_check [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter-build/root-all/bin/\.\./lib/libdep1\.so]] [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter-build/root-all/bin/\.\./lib/libdep2\.so]] diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter.cmake index fef084b96a..30f0b14c42 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter.cmake +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/file-filter.cmake @@ -40,7 +40,7 @@ ${call_list} add_executable(exe "${CMAKE_BINARY_DIR}/main.c") target_link_libraries(exe PRIVATE ${dep_list}) -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") set_property(TARGET exe PROPERTY INSTALL_RPATH "\${ORIGIN}/../lib") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set_property(TARGET exe PROPERTY INSTALL_RPATH "@loader_path/../lib") From ad0dfd51ba59d34accd73d5d494b85ff4a3823bf Mon Sep 17 00:00:00 2001 From: Gleb Popov <6yearold@gmail.com> Date: Mon, 22 Jun 2026 22:50:38 +0300 Subject: [PATCH 2/2] Tests: Enable some Linux cases on FreeBSD --- Tests/ExportImport/CMakeLists.txt | 2 +- Tests/ExportImport/Import/CMakeLists.txt | 2 +- .../install-IMPORTED_RUNTIME_ARTIFACTS/check_installed.cmake | 2 +- .../Import/install-RUNTIME_DEPENDENCIES/check_installed.cmake | 2 +- .../install-RUNTIME_DEPENDENCY_SET/check_installed.cmake | 2 +- Tests/RunCMake/install/RunCMakeTest.cmake | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Tests/ExportImport/CMakeLists.txt b/Tests/ExportImport/CMakeLists.txt index 82b21c4f13..1680f25845 100644 --- a/Tests/ExportImport/CMakeLists.txt +++ b/Tests/ExportImport/CMakeLists.txt @@ -80,7 +80,7 @@ set_property( # Run the install tests. set(install_deps) set(rdep_tests) -if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|Windows|Darwin)$" AND NOT CMake_INSTALL_NAME_TOOL_BUG) +if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|Windows|Darwin|FreeBSD)$" AND NOT CMake_INSTALL_NAME_TOOL_BUG) set(rdep_tests RUNTIME_DEPENDENCIES RUNTIME_DEPENDENCY_SET) endif() foreach(name IMPORTED_RUNTIME_ARTIFACTS ${rdep_tests}) diff --git a/Tests/ExportImport/Import/CMakeLists.txt b/Tests/ExportImport/Import/CMakeLists.txt index fdc07ed423..2dd1b1799c 100644 --- a/Tests/ExportImport/Import/CMakeLists.txt +++ b/Tests/ExportImport/Import/CMakeLists.txt @@ -33,7 +33,7 @@ add_subdirectory(version_range) add_subdirectory(install-IMPORTED_RUNTIME_ARTIFACTS) # Test install(RUNTIME_DEPENDENCIES) and install(RUNTIME_DEPENDENCY_SET) -if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|Windows|Darwin)$") +if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|Windows|Darwin|FreeBSD)$") add_subdirectory(install-RUNTIME_DEPENDENCIES) add_subdirectory(install-RUNTIME_DEPENDENCY_SET) endif() diff --git a/Tests/ExportImport/Import/install-IMPORTED_RUNTIME_ARTIFACTS/check_installed.cmake b/Tests/ExportImport/Import/install-IMPORTED_RUNTIME_ARTIFACTS/check_installed.cmake index 054ce9cc04..61aa12b438 100644 --- a/Tests/ExportImport/Import/install-IMPORTED_RUNTIME_ARTIFACTS/check_installed.cmake +++ b/Tests/ExportImport/Import/install-IMPORTED_RUNTIME_ARTIFACTS/check_installed.cmake @@ -1,6 +1,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/../check_installed.cmake") -if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD") set(_dirs [[aaa;aaa/executables;aaa/executables/testExe1-4;aaa/executables/testExe3;aaa/libraries;aaa/libraries/libtestExe2lib\.so;aaa/libraries/libtestLib3lib(-d|-r)?\.so\.1\.2;aaa/libraries/libtestLib3lib(-d|-r)?\.so\.3;aaa/libraries/libtestLib4\.so;aaa/libraries/libtestMod1\.so;aaa/libraries/libtestMod2\.so]]) set(_alldest [[bbb;bbb/libtestExe2lib\.so;bbb/libtestLib3lib(-d|-r)?\.so\.1\.2;bbb/libtestLib3lib(-d|-r)?\.so\.3;bbb/libtestLib4\.so;bbb/libtestMod1\.so;bbb/libtestMod2\.so;bbb/testExe1-4;bbb/testExe3]]) set(_default [[bin;bin/testExe1-4;bin/testExe3;lib;lib/libtestExe2lib\.so;lib/libtestLib3lib(-d|-r)?\.so\.1\.2;lib/libtestLib3lib(-d|-r)?\.so\.3;lib/libtestLib4\.so;lib/libtestMod1\.so;lib/libtestMod2\.so]]) diff --git a/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/check_installed.cmake b/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/check_installed.cmake index 8b193f6b8d..7dd65c6eb7 100644 --- a/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/check_installed.cmake +++ b/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/check_installed.cmake @@ -1,6 +1,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/../check_installed.cmake") -if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD") check_installed([[^lib;lib/libdep8\.so;lib/liblib\.so;subdir;subdir/bin;subdir/bin/exe1;subdir/bin/exe2;subdir/lib;subdir/lib/libdep10\.so;subdir/lib/libdep11\.so;subdir/lib/libdep2\.so\.1;subdir/lib/libdep2\.so\.1\.2\.3;subdir/lib/libdep3\.so;subdir/lib/libdep5\.so;subdir/lib/libdep6\.so;subdir/lib/libdep8\.so;subdir/lib/libdep9\.so;subdir/lib/liblib\.so;subdir/lib/libmod\.so;subdir/lib/libsublib1\.so$]]) elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") set(_msvc_check [[bin;bin/dep8\.dll;bin/lib\.dll;lib;lib/lib\.(lib|l);subdir;subdir/bin;subdir/bin/dep10\.dll;subdir/bin/dep11\.dll;subdir/bin/dep2\.dll;subdir/bin/dep3\.dll;subdir/bin/dep5\.dll;subdir/bin/dep6\.dll;subdir/bin/dep8\.dll;subdir/bin/dep9\.dll;subdir/bin/exe1\.exe;subdir/bin/exe2\.exe;subdir/bin/lib\.dll;subdir/bin/sublib1\.dll;subdir/lib;subdir/lib/mod\.dll]]) diff --git a/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCY_SET/check_installed.cmake b/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCY_SET/check_installed.cmake index 052ccede57..ee8b04aeed 100644 --- a/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCY_SET/check_installed.cmake +++ b/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCY_SET/check_installed.cmake @@ -1,6 +1,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/../check_installed.cmake") -if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD") check_installed([[^bin;bin/exe;lib;lib/libdep1\.so;lib/libdep3\.so;lib/libdeplib\.so;yyy;yyy/lib;yyy/lib/libdep1\.so;yyy/lib/libdep3\.so;yyy/lib/libdep4\.so;zzz;zzz/libdep1\.so;zzz/libdep3\.so;zzz/libdep4\.so$]]) elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") set(_msvc_check [[bin;bin/dep1\.dll;bin/dep3\.dll;bin/deplib\.dll;bin/exe\.exe;yyy;yyy/bin;yyy/bin/dep1\.dll;yyy/bin/dep3\.dll;yyy/bin/dep4\.dll;zzz;zzz/dep1\.dll;zzz/dep3\.dll;zzz/dep4\.dll]]) diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index 1bbe001bfc..6f1be1e192 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -58,7 +58,7 @@ function(run_cmake_EDIT_RPATH_only case) run_cmake(${case}) else() # Sanity check against a platform known to be ELF-based - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") message(FATAL_ERROR "Expected platform Linux to advertise itself as ELF-based, but it did not.") elseif(CMAKE_SYSTEM_NAME STREQUAL "AIX") message(FATAL_ERROR "Expected platform AIX to advertise itself as XCOFF-based, but it did not.") @@ -216,7 +216,7 @@ elseif (CMake_TEST_install_VARIANT STREQUAL "Targets") run_cmake(TARGETS-RUNTIME_DEPENDENCIES-macos-no-framework) endif() - if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$") + if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows|FreeBSD)$") run_install_test(TARGETS-RUNTIME_DEPENDENCIES-nodep) run_install_test(TARGETS-RUNTIME_DEPENDENCIES-empty) set(RunCMake_TEST_OPTIONS "-DCMAKE_SYSTEM_NAME:STRING=${CMAKE_SYSTEM_NAME}")