1 Commits

Author SHA1 Message Date
Alexis López Zubieta 7aa7b68266 Patch prefix path in libQt5Core 2018-06-26 07:23:11 -05:00
3 changed files with 294 additions and 128 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
add_executable(linuxdeploy-plugin-qt main.cpp qt-modules.h) add_executable(linuxdeploy-plugin-qt main.cpp qt-modules.h qt_tools_utils.hpp)
target_link_libraries(linuxdeploy-plugin-qt linuxdeploy_core args) target_link_libraries(linuxdeploy-plugin-qt linuxdeploy_core args)
set_target_properties(linuxdeploy-plugin-qt PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") set_target_properties(linuxdeploy-plugin-qt PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+129 -82
View File
@@ -16,6 +16,7 @@
// local includes // local includes
#include "qt-modules.h" #include "qt-modules.h"
#include "qt_tools_utils.hpp"
namespace bf = boost::filesystem; namespace bf = boost::filesystem;
@@ -29,23 +30,25 @@ typedef struct {
std::string stderrOutput; std::string stderrOutput;
} procOutput; } procOutput;
procOutput check_command(const std::initializer_list<const char*> args) { procOutput check_command(const std::initializer_list<const char*> args)
{
subprocess::Popen proc(args, subprocess::output(subprocess::PIPE), subprocess::error(subprocess::PIPE)); subprocess::Popen proc(args, subprocess::output(subprocess::PIPE), subprocess::error(subprocess::PIPE));
auto output = proc.communicate(); auto output = proc.communicate();
std::string out, err; std::string out, err;
if (output.first.length > 0) if (output.first.length>0)
out = output.first.buf.data(); out = output.first.buf.data();
if (output.second.length > 0) if (output.second.length>0)
err = output.second.buf.data(); err = output.second.buf.data();
return {proc.retcode() == 0, proc.retcode(), out, err}; return {proc.retcode()==0, proc.retcode(), out, err};
}; };
const std::map<std::string, std::string> queryQmake(const bf::path& qmakePath) { const std::map<std::string, std::string> queryQmake(const bf::path& qmakePath)
{
auto qmakeCall = check_command({qmakePath.c_str(), "-query"}); auto qmakeCall = check_command({qmakePath.c_str(), "-query"});
if (!qmakeCall.success) { if (!qmakeCall.success) {
@@ -77,7 +80,7 @@ const std::map<std::string, std::string> queryQmake(const bf::path& qmakePath) {
while (std::getline(ss, line)) { while (std::getline(ss, line)) {
auto parts = stringSplit(line, ':'); auto parts = stringSplit(line, ':');
if (parts.size() != 2) if (parts.size()!=2)
continue; continue;
rv[parts[0]] = parts[1]; rv[parts[0]] = parts[1];
@@ -86,29 +89,32 @@ const std::map<std::string, std::string> queryQmake(const bf::path& qmakePath) {
return rv; return rv;
}; };
static std::string which(const std::string& name) { static std::string which(const std::string& name)
{
subprocess::Popen proc({"which", name.c_str()}, subprocess::output(subprocess::PIPE)); subprocess::Popen proc({"which", name.c_str()}, subprocess::output(subprocess::PIPE));
auto output = proc.communicate(); auto output = proc.communicate();
ldLog() << LD_DEBUG << "Calling 'which" << name << LD_NO_SPACE << "'" << std::endl; ldLog() << LD_DEBUG << "Calling 'which" << name << LD_NO_SPACE << "'" << std::endl;
if (proc.retcode() != 0) { if (proc.retcode()!=0) {
ldLog() << LD_DEBUG << "which call failed, exit code:" << proc.retcode() << std::endl; ldLog() << LD_DEBUG << "which call failed, exit code:" << proc.retcode() << std::endl;
return ""; return "";
} }
std::string path = output.first.buf.data(); std::string path = output.first.buf.data();
while (path.back() == '\n') { while (path.back()=='\n') {
path.erase(path.end() - 1, path.end()); path.erase(path.end()-1, path.end());
} }
return path; return path;
} }
template<typename Iter> std::string join(Iter beg, Iter end) { template<typename Iter>
std::string join(Iter beg, Iter end)
{
std::stringstream rv; std::stringstream rv;
if (beg != end) { if (beg!=end) {
rv << *beg; rv << *beg;
std::for_each(++beg, end, [&rv](const std::string& s) { std::for_each(++beg, end, [&rv](const std::string& s) {
@@ -119,41 +125,46 @@ template<typename Iter> std::string join(Iter beg, Iter end) {
return rv.str(); return rv.str();
} }
std::string join(const std::vector<std::string>& list) { std::string join(const std::vector<std::string>& list)
{
return join(list.begin(), list.end()); return join(list.begin(), list.end());
} }
std::string join(const std::set<std::string>& list) { std::string join(const std::set<std::string>& list)
{
return join(list.begin(), list.end()); return join(list.begin(), list.end());
} }
bool strStartsWith(const std::string& str, const std::string& prefix) { bool strStartsWith(const std::string& str, const std::string& prefix)
if (str.size() < prefix.size()) {
if (str.size()<prefix.size())
return false; return false;
return strncmp(str.c_str(), prefix.c_str(), prefix.size()) == 0; return strncmp(str.c_str(), prefix.c_str(), prefix.size())==0;
} }
bool strEndsWith(const std::string& str, const std::string& suffix) { bool strEndsWith(const std::string& str, const std::string& suffix)
if (str.size() < suffix.size()) {
if (str.size()<suffix.size())
return false; return false;
return strncmp(str.c_str() + (str.size() - suffix.size()), suffix.c_str(), suffix.size()) == 0; return strncmp(str.c_str()+(str.size()-suffix.size()), suffix.c_str(), suffix.size())==0;
} }
bool deployPlatformPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) { bool deployPlatformPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
{
ldLog() << "Deploying platform plugins" << std::endl; ldLog() << "Deploying platform plugins" << std::endl;
if (!appDir.deployLibrary(qtPluginsPath / "platforms/libqxcb.so", appDir.path() / "usr/plugins/platforms/")) if (!appDir.deployLibrary(qtPluginsPath/"platforms/libqxcb.so", appDir.path()/"usr/plugins/platforms/"))
return false; return false;
for (bf::directory_iterator i(qtPluginsPath / "platforminputcontexts"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"platforminputcontexts"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/platforminputcontexts/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/platforminputcontexts/"))
return false; return false;
} }
for (bf::directory_iterator i(qtPluginsPath / "imageformats"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"imageformats"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/imageformats/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/imageformats/"))
return false; return false;
} }
@@ -162,81 +173,89 @@ bool deployPlatformPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath
return true; return true;
} }
bool deployXcbglIntegrationPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) { bool deployXcbglIntegrationPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
{
ldLog() << "Deploying xcb-gl integrations" << std::endl; ldLog() << "Deploying xcb-gl integrations" << std::endl;
for (bf::directory_iterator i(qtPluginsPath / "xcbglintegrations"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"xcbglintegrations"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/xcbglintegrations/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/xcbglintegrations/"))
return false; return false;
} }
return true; return true;
} }
bool deploySvgPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) { bool deploySvgPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
{
ldLog() << "Deploying svg icon engine" << std::endl; ldLog() << "Deploying svg icon engine" << std::endl;
if (!appDir.deployLibrary(qtPluginsPath / "iconengines/libqsvgicon.so", appDir.path() / "usr/plugins/iconengines/")) if (!appDir.deployLibrary(qtPluginsPath/"iconengines/libqsvgicon.so", appDir.path()/"usr/plugins/iconengines/"))
return false; return false;
return true; return true;
} }
bool deployBearerPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) { bool deployBearerPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
{
ldLog() << "Deploying bearer plugins" << std::endl; ldLog() << "Deploying bearer plugins" << std::endl;
for (bf::directory_iterator i(qtPluginsPath / "bearer"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"bearer"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/bearer/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/bearer/"))
return false; return false;
} }
return true; return true;
} }
bool deploySqlPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) { bool deploySqlPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
{
ldLog() << "Deploying SQL plugins" << std::endl; ldLog() << "Deploying SQL plugins" << std::endl;
for (bf::directory_iterator i(qtPluginsPath / "sqldrivers"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"sqldrivers"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/sqldrivers/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/sqldrivers/"))
return false; return false;
} }
return true; return true;
} }
bool deployPositioningPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) { bool deployPositioningPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
{
ldLog() << "Deploying positioning plugins" << std::endl; ldLog() << "Deploying positioning plugins" << std::endl;
for (bf::directory_iterator i(qtPluginsPath / "position"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"position"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/position/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/position/"))
return false; return false;
} }
return true; return true;
} }
bool deployMultimediaPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) { bool deployMultimediaPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
{
ldLog() << "Deploying mediaservice plugins" << std::endl; ldLog() << "Deploying mediaservice plugins" << std::endl;
for (bf::directory_iterator i(qtPluginsPath / "mediaservice"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"mediaservice"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/mediaservice/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/mediaservice/"))
return false; return false;
} }
ldLog() << "Deploying audio plugins" << std::endl; ldLog() << "Deploying audio plugins" << std::endl;
for (bf::directory_iterator i(qtPluginsPath / "audio"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtPluginsPath/"audio"); i!=bf::directory_iterator(); ++i) {
if (!appDir.deployLibrary(*i, appDir.path() / "usr/plugins/audio/")) if (!appDir.deployLibrary(*i, appDir.path()/"usr/plugins/audio/"))
return false; return false;
} }
return true; return true;
} }
bool deployWebEnginePlugins(appdir::AppDir& appDir, const bf::path& qtLibexecsPath, const bf::path& qtDataPath, const bf::path& qtTranslationsPath) { bool deployWebEnginePlugins(appdir::AppDir& appDir, const bf::path& qtLibexecsPath, const bf::path& qtDataPath,
const bf::path& qtTranslationsPath)
{
ldLog() << "Deploying web engine plugins" << std::endl; ldLog() << "Deploying web engine plugins" << std::endl;
for (bf::directory_iterator i(qtLibexecsPath); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtLibexecsPath); i!=bf::directory_iterator(); ++i) {
auto& entry = *i; auto& entry = *i;
const std::string prefix = "QtWeb"; const std::string prefix = "QtWeb";
@@ -246,7 +265,7 @@ bool deployWebEnginePlugins(appdir::AppDir& appDir, const bf::path& qtLibexecsPa
if (!strStartsWith(fileName.string(), prefix)) if (!strStartsWith(fileName.string(), prefix))
continue; continue;
if (!appDir.deployExecutable(*i, appDir.path() / "usr/libexec/")) if (!appDir.deployExecutable(*i, appDir.path()/"usr/libexec/"))
return false; return false;
} }
@@ -254,27 +273,29 @@ bool deployWebEnginePlugins(appdir::AppDir& appDir, const bf::path& qtLibexecsPa
"qtwebengine_devtools_resources.pak", "qtwebengine_devtools_resources.pak",
"qtwebengine_resources_100p.pak", "qtwebengine_resources_100p.pak",
"qtwebengine_resources_200p.pak", "icudtl.dat"}) { "qtwebengine_resources_200p.pak", "icudtl.dat"}) {
auto path = qtDataPath / "resources" / fileName; auto path = qtDataPath/"resources"/fileName;
if (bf::is_regular_file(path)) if (bf::is_regular_file(path))
appDir.deployFile(path, appDir.path() / "usr/data/resources/"); appDir.deployFile(path, appDir.path()/"usr/data/resources/");
} }
if (bf::is_directory(qtTranslationsPath / "qtwebengine_locales")) { if (bf::is_directory(qtTranslationsPath/"qtwebengine_locales")) {
for (bf::directory_iterator i(qtTranslationsPath / "qtwebengine_locales"); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtTranslationsPath/"qtwebengine_locales"); i!=bf::directory_iterator(); ++i) {
appDir.deployFile(*i, appDir.path() / "usr/qtwebengine_locales/"); appDir.deployFile(*i, appDir.path()/"usr/qtwebengine_locales/");
} }
} }
return true; return true;
} }
bool createQtConf(appdir::AppDir& appDir) { bool createQtConf(appdir::AppDir& appDir)
auto qtConfPath = appDir.path() / "usr" / "bin" / "qt.conf"; {
auto qtConfPath = appDir.path()/"usr"/"bin"/"qt.conf";
if (bf::is_regular_file(qtConfPath)) { if (bf::is_regular_file(qtConfPath)) {
ldLog() << LD_WARNING << "Skipping creation of Qt conf file: file exists:" << qtConfPath << std::endl; ldLog() << LD_WARNING << "Skipping creation of Qt conf file: file exists:" << qtConfPath << std::endl;
} else { }
else {
ldLog() << "Creating Qt conf file:" << qtConfPath << std::endl; ldLog() << "Creating Qt conf file:" << qtConfPath << std::endl;
} }
@@ -295,7 +316,9 @@ bool createQtConf(appdir::AppDir& appDir) {
return true; return true;
} }
bool deployTranslations(appdir::AppDir& appDir, const bf::path& qtTranslationsPath, const std::vector<QtModule>& modules) { bool
deployTranslations(appdir::AppDir& appDir, const bf::path& qtTranslationsPath, const std::vector<QtModule>& modules)
{
if (qtTranslationsPath.empty() || !bf::is_directory(qtTranslationsPath)) { if (qtTranslationsPath.empty() || !bf::is_directory(qtTranslationsPath)) {
ldLog() << LD_WARNING << "Translation directory does not exist, skipping deployment"; ldLog() << LD_WARNING << "Translation directory does not exist, skipping deployment";
return true; return true;
@@ -308,7 +331,8 @@ bool deployTranslations(appdir::AppDir& appDir, const bf::path& qtTranslationsPa
return false; return false;
// always deploy basic Qt translations // always deploy basic Qt translations
if (strStartsWith(fileName.string(), "qt_") && bf::basename(fileName).size() >= 5 && bf::basename(fileName).size() <= 6) if (strStartsWith(fileName.string(), "qt_") && bf::basename(fileName).size()>=5
&& bf::basename(fileName).size()<=6)
return true; return true;
for (const auto& module : modules) { for (const auto& module : modules) {
@@ -319,35 +343,39 @@ bool deployTranslations(appdir::AppDir& appDir, const bf::path& qtTranslationsPa
return false; return false;
}; };
for (bf::directory_iterator i(qtTranslationsPath); i != bf::directory_iterator(); ++i) { for (bf::directory_iterator i(qtTranslationsPath); i!=bf::directory_iterator(); ++i) {
if (!bf::is_regular_file(*i)) if (!bf::is_regular_file(*i))
continue; continue;
const auto fileName = (*i).path().filename(); const auto fileName = (*i).path().filename();
if (checkName(fileName)) if (checkName(fileName))
appDir.deployFile(*i, appDir.path() / "usr/translations/"); appDir.deployFile(*i, appDir.path()/"usr/translations/");
} }
return true; return true;
} }
int main(const int argc, const char* const* const argv) { int main(const int argc, const char* const* const argv)
{
// set up verbose logging if $DEBUG is set // set up verbose logging if $DEBUG is set
if (getenv("DEBUG")) if (getenv("DEBUG"))
ldLog::setVerbosity(LD_DEBUG); ldLog::setVerbosity(LD_DEBUG);
args::ArgumentParser parser("linuxdeploy Qt plugin", "Bundles Qt resources. For use with an existing AppDir, created by linuxdeploy."); args::ArgumentParser parser("linuxdeploy Qt plugin",
"Bundles Qt resources. For use with an existing AppDir, created by linuxdeploy.");
args::ValueFlag<bf::path> appDirPath(parser, "appdir path", "Path to an existing AppDir", {"appdir"}); args::ValueFlag<bf::path> appDirPath(parser, "appdir path", "Path to an existing AppDir", {"appdir"});
args::ValueFlagList<std::string> extraPlugins(parser, "plugin", "Extra Qt plugin to deploy (specified by name, filename or path)", {'p', "extra-plugin"}); args::ValueFlagList<std::string> extraPlugins(parser, "plugin",
"Extra Qt plugin to deploy (specified by name, filename or path)", {'p', "extra-plugin"});
args::Flag pluginType(parser, "", "Print plugin type and exit", {"plugin-type"}); args::Flag pluginType(parser, "", "Print plugin type and exit", {"plugin-type"});
args::Flag pluginApiVersion(parser, "", "Print plugin API version and exit", {"plugin-api-version"}); args::Flag pluginApiVersion(parser, "", "Print plugin API version and exit", {"plugin-api-version"});
try { try {
parser.ParseCLI(argc, argv); parser.ParseCLI(argc, argv);
} catch (const args::ParseError&) { }
catch (const args::ParseError&) {
std::cerr << parser; std::cerr << parser;
return 1; return 1;
} }
@@ -382,7 +410,8 @@ int main(const int argc, const char* const* const argv) {
for (const auto& dependency : elf::ElfFile(path).traceDynamicDependencies()) { for (const auto& dependency : elf::ElfFile(path).traceDynamicDependencies()) {
libraryNames.insert(dependency.filename().string()); libraryNames.insert(dependency.filename().string());
} }
} catch (const elf::ElfFileParseError& e) { }
catch (const elf::ElfFileParseError& e) {
ldLog() << LD_DEBUG << "Failed to parse file as ELF file:" << path << std::endl; ldLog() << LD_DEBUG << "Failed to parse file as ELF file:" << path << std::endl;
} }
} }
@@ -397,20 +426,20 @@ int main(const int argc, const char* const* const argv) {
libraryName = bf::path(libraryName).filename().string(); libraryName = bf::path(libraryName).filename().string();
// adding the trailing dot makes sure e.g., libQt5WebEngineCore won't be matched as webengine and webenginecore // adding the trailing dot makes sure e.g., libQt5WebEngineCore won't be matched as webengine and webenginecore
const auto& libraryPrefix = module.libraryFilePrefix + "."; const auto& libraryPrefix = module.libraryFilePrefix+".";
ldLog() << LD_DEBUG << "Checking library name '" << LD_NO_SPACE << libraryName ldLog() << LD_DEBUG << "Checking library name '" << LD_NO_SPACE << libraryName
<< LD_NO_SPACE << "' against library prefix '" << LD_NO_SPACE << libraryPrefix << LD_NO_SPACE << LD_NO_SPACE << "' against library prefix '" << LD_NO_SPACE << libraryPrefix << LD_NO_SPACE
<< "' and module name '" << LD_NO_SPACE << module.name << LD_NO_SPACE << "'" << std::endl; << "' and module name '" << LD_NO_SPACE << module.name << LD_NO_SPACE << "'" << std::endl;
// match plugin filename // match plugin filename
if (strncmp(libraryName.c_str(), libraryPrefix.c_str(), libraryPrefix.size()) == 0) { if (strncmp(libraryName.c_str(), libraryPrefix.c_str(), libraryPrefix.size())==0) {
ldLog() << LD_DEBUG << "-> matches library filename, found module:" << module.name << std::endl; ldLog() << LD_DEBUG << "-> matches library filename, found module:" << module.name << std::endl;
return true; return true;
} }
// match plugin name // match plugin name
if (strcmp(libraryName.c_str(), module.name.c_str()) == 0) { if (strcmp(libraryName.c_str(), module.name.c_str())==0) {
ldLog() << LD_DEBUG << "-> matches module name, found module:" << module.name << std::endl; ldLog() << LD_DEBUG << "-> matches module name, found module:" << module.name << std::endl;
return true; return true;
} }
@@ -418,16 +447,20 @@ int main(const int argc, const char* const* const argv) {
return false; return false;
}; };
std::copy_if(QtModules.begin(), QtModules.end(), std::back_inserter(foundQtModules), [&matchesQtModule, &libraryNames, &extraPlugins](const QtModule& module) { std::copy_if(QtModules.begin(), QtModules.end(), std::back_inserter(foundQtModules),
return std::find_if(libraryNames.begin(), libraryNames.end(), [&matchesQtModule, &module](const std::string& libraryName) { [&matchesQtModule, &libraryNames, &extraPlugins](const QtModule& module) {
return std::find_if(libraryNames.begin(), libraryNames.end(),
[&matchesQtModule, &module](const std::string& libraryName) {
return matchesQtModule(libraryName, module); return matchesQtModule(libraryName, module);
}) != libraryNames.end(); })!=libraryNames.end();
}); });
std::copy_if(QtModules.begin(), QtModules.end(), std::back_inserter(extraQtModules), [&matchesQtModule, libraryNames, &extraPlugins](const QtModule& module) { std::copy_if(QtModules.begin(), QtModules.end(), std::back_inserter(extraQtModules),
return std::find_if(extraPlugins.Get().begin(), extraPlugins.Get().end(), [&matchesQtModule, &module](const std::string& libraryName) { [&matchesQtModule, libraryNames, &extraPlugins](const QtModule& module) {
return std::find_if(extraPlugins.Get().begin(), extraPlugins.Get().end(),
[&matchesQtModule, &module](const std::string& libraryName) {
return matchesQtModule(libraryName, module); return matchesQtModule(libraryName, module);
}) != extraPlugins.Get().end(); })!=extraPlugins.Get().end();
}); });
{ {
@@ -484,42 +517,56 @@ int main(const int argc, const char* const* const argv) {
for (const auto& module : qtModulesToDeploy) { for (const auto& module : qtModulesToDeploy) {
ldLog() << std::endl << "-- Deploying module:" << module.name << "--" << std::endl; ldLog() << std::endl << "-- Deploying module:" << module.name << "--" << std::endl;
if (module.name == "gui") { if (module.name=="core") {
string errStr;
string qtCoreLibraryPath;
for (auto libraryName: appDir.listSharedLibraries()) {
if (libraryName.filename().string().find("Qt5Core.")!=std::string::npos)
qtCoreLibraryPath = libraryName.string();
}
patchQtCore(qtCoreLibraryPath, &errStr);
if (!errStr.empty()) {
ldLog() << "Failed to patch QtCore. " << errStr;
return 1;
}
}
if (module.name=="gui") {
if (!deployPlatformPlugins(appDir, qtPluginsPath)) if (!deployPlatformPlugins(appDir, qtPluginsPath))
return 1; return 1;
} }
if (module.name == "opengl" || module.name == "gui" || module.name == "xcbqpa") { if (module.name=="opengl" || module.name=="gui" || module.name=="xcbqpa") {
if (!deployXcbglIntegrationPlugins(appDir, qtPluginsPath)) if (!deployXcbglIntegrationPlugins(appDir, qtPluginsPath))
return 1; return 1;
} }
if (module.name == "network") { if (module.name=="network") {
if (!deployBearerPlugins(appDir, qtPluginsPath)) if (!deployBearerPlugins(appDir, qtPluginsPath))
return 1; return 1;
} }
if (module.name == "svg") { if (module.name=="svg") {
if (!deploySvgPlugins(appDir, qtPluginsPath)) if (!deploySvgPlugins(appDir, qtPluginsPath))
return 1; return 1;
} }
if (module.name == "sql") { if (module.name=="sql") {
if (!deploySqlPlugins(appDir, qtPluginsPath)) if (!deploySqlPlugins(appDir, qtPluginsPath))
return 1; return 1;
} }
if (module.name == "positioning") { if (module.name=="positioning") {
if (!deployPositioningPlugins(appDir, qtPluginsPath)) if (!deployPositioningPlugins(appDir, qtPluginsPath))
return 1; return 1;
} }
if (module.name == "multimedia") { if (module.name=="multimedia") {
if (!deployMultimediaPlugins(appDir, qtPluginsPath)) if (!deployMultimediaPlugins(appDir, qtPluginsPath))
return 1; return 1;
} }
if (module.name == "webenginecore") { if (module.name=="webenginecore") {
if (!deployWebEnginePlugins(appDir, qtLibexecsPath, qtDataPath, qtTranslationsPath)) if (!deployWebEnginePlugins(appDir, qtLibexecsPath, qtDataPath, qtTranslationsPath))
return 1; return 1;
} }
+119
View File
@@ -0,0 +1,119 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QT_TOOLS_UTILS
#define QT_TOOLS_UTILS
#include <string>
#include <fstream>
#include <iostream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "../lib/linuxdeploy/include/linuxdeploy/core/log.h"
using namespace std;
using namespace boost::filesystem;
using namespace linuxdeploy::core::log;
vector<char> readFileContent(const path& path, string* errorMessage);
void writeFileContent(const path& path, const vector<char>& content, string* errorMessage);
// Search for "qt_prfxpath=xxxx" in \a path, and replace it with "qt_prfxpath=."
void patchQtCore(const path& path, string* errorMessage = nullptr)
{
ldLog() << "Patching " << path.filename() << "...\n";
auto content = readFileContent(path, errorMessage);
if (content.empty()) {
*errorMessage = "Unable to patch"+path.string()+": Could not read file content";
return;
}
char prfxpath[] = "qt_prfxpath=";
size_t len = strlen(prfxpath);
auto startPos = std::search(content.begin(), content.end(), prfxpath, prfxpath+len);
if (startPos==content.end()) {
*errorMessage = "Unable to patch "+path.string()+": Could not locate pattern \"qt_prfxpath=\"";
return;
}
startPos += len;
auto endPos = startPos;
while (endPos!=content.end() && *endPos!='\0')
endPos++;
if (endPos==content.end()) {
*errorMessage = "Unable to patch "+path.string()+": Internal error";
return;
}
auto oldValue = vector<char>(startPos, endPos);
vector<char> newValue(static_cast<unsigned long>(endPos-startPos), char(0));
newValue[0] = '.';
ldLog() << "Replaced prfxpath: " << oldValue << " by " << newValue;
for (auto i = startPos; i<endPos; i++)
*i = newValue[i-startPos];
writeFileContent(path, content, errorMessage);
}
void writeFileContent(const path& path, const vector<char>& content, string* errorMessage)
{
std::ofstream outfile(path.string(), std::ofstream::binary);
outfile.write(content.data(), content.size());
if (outfile.fail())
*errorMessage = "Unable to write : "+path.string();
outfile.close();
}
vector<char> readFileContent(const path& path, string* errorMessage)
{
std::ifstream inFileStream(path.string(), std::ifstream::binary);
if (inFileStream) {
// get length of file:
inFileStream.seekg(0, std::ifstream::end);
auto length = static_cast<unsigned long>(inFileStream.tellg());
inFileStream.seekg(0, std::ifstream::beg);
auto* buffer = new char[length];
inFileStream.read(buffer, length);
if (inFileStream.fail())
*errorMessage = "Unable to read : "+path.string();
inFileStream.close();
vector<char> output(buffer, buffer+length);
delete[] buffer;
return output;
}
}
#endif QT_TOOLS_UTILS