summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2021-04-23 15:19:11 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2021-06-04 12:52:01 (GMT)
commit2ef3ea394f424bf2397878b00725b93ebe04c589 (patch)
tree8af040cd82162771cda213033da055d7fa2829e0
parentb613e09778260c26c6323026dc2ccb980c102f3e (diff)
downloadCMake-2ef3ea394f424bf2397878b00725b93ebe04c589.zip
CMake-2ef3ea394f424bf2397878b00725b93ebe04c589.tar.gz
CMake-2ef3ea394f424bf2397878b00725b93ebe04c589.tar.bz2
file(GET_RUNTIME_DEPENDENCIES): Add undocumented RPATH_PREFIX option
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.cxx22
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.h2
-rw-r--r--Source/cmFileCommand.cxx7
-rw-r--r--Source/cmRuntimeDependencyArchive.cxx13
-rw-r--r--Source/cmRuntimeDependencyArchive.h4
-rw-r--r--Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-rpath.cmake35
7 files changed, 72 insertions, 12 deletions
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index 0f47146..47f77d8 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -65,18 +65,18 @@ bool cmBinUtilsMacOSMachOLinker::ScanDependencies(
if (!executableFile.empty()) {
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> rpaths;
if (!this->Tool->GetFileInfo(file, libs, rpaths)) {
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);
return this->GetFileDependencies(libs, executablePath, loaderPath, rpaths);
}
@@ -98,8 +98,14 @@ bool cmBinUtilsMacOSMachOLinker::GetFileDependencies(
!IsMissingSystemDylib(path)) {
auto filename = cmSystemTools::GetFilenameName(path);
bool unique;
- this->Archive->AddResolvedPath(filename, path, unique);
- if (unique && !this->ScanDependencies(path, executablePath)) {
+ std::vector<std::string> libs;
+ 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;
}
}
diff --git a/Source/cmBinUtilsMacOSMachOLinker.h b/Source/cmBinUtilsMacOSMachOLinker.h
index 1c4a5fc..eae23cc 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.h
+++ b/Source/cmBinUtilsMacOSMachOLinker.h
@@ -27,6 +27,8 @@ private:
std::unique_ptr<cmBinUtilsMacOSMachOGetRuntimeDependenciesTool> Tool;
bool ScanDependencies(std::string const& file,
+ std::vector<std::string> const& libs,
+ std::vector<std::string> const& rpaths,
std::string const& executablePath);
bool GetFileDependencies(std::vector<std::string> const& names,
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index f2d4cda..b685d14 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -3032,6 +3032,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
std::string ResolvedDependenciesVar;
std::string UnresolvedDependenciesVar;
std::string ConflictingDependenciesPrefix;
+ std::string RPathPrefix;
std::string BundleExecutable;
std::vector<std::string> Executables;
std::vector<std::string> Libraries;
@@ -3053,6 +3054,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
&Arguments::UnresolvedDependenciesVar)
.Bind("CONFLICTING_DEPENDENCIES_PREFIX"_s,
&Arguments::ConflictingDependenciesPrefix)
+ .Bind("RPATH_PREFIX"_s, &Arguments::RPathPrefix)
.Bind("BUNDLE_EXECUTABLE"_s, &Arguments::BundleExecutable)
.Bind("EXECUTABLES"_s, &Arguments::Executables)
.Bind("LIBRARIES"_s, &Arguments::Libraries)
@@ -3135,6 +3137,11 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
if (unique) {
deps.push_back(firstPath);
+ if (!parsedArgs.RPathPrefix.empty()) {
+ status.GetMakefile().AddDefinition(
+ parsedArgs.RPathPrefix + "_" + firstPath,
+ cmJoin(archive.GetRPaths().at(firstPath), ";"));
+ }
} else if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
conflictingDeps.push_back(val.first);
std::vector<std::string> paths;
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 57b4bd6..06246d1 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -354,9 +354,9 @@ bool cmRuntimeDependencyArchive::IsPostExcluded(const std::string& name) const
fileSearch(this->PostExcludeFiles)));
}
-void cmRuntimeDependencyArchive::AddResolvedPath(const std::string& name,
- const std::string& path,
- bool& unique)
+void cmRuntimeDependencyArchive::AddResolvedPath(
+ const std::string& name, const std::string& path, bool& unique,
+ std::vector<std::string> rpaths)
{
auto it = this->ResolvedPaths.emplace(name, std::set<std::string>{}).first;
unique = true;
@@ -367,6 +367,7 @@ void cmRuntimeDependencyArchive::AddResolvedPath(const std::string& name,
}
}
it->second.insert(path);
+ this->RPaths[path] = std::move(rpaths);
}
void cmRuntimeDependencyArchive::AddUnresolvedPath(const std::string& name)
@@ -390,3 +391,9 @@ const std::set<std::string>& cmRuntimeDependencyArchive::GetUnresolvedPaths()
{
return this->UnresolvedPaths;
}
+
+const std::map<std::string, std::vector<std::string>>&
+cmRuntimeDependencyArchive::GetRPaths() const
+{
+ return this->RPaths;
+}
diff --git a/Source/cmRuntimeDependencyArchive.h b/Source/cmRuntimeDependencyArchive.h
index 3f368c5..20a38e2 100644
--- a/Source/cmRuntimeDependencyArchive.h
+++ b/Source/cmRuntimeDependencyArchive.h
@@ -45,12 +45,13 @@ public:
bool IsPostExcluded(const std::string& name) const;
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);
cmMakefile* GetMakefile() const;
const std::map<std::string, std::set<std::string>>& GetResolvedPaths() const;
const std::set<std::string>& GetUnresolvedPaths() const;
+ const std::map<std::string, std::vector<std::string>>& GetRPaths() const;
private:
cmExecutionStatus& Status;
@@ -70,4 +71,5 @@ private:
std::vector<std::string> PostExcludeFilesStrict;
std::map<std::string, std::set<std::string>> ResolvedPaths;
std::set<std::string> UnresolvedPaths;
+ std::map<std::string, std::vector<std::string>> RPaths;
};
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
index c71b9ba..07679b7 100644
--- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
@@ -36,6 +36,7 @@ endfunction()
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
if(NOT CMake_INSTALL_NAME_TOOL_BUG)
run_install_test(macos)
+ run_install_test(macos-rpath)
run_install_test(macos-unresolved)
run_install_test(macos-conflict)
run_install_test(macos-notfile)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-rpath.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-rpath.cmake
new file mode 100644
index 0000000..798045f
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-rpath.cmake
@@ -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()
+ ]])