Skip to content
Snippets Groups Projects
Commit 93c5864a authored by Seth R Johnson's avatar Seth R Johnson Committed by Brad King
Browse files

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.
parent fc92d664
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
}
......
......@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment