From 5919c7f97964e9e8a672527a3c36ab0809ae7158 Mon Sep 17 00:00:00 2001 From: SCG82 Date: Tue, 14 Jan 2020 01:23:15 -0800 Subject: [PATCH] resolve run-time paths --- Makefile | 2 +- src/Dependency.cpp | 19 +++----- src/Dependency.h | 2 +- src/DylibBundler.cpp | 102 +++++++++++++++++++++++++++++++++++++------ src/DylibBundler.h | 1 + src/Utils.cpp | 5 ++- src/Utils.h | 1 + 7 files changed, 102 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index d06633d..87bb95e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ DESTDIR= PREFIX=/usr/local -CXXFLAGS = -O2 +CXXFLAGS = -O2 -std=c++14 all: dylibbundler diff --git a/src/Dependency.cpp b/src/Dependency.cpp index 32efff0..efb170f 100644 --- a/src/Dependency.cpp +++ b/src/Dependency.cpp @@ -87,14 +87,14 @@ void initSearchPaths(){ // more stuff will then be necessary to do bool missing_prefixes = false; -Dependency::Dependency(std::string path) +Dependency::Dependency(std::string path, std::string dependent_file) { char original_file_buffer[PATH_MAX]; std::string original_file; if (isRpath(path)) { - original_file = searchFilenameInRpaths(path); + original_file = searchFilenameInRpaths(path, dependent_file); } else if (not realpath(rtrim(path).c_str(), original_file_buffer)) { @@ -107,17 +107,10 @@ Dependency::Dependency(std::string path) } // check if given path is a symlink - if (original_file != rtrim(path)) - { - filename = stripPrefix(original_file); - prefix = original_file.substr(0, original_file.rfind("/")+1); - addSymlink(path); - } - else - { - filename = stripPrefix(path); - prefix = path.substr(0, path.rfind("/")+1); - } + if (original_file != rtrim(path)) addSymlink(path); + + filename = stripPrefix(path); + prefix = filePrefix(original_file); //check if the lib is in a known location if( !prefix.empty() && prefix[ prefix.size()-1 ] != '/' ) prefix += "/"; diff --git a/src/Dependency.h b/src/Dependency.h index c3c4e0c..c8dab7c 100644 --- a/src/Dependency.h +++ b/src/Dependency.h @@ -39,7 +39,7 @@ class Dependency // installation std::string new_name; public: - Dependency(std::string path); + Dependency(std::string path, std::string dependent_file); void print(); diff --git a/src/DylibBundler.cpp b/src/DylibBundler.cpp index 90d3792..3775dc4 100644 --- a/src/DylibBundler.cpp +++ b/src/DylibBundler.cpp @@ -26,6 +26,7 @@ THE SOFTWARE. #include #include #include +#include #include #include #ifdef __linux @@ -40,7 +41,8 @@ std::vector deps; std::map > deps_per_file; std::map deps_collected; std::set rpaths; -std::map > rpaths_per_file; +std::map > rpaths_per_file; +std::map rpath_to_fullpath; void changeLibPathsOnFile(std::string file_to_fix) { @@ -96,7 +98,7 @@ void collectRpaths(const std::string& filename) start_pos += 5; std::string rpath = line.substr(start_pos, end_pos - start_pos); rpaths.insert(rpath); - rpaths_per_file[filename].push_back(rpath); + rpaths_per_file[filename].insert(rpath); read_rpath = false; continue; } @@ -117,19 +119,86 @@ void collectRpathsForFilename(const std::string& filename) } } -std::string searchFilenameInRpaths(const std::string& rpath_file) +std::string searchFilenameInRpaths(const std::string& rpath_file, const std::string& dependent_file) { char buffer[PATH_MAX]; std::string fullpath; std::string suffix = rpath_file.substr(rpath_file.rfind("/")+1); - for (std::set::iterator it = rpaths.begin(); it != rpaths.end(); ++it) + const auto check_path = [&](std::string path) { - std::string path = *it + "/" + suffix; - if (realpath(path.c_str(), buffer)) + if (path.find("@executable_path") != std::string::npos) { - fullpath = buffer; - break; + int count = Settings::fileToFixAmount(); + for (int n=0; n::iterator it = rpaths_per_file[dependent_file].begin(); it != rpaths_per_file[dependent_file].end(); ++it) + { + std::string rpath = *it; + if (rpath[rpath.size()-1] != '/') rpath += "/"; + + std::string path = rpath + suffix; + if (check_path(path)) break; } } @@ -145,19 +214,24 @@ std::string searchFilenameInRpaths(const std::string& rpath_file) return fullpath; } +std::string searchFilenameInRpaths(const std::string& rpath_file) +{ + return searchFilenameInRpaths(rpath_file, rpath_file); +} + void fixRpathsOnFile(const std::string& original_file, const std::string& file_to_fix) { - std::vector rpaths_to_fix; - std::map >::iterator found = rpaths_per_file.find(original_file); + std::set rpaths_to_fix; + std::map >::iterator found = rpaths_per_file.find(original_file); if (found != rpaths_per_file.end()) { rpaths_to_fix = found->second; } - for (size_t i=0; i < rpaths_to_fix.size(); ++i) + for (const auto& rpath_to_fix : rpaths_to_fix) { std::string command = std::string("install_name_tool -rpath ") + - rpaths_to_fix[i] + " " + Settings::inside_lib_path() + " " + file_to_fix; + rpath_to_fix + " " + Settings::inside_lib_path() + " " + file_to_fix; if ( systemp(command) != 0) { std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl; @@ -168,7 +242,7 @@ void fixRpathsOnFile(const std::string& original_file, const std::string& file_t void addDependency(std::string path, std::string filename) { - Dependency dep(path); + Dependency dep(path, filename); // we need to check if this library was already added to avoid duplicates bool in_deps = false; @@ -213,7 +287,6 @@ void collectDependencies(std::string filename, std::vector& lines) deps_collected[filename] = true; } - void collectDependencies(std::string filename) { std::vector lines; @@ -238,6 +311,7 @@ void collectDependencies(std::string filename) addDependency(dep_path, filename); } } + void collectSubDependencies() { // print status to user diff --git a/src/DylibBundler.h b/src/DylibBundler.h index edf557b..1202e56 100644 --- a/src/DylibBundler.h +++ b/src/DylibBundler.h @@ -31,6 +31,7 @@ void collectDependencies(std::string filename); void collectSubDependencies(); void doneWithDeps_go(); bool isRpath(const std::string& path); +std::string searchFilenameInRpaths(const std::string& rpath_file, const std::string& dependent_file); std::string searchFilenameInRpaths(const std::string& rpath_dep); #endif diff --git a/src/Utils.cpp b/src/Utils.cpp index 68d23a7..f504d9d 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -67,7 +67,10 @@ void tokenize(const string& str, const char* delim, vector* vectorarg) } - +std::string filePrefix(std::string in) +{ + return in.substr(0, in.rfind("/")+1); +} bool fileExists( std::string filename ) { diff --git a/src/Utils.h b/src/Utils.h index 6599471..7577f9a 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -32,6 +32,7 @@ THE SOFTWARE. class Library; void tokenize(const std::string& str, const char* delimiters, std::vector*); +std::string filePrefix(std::string in); bool fileExists( std::string filename ); void copyFile(std::string from, std::string to);