Android:CMake: Add QT_ANDROID_PACKAGE_NAME property
Allow setting the package name directly from CMake properties. If the package name is not set manually under AndroidManifest.xml nor build.gradle, then the value set by this property is used. The value is passed to build.gradle as "namespace" which is the way to set the package name after AGP 7.4 instead of AndroidManifest.xml "package" attribute. Task-number: QTBUG-106907 Change-Id: I94bd73c294d751eabfd96c0a10a6b3ff270d8137 Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
parent
c9ddc4b8e1
commit
fbb35cdb0b
@ -32,6 +32,10 @@
|
||||
\externalpage https://source.android.com/devices/tech/debug/tagged-pointers
|
||||
\title Android: Tagged Pointers
|
||||
*/
|
||||
/*!
|
||||
\externalpage https://developer.android.com/build/configure-app-module
|
||||
\title Android: Configure the app module
|
||||
*/
|
||||
/*!
|
||||
\externalpage https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl
|
||||
\title iOS: canOpenURL:
|
||||
|
@ -216,6 +216,10 @@ function(qt6_android_generate_deployment_settings target)
|
||||
_qt_internal_add_android_deployment_property(file_contents "android-package-source-directory"
|
||||
${target} "_qt_android_native_package_source_dir")
|
||||
|
||||
# version code
|
||||
_qt_internal_add_android_deployment_property(file_contents "android-package-name"
|
||||
${target} "QT_ANDROID_PACKAGE_NAME")
|
||||
|
||||
# version code
|
||||
_qt_internal_add_android_deployment_property(file_contents "android-version-code"
|
||||
${target} "QT_ANDROID_VERSION_CODE")
|
||||
|
@ -244,6 +244,55 @@ CMake will attempt to use the latest installed version.
|
||||
\sa{qt6_android_generate_deployment_settings}{qt_android_generate_deployment_settings()}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\page cmake-target-property-qt-android-package-name.html
|
||||
\ingroup cmake-properties-qtcore
|
||||
\ingroup cmake-target-properties-qtcore
|
||||
|
||||
\title QT_ANDROID_PACKAGE_NAME
|
||||
\target cmake-target-property-QT_ANDROID_PACKAGE_NAME
|
||||
|
||||
\summary {The app's package name.}
|
||||
|
||||
\cmakepropertysince 6.8
|
||||
\preliminarycmakeproperty
|
||||
\cmakepropertyandroidonly
|
||||
|
||||
Specifies the app's package name. This is usually a unique dot separated
|
||||
name for the app, that will be used to identify the app on devices or in
|
||||
the Play Store. For example, "org.qtproject.example.gallery".
|
||||
|
||||
The package name set by this property is passed to the \c build.gradle file
|
||||
as a \c namespace property, instead of \c AndroidManifest.xml, since the
|
||||
latter is deprecated since Android Gradle Plugin 7.4.
|
||||
|
||||
The package name considers some words or characters as illegal and the build
|
||||
will clean such names if any is encountered. An underscore (\c _) either replaces
|
||||
illegal characters or is appended to illegal words.
|
||||
|
||||
\list
|
||||
\li Allowed characters: alphanumeric, an underscore or a dot [a-zA-Z0-9_.].
|
||||
\li Illegal words: abstract, continue, for, new, switch, assert, default,
|
||||
if, package, synchronized, boolean, do, goto, private, this, break,
|
||||
double, implements, protected, throw, byte, else, import, public,
|
||||
throws, case, enum, instanceof, return, transient, catch, extends,
|
||||
int, short, try, char, final, interface, static, void, class, finally,
|
||||
long, strictfp, volatile, const, float, native, super, while.
|
||||
\endlist
|
||||
|
||||
The default package name for Qt for Android apps is \c org.qtproject.example.<target_name>.
|
||||
|
||||
\note Setting the package name manually in \c build.gradle (via
|
||||
\c namespace property) takes precedence over \c AndroidManifest.xml
|
||||
(via \c package attribute), and the latter also takes precedence over
|
||||
this property.
|
||||
|
||||
For more information, see Android's
|
||||
\l{Android: Configure the app module}{configure the app module}.
|
||||
|
||||
\sa{qt6_android_generate_deployment_settings}{qt_android_generate_deployment_settings()}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\page cmake-target-property-qt-android-version-code.html
|
||||
\ingroup cmake-properties-qtcore
|
||||
|
@ -63,6 +63,7 @@ how to accomplish this.
|
||||
\li \l{cmake-target-property-QT_ANDROID_MIN_SDK_VERSION}{QT_ANDROID_MIN_SDK_VERSION}
|
||||
\li \l{cmake-target-property-QT_ANDROID_PACKAGE_SOURCE_DIR}{QT_ANDROID_PACKAGE_SOURCE_DIR}
|
||||
\li \l{cmake-target-property-QT_ANDROID_TARGET_SDK_VERSION}{QT_ANDROID_TARGET_SDK_VERSION}
|
||||
\li \l{cmake-target-property-QT_ANDROID_PACKAGE_NAME}{QT_ANDROID_PACKAGE_NAME}
|
||||
\li \l{cmake-target-property-QT_ANDROID_VERSION_NAME}{QT_ANDROID_VERSION_NAME}
|
||||
\li \l{cmake-target-property-QT_ANDROID_VERSION_CODE}{QT_ANDROID_VERSION_CODE}
|
||||
\li \l{cmake-target-property-QT_QML_IMPORT_PATH}{QT_QML_IMPORT_PATH}
|
||||
|
@ -802,18 +802,25 @@ GradleBuildConfigs gradleBuildConfigs(const QString &path)
|
||||
return configs;
|
||||
}
|
||||
|
||||
QString cleanPackageName(QString packageName)
|
||||
QString cleanPackageName(QString packageName, bool *cleaned = nullptr)
|
||||
{
|
||||
auto isLegalChar = [] (QChar c) -> bool {
|
||||
ushort ch = c.unicode();
|
||||
return (ch >= '0' && ch <= '9') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= 'a' && ch <= 'z') ||
|
||||
ch == '.';
|
||||
ch == '.' || ch == '_';
|
||||
};
|
||||
|
||||
if (cleaned)
|
||||
*cleaned = false;
|
||||
|
||||
for (QChar &c : packageName) {
|
||||
if (!isLegalChar(c))
|
||||
if (!isLegalChar(c)) {
|
||||
c = u'_';
|
||||
if (cleaned)
|
||||
*cleaned = true;
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList keywords;
|
||||
@ -848,12 +855,16 @@ QString cleanPackageName(QString packageName)
|
||||
QChar c = word[0];
|
||||
if ((c >= u'0' && c <= u'9') || c == u'_') {
|
||||
packageName.insert(index + 1, u'a');
|
||||
if (cleaned)
|
||||
*cleaned = true;
|
||||
index = next + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (keywords.contains(word)) {
|
||||
packageName.insert(next, "_"_L1);
|
||||
if (cleaned)
|
||||
*cleaned = true;
|
||||
index = next + 1;
|
||||
} else {
|
||||
index = next;
|
||||
@ -885,26 +896,29 @@ QString detectLatestAndroidPlatform(const QString &sdkPath)
|
||||
|
||||
QString extractPackageName(Options *options)
|
||||
{
|
||||
QString packageName;
|
||||
{
|
||||
const QString gradleBuildFile = options->androidSourceDirectory + "/build.gradle"_L1;
|
||||
QString packageName = gradleBuildConfigs(gradleBuildFile).appNamespace;
|
||||
|
||||
if (!packageName.isEmpty() && packageName != "androidPackageName"_L1)
|
||||
return packageName;
|
||||
}
|
||||
|
||||
QFile androidManifestXml(options->androidSourceDirectory + "/AndroidManifest.xml"_L1);
|
||||
if (androidManifestXml.open(QIODevice::ReadOnly)) {
|
||||
QXmlStreamReader reader(&androidManifestXml);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.isStartElement() && reader.name() == "manifest"_L1)
|
||||
packageName = reader.attributes().value("package"_L1).toString();
|
||||
if (reader.isStartElement() && reader.name() == "manifest"_L1) {
|
||||
QString packageName = reader.attributes().value("package"_L1).toString();
|
||||
if (!packageName.isEmpty() && packageName != "org.qtproject.example"_L1)
|
||||
return packageName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (packageName.isEmpty()) {
|
||||
const QString gradleBuildFile = options->androidSourceDirectory + "/build.gradle"_L1;
|
||||
packageName = gradleBuildConfigs(gradleBuildFile).appNamespace;
|
||||
}
|
||||
|
||||
if (packageName.isEmpty() || packageName == "androidPackageName"_L1)
|
||||
packageName = "org.qtproject.example.%1"_L1.arg(options->applicationBinary);
|
||||
|
||||
return cleanPackageName(packageName);
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool parseCmakeBoolean(const QJsonValue &value)
|
||||
@ -1301,6 +1315,24 @@ bool readInputFile(Options *options)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const QJsonValue androidPackageName = jsonObject.value("android-package-name"_L1);
|
||||
const QString extractedPackageName = extractPackageName(options);
|
||||
if (!extractedPackageName.isEmpty())
|
||||
options->packageName = extractedPackageName;
|
||||
else if (!androidPackageName.isUndefined())
|
||||
options->packageName = androidPackageName.toString();
|
||||
else
|
||||
options->packageName = "org.qtproject.example.%1"_L1.arg(options->applicationBinary);
|
||||
|
||||
bool cleaned;
|
||||
options->packageName = cleanPackageName(options->packageName, &cleaned);
|
||||
if (cleaned) {
|
||||
fprintf(stderr, "Warning: Package name contained illegal characters and was cleaned "
|
||||
"to \"%s\"\n", qPrintable(options->packageName));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
using ItFlag = QDirListing::IteratorFlag;
|
||||
const QJsonValue deploymentDependencies = jsonObject.value("deployment-dependencies"_L1);
|
||||
@ -1358,7 +1390,6 @@ bool readInputFile(Options *options)
|
||||
options->isZstdCompressionEnabled = zstdCompressionFlag.toBool();
|
||||
}
|
||||
}
|
||||
options->packageName = extractPackageName(options);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ set_target_properties(${target} PROPERTIES
|
||||
QT_ANDROID_SDK_BUILD_TOOLS_REVISION "23.0.2"
|
||||
QT_ANDROID_MIN_SDK_VERSION "1"
|
||||
QT_ANDROID_TARGET_SDK_VERSION "2"
|
||||
QT_ANDROID_PACKAGE_NAME "org.qtproject.android_deployment_settings_test"
|
||||
QT_ANDROID_DEPLOYMENT_DEPENDENCIES "dep1.so;dep2.so;dep3.so"
|
||||
QT_ANDROID_DEPLOYMENT_SETTINGS_FILE "attempt_to_rewrite.json"
|
||||
QT_ANDROID_EXTRA_LIBS
|
||||
@ -53,6 +54,7 @@ set_target_properties(${target} PROPERTIES
|
||||
QT_ANDROID_SDK_BUILD_TOOLS_REVISION "23.0.2"
|
||||
QT_ANDROID_MIN_SDK_VERSION "1"
|
||||
QT_ANDROID_TARGET_SDK_VERSION "2"
|
||||
QT_ANDROID_PACKAGE_NAME "org.qtproject.android_deployment_settings_test"
|
||||
QT_ANDROID_DEPLOYMENT_DEPENDENCIES "dep1.so;dep2.so;dep3.so"
|
||||
QT_ANDROID_EXTRA_LIBS
|
||||
"some/path/to/lib1.so;some/path\\to/lib2.so;some\\path\\to\\lib3.so;some/path/to/lib4.so"
|
||||
|
@ -76,6 +76,8 @@ void tst_android_deployment_settings::DeploymentSettings_data()
|
||||
<< "1";
|
||||
QTest::newRow("android-target-sdk-version") << "android-target-sdk-version"
|
||||
<< "2";
|
||||
QTest::newRow("android-package-name") << "android-package-name"
|
||||
<< "org.qtproject.android_deployment_settings_test";
|
||||
}
|
||||
|
||||
void tst_android_deployment_settings::DeploymentSettings()
|
||||
|
Loading…
x
Reference in New Issue
Block a user