file(GET_RUNTIME_DEPENDENCIES): Implement command for FreeBSD

Closes: #25305
This commit is contained in:
Gleb Popov
2026-06-18 20:58:29 +03:00
parent 23c5b40924
commit 144021a43b
7 changed files with 50 additions and 8 deletions

View File

@@ -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``
================================================= =============================================

View File

@@ -0,0 +1,5 @@
freebsd-get-runtime-dependencies
--------------------------------
* The :command:`file(GET_RUNTIME_DEPENDENCIES)` command is now implemented
on FreeBSD.

View File

@@ -36,9 +36,13 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& 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<std::string>& 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 <builtin>: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");

View File

@@ -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<cmBinUtilsLinuxELFLinker>(this);
} else if (platform == "windows+pe") {
this->Linker = cm::make_unique<cmBinUtilsWindowsPELinker>(this);
@@ -403,7 +405,11 @@ cmRuntimeDependencyArchive::GetRPaths() const
bool cmRuntimeDependencyArchive::PlatformSupportsRuntimeDependencies(
std::string const& platform)
{
static std::set<std::string> const supportedPlatforms = { "Windows", "Linux",
"Darwin" };
static std::set<std::string> const supportedPlatforms = {
"Windows",
"Linux",
"Darwin",
"FreeBSD",
};
return supportedPlatforms.count(platform);
}

View File

@@ -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}")

View File

@@ -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]]

View File

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