summaryrefslogtreecommitdiffstats
path: root/src/tools/androiddeployqt/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/androiddeployqt/main.cpp')
-rw-r--r--src/tools/androiddeployqt/main.cpp152
1 files changed, 105 insertions, 47 deletions
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 3b78d2487f..3af5237f3d 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -43,6 +43,15 @@
#include <QRegExp>
#include <algorithm>
+
+#ifdef Q_CC_MSVC
+#define popen _popen
+#define QT_POPEN_READ "rb"
+#define pclose _pclose
+#else
+#define QT_POPEN_READ "r"
+#endif
+
static const bool mustReadOutputAnyway = true; // pclose seems to return the wrong error code unless we read the output
void deleteRecursively(const QString &dirName)
@@ -70,7 +79,7 @@ FILE *openProcess(const QString &command)
QString processedCommand = command;
#endif
- return popen(processedCommand.toLocal8Bit().constData(), "r");
+ return popen(processedCommand.toLocal8Bit().constData(), QT_POPEN_READ);
}
struct QtDependency
@@ -128,6 +137,7 @@ struct Options
bool build;
bool gradle;
bool auxMode;
+ bool stripLibraries = true;
QTime timer;
// External tools
@@ -147,6 +157,10 @@ struct Options
QString rootPath;
QStringList qmlImportPaths;
+ // Versioning
+ QString versionName;
+ QString versionCode;
+
// lib c++ path
QString stdCppPath;
QString stdCppName = QStringLiteral("gnustl_shared");
@@ -157,6 +171,7 @@ struct Options
QString toolchainVersion;
QString toolchainPrefix;
QString toolPrefix;
+ bool useLLVM = false;
QString ndkHost;
// Package information
@@ -436,6 +451,8 @@ Options parseOptions()
options.generateAssetsFileList = false;
} else if (argument.compare(QLatin1String("--aux-mode"), Qt::CaseInsensitive) == 0) {
options.auxMode = true;
+ } else if (argument.compare(QLatin1String("--no-strip"), Qt::CaseInsensitive) == 0) {
+ options.stripLibraries = false;
}
}
@@ -524,6 +541,7 @@ void printHelp()
" --aux-mode: Operate in auxiliary mode. This will only copy the\n"
" dependencies into the build directory and update the XML templates.\n"
" The project will not be built or installed.\n"
+ " --no-strip: Do not strip debug symbols from libraries.\n"
" --help: Displays this information.\n\n",
qPrintable(QCoreApplication::arguments().at(0))
);
@@ -707,7 +725,7 @@ bool readInputFile(Options *options)
return false;
}
- options->sdkPath = sdkPath.toString();
+ options->sdkPath = QDir::fromNativeSeparators(sdkPath.toString());
if (options->androidPlatform.isEmpty()) {
options->androidPlatform = detectLatestAndroidPlatform(options->sdkPath);
@@ -752,6 +770,22 @@ bool readInputFile(Options *options)
}
{
+ const QJsonValue androidVersionName = jsonObject.value(QStringLiteral("android-version-name"));
+ if (!androidVersionName.isUndefined())
+ options->versionName = androidVersionName.toString();
+ else
+ options->versionName = QStringLiteral("1.0");
+ }
+
+ {
+ const QJsonValue androidVersionCode = jsonObject.value(QStringLiteral("android-version-code"));
+ if (!androidVersionCode.isUndefined())
+ options->versionCode = androidVersionCode.toString();
+ else
+ options->versionCode = QStringLiteral("1");
+ }
+
+ {
const QJsonValue applicationBinary = jsonObject.value(QStringLiteral("application-binary"));
if (applicationBinary.isUndefined()) {
fprintf(stderr, "No application binary defined in json file.\n");
@@ -809,6 +843,11 @@ bool readInputFile(Options *options)
}
{
+ const QJsonValue value = jsonObject.value(QStringLiteral("useLLVM"));
+ options->useLLVM = value.toBool(false);
+ }
+
+ {
const QJsonValue toolchainPrefix = jsonObject.value(QStringLiteral("toolchain-prefix"));
if (toolchainPrefix.isUndefined()) {
fprintf(stderr, "No toolchain prefix defined in json file.\n");
@@ -827,7 +866,7 @@ bool readInputFile(Options *options)
}
}
- {
+ if (!options->useLLVM) {
const QJsonValue toolchainVersion = jsonObject.value(QStringLiteral("toolchain-version"));
if (toolchainVersion.isUndefined()) {
fprintf(stderr, "No toolchain version defined in json file.\n");
@@ -861,17 +900,19 @@ bool readInputFile(Options *options)
options->extraPlugins = extraPlugins.toString().split(QLatin1Char(','));
}
- {
+ if (!options->auxMode) {
const QJsonValue stdcppPath = jsonObject.value(QStringLiteral("stdcpp-path"));
- if (!stdcppPath.isUndefined()) {
- options->stdCppPath = stdcppPath.toString();
- auto name = QFileInfo(options->stdCppPath).baseName();
- if (!name.startsWith(QLatin1String("lib"))) {
- fprintf(stderr, "Invalid STD C++ library name.\n");
- return false;
- }
- options->stdCppName = name.mid(3);
+ if (stdcppPath.isUndefined()) {
+ fprintf(stderr, "No stdcpp-path defined in json file.\n");
+ return false;
+ }
+ options->stdCppPath = stdcppPath.toString();
+ auto name = QFileInfo(options->stdCppPath).baseName();
+ if (!name.startsWith(QLatin1String("lib"))) {
+ fprintf(stderr, "Invalid STD C++ library name.\n");
+ return false;
}
+ options->stdCppName = name.mid(3);
}
{
@@ -1220,7 +1261,7 @@ bool updateStringsXml(const Options &options)
fprintf(stderr, "Can't open %s for writing.\n", qPrintable(fileName));
return false;
}
- file.write(QByteArray("<?xml version='1.0' encoding='utf-8'?><resources><string name=\"app_name\">")
+ file.write(QByteArray("<?xml version='1.0' encoding='utf-8'?><resources><string name=\"app_name\" translatable=\"false\">")
.append(QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1).toLatin1())
.append("</string></resources>\n"));
return true;
@@ -1312,6 +1353,8 @@ bool updateAndroidManifest(Options &options)
replacements[QLatin1String("-- %%INSERT_LOCAL_LIBS%% --")] = localLibs.join(QLatin1Char(':'));
replacements[QLatin1String("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':'));
replacements[QLatin1String("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':'));
+ replacements[QLatin1String("-- %%INSERT_VERSION_NAME%% --")] = options.versionName;
+ replacements[QLatin1String("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
replacements[QLatin1String("package=\"org.qtproject.example\"")] = QString::fromLatin1("package=\"%1\"").arg(options.packageName);
replacements[QLatin1String("-- %%BUNDLE_LOCAL_QT_LIBS%% --")]
= (options.deploymentMechanism == Options::Bundled) ? QString::fromLatin1("1") : QString::fromLatin1("0");
@@ -1357,8 +1400,8 @@ bool updateAndroidManifest(Options &options)
options.packageName = reader.attributes().value(QLatin1String("package")).toString();
} else if (reader.name() == QLatin1String("uses-sdk")) {
if (reader.attributes().hasAttribute(QLatin1String("android:minSdkVersion")))
- if (reader.attributes().value(QLatin1String("android:minSdkVersion")).toInt() < 16) {
- fprintf(stderr, "Invalid minSdkVersion version, minSdkVersion must be >= 16\n");
+ if (reader.attributes().value(QLatin1String("android:minSdkVersion")).toInt() < 21) {
+ fprintf(stderr, "Invalid minSdkVersion version, minSdkVersion must be >= 21\n");
return false;
}
} else if ((reader.name() == QLatin1String("application") ||
@@ -1546,14 +1589,16 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
{
QString readElf = options.ndkPath
+ QLatin1String("/toolchains/")
- + options.toolchainPrefix
- + QLatin1Char('-')
- + options.toolchainVersion
- + QLatin1String("/prebuilt/")
+ + options.toolchainPrefix;
+
+ if (!options.useLLVM)
+ readElf += QLatin1Char('-') + options.toolchainVersion;
+
+ readElf += QLatin1String("/prebuilt/")
+ options.ndkHost
+ QLatin1String("/bin/")
- + options.toolPrefix
- + QLatin1String("-readelf");
+ + options.toolPrefix +
+ (options.useLLVM ? QLatin1String("-readobj") : QLatin1String("-readelf"));
#if defined(Q_OS_WIN32)
readElf += QLatin1String(".exe");
#endif
@@ -1563,27 +1608,40 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
return QStringList();
}
- readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf)).arg(shellQuote(fileName));
+ if (options.useLLVM)
+ readElf = QString::fromLatin1("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(fileName));
+ else
+ readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf), shellQuote(fileName));
FILE *readElfCommand = openProcess(readElf);
- if (readElfCommand == 0) {
+ if (!readElfCommand) {
fprintf(stderr, "Cannot execute command %s", qPrintable(readElf));
return QStringList();
}
QStringList ret;
+ bool readLibs = false;
char buffer[512];
while (fgets(buffer, sizeof(buffer), readElfCommand) != 0) {
QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer));
- if (line.contains("(NEEDED)") && line.contains("Shared library:") ) {
- const int pos = line.lastIndexOf('[') + 1;
- QString libraryName = QLatin1String("lib/") + QString::fromLatin1(line.mid(pos, line.length() - pos - 2));
- if (QFile::exists(absoluteFilePath(&options, libraryName))) {
- ret += libraryName;
+ QString library;
+ if (options.useLLVM) {
+ line = line.trimmed();
+ if (!readLibs) {
+ readLibs = line.startsWith("NeededLibraries");
+ continue;
}
-
+ if (!line.startsWith("lib"))
+ continue;
+ library = QString::fromLatin1(line);
+ } else if (line.contains("(NEEDED)") && line.contains("Shared library:")) {
+ const int pos = line.lastIndexOf('[') + 1;
+ library = QString::fromLatin1(line.mid(pos, line.length() - pos - 2));
}
+ QString libraryName = QLatin1String("lib/") + library;
+ if (QFile::exists(absoluteFilePath(&options, libraryName)))
+ ret += libraryName;
}
pclose(readElfCommand);
@@ -1664,7 +1722,7 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
QStringList importPaths;
importPaths += shellQuote(options->qtInstallDirectory + QLatin1String("/qml"));
- importPaths += rootPath;
+ importPaths += shellQuote(rootPath);
for (const QString &qmlImportPath : qAsConst(options->qmlImportPaths))
importPaths += shellQuote(qmlImportPath);
@@ -1672,7 +1730,7 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
.arg(shellQuote(rootPath))
.arg(importPaths.join(QLatin1Char(' ')));
- FILE *qmlImportScannerCommand = popen(qmlImportScanner.toLocal8Bit().constData(), "r");
+ FILE *qmlImportScannerCommand = popen(qmlImportScanner.toLocal8Bit().constData(), QT_POPEN_READ);
if (qmlImportScannerCommand == 0) {
fprintf(stderr, "Couldn't run qmlimportscanner.\n");
return false;
@@ -1837,10 +1895,12 @@ bool stripFile(const Options &options, const QString &fileName)
{
QString strip = options.ndkPath
+ QLatin1String("/toolchains/")
- + options.toolchainPrefix
- + QLatin1Char('-')
- + options.toolchainVersion
- + QLatin1String("/prebuilt/")
+ + options.toolchainPrefix;
+
+ if (!options.useLLVM)
+ strip += QLatin1Char('-') + options.toolchainVersion;
+
+ strip += QLatin1String("/prebuilt/")
+ options.ndkHost
+ QLatin1String("/bin/")
+ options.toolPrefix
@@ -1854,7 +1914,10 @@ bool stripFile(const Options &options, const QString &fileName)
return false;
}
- strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip)).arg(shellQuote(fileName));
+ if (options.useLLVM)
+ strip = QString::fromLatin1("%1 -strip-all %2").arg(shellQuote(strip), shellQuote(fileName));
+ else
+ strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip), shellQuote(fileName));
FILE *stripCommand = openProcess(strip);
if (stripCommand == 0) {
@@ -1869,6 +1932,8 @@ bool stripFile(const Options &options, const QString &fileName)
bool stripLibraries(const Options &options)
{
+ if (!options.stripLibraries)
+ return true;
if (options.verbose)
fprintf(stdout, "Stripping libraries to minimize size.\n");
@@ -2104,7 +2169,7 @@ bool createAndroidProject(const Options &options)
if (options.verbose)
fprintf(stdout, " -- Command: %s\n", qPrintable(androidTool));
- FILE *androidToolCommand = popen(androidTool.toLocal8Bit().constData(), "r");
+ FILE *androidToolCommand = popen(androidTool.toLocal8Bit().constData(), QT_POPEN_READ);
if (androidToolCommand == 0) {
fprintf(stderr, "Cannot run command '%s'\n", qPrintable(androidTool));
return false;
@@ -2423,22 +2488,15 @@ bool copyStdCpp(Options *options)
if (options->verbose)
fprintf(stdout, "Copying STL library\n");
- QString filePath = !options->stdCppPath.isEmpty() ? options->stdCppPath
- : options->ndkPath
- + QLatin1String("/sources/cxx-stl/gnu-libstdc++/")
- + options->toolchainVersion
- + QLatin1String("/libs/")
- + options->architecture
- + QLatin1String("/libgnustl_shared.so");
- if (!QFile::exists(filePath)) {
- fprintf(stderr, "STL library does not exist at %s\n", qPrintable(filePath));
+ if (!QFile::exists(options->stdCppPath)) {
+ fprintf(stderr, "STL library does not exist at %s\n", qPrintable(options->stdCppPath));
return false;
}
const QString destinationDirectory = options->outputDirectory
+ QLatin1String("/libs/") + options->architecture;
- if (!copyFileIfNewer(filePath, destinationDirectory + QLatin1String("/lib")
+ if (!copyFileIfNewer(options->stdCppPath, destinationDirectory + QLatin1String("/lib")
+ options->stdCppName + QLatin1String(".so"),
options->verbose)) {
return false;