improve backwards compatibility. more refining
This commit is contained in:
parent
6348de25a8
commit
ad8e86a7ea
|
@ -21,43 +21,6 @@
|
|||
#include "Settings.h"
|
||||
#include "Utils.h"
|
||||
|
||||
// the paths to search for dylibs, store it globally to parse the environment variables only once
|
||||
std::vector<std::string> paths;
|
||||
|
||||
// initialize the dylib search paths
|
||||
void initSearchPaths()
|
||||
{
|
||||
// check the same paths the system would search for dylibs
|
||||
std::string searchPaths;
|
||||
char *dyldLibPath = std::getenv("DYLD_LIBRARY_PATH");
|
||||
if (dyldLibPath != 0)
|
||||
searchPaths = dyldLibPath;
|
||||
dyldLibPath = std::getenv("DYLD_FALLBACK_FRAMEWORK_PATH");
|
||||
if (dyldLibPath != 0) {
|
||||
if (!searchPaths.empty() && searchPaths[searchPaths.size()-1] != ':')
|
||||
searchPaths += ":";
|
||||
searchPaths += dyldLibPath;
|
||||
}
|
||||
dyldLibPath = std::getenv("DYLD_FALLBACK_LIBRARY_PATH");
|
||||
if (dyldLibPath != 0) {
|
||||
if (!searchPaths.empty() && searchPaths[searchPaths.size()-1] != ':')
|
||||
searchPaths += ":";
|
||||
searchPaths += dyldLibPath;
|
||||
}
|
||||
if (!searchPaths.empty()) {
|
||||
std::stringstream ss(searchPaths);
|
||||
std::string item;
|
||||
while (std::getline(ss, item, ':')) {
|
||||
if (item[item.size()-1] != '/')
|
||||
item += "/";
|
||||
paths.push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if some libs are missing prefixes, then more stuff will be necessary to do
|
||||
bool missing_prefixes = false;
|
||||
|
||||
Dependency::Dependency(std::string path, std::string dependent_file) : is_framework(false)
|
||||
{
|
||||
char original_file_buffer[PATH_MAX];
|
||||
|
@ -93,6 +56,9 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
prefix = filePrefix(original_file);
|
||||
filename = stripPrefix(original_file);
|
||||
|
||||
if (!prefix.empty() && prefix[prefix.size()-1] != '/')
|
||||
prefix += "/";
|
||||
|
||||
// check if this dependency is in /usr/lib, /System/Library, or in ignored list
|
||||
if (!Settings::isPrefixBundled(prefix))
|
||||
return;
|
||||
|
@ -102,8 +68,8 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
std::string framework_root = getFrameworkRoot(original_file);
|
||||
std::string framework_path = getFrameworkPath(original_file);
|
||||
std::string framework_name = stripPrefix(framework_root);
|
||||
filename = framework_name + "/" + framework_path;
|
||||
prefix = filePrefix(framework_root);
|
||||
filename = framework_name + "/" + framework_path;
|
||||
if (Settings::verboseOutput()) {
|
||||
std::cout << "framework root: " << framework_root << std::endl;
|
||||
std::cout << "framework path: " << framework_path << std::endl;
|
||||
|
@ -112,20 +78,20 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
}
|
||||
|
||||
// check if the lib is in a known location
|
||||
if (!prefix.empty() && prefix[prefix.size()-1] != '/')
|
||||
prefix += "/";
|
||||
|
||||
if (prefix.empty() || !fileExists(prefix+filename)) {
|
||||
// the paths contains at least /usr/lib so if it is empty we have not initialized it
|
||||
if (paths.empty())
|
||||
size_t search_path_count = Settings::searchPathCount();
|
||||
if (search_path_count == 0)
|
||||
initSearchPaths();
|
||||
|
||||
// check if file is contained in one of the paths
|
||||
for (size_t i=0; i<paths.size(); ++i) {
|
||||
if (fileExists(paths[i]+filename)) {
|
||||
warning_msg += "FOUND " + filename + " in " + paths[i] + "\n";
|
||||
prefix = paths[i];
|
||||
missing_prefixes = true;
|
||||
search_path_count = Settings::searchPathCount();
|
||||
for (size_t i=0; i<search_path_count; ++i) {
|
||||
std::string search_path = Settings::searchPath(i);
|
||||
if (fileExists(search_path+filename)) {
|
||||
warning_msg += "FOUND " + filename + " in " + search_path + "\n";
|
||||
prefix = search_path;
|
||||
Settings::missingPrefixes(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -140,8 +106,8 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
std::cerr << "\n/!\\ WARNING: Dependency " << filename << " of " << dependent_file << " not found\n";
|
||||
if (Settings::verboseOutput())
|
||||
std::cout << " path: " << (prefix+filename) << std::endl;
|
||||
missing_prefixes = true;
|
||||
paths.push_back(getUserInputDirForFile(filename));
|
||||
Settings::missingPrefixes(true);
|
||||
Settings::addSearchPath(getUserInputDirForFile(filename));
|
||||
}
|
||||
|
||||
new_name = filename;
|
||||
|
@ -188,8 +154,6 @@ void Dependency::copyYourself()
|
|||
{
|
||||
std::string original_path = getOriginalPath();
|
||||
std::string dest_path = getInstallPath();
|
||||
std::string inner_path = getInnerPath();
|
||||
std::string install_path = getInstallPath();
|
||||
|
||||
if (is_framework) {
|
||||
original_path = getFrameworkRoot(original_path);
|
||||
|
@ -197,33 +161,31 @@ void Dependency::copyYourself()
|
|||
}
|
||||
|
||||
if (Settings::verboseOutput()) {
|
||||
std::string inner_path = getInnerPath();
|
||||
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: " << install_path << std::endl;
|
||||
std::cout << "install path: " << getInstallPath() << std::endl;
|
||||
}
|
||||
|
||||
copyFile(original_path, dest_path);
|
||||
|
||||
if (is_framework) {
|
||||
std::string headers_path = dest_path + std::string("/Headers");
|
||||
std::string headers_realpath = headers_path;
|
||||
char buffer[PATH_MAX];
|
||||
|
||||
if (realpath(rtrim(headers_path).c_str(), buffer))
|
||||
headers_realpath = buffer;
|
||||
headers_path = buffer;
|
||||
|
||||
if (Settings::verboseOutput())
|
||||
std::cout << "headers path: " << headers_realpath << std::endl;
|
||||
std::cout << "headers path: " << headers_path << std::endl;
|
||||
|
||||
deleteFile(headers_path, true);
|
||||
deleteFile(headers_realpath, true);
|
||||
|
||||
deleteFile(dest_path + "/*.prl");
|
||||
}
|
||||
|
||||
// fix the lib's inner name
|
||||
changeId(install_path, "@rpath/"+new_name);
|
||||
changeId(getInstallPath(), "@rpath/"+new_name);
|
||||
}
|
||||
|
||||
void Dependency::fixFileThatDependsOnMe(std::string file_to_fix)
|
||||
|
@ -236,7 +198,7 @@ void Dependency::fixFileThatDependsOnMe(std::string file_to_fix)
|
|||
}
|
||||
|
||||
// TODO: revise
|
||||
if (missing_prefixes) {
|
||||
if (Settings::missingPrefixes()) {
|
||||
// for main lib file
|
||||
changeInstallName(file_to_fix, filename, getInnerPath());
|
||||
// for symlinks
|
||||
|
|
|
@ -234,7 +234,7 @@ void addDependency(std::string path, std::string dependent_file)
|
|||
}
|
||||
|
||||
// Fill |lines| with dependencies of given |filename|
|
||||
void collectDependencies(std::string dependent_file, std::vector<std::string>& lines)
|
||||
void collectDependencies(const std::string& dependent_file, std::vector<std::string>& lines)
|
||||
{
|
||||
std::string cmd = "otool -l " + dependent_file;
|
||||
std::string output = systemOutput(cmd);
|
||||
|
@ -268,19 +268,17 @@ void collectDependencies(std::string dependent_file, std::vector<std::string>& l
|
|||
}
|
||||
}
|
||||
|
||||
void collectDependencies(std::string dependent_file)
|
||||
void collectDependencies(const std::string& dependent_file)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
collectDependencies(dependent_file, lines);
|
||||
|
||||
for (size_t i=0; i<lines.size(); ++i) {
|
||||
if (!Settings::bundleFrameworks()) {
|
||||
if (lines[i].find(".framework") != std::string::npos)
|
||||
continue;
|
||||
}
|
||||
// lines containing path begin with a tab
|
||||
if (lines[i][0] != '\t')
|
||||
continue;
|
||||
if (!Settings::isPrefixBundled(lines[i]))
|
||||
continue;
|
||||
// trim useless info, keep only library path
|
||||
std::string dep_path = lines[i].substr(1, lines[i].rfind(" (") - 1);
|
||||
if (isRpath(dep_path))
|
||||
|
@ -313,18 +311,16 @@ void collectSubDependencies()
|
|||
original_path = searchFilenameInRpaths(original_path);
|
||||
|
||||
collectRpathsForFilename(original_path);
|
||||
|
||||
std::vector<std::string> lines;
|
||||
collectDependencies(original_path, lines);
|
||||
|
||||
for (size_t i=0; i<lines.size(); ++i) {
|
||||
if (!Settings::bundleFrameworks()) {
|
||||
if (lines[i].find(".framework") != std::string::npos)
|
||||
continue;
|
||||
}
|
||||
// lines containing path begin with a tab
|
||||
if (lines[i][0] != '\t')
|
||||
continue;
|
||||
// skip system/ignored prefixes
|
||||
if (!Settings::isPrefixBundled(lines[i]))
|
||||
continue;
|
||||
// trim useless info, keep only library name
|
||||
std::string dep_path = lines[i].substr(1, lines[i].rfind(" (") - 1);
|
||||
if (isRpath(dep_path)) {
|
||||
|
|
|
@ -14,7 +14,8 @@ std::string searchFilenameInRpaths(const std::string& rpath_file);
|
|||
void fixRpathsOnFile(const std::string& original_file, const std::string& file_to_fix);
|
||||
|
||||
void addDependency(std::string path, std::string dependent_file);
|
||||
void collectDependencies(std::string dependent_file);
|
||||
void collectDependencies(const std::string& dependent_file, std::vector<std::string>& lines);
|
||||
void collectDependencies(const std::string& dependent_file);
|
||||
void collectSubDependencies();
|
||||
|
||||
void doneWithDeps_go();
|
||||
|
|
|
@ -11,18 +11,22 @@ bool verbose_output = false;
|
|||
bool bundle_libs = true;
|
||||
bool bundle_frameworks = false;
|
||||
|
||||
std::string dest_folder_str = "Frameworks";
|
||||
std::string inside_path_str = "@executable_path/../Frameworks/";
|
||||
std::string dest_folder_str = "./libs/";
|
||||
std::string dest_folder_str_app = "./Frameworks/";
|
||||
std::string dest_folder = dest_folder_str;
|
||||
std::string dest_path = dest_folder;
|
||||
|
||||
std::string inside_path_str = "@executable_path/../libs/";
|
||||
std::string inside_path_str_app = "@executable_path/../Frameworks/";
|
||||
std::string inside_path = inside_path_str;
|
||||
|
||||
std::string app_bundle;
|
||||
std::string dest_folder;
|
||||
|
||||
bool appBundleProvided() { return !app_bundle.empty(); }
|
||||
std::string appBundle() { return app_bundle; }
|
||||
void appBundle(std::string path) {
|
||||
app_bundle = path;
|
||||
// fix path if needed so it ends with '/'
|
||||
if (app_bundle[app_bundle.size()-1] != '/')
|
||||
app_bundle += "/";
|
||||
app_bundle += "/"; // fix path if needed so it ends with '/'
|
||||
|
||||
std::string cmd = "/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' ";
|
||||
cmd += app_bundle + "Contents/Info.plist";
|
||||
|
@ -30,60 +34,63 @@ void appBundle(std::string path) {
|
|||
|
||||
addFileToFix(app_bundle + "Contents/MacOS/" + bundle_executable);
|
||||
|
||||
// fix path if needed so it ends with '/'
|
||||
if (dest_folder_str[dest_folder_str.size()-1] != '/')
|
||||
dest_folder_str += "/";
|
||||
dest_folder = app_bundle + "Contents/" + dest_folder_str;
|
||||
if (inside_path == inside_path_str)
|
||||
inside_path = inside_path_str_app;
|
||||
if (dest_folder == dest_folder_str)
|
||||
dest_folder = dest_folder_str_app;
|
||||
|
||||
dest_path = app_bundle + "Contents/" + dest_folder;
|
||||
char buffer[PATH_MAX];
|
||||
if (realpath(dest_path.c_str(), buffer))
|
||||
dest_path = buffer;
|
||||
if (dest_path[dest_path.size()-1] != '/')
|
||||
dest_path += "/";
|
||||
}
|
||||
|
||||
std::string destFolder() { return dest_folder; }
|
||||
std::string destFolder() { return dest_path; }
|
||||
void destFolder(std::string path)
|
||||
{
|
||||
dest_folder_str = path;
|
||||
// fix path if needed so it ends with '/'
|
||||
if (dest_folder_str[dest_folder_str.size()-1] != '/')
|
||||
dest_folder_str += "/";
|
||||
dest_folder = dest_folder_str;
|
||||
if (!app_bundle.empty())
|
||||
dest_folder = app_bundle + "Contents/" + dest_folder_str;
|
||||
if (path[path.size()-1] != '/')
|
||||
path += "/";
|
||||
dest_folder = path;
|
||||
if (appBundleProvided()) {
|
||||
char buffer[PATH_MAX];
|
||||
std::string dest_path = app_bundle + "Contents/" + path;
|
||||
if (realpath(dest_path.c_str(), buffer))
|
||||
dest_path = buffer;
|
||||
if (dest_path[dest_path.size()-1] != '/')
|
||||
dest_path += "/";
|
||||
dest_folder = dest_path;
|
||||
}
|
||||
}
|
||||
|
||||
std::string executableFolder() { return app_bundle + "Contents/MacOS/"; }
|
||||
|
||||
std::string frameworksFolder() { return app_bundle + "Contents/Frameworks/"; }
|
||||
|
||||
std::string pluginsFolder() { return app_bundle + "Contents/PlugIns/"; }
|
||||
|
||||
std::string resourcesFolder() { return app_bundle + "Contents/Resources/"; }
|
||||
|
||||
std::vector<std::string> files;
|
||||
|
||||
void addFileToFix(std::string path) { files.push_back(path); }
|
||||
|
||||
std::string fileToFix(const int n) { return files[n]; }
|
||||
|
||||
std::vector<std::string> filesToFix() { return files; }
|
||||
|
||||
size_t filesToFixCount() { return files.size(); }
|
||||
|
||||
std::string insideLibPath() { return inside_path_str; }
|
||||
std::string insideLibPath() { return inside_path; }
|
||||
void insideLibPath(std::string p)
|
||||
{
|
||||
inside_path_str = p;
|
||||
inside_path = p;
|
||||
// fix path if needed so it ends with '/'
|
||||
if (inside_path_str[inside_path_str.size()-1] != '/')
|
||||
inside_path_str += "/";
|
||||
if (inside_path[inside_path.size()-1] != '/')
|
||||
inside_path += "/";
|
||||
}
|
||||
|
||||
std::vector<std::string> prefixes_to_ignore;
|
||||
|
||||
void ignorePrefix(std::string prefix)
|
||||
{
|
||||
if (prefix[prefix.size()-1] != '/')
|
||||
prefix += "/";
|
||||
prefixes_to_ignore.push_back(prefix);
|
||||
}
|
||||
|
||||
bool isPrefixIgnored(std::string prefix)
|
||||
{
|
||||
for (size_t n=0; n<prefixes_to_ignore.size(); n++) {
|
||||
|
@ -134,4 +141,9 @@ void quietOutput(bool status) { quiet_output = status; }
|
|||
bool verboseOutput() { return verbose_output; }
|
||||
void verboseOutput(bool status) { verbose_output = status; }
|
||||
|
||||
// if some libs are missing prefixes, then more stuff will be necessary to do
|
||||
bool missing_prefixes = false;
|
||||
bool missingPrefixes() { return missing_prefixes; }
|
||||
void missingPrefixes(bool status) { missing_prefixes = status; }
|
||||
|
||||
} // namespace Settings
|
||||
|
|
|
@ -54,6 +54,9 @@ void quietOutput(bool status);
|
|||
bool verboseOutput();
|
||||
void verboseOutput(bool status);
|
||||
|
||||
bool missingPrefixes();
|
||||
void missingPrefixes(bool status);
|
||||
|
||||
} // namespace Settings
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -290,3 +291,33 @@ std::string getUserInputDirForFile(const std::string& filename)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initSearchPaths()
|
||||
{
|
||||
// check the same paths the system would search for dylibs
|
||||
std::string searchPaths;
|
||||
char *dyldLibPath = std::getenv("DYLD_LIBRARY_PATH");
|
||||
if (dyldLibPath != 0)
|
||||
searchPaths = dyldLibPath;
|
||||
dyldLibPath = std::getenv("DYLD_FALLBACK_FRAMEWORK_PATH");
|
||||
if (dyldLibPath != 0) {
|
||||
if (!searchPaths.empty() && searchPaths[searchPaths.size()-1] != ':')
|
||||
searchPaths += ":";
|
||||
searchPaths += dyldLibPath;
|
||||
}
|
||||
dyldLibPath = std::getenv("DYLD_FALLBACK_LIBRARY_PATH");
|
||||
if (dyldLibPath != 0) {
|
||||
if (!searchPaths.empty() && searchPaths[searchPaths.size()-1] != ':')
|
||||
searchPaths += ":";
|
||||
searchPaths += dyldLibPath;
|
||||
}
|
||||
if (!searchPaths.empty()) {
|
||||
std::stringstream ss(searchPaths);
|
||||
std::string item;
|
||||
while (std::getline(ss, item, ':')) {
|
||||
if (item[item.size()-1] != '/')
|
||||
item += "/";
|
||||
Settings::addSearchPath(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,7 @@ bool mkdir(std::string path);
|
|||
void createDestDir();
|
||||
std::string getUserInputDirForFile(const std::string& filename);
|
||||
|
||||
// check the same paths the system would search for dylibs
|
||||
void initSearchPaths();
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue