collect dependencies & rpaths in a single otool call
This commit is contained in:
parent
7f41661132
commit
e5cacbb3e6
|
@ -15,35 +15,33 @@
|
|||
|
||||
Dependency::Dependency(std::string path, const std::string& dependent_file) : is_framework(false)
|
||||
{
|
||||
char original_file_buffer[PATH_MAX];
|
||||
char buffer[PATH_MAX];
|
||||
rtrim_in_place(path);
|
||||
std::string original_file;
|
||||
std::string warning_msg;
|
||||
|
||||
rtrim_in_place(path);
|
||||
|
||||
if (Settings::verboseOutput()) {
|
||||
std::cout<< "** Dependency ctor **" << std::endl;
|
||||
if (path != dependent_file)
|
||||
std::cout << " dependent file: " << dependent_file << std::endl;
|
||||
std::cout << " dependency path: " << path << std::endl;
|
||||
}
|
||||
|
||||
if (isRpath(path)) {
|
||||
original_file = searchFilenameInRpaths(path, dependent_file);
|
||||
}
|
||||
else if (realpath(path.c_str(), original_file_buffer)) {
|
||||
original_file = original_file_buffer;
|
||||
if (Settings::verboseOutput())
|
||||
std::cout << " original_file: " << original_file << std::endl;
|
||||
else if (realpath(path.c_str(), buffer)) {
|
||||
original_file = buffer;
|
||||
}
|
||||
else {
|
||||
warning_msg = "\n/!\\ WARNING: Cannot resolve path '" + path + "'\n";
|
||||
original_file = path;
|
||||
}
|
||||
|
||||
if (Settings::verboseOutput()) {
|
||||
std::cout<< "** Dependency ctor **" << std::endl;
|
||||
if (path != dependent_file)
|
||||
std::cout << " dependent file: " << dependent_file << std::endl;
|
||||
std::cout << " dependency path: " << path << std::endl;
|
||||
std::cout << " original_file: " << original_file << std::endl;
|
||||
}
|
||||
|
||||
// check if given path is a symlink
|
||||
if (original_file != path)
|
||||
addSymlink(path);
|
||||
AddSymlink(path);
|
||||
|
||||
prefix = filePrefix(original_file);
|
||||
filename = stripPrefix(original_file);
|
||||
|
@ -72,10 +70,8 @@ Dependency::Dependency(std::string path, const std::string& dependent_file) : is
|
|||
// check if the lib is in a known location
|
||||
if (prefix.empty() || !fileExists(prefix+filename)) {
|
||||
std::vector<std::string> search_paths = Settings::searchPaths();
|
||||
// the paths contains at least /usr/lib so if it is empty we have not initialized it
|
||||
if (search_paths.empty())
|
||||
initSearchPaths();
|
||||
|
||||
// check if file is contained in one of the paths
|
||||
for (const auto& search_path : search_paths) {
|
||||
if (fileExists(search_path+filename)) {
|
||||
|
@ -103,45 +99,37 @@ Dependency::Dependency(std::string path, const std::string& dependent_file) : is
|
|||
new_name = filename;
|
||||
}
|
||||
|
||||
std::string Dependency::getInstallPath() const
|
||||
{
|
||||
return Settings::destFolder() + new_name;
|
||||
}
|
||||
|
||||
std::string Dependency::getInnerPath() const
|
||||
std::string Dependency::InnerPath() const
|
||||
{
|
||||
return Settings::insideLibPath() + new_name;
|
||||
}
|
||||
|
||||
void Dependency::print() const
|
||||
std::string Dependency::InstallPath() const
|
||||
{
|
||||
std::cout << "\n* " << filename << " from " << prefix << std::endl;
|
||||
for (const auto& symlink : symlinks) {
|
||||
std::cout << " symlink --> " << symlink << std::endl;
|
||||
}
|
||||
return Settings::destFolder() + new_name;
|
||||
}
|
||||
|
||||
void Dependency::addSymlink(const std::string& s)
|
||||
void Dependency::AddSymlink(const std::string& path)
|
||||
{
|
||||
if (std::find(symlinks.begin(), symlinks.end(), s) == symlinks.end())
|
||||
symlinks.push_back(s);
|
||||
if (std::find(symlinks.begin(), symlinks.end(), path) == symlinks.end())
|
||||
symlinks.push_back(path);
|
||||
}
|
||||
|
||||
bool Dependency::mergeIfSameAs(Dependency& dep2)
|
||||
bool Dependency::MergeIfIdentical(Dependency& dependency)
|
||||
{
|
||||
if (dep2.getOriginalFileName() == filename) {
|
||||
if (dependency.OriginalFilename() == filename) {
|
||||
for (const auto& symlink : symlinks) {
|
||||
dep2.addSymlink(symlink);
|
||||
dependency.AddSymlink(symlink);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Dependency::copyToAppBundle() const
|
||||
void Dependency::CopyToBundle() const
|
||||
{
|
||||
std::string original_path = getOriginalPath();
|
||||
std::string dest_path = getInstallPath();
|
||||
std::string original_path = OriginalPath();
|
||||
std::string dest_path = InstallPath();
|
||||
|
||||
if (is_framework) {
|
||||
original_path = getFrameworkRoot(original_path);
|
||||
|
@ -149,11 +137,11 @@ void Dependency::copyToAppBundle() const
|
|||
}
|
||||
|
||||
if (Settings::verboseOutput()) {
|
||||
std::string inner_path = getInnerPath();
|
||||
std::string inner_path = InnerPath();
|
||||
std::cout << " - original path: " << original_path << std::endl;
|
||||
std::cout << " - inner path: " << inner_path << std::endl;
|
||||
std::cout << " - dest_path: " << dest_path << std::endl;
|
||||
std::cout << " - install path: " << getInstallPath() << std::endl;
|
||||
std::cout << " - install path: " << InstallPath() << std::endl;
|
||||
}
|
||||
|
||||
copyFile(original_path, dest_path);
|
||||
|
@ -167,20 +155,28 @@ void Dependency::copyToAppBundle() const
|
|||
deleteFile(dest_path + "/*.prl");
|
||||
}
|
||||
|
||||
changeId(getInstallPath(), "@rpath/"+new_name);
|
||||
changeId(InstallPath(), "@rpath/" + new_name);
|
||||
}
|
||||
|
||||
void Dependency::fixDependentFiles(const std::string& file) const
|
||||
void Dependency::FixDependentFile(const std::string& dependent_file) const
|
||||
{
|
||||
changeInstallName(file, getOriginalPath(), getInnerPath());
|
||||
changeInstallName(dependent_file, OriginalPath(), InnerPath());
|
||||
for (const auto& symlink : symlinks) {
|
||||
changeInstallName(file, symlink, getInnerPath());
|
||||
changeInstallName(dependent_file, symlink, InnerPath());
|
||||
}
|
||||
|
||||
if (Settings::missingPrefixes()) {
|
||||
changeInstallName(file, filename, getInnerPath());
|
||||
changeInstallName(dependent_file, filename, InnerPath());
|
||||
for (const auto& symlink : symlinks) {
|
||||
changeInstallName(file, symlink, getInnerPath());
|
||||
changeInstallName(dependent_file, symlink, InnerPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dependency::Print() const
|
||||
{
|
||||
std::cout << "\n* " << filename << " from " << prefix << std::endl;
|
||||
for (const auto& symlink : symlinks) {
|
||||
std::cout << " symlink --> " << symlink << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef _depend_h_
|
||||
#define _depend_h_
|
||||
#ifndef DYLIBBUNDLER_DEPENDENCY_H
|
||||
#define DYLIBBUNDLER_DEPENDENCY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -10,25 +10,25 @@ class Dependency {
|
|||
public:
|
||||
Dependency(std::string path, const std::string& dependent_file);
|
||||
|
||||
[[nodiscard]] bool isFramework() const { return is_framework; }
|
||||
[[nodiscard]] bool IsFramework() const { return is_framework; }
|
||||
|
||||
[[nodiscard]] std::string getPrefix() const { return prefix; }
|
||||
[[nodiscard]] std::string getOriginalFileName() const { return filename; }
|
||||
[[nodiscard]] std::string getOriginalPath() const { return prefix + filename; }
|
||||
[[nodiscard]] std::string Prefix() const { return prefix; }
|
||||
[[nodiscard]] std::string OriginalFilename() const { return filename; }
|
||||
[[nodiscard]] std::string OriginalPath() const { return prefix + filename; }
|
||||
|
||||
[[nodiscard]] std::string getInstallPath() const;
|
||||
[[nodiscard]] std::string getInnerPath() const;
|
||||
[[nodiscard]] std::string InnerPath() const;
|
||||
[[nodiscard]] std::string InstallPath() const;
|
||||
|
||||
void print() const;
|
||||
|
||||
void addSymlink(const std::string& s);
|
||||
void AddSymlink(const std::string& path);
|
||||
|
||||
// Compare the given dependency with this one. If both refer to the same file,
|
||||
// merge both entries into one and return true.
|
||||
bool mergeIfSameAs(Dependency& dep2);
|
||||
bool MergeIfIdentical(Dependency& dependency);
|
||||
|
||||
void copyToAppBundle() const;
|
||||
void fixDependentFiles(const std::string& file) const;
|
||||
void CopyToBundle() const;
|
||||
void FixDependentFile(const std::string& dependent_file) const;
|
||||
|
||||
void Print() const;
|
||||
|
||||
private:
|
||||
bool is_framework;
|
||||
|
|
|
@ -23,6 +23,7 @@ std::map<std::string, std::vector<Dependency>> deps_per_file;
|
|||
std::map<std::string, bool> deps_collected;
|
||||
std::set<std::string> frameworks;
|
||||
std::set<std::string> rpaths;
|
||||
std::map<std::string, bool> rpaths_collected;
|
||||
bool qt_plugins_called = false;
|
||||
|
||||
void addDependency(const std::string& path, const std::string& dependent_file)
|
||||
|
@ -32,71 +33,98 @@ void addDependency(const std::string& path, const std::string& dependent_file)
|
|||
// check if this library was already added to |deps| to avoid duplicates
|
||||
bool in_deps = false;
|
||||
for (auto& dep : deps) {
|
||||
if (dependency.mergeIfSameAs(dep))
|
||||
if (dependency.MergeIfIdentical(dep))
|
||||
in_deps = true;
|
||||
}
|
||||
|
||||
// check if this library was already added to |deps_per_file[dependent_file]| to avoid duplicates
|
||||
bool in_deps_per_file = false;
|
||||
for (auto& dep : deps_per_file[dependent_file]) {
|
||||
if (dependency.mergeIfSameAs(dep))
|
||||
if (dependency.MergeIfIdentical(dep))
|
||||
in_deps_per_file = true;
|
||||
}
|
||||
|
||||
// check if this library is in /usr/lib, /System/Library, or in ignored list
|
||||
if (!Settings::isPrefixBundled(dependency.getPrefix()))
|
||||
if (!Settings::isPrefixBundled(dependency.Prefix()))
|
||||
return;
|
||||
|
||||
if (!in_deps && dependency.isFramework())
|
||||
frameworks.insert(dependency.getOriginalPath());
|
||||
if (!in_deps && dependency.IsFramework())
|
||||
frameworks.insert(dependency.OriginalPath());
|
||||
if (!in_deps)
|
||||
deps.push_back(dependency);
|
||||
if (!in_deps_per_file)
|
||||
deps_per_file[dependent_file].push_back(dependency);
|
||||
}
|
||||
|
||||
void collectDependencies(const std::string& dependent_file, std::vector<std::string>& lines)
|
||||
void collectDependencies(const std::string& dependent_file)
|
||||
{
|
||||
parseLoadCommands(dependent_file, std::string("LC_LOAD_DYLIB"), std::string("name"), lines);
|
||||
}
|
||||
if (deps_collected.find(dependent_file) != deps_collected.end() && Settings::fileHasRpath(dependent_file))
|
||||
return;
|
||||
|
||||
void collectDependenciesForFile(const std::string& file, std::vector<std::string>& lines)
|
||||
{
|
||||
if (deps_collected.find(file) == deps_collected.end())
|
||||
collectDependencies(file, lines);
|
||||
}
|
||||
std::map<std::string,std::string> cmds_values;
|
||||
std::string dylib = "LC_LOAD_DYLIB";
|
||||
std::string rpath = "LC_RPATH";
|
||||
cmds_values[dylib] = "name";
|
||||
cmds_values[rpath] = "path";
|
||||
std::map<std::string,std::vector<std::string>> cmds_results;
|
||||
|
||||
void collectDependenciesForFile(const std::string& dependent_file)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
collectDependenciesForFile(dependent_file, lines);
|
||||
collectRpathsForFilename(dependent_file);
|
||||
parseLoadCommands(dependent_file, cmds_values, cmds_results);
|
||||
|
||||
for (const auto& line : lines) {
|
||||
if (!Settings::isPrefixBundled(line))
|
||||
continue; // skip system/ignored prefixes
|
||||
addDependency(line, dependent_file);
|
||||
if (rpaths_collected.find(dependent_file) == rpaths_collected.end()) {
|
||||
auto rpath_results = cmds_results[rpath];
|
||||
for (const auto& rpath_result : rpath_results) {
|
||||
rpaths.insert(rpath_result);
|
||||
Settings::addRpathForFile(dependent_file, rpath_result);
|
||||
if (Settings::verboseOutput())
|
||||
std::cout << " rpath: " << rpath_result << std::endl;
|
||||
}
|
||||
rpaths_collected[dependent_file] = true;
|
||||
}
|
||||
|
||||
if (deps_collected.find(dependent_file) == deps_collected.end()) {
|
||||
auto dylib_results = cmds_results[dylib];
|
||||
for (const auto& dylib_result : dylib_results) {
|
||||
// skip system/ignored prefixes
|
||||
if (Settings::isPrefixBundled(dylib_result))
|
||||
addDependency(dylib_result, dependent_file);
|
||||
}
|
||||
deps_collected[dependent_file] = true;
|
||||
}
|
||||
|
||||
void collectRpaths(const std::string& filename)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
parseLoadCommands(filename, std::string("LC_RPATH"), std::string("path"), lines);
|
||||
for (const auto& line : lines) {
|
||||
rpaths.insert(line);
|
||||
Settings::addRpathForFile(filename, line);
|
||||
if (Settings::verboseOutput())
|
||||
std::cout << " rpath: " << line << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void collectRpathsForFilename(const std::string& filename)
|
||||
{
|
||||
if (!Settings::fileHasRpath(filename))
|
||||
collectRpaths(filename);
|
||||
}
|
||||
//void collectDependencies(const std::string& dependent_file, std::vector<std::string>& lines)
|
||||
//{
|
||||
// if (deps_collected.find(dependent_file) == deps_collected.end())
|
||||
// parseLoadCommands(dependent_file, std::string("LC_LOAD_DYLIB"), std::string("name"), lines);
|
||||
//}
|
||||
|
||||
//void collectDependencies(const std::string& dependent_file)
|
||||
//{
|
||||
// std::vector<std::string> lines;
|
||||
// collectDependencies(dependent_file, lines);
|
||||
// collectRpaths(dependent_file);
|
||||
//
|
||||
// for (const auto& line : lines) {
|
||||
// if (!Settings::isPrefixBundled(line))
|
||||
// continue; // skip system/ignored prefixes
|
||||
// addDependency(line, dependent_file);
|
||||
// }
|
||||
// deps_collected[dependent_file] = true;
|
||||
//}
|
||||
|
||||
//void collectRpaths(const std::string& filename)
|
||||
//{
|
||||
// if (!Settings::fileHasRpath(filename)) {
|
||||
// std::vector<std::string> lines;
|
||||
// parseLoadCommands(filename, std::string("LC_RPATH"), std::string("path"), lines);
|
||||
// for (const auto &line : lines) {
|
||||
// rpaths.insert(line);
|
||||
// Settings::addRpathForFile(filename, line);
|
||||
// if (Settings::verboseOutput())
|
||||
// std::cout << " rpath: " << line << std::endl;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
void collectSubDependencies()
|
||||
{
|
||||
|
@ -110,21 +138,23 @@ void collectSubDependencies()
|
|||
while (true) {
|
||||
deps_size = deps.size();
|
||||
for (size_t n=0; n<deps_size; ++n) {
|
||||
std::string original_path = deps[n].getOriginalPath();
|
||||
std::string original_path = deps[n].OriginalPath();
|
||||
if (Settings::verboseOutput())
|
||||
std::cout << " (collect sub deps) original path: " << original_path << std::endl;
|
||||
if (isRpath(original_path))
|
||||
original_path = searchFilenameInRpaths(original_path);
|
||||
|
||||
std::vector<std::string> lines;
|
||||
collectDependenciesForFile(original_path, lines);
|
||||
collectRpathsForFilename(original_path);
|
||||
// std::vector<std::string> lines;
|
||||
// collectDependencies(original_path, lines);
|
||||
// collectRpaths(original_path);
|
||||
//
|
||||
// for (const auto& line : lines) {
|
||||
// if (!Settings::isPrefixBundled(line))
|
||||
// continue; // skip system/ignored prefixes
|
||||
// addDependency(line, original_path);
|
||||
// }
|
||||
|
||||
for (const auto& line : lines) {
|
||||
if (!Settings::isPrefixBundled(line))
|
||||
continue; // skip system/ignored prefixes
|
||||
addDependency(line, original_path);
|
||||
}
|
||||
collectDependencies(original_path);
|
||||
}
|
||||
// if no more dependencies were added on this iteration, stop searching
|
||||
if (deps.size() == deps_size)
|
||||
|
@ -143,28 +173,30 @@ void collectSubDependencies()
|
|||
|
||||
void changeLibPathsOnFile(const std::string& file_to_fix)
|
||||
{
|
||||
if (deps_collected.find(file_to_fix) == deps_collected.end())
|
||||
collectDependenciesForFile(file_to_fix);
|
||||
if (deps_collected.find(file_to_fix) == deps_collected.end() || rpaths_collected.find(file_to_fix) == rpaths_collected.end())
|
||||
collectDependencies(file_to_fix);
|
||||
|
||||
std::cout << "* Fixing dependencies on " << file_to_fix << "\n";
|
||||
|
||||
const size_t dep_amount = deps_per_file[file_to_fix].size();
|
||||
for (size_t n=0; n<dep_amount; ++n) {
|
||||
deps_per_file[file_to_fix][n].fixDependentFiles(file_to_fix);
|
||||
std::vector<Dependency> dependencies = deps_per_file[file_to_fix];
|
||||
for (auto& dependency : dependencies) {
|
||||
dependency.FixDependentFile(file_to_fix);
|
||||
}
|
||||
}
|
||||
|
||||
void fixRpathsOnFile(const std::string& original_file, const std::string& file_to_fix)
|
||||
{
|
||||
std::vector<std::string> rpaths_to_fix;
|
||||
if (Settings::fileHasRpath(original_file))
|
||||
rpaths_to_fix = Settings::getRpathsForFile(original_file);
|
||||
if (!Settings::fileHasRpath(original_file))
|
||||
return;
|
||||
|
||||
for (const auto& i : rpaths_to_fix) {
|
||||
rpaths_to_fix = Settings::getRpathsForFile(original_file);
|
||||
for (const auto& rpath_to_fix : rpaths_to_fix) {
|
||||
std::string command = std::string("install_name_tool -rpath ");
|
||||
command += i + " " + Settings::insideLibPath() + " " + file_to_fix;
|
||||
command.append(rpath_to_fix).append(" ").append(Settings::insideLibPath());
|
||||
command.append(" ").append(file_to_fix);
|
||||
if (systemp(command) != 0) {
|
||||
std::cerr << "\n\n/!\\ ERROR: An error occured while trying to fix dependencies of " << file_to_fix << "\n";
|
||||
std::cerr << "\n\n/!\\ ERROR: An error occured while trying to fix rpath " << rpath_to_fix << " of " << file_to_fix << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -173,21 +205,22 @@ void fixRpathsOnFile(const std::string& original_file, const std::string& file_t
|
|||
void bundleDependencies()
|
||||
{
|
||||
for (const auto& dep : deps) {
|
||||
dep.print();
|
||||
dep.Print();
|
||||
}
|
||||
std::cout << "\n";
|
||||
if (Settings::verboseOutput()) {
|
||||
std::cout << "rpaths:" << std::endl;
|
||||
for (const auto& rpath : rpaths) {
|
||||
std::cout << "rpaths: " << rpath << std::endl;
|
||||
std::cout << "* " << rpath << std::endl;
|
||||
}
|
||||
}
|
||||
// copy & fix up dependencies
|
||||
if (Settings::bundleLibs()) {
|
||||
createDestDir();
|
||||
for (const auto& dep : deps) {
|
||||
dep.copyToAppBundle();
|
||||
changeLibPathsOnFile(dep.getInstallPath());
|
||||
fixRpathsOnFile(dep.getOriginalPath(), dep.getInstallPath());
|
||||
dep.CopyToBundle();
|
||||
changeLibPathsOnFile(dep.InstallPath());
|
||||
fixRpathsOnFile(dep.OriginalPath(), dep.InstallPath());
|
||||
}
|
||||
}
|
||||
// fix up selected files
|
||||
|
@ -261,7 +294,7 @@ void bundleQtPlugins()
|
|||
std::vector<std::string> files = lsDir(dest + plugin+"/");
|
||||
for (const auto& file : files) {
|
||||
Settings::addFileToFix(dest + plugin+"/"+file);
|
||||
collectDependenciesForFile(dest + plugin+"/"+file);
|
||||
collectDependencies(dest + plugin + "/" + file);
|
||||
changeId(dest + plugin+"/"+file, "@rpath/" + plugin+"/"+file);
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +309,7 @@ void bundleQtPlugins()
|
|||
mkdir(dest + "platforms");
|
||||
copyFile(qt_plugins_prefix + "platforms/libqcocoa.dylib", dest + "platforms");
|
||||
Settings::addFileToFix(dest + "platforms/libqcocoa.dylib");
|
||||
collectDependenciesForFile(dest + "platforms/libqcocoa.dylib");
|
||||
collectDependencies(dest + "platforms/libqcocoa.dylib");
|
||||
|
||||
fixupPlugin("printsupport");
|
||||
fixupPlugin("styles");
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef _DYLIB_BUNDLER_H_
|
||||
#define _DYLIB_BUNDLER_H_
|
||||
#ifndef DYLIBBUNDLER_DYLIBBUNDLER_H
|
||||
#define DYLIBBUNDLER_DYLIBBUNDLER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
void addDependency(const std::string& path, const std::string& dependent_file);
|
||||
|
||||
// std::string searchFilenameInRpaths(const std::string& rpath_file, const std::string& dependent_file);
|
||||
// std::string searchFilenameInRpaths(const std::string& rpath_file);
|
||||
|
||||
// fill |lines| with dependencies of |dependent_file|
|
||||
void collectDependencies(const std::string& dependent_file, std::vector<std::string>& lines);
|
||||
void collectDependenciesForFile(const std::string& dependent_file, std::vector<std::string>& lines);
|
||||
void collectDependenciesForFile(const std::string& dependent_file);
|
||||
//void collectDependencies(const std::string& dependent_file, std::vector<std::string>& lines);
|
||||
void collectDependencies(const std::string& dependent_file);
|
||||
|
||||
void collectRpaths(const std::string& filename);
|
||||
void collectRpathsForFilename(const std::string& filename);
|
||||
//void collectRpaths(const std::string& filename);
|
||||
|
||||
// recursively collect each dependency's dependencies
|
||||
void collectSubDependencies();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef _settings_
|
||||
#define _settings_
|
||||
#ifndef DYLIBBUNDLER_SETTINGS_H
|
||||
#define DYLIBBUNDLER_SETTINGS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
|
@ -299,9 +299,9 @@ std::string getUserInputDirForFile(const std::string& filename, const std::strin
|
|||
}
|
||||
}
|
||||
|
||||
void parseLoadCommands(const std::string& file, const std::string& cmd, const std::string& value, std::vector<std::string>& lines)
|
||||
void otool(const std::string& flags, const std::string& file, std::vector<std::string>& lines)
|
||||
{
|
||||
std::string command = "otool -l " + file;
|
||||
std::string command = "otool " + flags + " " + file;
|
||||
std::string output = systemOutput(command);
|
||||
|
||||
if (output.find("can't open file") != std::string::npos
|
||||
|
@ -312,14 +312,19 @@ void parseLoadCommands(const std::string& file, const std::string& cmd, const st
|
|||
exit(1);
|
||||
}
|
||||
|
||||
tokenize(output, "\n", &lines);
|
||||
}
|
||||
|
||||
void parseLoadCommands(const std::string& file, const std::string& cmd, const std::string& value, std::vector<std::string>& lines)
|
||||
{
|
||||
std::vector<std::string> raw_lines;
|
||||
tokenize(output, "\n", &raw_lines);
|
||||
otool("-l", file, raw_lines);
|
||||
|
||||
bool searching = false;
|
||||
std::string cmd_line = std::string("cmd ") + cmd;
|
||||
std::string value_line = std::string(value + std::string(" "));
|
||||
for (const auto& line : raw_lines) {
|
||||
if (line.find(cmd_line) != std::string::npos) {
|
||||
for (const auto& raw_line : raw_lines) {
|
||||
if (raw_line.find(cmd_line) != std::string::npos) {
|
||||
if (searching) {
|
||||
std::cerr << "\n\n/!\\ ERROR: Failed to find " << value << " before next cmd\n";
|
||||
exit(1);
|
||||
|
@ -327,23 +332,62 @@ void parseLoadCommands(const std::string& file, const std::string& cmd, const st
|
|||
searching = true;
|
||||
}
|
||||
else if (searching) {
|
||||
size_t start_pos = line.find(value_line);
|
||||
size_t start_pos = raw_line.find(value_line);
|
||||
if (start_pos == std::string::npos)
|
||||
continue;
|
||||
size_t start = start_pos + value.size() + 1; // exclude data label "|value| "
|
||||
size_t end = std::string::npos;
|
||||
if (value == "name" || value == "path") {
|
||||
size_t end_pos = line.find(" (");
|
||||
size_t end_pos = raw_line.find(" (");
|
||||
if (end_pos == std::string::npos)
|
||||
continue;
|
||||
end = end_pos - start;
|
||||
}
|
||||
lines.push_back(line.substr(start, end));
|
||||
lines.push_back(raw_line.substr(start, end));
|
||||
searching = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void parseLoadCommands(const std::string& file, const std::map<std::string,std::string>& cmds_values, std::map<std::string,std::vector<std::string>>& cmds_results)
|
||||
{
|
||||
std::vector<std::string> raw_lines;
|
||||
otool("-l", file, raw_lines);
|
||||
|
||||
for (const auto& cmd_value : cmds_values) {
|
||||
std::vector<std::string> lines;
|
||||
std::string cmd = cmd_value.first;
|
||||
std::string value = cmd_value.second;
|
||||
std::string cmd_line = std::string("cmd ") + cmd;
|
||||
std::string value_line = std::string(value) + std::string(" ");
|
||||
bool searching = false;
|
||||
for (const auto& raw_line : raw_lines) {
|
||||
if (raw_line.find(cmd_line) != std::string::npos) {
|
||||
if (searching) {
|
||||
std::cerr << "\n\n/!\\ ERROR: Failed to find " << value << " before next cmd\n";
|
||||
exit(1);
|
||||
}
|
||||
searching = true;
|
||||
} else if (searching) {
|
||||
size_t start_pos = raw_line.find(value_line);
|
||||
if (start_pos == std::string::npos)
|
||||
continue;
|
||||
size_t start = start_pos + value.size() + 1; // exclude data label "|value| "
|
||||
size_t end = std::string::npos;
|
||||
if (value == "name" || value == "path") {
|
||||
size_t end_pos = raw_line.find(" (");
|
||||
if (end_pos == std::string::npos)
|
||||
continue;
|
||||
end = end_pos - start;
|
||||
}
|
||||
lines.push_back(raw_line.substr(start, end));
|
||||
searching = false;
|
||||
}
|
||||
}
|
||||
cmds_results[cmd] = lines;
|
||||
}
|
||||
}
|
||||
|
||||
std::string searchFilenameInRpaths(const std::string& rpath_file, const std::string& dependent_file)
|
||||
{
|
||||
if (Settings::verboseOutput()) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef _utils_h_
|
||||
#define _utils_h_
|
||||
#ifndef DYLIBBUNDLER_UTILS_H
|
||||
#define DYLIBBUNDLER_UTILS_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -44,7 +45,9 @@ void createDestDir();
|
|||
|
||||
std::string getUserInputDirForFile(const std::string& filename, const std::string& dependent_file);
|
||||
|
||||
void otool(const std::string& flags, const std::string& file, std::vector<std::string>& lines);
|
||||
void parseLoadCommands(const std::string& file, const std::string& cmd, const std::string& value, std::vector<std::string>& lines);
|
||||
void parseLoadCommands(const std::string& file, const std::map<std::string,std::string>& cmds_values, std::map<std::string,std::vector<std::string>>& cmds_results);
|
||||
|
||||
std::string searchFilenameInRpaths(const std::string& rpath_file, const std::string& dependent_file);
|
||||
std::string searchFilenameInRpaths(const std::string& rpath_file);
|
||||
|
|
|
@ -126,7 +126,7 @@ int main(int argc, const char* argv[])
|
|||
|
||||
const std::vector<std::string> files_to_fix = Settings::filesToFix();
|
||||
for (const auto& file_to_fix : files_to_fix) {
|
||||
collectDependenciesForFile(file_to_fix);
|
||||
collectDependencies(file_to_fix);
|
||||
}
|
||||
collectSubDependencies();
|
||||
bundleDependencies();
|
||||
|
|
Loading…
Reference in New Issue