diff options
author | Brad King <brad.king@kitware.com> | 2021-10-13 12:57:35 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2021-10-13 12:57:51 (GMT) |
commit | 6bfe5f24da381bda4a7cfc334fe04bc7c7b73abc (patch) | |
tree | 4fbada8f35b9d0a82d3c688455786eef54774df4 | |
parent | 7257539e67930985eef82aeab29cb32ef357aec7 (diff) | |
parent | 93c5864aa19a9af058910172939db177bd5a3b9f (diff) | |
download | CMake-6bfe5f24da381bda4a7cfc334fe04bc7c7b73abc.zip CMake-6bfe5f24da381bda4a7cfc334fe04bc7c7b73abc.tar.gz CMake-6bfe5f24da381bda4a7cfc334fe04bc7c7b73abc.tar.bz2 |
Merge topic 'optimize-macos-runtime-dependencies' into release-3.22
93c5864aa1 cmBinUtilsMacOSMachOLinker: improve performance by memoizing otool calls
fc92d6640b cmFileCommand: improve error message
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !6616
7 files changed, 61 insertions, 16 deletions
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx index 47f77d8..c064377 100644 --- a/Source/cmBinUtilsMacOSMachOLinker.cxx +++ b/Source/cmBinUtilsMacOSMachOLinker.cxx @@ -5,6 +5,8 @@ #include <sstream> #include <string> +#include <type_traits> +#include <utility> #include <vector> #include <cm/memory> @@ -52,6 +54,26 @@ bool cmBinUtilsMacOSMachOLinker::Prepare() return true; } +auto cmBinUtilsMacOSMachOLinker::GetFileInfo(std::string const& file) + -> const FileInfo* +{ + // Memoize processed rpaths and library dependencies to reduce the number + // of calls to otool, especially in the case of heavily recursive libraries + auto iter = ScannedFileInfo.find(file); + if (iter != ScannedFileInfo.end()) { + return &iter->second; + } + + FileInfo file_info; + if (!this->Tool->GetFileInfo(file, file_info.libs, file_info.rpaths)) { + // Call to otool failed + return nullptr; + } + + auto iter_inserted = ScannedFileInfo.insert({ file, std::move(file_info) }); + return &iter_inserted.first->second; +} + bool cmBinUtilsMacOSMachOLinker::ScanDependencies( std::string const& file, cmStateEnums::TargetType type) { @@ -65,12 +87,12 @@ bool cmBinUtilsMacOSMachOLinker::ScanDependencies( if (!executableFile.empty()) { executablePath = cmSystemTools::GetFilenamePath(executableFile); } - std::vector<std::string> libs; - std::vector<std::string> rpaths; - if (!this->Tool->GetFileInfo(file, libs, rpaths)) { + const FileInfo* file_info = this->GetFileInfo(file); + if (file_info == nullptr) { return false; } - return this->ScanDependencies(file, libs, rpaths, executablePath); + return this->ScanDependencies(file, file_info->libs, file_info->rpaths, + executablePath); } bool cmBinUtilsMacOSMachOLinker::ScanDependencies( @@ -98,14 +120,16 @@ bool cmBinUtilsMacOSMachOLinker::GetFileDependencies( !IsMissingSystemDylib(path)) { auto filename = cmSystemTools::GetFilenameName(path); bool unique; - std::vector<std::string> libs; - std::vector<std::string> depRpaths; - if (!this->Tool->GetFileInfo(path, libs, depRpaths)) { + const FileInfo* dep_file_info = this->GetFileInfo(path); + if (dep_file_info == nullptr) { return false; } - this->Archive->AddResolvedPath(filename, path, unique, depRpaths); + + this->Archive->AddResolvedPath(filename, path, unique, + dep_file_info->rpaths); if (unique && - !this->ScanDependencies(path, libs, depRpaths, executablePath)) { + !this->ScanDependencies(path, dep_file_info->libs, + dep_file_info->rpaths, executablePath)) { return false; } } diff --git a/Source/cmBinUtilsMacOSMachOLinker.h b/Source/cmBinUtilsMacOSMachOLinker.h index eae23cc..ac1177b 100644 --- a/Source/cmBinUtilsMacOSMachOLinker.h +++ b/Source/cmBinUtilsMacOSMachOLinker.h @@ -5,6 +5,7 @@ #include <memory> #include <string> +#include <unordered_map> #include <vector> #include "cmBinUtilsLinker.h" @@ -24,7 +25,16 @@ public: cmStateEnums::TargetType type) override; private: + struct FileInfo + { + std::vector<std::string> libs; + std::vector<std::string> rpaths; + }; + std::unique_ptr<cmBinUtilsMacOSMachOGetRuntimeDependenciesTool> Tool; + std::unordered_map<std::string, FileInfo> ScannedFileInfo; + + const FileInfo* GetFileInfo(std::string const& file); bool ScanDependencies(std::string const& file, std::vector<std::string> const& libs, diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index d2341c5..fd0595d 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -3170,9 +3170,12 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, archive.GetUnresolvedPaths().begin(), archive.GetUnresolvedPaths().end()); } else { - auto it = archive.GetUnresolvedPaths().begin(); - assert(it != archive.GetUnresolvedPaths().end()); - status.SetError(cmStrCat("Could not resolve file ", *it)); + std::ostringstream e; + e << "Could not resolve runtime dependencies:"; + for (auto const& path : archive.GetUnresolvedPaths()) { + e << "\n " << path; + } + status.SetError(e.str()); cmSystemTools::SetFatalErrorOccured(); return false; } diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-stderr.txt index 5b86322..9ed1728 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-stderr.txt +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-stderr.txt @@ -1,2 +1,4 @@ ^CMake Error at cmake_install\.cmake:[0-9]+ \(file\): - file Could not resolve file libtest\.so$ + file Could not resolve runtime dependencies: + + libtest\.so$ diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-stderr.txt index eaca512..51010a1 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-stderr.txt +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-stderr.txt @@ -1,2 +1,4 @@ ^CMake Error at cmake_install\.cmake:[0-9]+ \(file\): - file Could not resolve file libunresolved\.so$ + file Could not resolve runtime dependencies: + + libunresolved\.so$ diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-stderr.txt index 01762b4..5743d27 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-stderr.txt +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-stderr.txt @@ -1,2 +1,4 @@ ^CMake Error at cmake_install\.cmake:[0-9]+ \(file\): - file Could not resolve file @rpath/libunresolved\.dylib$ + file Could not resolve runtime dependencies: + + @rpath/libunresolved\.dylib$ diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-stderr.txt index a20654c..0efcb57 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-stderr.txt +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-stderr.txt @@ -1,2 +1,4 @@ ^CMake Error at cmake_install\.cmake:[0-9]+ \(file\): - file Could not resolve file (lib)?unresolved\.dll$ + file Could not resolve runtime dependencies: + + (lib)?unresolved\.dll$ |