You've already forked linuxdeploy-plugin-qt
mirror of
https://github.com/encounter/linuxdeploy-plugin-qt.git
synced 2026-03-30 11:19:03 -07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7aa7b68266 |
+1
-1
@@ -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")
|
||||||
|
|
||||||
|
|||||||
+76
-29
@@ -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,7 +30,8 @@ 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();
|
||||||
@@ -45,7 +47,8 @@ procOutput check_command(const std::initializer_list<const char*> args) {
|
|||||||
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) {
|
||||||
@@ -86,7 +89,8 @@ 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();
|
||||||
|
|
||||||
@@ -105,7 +109,9 @@ static std::string which(const std::string& name) {
|
|||||||
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) {
|
||||||
@@ -119,29 +125,34 @@ 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/"))
|
||||||
@@ -162,7 +173,8 @@ 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) {
|
||||||
@@ -173,7 +185,8 @@ bool deployXcbglIntegrationPlugins(appdir::AppDir& appDir, const bf::path& qtPlu
|
|||||||
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/"))
|
||||||
@@ -182,7 +195,8 @@ bool deploySvgPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) {
|
|||||||
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) {
|
||||||
@@ -193,7 +207,8 @@ bool deployBearerPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath)
|
|||||||
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) {
|
||||||
@@ -204,7 +219,8 @@ bool deploySqlPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPath) {
|
|||||||
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) {
|
||||||
@@ -215,7 +231,8 @@ bool deployPositioningPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsP
|
|||||||
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) {
|
||||||
@@ -233,7 +250,9 @@ bool deployMultimediaPlugins(appdir::AppDir& appDir, const bf::path& qtPluginsPa
|
|||||||
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) {
|
||||||
@@ -269,12 +288,14 @@ bool deployWebEnginePlugins(appdir::AppDir& appDir, const bf::path& qtLibexecsPa
|
|||||||
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) {
|
||||||
@@ -332,22 +356,26 @@ bool deployTranslations(appdir::AppDir& appDir, const bf::path& qtTranslationsPa
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -418,14 +447,18 @@ 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,6 +517,20 @@ 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=="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 (module.name=="gui") {
|
||||||
if (!deployPlatformPlugins(appDir, qtPluginsPath))
|
if (!deployPlatformPlugins(appDir, qtPluginsPath))
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user