diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-04-23 15:19:11 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-06-04 12:52:01 (GMT) |
commit | 2ef3ea394f424bf2397878b00725b93ebe04c589 (patch) | |
tree | 8af040cd82162771cda213033da055d7fa2829e0 | |
parent | b613e09778260c26c6323026dc2ccb980c102f3e (diff) | |
download | CMake-2ef3ea394f424bf2397878b00725b93ebe04c589.zip CMake-2ef3ea394f424bf2397878b00725b93ebe04c589.tar.gz CMake-2ef3ea394f424bf2397878b00725b93ebe04c589.tar.bz2 |
file(GET_RUNTIME_DEPENDENCIES): Add undocumented RPATH_PREFIX option
-rw-r--r-- | Source/cmBinUtilsMacOSMachOLinker.cxx | 22 | ||||
-rw-r--r-- | Source/cmBinUtilsMacOSMachOLinker.h | 2 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 7 | ||||
-rw-r--r-- | Source/cmRuntimeDependencyArchive.cxx | 13 | ||||
-rw-r--r-- | Source/cmRuntimeDependencyArchive.h | 4 | ||||
-rw-r--r-- | Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake | 1 | ||||
-rw-r--r-- | Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-rpath.cmake | 35 |
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() + ]]) |