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] 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")