mirror of
https://github.com/status-im/macdylibbundler.git
synced 2025-02-21 07:08:25 +00:00
resolve run-time paths
This commit is contained in:
parent
c589a4fcaf
commit
5919c7f979
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
|||||||
DESTDIR=
|
DESTDIR=
|
||||||
PREFIX=/usr/local
|
PREFIX=/usr/local
|
||||||
CXXFLAGS = -O2
|
CXXFLAGS = -O2 -std=c++14
|
||||||
|
|
||||||
all: dylibbundler
|
all: dylibbundler
|
||||||
|
|
||||||
|
@ -87,14 +87,14 @@ void initSearchPaths(){
|
|||||||
// more stuff will then be necessary to do
|
// more stuff will then be necessary to do
|
||||||
bool missing_prefixes = false;
|
bool missing_prefixes = false;
|
||||||
|
|
||||||
Dependency::Dependency(std::string path)
|
Dependency::Dependency(std::string path, std::string dependent_file)
|
||||||
{
|
{
|
||||||
char original_file_buffer[PATH_MAX];
|
char original_file_buffer[PATH_MAX];
|
||||||
std::string original_file;
|
std::string original_file;
|
||||||
|
|
||||||
if (isRpath(path))
|
if (isRpath(path))
|
||||||
{
|
{
|
||||||
original_file = searchFilenameInRpaths(path);
|
original_file = searchFilenameInRpaths(path, dependent_file);
|
||||||
}
|
}
|
||||||
else if (not realpath(rtrim(path).c_str(), original_file_buffer))
|
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
|
// check if given path is a symlink
|
||||||
if (original_file != rtrim(path))
|
if (original_file != rtrim(path)) addSymlink(path);
|
||||||
{
|
|
||||||
filename = stripPrefix(original_file);
|
filename = stripPrefix(path);
|
||||||
prefix = original_file.substr(0, original_file.rfind("/")+1);
|
prefix = filePrefix(original_file);
|
||||||
addSymlink(path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filename = stripPrefix(path);
|
|
||||||
prefix = path.substr(0, path.rfind("/")+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//check if the lib is in a known location
|
//check if the lib is in a known location
|
||||||
if( !prefix.empty() && prefix[ prefix.size()-1 ] != '/' ) prefix += "/";
|
if( !prefix.empty() && prefix[ prefix.size()-1 ] != '/' ) prefix += "/";
|
||||||
|
@ -39,7 +39,7 @@ class Dependency
|
|||||||
// installation
|
// installation
|
||||||
std::string new_name;
|
std::string new_name;
|
||||||
public:
|
public:
|
||||||
Dependency(std::string path);
|
Dependency(std::string path, std::string dependent_file);
|
||||||
|
|
||||||
void print();
|
void print();
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ THE SOFTWARE.
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <regex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
@ -40,7 +41,8 @@ std::vector<Dependency> deps;
|
|||||||
std::map<std::string, std::vector<Dependency> > deps_per_file;
|
std::map<std::string, std::vector<Dependency> > deps_per_file;
|
||||||
std::map<std::string, bool> deps_collected;
|
std::map<std::string, bool> deps_collected;
|
||||||
std::set<std::string> rpaths;
|
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)
|
void changeLibPathsOnFile(std::string file_to_fix)
|
||||||
{
|
{
|
||||||
@ -96,7 +98,7 @@ void collectRpaths(const std::string& filename)
|
|||||||
start_pos += 5;
|
start_pos += 5;
|
||||||
std::string rpath = line.substr(start_pos, end_pos - start_pos);
|
std::string rpath = line.substr(start_pos, end_pos - start_pos);
|
||||||
rpaths.insert(rpath);
|
rpaths.insert(rpath);
|
||||||
rpaths_per_file[filename].push_back(rpath);
|
rpaths_per_file[filename].insert(rpath);
|
||||||
read_rpath = false;
|
read_rpath = false;
|
||||||
continue;
|
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];
|
char buffer[PATH_MAX];
|
||||||
std::string fullpath;
|
std::string fullpath;
|
||||||
std::string suffix = rpath_file.substr(rpath_file.rfind("/")+1);
|
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 (path.find("@executable_path") != std::string::npos)
|
||||||
if (realpath(path.c_str(), buffer))
|
|
||||||
{
|
{
|
||||||
fullpath = buffer;
|
int count = Settings::fileToFixAmount();
|
||||||
break;
|
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;
|
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)
|
void fixRpathsOnFile(const std::string& original_file, const std::string& file_to_fix)
|
||||||
{
|
{
|
||||||
std::vector<std::string> rpaths_to_fix;
|
std::set<std::string> rpaths_to_fix;
|
||||||
std::map<std::string, std::vector<std::string> >::iterator found = rpaths_per_file.find(original_file);
|
std::map<std::string, std::set<std::string> >::iterator found = rpaths_per_file.find(original_file);
|
||||||
if (found != rpaths_per_file.end())
|
if (found != rpaths_per_file.end())
|
||||||
{
|
{
|
||||||
rpaths_to_fix = found->second;
|
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 ") +
|
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)
|
if ( systemp(command) != 0)
|
||||||
{
|
{
|
||||||
std::cerr << "\n\nError : An error occured while trying to fix dependencies of " << file_to_fix << std::endl;
|
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)
|
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
|
// we need to check if this library was already added to avoid duplicates
|
||||||
bool in_deps = false;
|
bool in_deps = false;
|
||||||
@ -213,7 +287,6 @@ void collectDependencies(std::string filename, std::vector<std::string>& lines)
|
|||||||
deps_collected[filename] = true;
|
deps_collected[filename] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void collectDependencies(std::string filename)
|
void collectDependencies(std::string filename)
|
||||||
{
|
{
|
||||||
std::vector<std::string> lines;
|
std::vector<std::string> lines;
|
||||||
@ -238,6 +311,7 @@ void collectDependencies(std::string filename)
|
|||||||
addDependency(dep_path, filename);
|
addDependency(dep_path, filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void collectSubDependencies()
|
void collectSubDependencies()
|
||||||
{
|
{
|
||||||
// print status to user
|
// print status to user
|
||||||
|
@ -31,6 +31,7 @@ void collectDependencies(std::string filename);
|
|||||||
void collectSubDependencies();
|
void collectSubDependencies();
|
||||||
void doneWithDeps_go();
|
void doneWithDeps_go();
|
||||||
bool isRpath(const std::string& path);
|
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);
|
std::string searchFilenameInRpaths(const std::string& rpath_dep);
|
||||||
|
|
||||||
#endif
|
#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 )
|
bool fileExists( std::string filename )
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@ THE SOFTWARE.
|
|||||||
class Library;
|
class Library;
|
||||||
|
|
||||||
void tokenize(const std::string& str, const char* delimiters, std::vector<std::string>*);
|
void tokenize(const std::string& str, const char* delimiters, std::vector<std::string>*);
|
||||||
|
std::string filePrefix(std::string in);
|
||||||
bool fileExists( std::string filename );
|
bool fileExists( std::string filename );
|
||||||
|
|
||||||
void copyFile(std::string from, std::string to);
|
void copyFile(std::string from, std::string to);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user