diff options
-rw-r--r-- | .github/workflows/main.yml | 6 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | docker-compose.yml | 2 | ||||
-rw-r--r-- | docker/focal/test-android.Dockerfile | 10 | ||||
-rw-r--r-- | share/qbs/module-providers/Qt/setup-qt.js | 6 | ||||
-rw-r--r-- | share/qbs/modules/Android/sdk/sdk.qbs | 2 | ||||
-rw-r--r-- | src/app/config/configcommand.h | 2 | ||||
-rw-r--r-- | src/app/config/configcommandexecutor.cpp | 12 | ||||
-rw-r--r-- | src/app/config/configcommandlineparser.cpp | 31 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-android/qt-app/TestQt6.java | 54 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs | 11 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.cpp | 61 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackbox.h | 2 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackboxandroid.cpp | 4 |
14 files changed, 190 insertions, 15 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 953f19949..98c1a8b11 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -264,6 +264,12 @@ jobs: script: './scripts/test-qt-for-android.sh', } - { + name: 'Run Android tests (Qt 6.0.0)', + image: 'focal-android-600', + profile: '', + script: './scripts/test-qt-for-android.sh', + } + - { name: 'Run Linux tests (Qt 4.8.7)', image: 'focal-qt4', profile: '', @@ -1 +1 @@ -1.19.0 +1.20.0 diff --git a/docker-compose.yml b/docker-compose.yml index 2df603fc5..e00b641c1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -73,7 +73,7 @@ services: focal-android-600: << : *linux hostname: focal-android - image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-android-6.0.0-1 + image: ${DOCKER_USER:-qbsbuild}/qbsdev:focal-android-6.0.0-2 build: dockerfile: docker/focal/test-android.Dockerfile context: . diff --git a/docker/focal/test-android.Dockerfile b/docker/focal/test-android.Dockerfile index 72c84ca0c..11c4a5757 100644 --- a/docker/focal/test-android.Dockerfile +++ b/docker/focal/test-android.Dockerfile @@ -72,8 +72,14 @@ ARG ANDROID_PLATFORM="android-29" ARG BUILD_TOOLS="29.0.2" RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" --verbose --licenses && \ sdkmanager "--sdk_root=${ANDROID_HOME}" --update && \ - sdkmanager "--sdk_root=${ANDROID_HOME}" "platforms;${ANDROID_PLATFORM}" "build-tools;${BUILD_TOOLS}" "platform-tools" "tools" "ndk-bundle" && \ - /usr/lib/jvm/java-8-openjdk-amd64/bin/keytool -genkey -keystore /home/${USER_NAME}/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname 'CN=Android Debug,O=Android,C=US' + sdkmanager "--sdk_root=${ANDROID_HOME}" "platforms;${ANDROID_PLATFORM}" + +RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "build-tools;${BUILD_TOOLS}" +RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "platform-tools" +RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "tools" +RUN yes | sdkmanager "--sdk_root=${ANDROID_HOME}" "ndk-bundle" + +RUN /usr/lib/jvm/java-8-openjdk-amd64/bin/keytool -genkey -keystore /home/${USER_NAME}/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname 'CN=Android Debug,O=Android,C=US' # Install ndk samples in ${ANDROID_NDK_ROOT}/samples RUN cd ${ANDROID_NDK_ROOT} && \ diff --git a/share/qbs/module-providers/Qt/setup-qt.js b/share/qbs/module-providers/Qt/setup-qt.js index 5cf1bcb44..c23d51d1b 100644 --- a/share/qbs/module-providers/Qt/setup-qt.js +++ b/share/qbs/module-providers/Qt/setup-qt.js @@ -268,8 +268,10 @@ function getQtProperties(qmakeFilePath, qbs) { (pathQueryValue(queryResult, "QT_INSTALL_DATA"), "mkspecs"); } - if (Utilities.versionCompare(qtProps.qtVersion, "6") >= 0) - qtProps.libExecPath = pathQueryValue(queryResult, "QT_INSTALL_LIBEXECS"); + if (Utilities.versionCompare(qtProps.qtVersion, "6") >= 0) { + qtProps.libExecPath = pathQueryValue(queryResult, "QT_HOST_LIBEXECS") + || pathQueryValue(queryResult, "QT_INSTALL_LIBEXECS"); + } if (!File.exists(qtProps.mkspecBasePath)) throw "Cannot extract the mkspecs directory."; diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs index cae5fc2e5..76f84dca6 100644 --- a/share/qbs/modules/Android/sdk/sdk.qbs +++ b/share/qbs/modules/Android/sdk/sdk.qbs @@ -150,7 +150,7 @@ Module { } property path buildToolsDir: FileInfo.joinPaths(sdkDir, "build-tools", buildToolsVersion) - property string aaptName: "aapt" + property string aaptName: "aapt2" PropertyOptions { name: "aaptName" allowedValues: ["aapt", "aapt2"] diff --git a/src/app/config/configcommand.h b/src/app/config/configcommand.h index 1574e3745..f8e2a8ae9 100644 --- a/src/app/config/configcommand.h +++ b/src/app/config/configcommand.h @@ -47,7 +47,7 @@ class ConfigCommand { public: - enum Command { CfgSet, CfgUnset, CfgList, CfgExport, CfgImport, CfgNone }; + enum Command { CfgSet, CfgUnset, CfgList, CfgExport, CfgImport, CfgAddProfile, CfgNone }; ConfigCommand() : command(CfgNone) {} diff --git a/src/app/config/configcommandexecutor.cpp b/src/app/config/configcommandexecutor.cpp index 0a6883aa7..a01058b11 100644 --- a/src/app/config/configcommandexecutor.cpp +++ b/src/app/config/configcommandexecutor.cpp @@ -42,6 +42,7 @@ #include "../shared/logging/consolelogger.h" #include <tools/error.h> +#include <tools/profile.h> #include <tools/qttools.h> #include <tools/settingsrepresentation.h> @@ -73,6 +74,17 @@ void ConfigCommandExecutor::execute(const ConfigCommand &command) for (const QString &varName : command.varNames) m_settings->remove(varName); break; + case ConfigCommand::CfgAddProfile: { + Profile profile(command.varValue, m_settings); + profile.removeProfile(); + Q_ASSERT(command.varNames.size() % 2 == 0); + for (int i = 0; i < command.varNames.size(); i += 2) { + const QString &key = command.varNames.at(i); + const QString &rawValue = command.varNames.at(i + 1); + profile.setValue(key, representationToSettingsValue(rawValue)); + } + break; + } case ConfigCommand::CfgExport: exportSettings(command.fileName); break; diff --git a/src/app/config/configcommandlineparser.cpp b/src/app/config/configcommandlineparser.cpp index 2f2d1610e..8652a58bc 100644 --- a/src/app/config/configcommandlineparser.cpp +++ b/src/app/config/configcommandlineparser.cpp @@ -71,6 +71,8 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine) setCommand(ConfigCommand::CfgExport); else if (arg == QLatin1String("import")) setCommand(ConfigCommand::CfgImport); + else if (arg == QLatin1String("add-profile")) + setCommand(ConfigCommand::CfgAddProfile); else if (arg == QLatin1String("settings-dir")) assignOptionArgument(arg, m_settingsDir); else if (arg == QLatin1String("user")) @@ -113,6 +115,22 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine) case ConfigCommand::CfgList: m_command.varNames = m_commandLine; break; + case ConfigCommand::CfgAddProfile: + if (m_commandLine.empty()) + throw Error(Tr::tr("Profile name missing.")); + m_command.varValue = m_commandLine.takeFirst(); + if (m_command.varValue.isEmpty()) + throw Error(Tr::tr("Profile name must not be empty.")); + m_command.varNames = m_commandLine; + if (m_command.varNames.isEmpty()) + throw Error(Tr::tr("Profile properties must be provided.")); + if (m_command.varNames.size() % 2 != 0) + throw Error(Tr::tr("Profile properties must be key/value pairs.")); + for (int i = 0; i < m_command.varNames.size(); ++i) { + if (m_command.varNames.at(i).isEmpty()) + throw Error(Tr::tr("Property names must not be empty.")); + } + break; default: break; } @@ -140,12 +158,13 @@ void ConfigCommandLineParser::printUsage() const " qbs config [--settings-dir <settings directory] <key> <value>" "\n" "Options:\n" - " --list [<root> ...] list keys under key <root> or all keys\n" - " --user consider only user-level settings\n" - " --system consider only system-level settings\n" - " --unset <name> remove key with given name\n" - " --import <file> import settings from given file\n" - " --export <file> export settings to given file\n"); + " --list [<root> ...] list keys under key <root> or all keys\n" + " --user consider only user-level settings\n" + " --system consider only system-level settings\n" + " --unset <name> remove key with given name\n" + " --add-profile <name> <key> <value> ... add profile with the given name and properties\n" + " --import <file> import settings from given file\n" + " --export <file> export settings to given file\n"); } void ConfigCommandLineParser::assignOptionArgument(const QString &option, QString &argument) diff --git a/tests/auto/blackbox/testdata-android/qt-app/TestQt6.java b/tests/auto/blackbox/testdata-android/qt-app/TestQt6.java new file mode 100644 index 000000000..239507122 --- /dev/null +++ b/tests/auto/blackbox/testdata-android/qt-app/TestQt6.java @@ -0,0 +1,54 @@ +package org.qbs.example; + +import org.qtproject.qt.android.bindings.QtActivity; +import android.os.*; +import android.content.*; +import android.app.*; +import android.util.Log; + +import java.lang.String; +import android.content.Intent; + +import org.qbs.example.*; + + +public class TestQt6 extends QtActivity +{ + public static native void testFunc(String test); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.d("qbs", "onCreate Test"); + Intent theIntent = getIntent(); + if (theIntent != null) { + String theAction = theIntent.getAction(); + if (theAction != null) { + Log.d("qbs onCreate ", theAction); + } + } + } + + @Override + public void onDestroy() { + Log.d("qbs", "onDestroy"); + System.exit(0); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + Log.d("qbs onActivityResult", "requestCode: "+requestCode); + if (resultCode == RESULT_OK) { + Log.d("qbs onActivityResult - resultCode: ", "SUCCESS"); + } else { + Log.d("qbs onActivityResult - resultCode: ", "CANCEL"); + } + } + + @Override + public void onNewIntent(Intent intent) { + Log.d("qbs", "onNewIntent"); + super.onNewIntent(intent); + setIntent(intent); + } +} diff --git a/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs b/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs index 94093af64..04dcbf403 100644 --- a/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs +++ b/tests/auto/blackbox/testdata-android/qt-app/qt-app.qbs @@ -1,7 +1,16 @@ Project { QtGuiApplication { Depends { name: "Lib" } - files: ["main.cpp", "MainWindow.cpp", "MainWindow.h", "Test.java"] + files: ["main.cpp", "MainWindow.cpp", "MainWindow.h" ] + Group { + condition: Qt.core.versionMajor == 5 + files: ["Test.java"] + } + Group { + condition: Qt.core.versionMajor == 6 + files: ["TestQt6.java"] + } + Android.sdk.packageName: "my.qtapp" Android.sdk.apkBaseName: name Depends { name: "Qt"; submodules: ["core", "widgets"] } diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 1b9fa0b15..7d75ab91f 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -5958,6 +5958,67 @@ void TestBlackbox::qbsConfig() } } +void TestBlackbox::qbsConfigAddProfile() +{ + QbsRunParameters params("config"); + QTemporaryDir settingsDir1; + QTemporaryDir settingsDir2; + QVERIFY(settingsDir1.isValid()); + QVERIFY(settingsDir2.isValid()); + const QStringList settingsDir1Args = QStringList{"--settings-dir", settingsDir1.path()}; + const QStringList settingsDir2Args = QStringList{"--settings-dir", settingsDir2.path()}; + + QFETCH(QStringList, args); + QFETCH(QString, errorMsg); + + // Step 1: Run --add-profile. + params.arguments = settingsDir1Args; + params.arguments << "--add-profile"; + params.arguments << args; + params.expectFailure = !errorMsg.isEmpty(); + QCOMPARE(runQbs(params) == 0, !params.expectFailure); + if (params.expectFailure) { + QVERIFY(QString::fromLocal8Bit(m_qbsStderr).contains(errorMsg)); + return; + } + params.expectFailure = false; + params.arguments = settingsDir1Args; + params.arguments << "--list"; + QCOMPARE(runQbs(params), 0); + const QByteArray output1 = m_qbsStdout; + + // Step 2: Set properties manually. + for (int i = 1; i < args.size(); i += 2) { + params.arguments = settingsDir2Args; + params.arguments << ("profiles." + args.first() + '.' + args.at(i)) << args.at(i + 1); + QCOMPARE(runQbs(params), 0); + } + params.arguments = settingsDir2Args; + params.arguments << "--list"; + QCOMPARE(runQbs(params), 0); + const QByteArray output2 = m_qbsStdout; + + // Step3: Compare results. + QCOMPARE(output1, output2); +} + +void TestBlackbox::qbsConfigAddProfile_data() +{ + QTest::addColumn<QStringList>("args"); + QTest::addColumn<QString>("errorMsg"); + QTest::newRow("no arguments") << QStringList() << QString("Profile name missing"); + QTest::newRow("empty name") << QStringList{"", "p", "v"} + << QString("Profile name must not be empty"); + QTest::newRow("no properties") << QStringList("p") + << QString("Profile properties must be provided"); + QTest::newRow("one property") << QStringList{"p", "p", "v"} << QString(); + QTest::newRow("two properties") << QStringList{"p", "p1", "v1", "p2", "v2"} << QString(); + QTest::newRow("missing value") << QStringList{"p", "p"} + << QString("Profile properties must be key/value pairs"); + QTest::newRow("missing values") << QStringList{"p", "p1", "v1", "p2"} + << QString("Profile properties must be key/value pairs"); +} + static QJsonObject getNextSessionPacket(QProcess &session, QByteArray &data) { int totalSize = -1; diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 8cc21378a..942cb6b47 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -258,6 +258,8 @@ private slots: void protobufLibraryInstall(); void pseudoMultiplexing(); void qbsConfig(); + void qbsConfigAddProfile(); + void qbsConfigAddProfile_data(); void qbsSession(); void qbsVersion(); void qtBug51237(); diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp index f8ed8a0b9..df48c35e9 100644 --- a/tests/auto/blackbox/tst_blackboxandroid.cpp +++ b/tests/auto/blackbox/tst_blackboxandroid.cpp @@ -619,6 +619,8 @@ void TestBlackboxAndroid::android_data() "lib/${ARCH}/libqml_QtQml_Models_modelsplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQml_WorkerScript_workerscriptplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so", + "lib/${ARCH}/libqml_QtQuick_Window_quickwindow_${ARCH}.so", + "lib/${ARCH}/libqml_QtQuick_tooling_quicktooling_${ARCH}.so", "lib/${ARCH}/libqml_QtQuick_Controls_Basic_impl_qtquickcontrols2basicstyleimplplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQuick_Controls_Basic_qtquickcontrols2basicstyleplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQuick_Controls_Fusion_impl_qtquickcontrols2fusionstyleimplplugin_${ARCH}.so", @@ -774,6 +776,8 @@ void TestBlackboxAndroid::android_data() "lib/${ARCH}/libqml_QtQml_Models_modelsplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQml_WorkerScript_workerscriptplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQml_qmlplugin_${ARCH}.so", + "lib/${ARCH}/libqml_QtQuick_Window_quickwindow_${ARCH}.so", + "lib/${ARCH}/libqml_QtQuick_tooling_quicktooling_${ARCH}.so", "lib/${ARCH}/libqml_QtQuick_Controls_Basic_impl_qtquickcontrols2basicstyleimplplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQuick_Controls_Basic_qtquickcontrols2basicstyleplugin_${ARCH}.so", "lib/${ARCH}/libqml_QtQuick_Controls_Fusion_impl_qtquickcontrols2fusionstyleimplplugin_${ARCH}.so", |