summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorSeth R Johnson <johnsonsr@ornl.gov>2021-10-10 10:33:33 (GMT)
committerBrad King <brad.king@kitware.com>2021-10-12 15:40:46 (GMT)
commit93c5864aa19a9af058910172939db177bd5a3b9f (patch)
tree4fbada8f35b9d0a82d3c688455786eef54774df4 /Source
parentfc92d6640b09def31d129f3e347b98af1aa1e098 (diff)
downloadCMake-93c5864aa19a9af058910172939db177bd5a3b9f.zip
CMake-93c5864aa19a9af058910172939db177bd5a3b9f.tar.gz
CMake-93c5864aa19a9af058910172939db177bd5a3b9f.tar.bz2
cmBinUtilsMacOSMachOLinker: improve performance by memoizing otool calls
Libraries with many repeated transitive dependencies (e.g. Trilinos) can result in very long runtime dependency call times, especially if system calls are made more expensive by antivirus software. This change caches the results of the calls to otool for efficiency.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.cxx42
-rw-r--r--Source/cmBinUtilsMacOSMachOLinker.h10
2 files changed, 43 insertions, 9 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,