deploy qt plugins
This commit is contained in:
parent
a58f2ec3b8
commit
bf0586f410
|
@ -44,6 +44,7 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
{
|
||||
char original_file_buffer[PATH_MAX];
|
||||
std::string original_file;
|
||||
std::string warning_msg;
|
||||
|
||||
rtrim_in_place(path);
|
||||
|
||||
|
@ -53,7 +54,7 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
}
|
||||
else if (not realpath(path.c_str(), original_file_buffer))
|
||||
{
|
||||
std::cerr << "\n/!\\ WARNING : Cannot resolve path '" << path.c_str() << "'" << std::endl;
|
||||
warning_msg = "\n/!\\ WARNING : Cannot resolve path '" + path + "'\n";
|
||||
original_file = path;
|
||||
}
|
||||
else
|
||||
|
@ -72,6 +73,16 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
// check if this dependency is in /usr/lib, /System/Library, or in ignored list
|
||||
if (!Settings::isPrefixBundled(prefix)) return;
|
||||
|
||||
if (original_file.find(".framework") != std::string::npos)
|
||||
{
|
||||
is_framework = true;
|
||||
std::string framework_root = getFrameworkRoot(original_file);
|
||||
std::string framework_path = getFrameworkPath(original_file);
|
||||
std::string framework_name = stripPrefix(framework_root);
|
||||
prefix = filePrefix(framework_root);
|
||||
filename = framework_name + "/" + framework_path;
|
||||
}
|
||||
|
||||
//check if the lib is in a known location
|
||||
if (prefix.empty() || !fileExists(prefix+filename))
|
||||
{
|
||||
|
@ -86,18 +97,23 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
std::string search_path = Settings::searchPath(i);
|
||||
if (fileExists(search_path+filename))
|
||||
{
|
||||
std::cout << "FOUND " << filename << " in " << search_path << std::endl;
|
||||
warning_msg += "FOUND " + filename + " in " + search_path + "\n";
|
||||
prefix = search_path;
|
||||
Settings::missingPrefixes(true); //the prefix was missing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Settings::quietOutput()) std::cout << warning_msg;
|
||||
|
||||
//If the location is still unknown, ask the user for search path
|
||||
if ( !Settings::isPrefixIgnored(prefix) && ( prefix.empty() || !fileExists(prefix+filename) ) )
|
||||
{
|
||||
std::cerr << "\n/!\\ WARNING : Library " << filename << " has an incomplete name (location unknown)" << std::endl;
|
||||
if (!Settings::quietOutput())
|
||||
{
|
||||
std::cerr << "\n/!\\ WARNING: Dependency " << filename << " of " << dependent_file << " not found\n";
|
||||
}
|
||||
Settings::missingPrefixes(true);
|
||||
Settings::addSearchPath(getUserInputDirForFile(filename));
|
||||
}
|
||||
|
@ -107,13 +123,12 @@ Dependency::Dependency(std::string path, std::string dependent_file) : is_framew
|
|||
|
||||
void Dependency::print()
|
||||
{
|
||||
std::cout << std::endl;
|
||||
std::cout << " * " << filename.c_str() << " from " << prefix.c_str() << std::endl;
|
||||
std::cout << "\n* " << filename.c_str() << " from " << prefix.c_str() << std::endl;
|
||||
|
||||
const int symamount = symlinks.size();
|
||||
for(int n=0; n<symamount; n++)
|
||||
{
|
||||
std::cout << " symlink --> " << symlinks[n].c_str() << std::endl;
|
||||
std::cout << " symlink --> " << symlinks[n].c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,9 @@ public:
|
|||
std::string getOriginalPath() const{ return prefix+filename; }
|
||||
std::string getInstallPath();
|
||||
std::string getInnerPath();
|
||||
|
||||
|
||||
bool isFramework(){ return is_framework; }
|
||||
|
||||
void addSymlink(std::string s);
|
||||
int getSymlinkAmount() const{ return symlinks.size(); }
|
||||
|
||||
|
|
|
@ -40,9 +40,11 @@ THE SOFTWARE.
|
|||
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> frameworks;
|
||||
std::set<std::string> rpaths;
|
||||
std::map<std::string, std::vector<std::string> > rpaths_per_file;
|
||||
std::map<std::string, std::string> rpath_to_fullpath;
|
||||
bool qt_plugins_called = false;
|
||||
|
||||
void changeLibPathsOnFile(std::string file_to_fix)
|
||||
{
|
||||
|
@ -50,7 +52,8 @@ void changeLibPathsOnFile(std::string file_to_fix)
|
|||
{
|
||||
collectDependencies(file_to_fix);
|
||||
}
|
||||
std::cout << "\n* Fixing dependencies on " << file_to_fix.c_str() << std::endl;
|
||||
if (!Settings::quietOutput()) std::cout << "\n";
|
||||
std::cout << "* Fixing dependencies on " << file_to_fix.c_str() << std::endl;
|
||||
|
||||
const int dep_amount = deps_per_file[file_to_fix].size();
|
||||
for(int n=0; n<dep_amount; n++)
|
||||
|
@ -206,11 +209,21 @@ std::string searchFilenameInRpaths(const std::string& rpath_file, const std::str
|
|||
break;
|
||||
}
|
||||
}
|
||||
std::cerr << "\n/!\\ WARNING : can't get path for '" << rpath_file << "'\n";
|
||||
fullpath = getUserInputDirForFile(suffix) + suffix;
|
||||
if (realpath(fullpath.c_str(), fullpath_buffer))
|
||||
if (fullpath.empty())
|
||||
{
|
||||
fullpath = fullpath_buffer;
|
||||
if (!Settings::quietOutput())
|
||||
{
|
||||
std::cerr << "\n/!\\ WARNING : can't get path for '" << rpath_file << "'\n";
|
||||
}
|
||||
fullpath = getUserInputDirForFile(suffix) + suffix;
|
||||
if (Settings::quietOutput() && fullpath.empty())
|
||||
{
|
||||
std::cerr << "\n/!\\ WARNING: Can't get path for '" << rpath_file << "'\n";
|
||||
}
|
||||
if (realpath(fullpath.c_str(), fullpath_buffer))
|
||||
{
|
||||
fullpath = fullpath_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,11 +244,11 @@ void fixRpathsOnFile(const std::string& original_file, const std::string& file_t
|
|||
rpaths_to_fix = found->second;
|
||||
}
|
||||
|
||||
for(size_t i=0; i < rpaths_to_fix.size(); ++i)
|
||||
for (size_t i=0; i < rpaths_to_fix.size(); ++i)
|
||||
{
|
||||
std::string command = std::string("install_name_tool -rpath ") +
|
||||
rpaths_to_fix[i] + " " + 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;
|
||||
exit(1);
|
||||
|
@ -252,22 +265,23 @@ void addDependency(std::string path, std::string filename)
|
|||
const int dep_amount = deps.size();
|
||||
for(int n=0; n<dep_amount; n++)
|
||||
{
|
||||
if (dep.mergeIfSameAs(deps[n])) in_deps = true;
|
||||
if(dep.mergeIfSameAs(deps[n])) in_deps = true;
|
||||
}
|
||||
|
||||
// check if this library was already added to |deps_per_file[filename]| to avoid duplicates
|
||||
std::vector<Dependency> deps_in_file = deps_per_file[filename];
|
||||
bool in_deps_per_file = false;
|
||||
const int deps_in_file_amount = deps_in_file.size();
|
||||
const int deps_in_file_amount = deps_per_file[filename].size();
|
||||
for(int n=0; n<deps_in_file_amount; n++)
|
||||
{
|
||||
if (dep.mergeIfSameAs(deps_in_file[n])) in_deps_per_file = true;
|
||||
if(dep.mergeIfSameAs(deps_per_file[filename][n])) in_deps_per_file = true;
|
||||
}
|
||||
|
||||
if (!Settings::isPrefixBundled(dep.getPrefix())) return;
|
||||
if(!Settings::isPrefixBundled(dep.getPrefix())) return;
|
||||
|
||||
if(!in_deps && dep.isFramework()) frameworks.insert(dep.getOriginalPath());
|
||||
|
||||
if (!in_deps) deps.push_back(dep);
|
||||
if (!in_deps_per_file) deps_per_file[filename].push_back(dep);
|
||||
if(!in_deps) deps.push_back(dep);
|
||||
if(!in_deps_per_file) deps_per_file[filename].push_back(dep);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -316,23 +330,14 @@ void collectDependencies(std::string filename)
|
|||
{
|
||||
std::vector<std::string> lines;
|
||||
collectDependencies(filename, lines);
|
||||
|
||||
std::cout << "."; fflush(stdout);
|
||||
|
||||
|
||||
const int line_amount = lines.size();
|
||||
for(int n=0; n<line_amount; n++)
|
||||
{
|
||||
std::cout << "."; fflush(stdout);
|
||||
if (lines[n][0] != '\t') continue; // only lines beginning with a tab interest us
|
||||
if (!Settings::isPrefixBundled(lines[n])) continue; // skip system/ignored prefixes
|
||||
|
||||
if(lines[n][0] != '\t') continue; // only lines beginning with a tab interest us
|
||||
if(!Settings::isPrefixBundled(lines[n])) continue; // skip system/ignored prefixes
|
||||
// trim useless info, keep only library name
|
||||
std::string dep_path = lines[n].substr(1, lines[n].rfind(" (") - 1);
|
||||
if (isRpath(dep_path))
|
||||
{
|
||||
collectRpathsForFilename(filename);
|
||||
}
|
||||
|
||||
addDependency(dep_path, filename);
|
||||
}
|
||||
deps_collected[filename] = true;
|
||||
|
@ -340,7 +345,7 @@ void collectDependencies(std::string filename)
|
|||
|
||||
void collectSubDependencies()
|
||||
{
|
||||
// print status to user
|
||||
size_t dep_counter = deps.size();
|
||||
int dep_amount = deps.size();
|
||||
|
||||
// recursively collect each dependencie's dependencies
|
||||
|
@ -349,51 +354,48 @@ void collectSubDependencies()
|
|||
dep_amount = deps.size();
|
||||
for(int n=0; n<dep_amount; n++)
|
||||
{
|
||||
std::cout << "."; fflush(stdout);
|
||||
std::vector<std::string> lines;
|
||||
std::string original_path = deps[n].getOriginalPath();
|
||||
std::string full_path = original_path;
|
||||
if (isRpath(original_path))
|
||||
{
|
||||
full_path = searchFilenameInRpaths(original_path);
|
||||
original_path = searchFilenameInRpaths(original_path);
|
||||
}
|
||||
collectRpathsForFilename(full_path);
|
||||
collectDependencies(full_path, lines);
|
||||
collectRpathsForFilename(original_path);
|
||||
collectDependencies(original_path, lines);
|
||||
|
||||
const int line_amount = lines.size();
|
||||
for(int n=0; n<line_amount; n++)
|
||||
{
|
||||
if (lines[n][0] != '\t') continue; // only lines beginning with a tab interest us
|
||||
if (!Settings::isPrefixBundled(lines[n])) continue; // skip system/ignored prefixes
|
||||
|
||||
// trim useless info, keep only library name
|
||||
std::string dep_path = lines[n].substr(1, lines[n].rfind(" (") - 1);
|
||||
if (isRpath(dep_path))
|
||||
{
|
||||
collectRpathsForFilename(searchFilenameInRpaths(dep_path, original_path));
|
||||
}
|
||||
|
||||
addDependency(dep_path, original_path);
|
||||
}//next
|
||||
}//next
|
||||
|
||||
if (deps.size() == dep_amount) break; // no more dependencies were added on this iteration, stop searching
|
||||
}
|
||||
|
||||
if (Settings::bundleLibs() && Settings::bundleFrameworks())
|
||||
{
|
||||
if ( !qt_plugins_called || (deps.size() != dep_counter) ) copyQtPlugins();
|
||||
}
|
||||
}
|
||||
|
||||
void createDestDir()
|
||||
{
|
||||
std::string dest_folder = Settings::destFolder();
|
||||
std::cout << "* Checking output directory " << dest_folder.c_str() << std::endl;
|
||||
std::cout << "Checking output directory " << dest_folder.c_str() << std::endl;
|
||||
|
||||
// ----------- check dest folder stuff ----------
|
||||
bool dest_exists = fileExists(dest_folder);
|
||||
|
||||
if (dest_exists and Settings::canOverwriteDir())
|
||||
if(dest_exists and Settings::canOverwriteDir())
|
||||
{
|
||||
std::cout << "* Erasing old output directory " << dest_folder.c_str() << std::endl;
|
||||
std::cout << "Erasing old output directory " << dest_folder.c_str() << std::endl;
|
||||
std::string command = std::string("rm -r ") + dest_folder;
|
||||
if (systemp(command) != 0)
|
||||
if( systemp( command ) != 0)
|
||||
{
|
||||
std::cerr << "\n\nError : An error occured while attempting to overwrite dest folder." << std::endl;
|
||||
exit(1);
|
||||
|
@ -401,14 +403,14 @@ void createDestDir()
|
|||
dest_exists = false;
|
||||
}
|
||||
|
||||
if (!dest_exists)
|
||||
if(!dest_exists)
|
||||
{
|
||||
|
||||
if (Settings::canCreateDir())
|
||||
if(Settings::canCreateDir())
|
||||
{
|
||||
std::cout << "* Creating output directory " << dest_folder.c_str() << std::endl;
|
||||
std::cout << "Creating output directory " << dest_folder.c_str() << "\n\n";
|
||||
std::string command = std::string("mkdir -p ") + dest_folder;
|
||||
if (systemp(command) != 0)
|
||||
if( systemp( command ) != 0)
|
||||
{
|
||||
std::cerr << "\n\nError : An error occured while creating dest folder." << std::endl;
|
||||
exit(1);
|
||||
|
@ -425,7 +427,6 @@ void createDestDir()
|
|||
|
||||
void doneWithDeps_go()
|
||||
{
|
||||
std::cout << std::endl;
|
||||
const int dep_amount = deps.size();
|
||||
// print info to user
|
||||
for(int n=0; n<dep_amount; n++)
|
||||
|
@ -435,7 +436,7 @@ void doneWithDeps_go()
|
|||
std::cout << std::endl;
|
||||
|
||||
// copy files if requested by user
|
||||
if (Settings::bundleLibs())
|
||||
if(Settings::bundleLibs())
|
||||
{
|
||||
createDestDir();
|
||||
|
||||
|
@ -454,3 +455,117 @@ void doneWithDeps_go()
|
|||
fixRpathsOnFile(Settings::fileToFix(n), Settings::fileToFix(n));
|
||||
}
|
||||
}
|
||||
|
||||
void copyQtPlugins()
|
||||
{
|
||||
bool qtCoreFound = false;
|
||||
bool qtGuiFound = false;
|
||||
bool qtNetworkFound = false;
|
||||
bool qtSqlFound = false;
|
||||
bool qtSvgFound = false;
|
||||
bool qtMultimediaFound = false;
|
||||
bool qt3dRenderFound = false;
|
||||
bool qt3dQuickRenderFound = false;
|
||||
bool qtPositioningFound = false;
|
||||
bool qtLocationFound = false;
|
||||
bool qtTextToSpeechFound = false;
|
||||
bool qtWebViewFound = false;
|
||||
std::string original_file;
|
||||
|
||||
for (std::set<std::string>::iterator it = frameworks.begin(); it != frameworks.end(); ++it)
|
||||
{
|
||||
std::string framework = *it;
|
||||
if (framework.find("QtCore") != std::string::npos)
|
||||
{
|
||||
qtCoreFound = true;
|
||||
original_file = framework;
|
||||
}
|
||||
if (framework.find("QtNetwork") != std::string::npos)
|
||||
qtNetworkFound = true;
|
||||
if (framework.find("QtSql") != std::string::npos)
|
||||
qtSqlFound = true;
|
||||
if (framework.find("QtSvg") != std::string::npos)
|
||||
qtSvgFound = true;
|
||||
if (framework.find("QtMultimedia") != std::string::npos)
|
||||
qtMultimediaFound = true;
|
||||
if (framework.find("Qt3DRender") != std::string::npos)
|
||||
qt3dRenderFound = true;
|
||||
if (framework.find("Qt3DQuickRender") != std::string::npos)
|
||||
qt3dQuickRenderFound = true;
|
||||
if (framework.find("QtPositioning") != std::string::npos)
|
||||
qtPositioningFound = true;
|
||||
if (framework.find("QtLocation") != std::string::npos)
|
||||
qtLocationFound = true;
|
||||
if (framework.find("TextToSpeech") != std::string::npos)
|
||||
qtTextToSpeechFound = true;
|
||||
if (framework.find("WebView") != std::string::npos)
|
||||
qtWebViewFound = true;
|
||||
}
|
||||
|
||||
if (!qtCoreFound) return;
|
||||
if (!qt_plugins_called) createQtConf(Settings::resourcesFolder());
|
||||
qt_plugins_called = true;
|
||||
|
||||
const auto fixupPlugin = [original_file](std::string plugin)
|
||||
{
|
||||
std::string dest = Settings::pluginsFolder();
|
||||
std::string framework_root = getFrameworkRoot(original_file);
|
||||
std::string prefix = filePrefix(framework_root);
|
||||
std::string qt_prefix = filePrefix(prefix.substr(0, prefix.size()-1));
|
||||
std::string qt_plugins_prefix = qt_prefix + "plugins/";
|
||||
if (fileExists(qt_plugins_prefix + plugin))
|
||||
{
|
||||
mkdir(dest + plugin);
|
||||
copyFile(qt_plugins_prefix + plugin, dest);
|
||||
std::vector<std::string> files = lsDir(dest + plugin+"/");
|
||||
for (const auto& file : files)
|
||||
{
|
||||
Settings::addFileToFix(dest + plugin+"/"+file);
|
||||
collectDependencies(dest + plugin+"/"+file);
|
||||
changeId(dest + plugin+"/"+file, "@rpath/" + plugin+"/"+file);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::string framework_root = getFrameworkRoot(original_file);
|
||||
std::string prefix = filePrefix(framework_root);
|
||||
std::string qt_prefix = filePrefix(prefix.substr(0, prefix.size()-1));
|
||||
std::string qt_plugins_prefix = qt_prefix + "plugins/";
|
||||
|
||||
std::string dest = Settings::pluginsFolder();
|
||||
mkdir(dest + "platforms");
|
||||
copyFile(qt_plugins_prefix + "platforms/libqcocoa.dylib", dest + "platforms");
|
||||
Settings::addFileToFix(dest + "platforms/libqcocoa.dylib");
|
||||
collectDependencies(dest + "platforms/libqcocoa.dylib");
|
||||
|
||||
fixupPlugin("printsupport");
|
||||
fixupPlugin("styles");
|
||||
fixupPlugin("imageformats");
|
||||
fixupPlugin("iconengines");
|
||||
if (!qtSvgFound) systemp(std::string("rm -f ") + dest + "imageformats/libqsvg.dylib");
|
||||
if (qtGuiFound)
|
||||
{
|
||||
fixupPlugin("platforminputcontexts");
|
||||
fixupPlugin("virtualkeyboard");
|
||||
}
|
||||
if (qtNetworkFound) fixupPlugin("bearer");
|
||||
if (qtSqlFound) fixupPlugin("sqldrivers");
|
||||
if (qtMultimediaFound)
|
||||
{
|
||||
fixupPlugin("mediaservice");
|
||||
fixupPlugin("audio");
|
||||
}
|
||||
if (qt3dRenderFound)
|
||||
{
|
||||
fixupPlugin("sceneparsers");
|
||||
fixupPlugin("geometryloaders");
|
||||
}
|
||||
if (qt3dQuickRenderFound) fixupPlugin("renderplugins");
|
||||
if (qtPositioningFound) fixupPlugin("position");
|
||||
if (qtLocationFound) fixupPlugin("geoservices");
|
||||
if (qtTextToSpeechFound) fixupPlugin("texttospeech");
|
||||
if (qtWebViewFound) fixupPlugin("webview");
|
||||
|
||||
collectSubDependencies();
|
||||
}
|
||||
|
||||
|
|
|
@ -37,9 +37,12 @@ std::string searchFilenameInRpaths(const std::string& rpath_dep);
|
|||
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 filename);
|
||||
void collectDependencies(std::string dependent_file, std::vector<std::string>& lines);
|
||||
void collectDependencies(std::string dependent_file);
|
||||
void collectSubDependencies();
|
||||
|
||||
void doneWithDeps_go();
|
||||
|
||||
void copyQtPlugins();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,7 @@ bool bundle_frameworks = false;
|
|||
bool quiet_output = false;
|
||||
|
||||
std::string dest_folder_str = "./libs/";
|
||||
std::string dest_folder_str_app = "Frameworks/";
|
||||
std::string dest_folder_str_app = "./Frameworks/";
|
||||
std::string dest_folder = dest_folder_str;
|
||||
std::string dest_path = dest_folder;
|
||||
|
||||
|
@ -59,8 +59,8 @@ void bundleLibs(bool on){ bundle_libs = on; }
|
|||
bool bundleFrameworks(){ return bundle_frameworks; }
|
||||
void bundleFrameworks(bool on){ bundle_frameworks = on; }
|
||||
|
||||
bool quietOutput() { return quiet_output; }
|
||||
void quietOutput(bool status) { quiet_output = status; }
|
||||
bool quietOutput(){ return quiet_output; }
|
||||
void quietOutput(bool status){ quiet_output = status; }
|
||||
|
||||
std::string app_bundle;
|
||||
bool appBundleProvided(){ return !app_bundle.empty(); }
|
||||
|
@ -68,50 +68,61 @@ 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 += "/";
|
||||
|
||||
addFileToFix(app_bundle + "Contents/MacOS/" + bundleExecutableName(app_bundle));
|
||||
|
||||
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/" + stripLSlash(dest_folder);
|
||||
char buffer[PATH_MAX];
|
||||
if(realpath(dest_path.c_str(), buffer)) dest_path = buffer;
|
||||
if(realpath(app_bundle.c_str(), buffer))
|
||||
app_bundle = buffer;
|
||||
// fix path if needed so it ends with '/'
|
||||
if(dest_path[ dest_path.size()-1 ] != '/') dest_path += "/";
|
||||
if( app_bundle[ app_bundle.size()-1 ] != '/' )
|
||||
app_bundle += "/";
|
||||
|
||||
std::string bundle_executable_path = app_bundle + "Contents/MacOS/" + bundleExecutableName(app_bundle);
|
||||
if(realpath(bundle_executable_path.c_str(), buffer))
|
||||
bundle_executable_path = buffer;
|
||||
addFileToFix(bundle_executable_path);
|
||||
|
||||
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/" + stripLSlash(dest_folder);
|
||||
if(realpath(dest_path.c_str(), buffer))
|
||||
dest_path = buffer;
|
||||
if( dest_path[ dest_path.size()-1 ] != '/' )
|
||||
dest_path += "/";
|
||||
}
|
||||
|
||||
std::string destFolder(){ return dest_path; }
|
||||
void destFolder(std::string path)
|
||||
{
|
||||
// fix path if needed so it ends with '/'
|
||||
if(path[ path.size()-1 ] != '/') path += "/";
|
||||
dest_folder = path;
|
||||
if(appBundleProvided())
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
std::string dest_path = app_bundle + "Contents/" + stripLSlash(path);
|
||||
if(realpath(dest_path.c_str(), buffer)) dest_path = buffer;
|
||||
// fix path if needed so it ends with '/'
|
||||
if(dest_path[ dest_path.size()-1 ] != '/') dest_path += "/";
|
||||
dest_folder = dest_path;
|
||||
}
|
||||
dest_path = path;
|
||||
if(appBundleProvided()) dest_path = app_bundle + "Contents/" + stripLSlash(path);
|
||||
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 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); }
|
||||
void addFileToFix(std::string path)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
if(realpath(path.c_str(), buffer)) path = buffer;
|
||||
files.push_back(path);
|
||||
}
|
||||
int fileToFixAmount(){ return files.size(); }
|
||||
std::string fileToFix(const int n){ return files[n]; }
|
||||
|
||||
std::string inside_lib_path(){ return inside_path_str; }
|
||||
std::string inside_lib_path(){ return inside_path; }
|
||||
void inside_lib_path(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;
|
||||
|
|
|
@ -60,6 +60,9 @@ std::string destFolder();
|
|||
void destFolder(std::string path);
|
||||
|
||||
std::string executableFolder();
|
||||
std::string frameworksFolder();
|
||||
std::string pluginsFolder();
|
||||
std::string resourcesFolder();
|
||||
|
||||
void addFileToFix(std::string path);
|
||||
int fileToFixAmount();
|
||||
|
|
150
src/Utils.cpp
150
src/Utils.cpp
|
@ -28,6 +28,7 @@ THE SOFTWARE.
|
|||
#include "Settings.h"
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
@ -76,49 +77,54 @@ string rtrim(string s)
|
|||
void tokenize(const string& str, const char* delim, vector<string>* vectorarg)
|
||||
{
|
||||
vector<string>& tokens = *vectorarg;
|
||||
|
||||
string delimiters(delim);
|
||||
|
||||
// skip delimiters at beginning.
|
||||
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
|
||||
string::size_type lastPos = str.find_first_not_of( delimiters , 0);
|
||||
|
||||
// find first "non-delimiter".
|
||||
string::size_type pos = str.find_first_of(delimiters, lastPos);
|
||||
|
||||
while(string::npos != pos || string::npos != lastPos)
|
||||
while (string::npos != pos || string::npos != lastPos)
|
||||
{
|
||||
// found a token, add it to the vector.
|
||||
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||||
|
||||
// skip delimiters. Note the "not_of"
|
||||
lastPos = str.find_first_not_of(delimiters, pos);
|
||||
|
||||
// find next "non-delimiter"
|
||||
pos = str.find_first_of(delimiters, lastPos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool fileExists(string filename)
|
||||
{
|
||||
if (access(filename.c_str(), F_OK) != -1) return true; // file exists
|
||||
if (access( filename.c_str(), F_OK ) != -1) return true; // file exists
|
||||
|
||||
string delims = " \f\n\r\t\v";
|
||||
string rtrimmed = filename.substr(0, filename.find_last_not_of(delims)+1);
|
||||
string ftrimmed = rtrimmed.substr(rtrimmed.find_first_not_of(delims));
|
||||
|
||||
if (access(ftrimmed.c_str(), F_OK) != -1) return true;
|
||||
if (access( ftrimmed.c_str(), F_OK ) != -1) return true;
|
||||
return false; // file doesn't exist
|
||||
}
|
||||
|
||||
void copyFile(string from, string to)
|
||||
{
|
||||
bool overwrite = Settings::canOverwriteFiles();
|
||||
if (!overwrite)
|
||||
if(!overwrite)
|
||||
{
|
||||
if (fileExists(to))
|
||||
if(fileExists( to ))
|
||||
{
|
||||
cerr << "\n\nError : File " << to.c_str() << " already exists. Remove it or enable overwriting." << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// copy file/directory
|
||||
// copy file to local directory
|
||||
string overwrite_permission = string(overwrite ? "-f " : "-n ");
|
||||
string command = string("cp -R ") + overwrite_permission + from + string(" ") + to;
|
||||
if (from != to && systemp(command) != 0)
|
||||
|
@ -127,9 +133,9 @@ void copyFile(string from, string to)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
// give file/directory write permission
|
||||
// give it write permission
|
||||
string command2 = string("chmod -R +w ") + to;
|
||||
if (systemp(command2) != 0)
|
||||
if( systemp( command2 ) != 0 )
|
||||
{
|
||||
cerr << "\n\nError : An error occured while trying to set write permissions on file " << to << endl;
|
||||
exit(1);
|
||||
|
@ -140,7 +146,7 @@ void deleteFile(string path, bool overwrite)
|
|||
{
|
||||
string overwrite_permission = string(overwrite ? "-f " : " ");
|
||||
string command = string("rm -r ") + overwrite_permission + path;
|
||||
if (systemp(command) != 0)
|
||||
if( systemp( command ) != 0 )
|
||||
{
|
||||
cerr << "\n\nError: An error occured while trying to delete " << path << endl;
|
||||
exit(1);
|
||||
|
@ -153,90 +159,118 @@ void deleteFile(string path)
|
|||
deleteFile(path, overwrite);
|
||||
}
|
||||
|
||||
string system_get_output(string cmd)
|
||||
std::vector<std::string> lsDir(const std::string& path)
|
||||
{
|
||||
FILE* command_output;
|
||||
std::string cmd = "ls " + path;
|
||||
std::string output = system_get_output(cmd);
|
||||
std::vector<std::string> files;
|
||||
tokenize(output, "\n", &files);
|
||||
return files;
|
||||
}
|
||||
|
||||
bool mkdir(const std::string& path)
|
||||
{
|
||||
cout << "Creating directory " << path << std::endl;
|
||||
string command = string("mkdir -p ") + path;
|
||||
if( systemp( command ) != 0 )
|
||||
{
|
||||
cerr << "\n/!\\ ERROR: An error occured while creating " << path << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string system_get_output(std::string cmd)
|
||||
{
|
||||
FILE * command_output;
|
||||
char output[128];
|
||||
int amount_read = 1;
|
||||
string full_output;
|
||||
|
||||
std::string full_output;
|
||||
|
||||
try
|
||||
{
|
||||
command_output = popen(cmd.c_str(), "r");
|
||||
if (command_output == NULL) throw;
|
||||
|
||||
if(command_output == NULL) throw;
|
||||
|
||||
while(amount_read > 0)
|
||||
{
|
||||
amount_read = fread(output, 1, 127, command_output);
|
||||
if (amount_read <= 0) break;
|
||||
output[amount_read] = '\0';
|
||||
full_output += output;
|
||||
if(amount_read <= 0) break;
|
||||
else
|
||||
{
|
||||
output[amount_read] = '\0';
|
||||
full_output += output;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "An error occured while executing command " << cmd.c_str() << endl;
|
||||
std::cerr << "An error occured while executing command " << cmd.c_str() << std::endl;
|
||||
pclose(command_output);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
int return_value = pclose(command_output);
|
||||
if (return_value != 0) return "";
|
||||
if(return_value != 0) return "";
|
||||
|
||||
return full_output;
|
||||
}
|
||||
|
||||
int systemp(string& cmd)
|
||||
int systemp(const std::string& cmd)
|
||||
{
|
||||
cout << " " << cmd.c_str() << endl;
|
||||
if(!Settings::quietOutput()) std::cout << " " << cmd << "\n";
|
||||
return system(cmd.c_str());
|
||||
}
|
||||
|
||||
string getUserInputDirForFile(const string& filename)
|
||||
std::string getUserInputDirForFile(const std::string& filename)
|
||||
{
|
||||
const int searchPathAmount = Settings::searchPathAmount();
|
||||
for(int n=0; n<searchPathAmount; n++)
|
||||
{
|
||||
string searchPath = Settings::searchPath(n);
|
||||
if (!searchPath.empty() && searchPath[ searchPath.size()-1 ] != '/') searchPath += "/";
|
||||
auto searchPath = Settings::searchPath(n);
|
||||
if( !searchPath.empty() && searchPath[ searchPath.size()-1 ] != '/' ) searchPath += "/";
|
||||
|
||||
if (!fileExists(searchPath+filename)) continue;
|
||||
cerr << (searchPath+filename) << " was found. /!\\ DYLIBBUNDLER MAY NOT CORRECTLY HANDLE THIS DEPENDENCY: Manually check the executable with 'otool -L'" << endl;
|
||||
if( !fileExists( searchPath+filename ) ) continue;
|
||||
std::cerr << (searchPath+filename) << " was found. /!\\ DYLIBBUNDLER MAY NOT CORRECTLY HANDLE THIS DEPENDENCY: Manually check the executable with 'otool -L'" << std::endl;
|
||||
return searchPath;
|
||||
}
|
||||
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
cout << "Please specify the directory where this library is located (or enter 'quit' to abort): "; fflush(stdout);
|
||||
std::cout << "Please specify the directory where this library is located (or enter 'quit' to abort): "; fflush(stdout);
|
||||
|
||||
string prefix;
|
||||
cin >> prefix;
|
||||
cout << endl;
|
||||
std::string prefix;
|
||||
std::cin >> prefix;
|
||||
std::cout << std::endl;
|
||||
|
||||
if (prefix.compare("quit") == 0) exit(1);
|
||||
if(prefix.compare("quit")==0) exit(1);
|
||||
if (!prefix.empty() && prefix[ prefix.size()-1 ] != '/') prefix += "/";
|
||||
|
||||
if (!fileExists(prefix+filename))
|
||||
if( !fileExists( prefix+filename ) )
|
||||
{
|
||||
cerr << (prefix+filename) << " does not exist. Try again" << endl;
|
||||
std::cerr << (prefix+filename) << " does not exist. Try again" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << (prefix+filename) << " was found. /!\\ DYLIBBUNDLER MAY NOT CORRECTLY HANDLE THIS DEPENDENCY: Manually check the executable with 'otool -L'" << endl;
|
||||
Settings::addSearchPath(prefix);
|
||||
return prefix;
|
||||
else
|
||||
{
|
||||
std::cerr << (prefix+filename) << " was found. /!\\ DYLIBBUNDLER MAY NOT CORRECTLY HANDLE THIS DEPENDENCY: Manually check the executable with 'otool -L'" << std::endl;
|
||||
Settings::addSearchPath(prefix);
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string bundleExecutableName(const string& app_bundle_path)
|
||||
{
|
||||
string cmd = "/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "
|
||||
+ app_bundle_path + "Contents/Info.plist";
|
||||
return system_get_output(cmd);
|
||||
string cmd = "/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' " + app_bundle_path + "Contents/Info.plist";
|
||||
return rtrim(system_get_output(cmd));
|
||||
}
|
||||
|
||||
void changeId(string binary_file, string new_id)
|
||||
{
|
||||
string command = string("install_name_tool -id ") + new_id + " " + binary_file;
|
||||
if (systemp(command) != 0)
|
||||
if( systemp( command ) != 0 )
|
||||
{
|
||||
cerr << "\n\nError: An error occured while trying to change identity of library " << binary_file << endl;
|
||||
exit(1);
|
||||
|
@ -246,7 +280,7 @@ void changeId(string binary_file, string new_id)
|
|||
void changeInstallName(string binary_file, string old_name, string new_name)
|
||||
{
|
||||
string command = string("install_name_tool -change ") + old_name + " " + new_name + " " + binary_file;
|
||||
if (systemp(command) != 0)
|
||||
if( systemp( command ) != 0 )
|
||||
{
|
||||
cerr << "\n\nError: An error occured while trying to fix dependencies of " << binary_file << endl;
|
||||
exit(1);
|
||||
|
@ -257,27 +291,39 @@ void initSearchPaths()
|
|||
{
|
||||
string searchPaths;
|
||||
char* dyldLibPath = getenv("DYLD_LIBRARY_PATH");
|
||||
if (dyldLibPath != 0) searchPaths = dyldLibPath;
|
||||
if(dyldLibPath != 0) searchPaths = dyldLibPath;
|
||||
dyldLibPath = getenv("DYLD_FALLBACK_FRAMEWORK_PATH");
|
||||
if (dyldLibPath != 0)
|
||||
if(dyldLibPath != 0)
|
||||
{
|
||||
if (!searchPaths.empty() && searchPaths[ searchPaths.size()-1 ] != ':') searchPaths += ":";
|
||||
if( !searchPaths.empty() && searchPaths[ searchPaths.size()-1 ] != ':' ) searchPaths += ":";
|
||||
searchPaths += dyldLibPath;
|
||||
}
|
||||
dyldLibPath = getenv("DYLD_FALLBACK_LIBRARY_PATH");
|
||||
if (dyldLibPath!=0)
|
||||
if(dyldLibPath != 0)
|
||||
{
|
||||
if (!searchPaths.empty() && searchPaths[ searchPaths.size()-1 ] != ':') searchPaths += ":";
|
||||
if( !searchPaths.empty() && searchPaths[ searchPaths.size()-1 ] != ':' ) searchPaths += ":";
|
||||
searchPaths += dyldLibPath;
|
||||
}
|
||||
if (!searchPaths.empty())
|
||||
if(!searchPaths.empty())
|
||||
{
|
||||
stringstream ss(searchPaths);
|
||||
string item;
|
||||
while(getline(ss, item, ':'))
|
||||
{
|
||||
if (item[ item.size()-1 ] != '/') item += "/";
|
||||
if( item[ item.size()-1 ] != '/' ) item += "/";
|
||||
Settings::addSearchPath(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createQtConf(std::string directory)
|
||||
{
|
||||
std::string contents = "[Paths]\n"
|
||||
"Plugins = PlugIns\n"
|
||||
"Imports = Resources/qml\n"
|
||||
"Qml2Imports = Resources/qml\n";
|
||||
if( directory[ directory.size()-1 ] != '/' ) directory += "/";
|
||||
std::ofstream out(directory + "qt.conf");
|
||||
out << contents;
|
||||
out.close();
|
||||
}
|
|
@ -48,13 +48,18 @@ void tokenize(const std::string& str, const char* delimiters, std::vector<std::s
|
|||
bool fileExists( std::string filename );
|
||||
|
||||
void copyFile(std::string from, std::string to);
|
||||
|
||||
void deleteFile(std::string path, bool overwrite);
|
||||
void deleteFile(std::string path);
|
||||
|
||||
std::vector<std::string> lsDir(const std::string& path);
|
||||
bool mkdir(const std::string& path);
|
||||
|
||||
// executes a command in the native shell and returns output in string
|
||||
std::string system_get_output(std::string cmd);
|
||||
|
||||
// like 'system', runs a command on the system shell, but also prints the command to stdout.
|
||||
int systemp(std::string& cmd);
|
||||
int systemp(const std::string& cmd);
|
||||
|
||||
std::string getUserInputDirForFile(const std::string& filename);
|
||||
|
||||
|
@ -66,4 +71,6 @@ void changeInstallName(std::string binary_file, std::string old_name, std::strin
|
|||
// check the same paths the system would search for dylibs
|
||||
void initSearchPaths();
|
||||
|
||||
void createQtConf(std::string directory);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -65,7 +65,7 @@ void showHelp()
|
|||
std::cout << "-od, --overwrite-dir (totally overwrite output directory if it already exists. implies --create-dir)" << std::endl;
|
||||
std::cout << "-cd, --create-dir (creates output directory if necessary)" << std::endl;
|
||||
std::cout << "-i, --ignore <location to ignore> (will ignore libraries in this directory)" << std::endl;
|
||||
std::cout << "-q, --quiet Less verbose output" << std::endl;
|
||||
std::cout << "-q, --quiet (less verbose output)" << std::endl;
|
||||
std::cout << "-h, --help" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ int main (int argc, char * const argv[])
|
|||
exit(0);
|
||||
}
|
||||
|
||||
std::cout << "* Collecting dependencies"; fflush(stdout);
|
||||
std::cout << "Collecting dependencies..." << std::endl;
|
||||
|
||||
const int amount = Settings::fileToFixAmount();
|
||||
for(int n=0; n<amount; n++)
|
||||
|
|
Loading…
Reference in New Issue