mirror of
https://github.com/status-im/macdylibbundler.git
synced 2025-02-19 14:24:12 +00:00
resolve run-time paths
This commit is contained in:
parent
c589a4fcaf
commit
5919c7f979
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
DESTDIR=
|
||||
PREFIX=/usr/local
|
||||
CXXFLAGS = -O2
|
||||
CXXFLAGS = -O2 -std=c++14
|
||||
|
||||
all: dylibbundler
|
||||
|
||||
|
@ -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 += "/";
|
||||
|
@ -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();
|
||||
|
||||
|
@ -26,6 +26,7 @@ THE SOFTWARE.
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#ifdef __linux
|
||||
@ -40,7 +41,8 @@ std::vector<Dependency> deps;
|
||||
std::map<std::string, std::vector<Dependency> > deps_per_file;
|
||||
std::map<std::string, bool> deps_collected;
|
||||
std::set<std::string> rpaths;
|
||||
std::map<std::string, std::vector<std::string> > rpaths_per_file;
|
||||
std::map<std::string, std::set<std::string> > rpaths_per_file;
|
||||
std::map<std::string, std::string> 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<std::string>::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<count; ++n)
|
||||
{
|
||||
std::string prefix = filePrefix(Settings::fileToFix(n));
|
||||
path = std::regex_replace(path, std::regex("@executable_path/"), prefix);
|
||||
if (realpath(path.c_str(), buffer))
|
||||
{
|
||||
fullpath = buffer;
|
||||
rpath_to_fullpath[rpath_file] = fullpath;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dependent_file != rpath_file)
|
||||
{
|
||||
if (path.find("@loader_path") != std::string::npos)
|
||||
{
|
||||
std::string prefix = filePrefix(dependent_file);
|
||||
path = std::regex_replace(path, std::regex("@loader_path/"), prefix);
|
||||
if (realpath(path.c_str(), buffer))
|
||||
{
|
||||
fullpath = buffer;
|
||||
rpath_to_fullpath[rpath_file] = fullpath;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (path.find("@rpath") != std::string::npos)
|
||||
{
|
||||
int count = Settings::fileToFixAmount();
|
||||
for (int n=0; n<count; ++n)
|
||||
{
|
||||
std::string prefix = filePrefix(Settings::fileToFix(n));
|
||||
path = std::regex_replace(path, std::regex("@rpath/"), prefix);
|
||||
if (realpath(path.c_str(), buffer))
|
||||
{
|
||||
fullpath = buffer;
|
||||
rpath_to_fullpath[rpath_file] = fullpath;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (dependent_file != rpath_file)
|
||||
{
|
||||
std::string prefix = filePrefix(dependent_file);
|
||||
path = std::regex_replace(path, std::regex("@rpath/"), prefix);
|
||||
if (realpath(path.c_str(), buffer))
|
||||
{
|
||||
fullpath = buffer;
|
||||
rpath_to_fullpath[rpath_file] = fullpath;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// fullpath previously stored
|
||||
if (rpath_to_fullpath.find(rpath_file) != rpath_to_fullpath.end())
|
||||
{
|
||||
fullpath = rpath_to_fullpath[rpath_file];
|
||||
}
|
||||
else if (!check_path(rpath_file))
|
||||
{
|
||||
for (std::set<std::string>::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<std::string> rpaths_to_fix;
|
||||
std::map<std::string, std::vector<std::string> >::iterator found = rpaths_per_file.find(original_file);
|
||||
std::set<std::string> rpaths_to_fix;
|
||||
std::map<std::string, std::set<std::string> >::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<std::string>& lines)
|
||||
deps_collected[filename] = true;
|
||||
}
|
||||
|
||||
|
||||
void collectDependencies(std::string filename)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
@ -238,6 +311,7 @@ void collectDependencies(std::string filename)
|
||||
addDependency(dep_path, filename);
|
||||
}
|
||||
}
|
||||
|
||||
void collectSubDependencies()
|
||||
{
|
||||
// print status to user
|
||||
|
@ -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
|
||||
|
@ -67,7 +67,10 @@ void tokenize(const string& str, const char* delim, vector<string>* vectorarg)
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::string filePrefix(std::string in)
|
||||
{
|
||||
return in.substr(0, in.rfind("/")+1);
|
||||
}
|
||||
|
||||
bool fileExists( std::string filename )
|
||||
{
|
||||
|
@ -32,6 +32,7 @@ THE SOFTWARE.
|
||||
class Library;
|
||||
|
||||
void tokenize(const std::string& str, const char* delimiters, std::vector<std::string>*);
|
||||
std::string filePrefix(std::string in);
|
||||
bool fileExists( std::string filename );
|
||||
|
||||
void copyFile(std::string from, std::string to);
|
||||
|
Loading…
x
Reference in New Issue
Block a user