mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
file(GET_RUNTIME_DEPENDENCIES): Add undocumented RPATH_PREFIX option
This commit is contained in:
@@ -65,18 +65,18 @@ bool cmBinUtilsMacOSMachOLinker::ScanDependencies(
|
|||||||
if (!executableFile.empty()) {
|
if (!executableFile.empty()) {
|
||||||
executablePath = cmSystemTools::GetFilenamePath(executableFile);
|
executablePath = cmSystemTools::GetFilenamePath(executableFile);
|
||||||
}
|
}
|
||||||
return this->ScanDependencies(file, executablePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cmBinUtilsMacOSMachOLinker::ScanDependencies(
|
|
||||||
std::string const& file, std::string const& executablePath)
|
|
||||||
{
|
|
||||||
std::vector<std::string> libs;
|
std::vector<std::string> libs;
|
||||||
std::vector<std::string> rpaths;
|
std::vector<std::string> rpaths;
|
||||||
if (!this->Tool->GetFileInfo(file, libs, rpaths)) {
|
if (!this->Tool->GetFileInfo(file, libs, rpaths)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return this->ScanDependencies(file, libs, rpaths, executablePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmBinUtilsMacOSMachOLinker::ScanDependencies(
|
||||||
|
std::string const& file, std::vector<std::string> const& libs,
|
||||||
|
std::vector<std::string> const& rpaths, std::string const& executablePath)
|
||||||
|
{
|
||||||
std::string loaderPath = cmSystemTools::GetFilenamePath(file);
|
std::string loaderPath = cmSystemTools::GetFilenamePath(file);
|
||||||
return this->GetFileDependencies(libs, executablePath, loaderPath, rpaths);
|
return this->GetFileDependencies(libs, executablePath, loaderPath, rpaths);
|
||||||
}
|
}
|
||||||
@@ -98,8 +98,14 @@ bool cmBinUtilsMacOSMachOLinker::GetFileDependencies(
|
|||||||
!IsMissingSystemDylib(path)) {
|
!IsMissingSystemDylib(path)) {
|
||||||
auto filename = cmSystemTools::GetFilenameName(path);
|
auto filename = cmSystemTools::GetFilenameName(path);
|
||||||
bool unique;
|
bool unique;
|
||||||
this->Archive->AddResolvedPath(filename, path, unique);
|
std::vector<std::string> libs;
|
||||||
if (unique && !this->ScanDependencies(path, executablePath)) {
|
std::vector<std::string> depRpaths;
|
||||||
|
if (!this->Tool->GetFileInfo(path, libs, depRpaths)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->Archive->AddResolvedPath(filename, path, unique, depRpaths);
|
||||||
|
if (unique &&
|
||||||
|
!this->ScanDependencies(path, libs, depRpaths, executablePath)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,8 @@ private:
|
|||||||
std::unique_ptr<cmBinUtilsMacOSMachOGetRuntimeDependenciesTool> Tool;
|
std::unique_ptr<cmBinUtilsMacOSMachOGetRuntimeDependenciesTool> Tool;
|
||||||
|
|
||||||
bool ScanDependencies(std::string const& file,
|
bool ScanDependencies(std::string const& file,
|
||||||
|
std::vector<std::string> const& libs,
|
||||||
|
std::vector<std::string> const& rpaths,
|
||||||
std::string const& executablePath);
|
std::string const& executablePath);
|
||||||
|
|
||||||
bool GetFileDependencies(std::vector<std::string> const& names,
|
bool GetFileDependencies(std::vector<std::string> const& names,
|
||||||
|
@@ -3032,6 +3032,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
|||||||
std::string ResolvedDependenciesVar;
|
std::string ResolvedDependenciesVar;
|
||||||
std::string UnresolvedDependenciesVar;
|
std::string UnresolvedDependenciesVar;
|
||||||
std::string ConflictingDependenciesPrefix;
|
std::string ConflictingDependenciesPrefix;
|
||||||
|
std::string RPathPrefix;
|
||||||
std::string BundleExecutable;
|
std::string BundleExecutable;
|
||||||
std::vector<std::string> Executables;
|
std::vector<std::string> Executables;
|
||||||
std::vector<std::string> Libraries;
|
std::vector<std::string> Libraries;
|
||||||
@@ -3053,6 +3054,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
|||||||
&Arguments::UnresolvedDependenciesVar)
|
&Arguments::UnresolvedDependenciesVar)
|
||||||
.Bind("CONFLICTING_DEPENDENCIES_PREFIX"_s,
|
.Bind("CONFLICTING_DEPENDENCIES_PREFIX"_s,
|
||||||
&Arguments::ConflictingDependenciesPrefix)
|
&Arguments::ConflictingDependenciesPrefix)
|
||||||
|
.Bind("RPATH_PREFIX"_s, &Arguments::RPathPrefix)
|
||||||
.Bind("BUNDLE_EXECUTABLE"_s, &Arguments::BundleExecutable)
|
.Bind("BUNDLE_EXECUTABLE"_s, &Arguments::BundleExecutable)
|
||||||
.Bind("EXECUTABLES"_s, &Arguments::Executables)
|
.Bind("EXECUTABLES"_s, &Arguments::Executables)
|
||||||
.Bind("LIBRARIES"_s, &Arguments::Libraries)
|
.Bind("LIBRARIES"_s, &Arguments::Libraries)
|
||||||
@@ -3135,6 +3137,11 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
|||||||
|
|
||||||
if (unique) {
|
if (unique) {
|
||||||
deps.push_back(firstPath);
|
deps.push_back(firstPath);
|
||||||
|
if (!parsedArgs.RPathPrefix.empty()) {
|
||||||
|
status.GetMakefile().AddDefinition(
|
||||||
|
parsedArgs.RPathPrefix + "_" + firstPath,
|
||||||
|
cmJoin(archive.GetRPaths().at(firstPath), ";"));
|
||||||
|
}
|
||||||
} else if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
|
} else if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
|
||||||
conflictingDeps.push_back(val.first);
|
conflictingDeps.push_back(val.first);
|
||||||
std::vector<std::string> paths;
|
std::vector<std::string> paths;
|
||||||
|
@@ -354,9 +354,9 @@ bool cmRuntimeDependencyArchive::IsPostExcluded(const std::string& name) const
|
|||||||
fileSearch(this->PostExcludeFiles)));
|
fileSearch(this->PostExcludeFiles)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmRuntimeDependencyArchive::AddResolvedPath(const std::string& name,
|
void cmRuntimeDependencyArchive::AddResolvedPath(
|
||||||
const std::string& path,
|
const std::string& name, const std::string& path, bool& unique,
|
||||||
bool& unique)
|
std::vector<std::string> rpaths)
|
||||||
{
|
{
|
||||||
auto it = this->ResolvedPaths.emplace(name, std::set<std::string>{}).first;
|
auto it = this->ResolvedPaths.emplace(name, std::set<std::string>{}).first;
|
||||||
unique = true;
|
unique = true;
|
||||||
@@ -367,6 +367,7 @@ void cmRuntimeDependencyArchive::AddResolvedPath(const std::string& name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
it->second.insert(path);
|
it->second.insert(path);
|
||||||
|
this->RPaths[path] = std::move(rpaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmRuntimeDependencyArchive::AddUnresolvedPath(const std::string& name)
|
void cmRuntimeDependencyArchive::AddUnresolvedPath(const std::string& name)
|
||||||
@@ -390,3 +391,9 @@ const std::set<std::string>& cmRuntimeDependencyArchive::GetUnresolvedPaths()
|
|||||||
{
|
{
|
||||||
return this->UnresolvedPaths;
|
return this->UnresolvedPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::map<std::string, std::vector<std::string>>&
|
||||||
|
cmRuntimeDependencyArchive::GetRPaths() const
|
||||||
|
{
|
||||||
|
return this->RPaths;
|
||||||
|
}
|
||||||
|
@@ -45,12 +45,13 @@ public:
|
|||||||
bool IsPostExcluded(const std::string& name) const;
|
bool IsPostExcluded(const std::string& name) const;
|
||||||
|
|
||||||
void AddResolvedPath(const std::string& name, const std::string& path,
|
void AddResolvedPath(const std::string& name, const std::string& path,
|
||||||
bool& unique);
|
bool& unique, std::vector<std::string> rpaths = {});
|
||||||
void AddUnresolvedPath(const std::string& name);
|
void AddUnresolvedPath(const std::string& name);
|
||||||
|
|
||||||
cmMakefile* GetMakefile() const;
|
cmMakefile* GetMakefile() const;
|
||||||
const std::map<std::string, std::set<std::string>>& GetResolvedPaths() const;
|
const std::map<std::string, std::set<std::string>>& GetResolvedPaths() const;
|
||||||
const std::set<std::string>& GetUnresolvedPaths() const;
|
const std::set<std::string>& GetUnresolvedPaths() const;
|
||||||
|
const std::map<std::string, std::vector<std::string>>& GetRPaths() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cmExecutionStatus& Status;
|
cmExecutionStatus& Status;
|
||||||
@@ -70,4 +71,5 @@ private:
|
|||||||
std::vector<std::string> PostExcludeFilesStrict;
|
std::vector<std::string> PostExcludeFilesStrict;
|
||||||
std::map<std::string, std::set<std::string>> ResolvedPaths;
|
std::map<std::string, std::set<std::string>> ResolvedPaths;
|
||||||
std::set<std::string> UnresolvedPaths;
|
std::set<std::string> UnresolvedPaths;
|
||||||
|
std::map<std::string, std::vector<std::string>> RPaths;
|
||||||
};
|
};
|
||||||
|
@@ -36,6 +36,7 @@ endfunction()
|
|||||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
if(NOT CMake_INSTALL_NAME_TOOL_BUG)
|
if(NOT CMake_INSTALL_NAME_TOOL_BUG)
|
||||||
run_install_test(macos)
|
run_install_test(macos)
|
||||||
|
run_install_test(macos-rpath)
|
||||||
run_install_test(macos-unresolved)
|
run_install_test(macos-unresolved)
|
||||||
run_install_test(macos-conflict)
|
run_install_test(macos-conflict)
|
||||||
run_install_test(macos-notfile)
|
run_install_test(macos-notfile)
|
||||||
|
@@ -0,0 +1,35 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
file(WRITE "${CMAKE_BINARY_DIR}/toplib.c" "extern void sublib1(void);\nextern void sublib2(void);\nvoid toplib(void)\n{\n sublib1();\n sublib2();\n}\n")
|
||||||
|
add_library(toplib SHARED "${CMAKE_BINARY_DIR}/toplib.c")
|
||||||
|
file(WRITE "${CMAKE_BINARY_DIR}/sublib1.c" "extern void sublib2(void);\nvoid sublib1(void)\n{\n sublib2();\n}\n")
|
||||||
|
add_library(sublib1 SHARED "${CMAKE_BINARY_DIR}/sublib1.c")
|
||||||
|
file(WRITE "${CMAKE_BINARY_DIR}/sublib2.c" "void sublib2(void)\n{\n}\n")
|
||||||
|
add_library(sublib2 SHARED "${CMAKE_BINARY_DIR}/sublib2.c")
|
||||||
|
target_link_libraries(toplib PRIVATE sublib1 sublib2)
|
||||||
|
target_link_libraries(sublib1 PRIVATE sublib2)
|
||||||
|
set_property(TARGET toplib PROPERTY INSTALL_RPATH "@loader_path/d1;@loader_path/d2")
|
||||||
|
set_property(TARGET sublib1 PROPERTY INSTALL_RPATH "@loader_path/;@loader_path/../d2")
|
||||||
|
install(TARGETS toplib DESTINATION lib)
|
||||||
|
install(TARGETS sublib1 DESTINATION lib/d1)
|
||||||
|
install(TARGETS sublib2 DESTINATION lib/d2)
|
||||||
|
|
||||||
|
install(CODE [[
|
||||||
|
file(GET_RUNTIME_DEPENDENCIES
|
||||||
|
LIBRARIES
|
||||||
|
"${CMAKE_INSTALL_PREFIX}/lib/$<TARGET_FILE_NAME:toplib>"
|
||||||
|
RPATH_PREFIX _rpaths
|
||||||
|
)
|
||||||
|
|
||||||
|
set(_expected_rpath "(^|;)@loader_path/;@loader_path/\\.\\./d2$")
|
||||||
|
set(_actual_rpath "${_rpaths_${CMAKE_INSTALL_PREFIX}/lib/d1/$<TARGET_FILE_NAME:sublib1>}")
|
||||||
|
if(NOT _actual_rpath MATCHES "${_expected_rpath}")
|
||||||
|
message(FATAL_ERROR "Expected rpath:\n ${_expected_rpath}\nActual rpath:\n ${_actual_rpath}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Since RPATH_PREFIX is an undocumented option for install(), we don't really need the rpath
|
||||||
|
# for the top files anyway.
|
||||||
|
if(DEFINED "_rpaths_${CMAKE_INSTALL_PREFIX}/lib/$<TARGET_FILE_NAME:toplib>")
|
||||||
|
message(FATAL_ERROR "rpath for top library should not be defined")
|
||||||
|
endif()
|
||||||
|
]])
|
Reference in New Issue
Block a user