aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSheree Morphett <[email protected]>2025-07-08 09:14:02 +0300
committerSheree Morphett <[email protected]>2025-10-13 11:29:58 +0000
commit039c794cc2a4b4a49a04ba3ff2b5959b896ca951 (patch)
tree1a5c32379f069681a47aaeb601880216457da1de
parenta284e2cd66e2d45364203a249bb3ec7a52f939b5 (diff)
Insert QT_ANDROID_SOURCE_PACKAGE_DIR on APK template creation
Inserts the QT_ANDROID_SOURCE_PACKAGE_DIR and chosen directory into the CMakeLists.txt for the project when using APK templates. Fixes: QTCREATORBUG-33360 Change-Id: If138a8bc9b296f1ccc2af76dadd77e7fcdfb3dca Reviewed-by: Ville Voutilainen <[email protected]>
-rw-r--r--src/plugins/android/androidconstants.h1
-rw-r--r--src/plugins/android/manifestwizard.cpp26
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp147
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.h15
-rw-r--r--src/plugins/projectexplorer/buildsystem.cpp10
-rw-r--r--src/plugins/projectexplorer/buildsystem.h3
6 files changed, 183 insertions, 19 deletions
diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h
index 7f787cd13cf..0ede9a08d4c 100644
--- a/src/plugins/android/androidconstants.h
+++ b/src/plugins/android/androidconstants.h
@@ -39,6 +39,7 @@ const char ANDROID_APPLICATION_ARGUMENTS[] = "ANDROID_APPLICATION_ARGUMENTS";
const char ANDROID_DEPLOYMENT_SETTINGS_FILE[] = "ANDROID_DEPLOYMENT_SETTINGS_FILE";
const char ANDROID_SO_LIBS_PATHS[] = "ANDROID_SO_LIBS_PATHS";
const char JAVA_HOME_ENV_VAR[] = "JAVA_HOME";
+const char QT_ANDROID_PACKAGE_SOURCE_DIR[] = "QT_ANDROID_PACKAGE_SOURCE_DIR";
const char ANDROID_RUNCONFIG_ID[] = "Qt4ProjectManager.AndroidRunConfiguration:";
const char ANDROID_PACKAGE_INSTALL_STEP_ID[] = "Qt4ProjectManager.AndroidPackageInstallationStep";
diff --git a/src/plugins/android/manifestwizard.cpp b/src/plugins/android/manifestwizard.cpp
index aec8d009c2c..982993f045c 100644
--- a/src/plugins/android/manifestwizard.cpp
+++ b/src/plugins/android/manifestwizard.cpp
@@ -274,8 +274,7 @@ void CreateAndroidManifestWizard::createAndroidTemplateFiles()
if (m_buildSystem->project()->type() != CMakeProjectManager::Constants::CMAKE_PROJECT_ID)
node->addFiles(copy.files());
- QString androidPackageDir;
- androidPackageDir = node->data(Android::Constants::AndroidPackageSourceDir).toString();
+ QString androidPackageDir = node->data(Android::Constants::AndroidPackageSourceDir).toString();
if (androidPackageDir.isEmpty()) {
const BuildTargetInfo bti = m_buildSystem->buildTarget(m_buildKey);
const FilePath projectDir = bti.projectFilePath.parentDir();
@@ -290,13 +289,22 @@ void CreateAndroidManifestWizard::createAndroidTemplateFiles()
? QString(QLatin1String("QT_")) + Android::Constants::ANDROID_PACKAGE_SOURCE_DIR
: QString(Android::Constants::ANDROID_PACKAGE_SOURCE_DIR);
- QMessageBox::warning(
- this,
- Tr::tr("Project File Update Failed"),
- Tr::tr(
- "Could not automatically update the project file for \"%1\".\n"
- "Set the %2 property manually.")
- .arg(bti.projectFilePath.toUserOutput(), androidPackageSrcDir));
+ const QString relativePath = m_directory
+ .relativePathFromDir(
+ m_buildSystem->buildTarget(m_buildKey).projectFilePath);
+ androidPackageDir = QString("${CMAKE_CURRENT_SOURCE_DIR}/%1").arg(relativePath);
+
+ bool result = m_buildSystem->setTargetProperty(node, androidPackageSrcDir, androidPackageDir,
+ "ANDROID");
+ if (!result) {
+ const BuildTargetInfo bti = m_buildSystem->buildTarget(m_buildKey);
+ QMessageBox::warning(
+ this,
+ Tr::tr("Project File not Updated"),
+ Tr::tr("Could not automatically update the build file for %1.\n"
+ "Please set %2 manually.")
+ .arg(bti.projectFilePath.toUserOutput(), Android::Constants::QT_ANDROID_PACKAGE_SOURCE_DIR));
+ }
}
}
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index a38f5017216..2ad31eb3bdc 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -351,14 +351,7 @@ static std::optional<cmListFileFunction> findFunction(
return std::make_optional(*function);
}
-struct SnippetAndLocation
-{
- QString snippet;
- long line = -1;
- long column = -1;
-};
-
-static SnippetAndLocation generateSnippetAndLocationForSources(
+static CMakeBuildSystem::SnippetAndLocation generateSnippetAndLocationForSources(
const QString &newSourceFiles,
const cmListFile &cmakeListFile,
const cmListFileFunction &function,
@@ -372,7 +365,7 @@ static SnippetAndLocation generateSnippetAndLocationForSources(
"qt6_add_library",
"qt_add_qml_module",
"qt6_add_qml_module"};
- SnippetAndLocation result;
+ CMakeBuildSystem::SnippetAndLocation result;
int extraChars = 0;
auto afterFunctionLastArgument =
[&result, &extraChars, newSourceFiles](const auto &f) {
@@ -408,8 +401,9 @@ static SnippetAndLocation generateSnippetAndLocationForSources(
result.line += extraChars;
return result;
}
+
static Result<bool> insertSnippetSilently(const FilePath &cmakeFile,
- const SnippetAndLocation &snippetLocation)
+ const CMakeBuildSystem::SnippetAndLocation &snippetLocation)
{
BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(Core::EditorManager::openEditorAt(
{cmakeFile, int(snippetLocation.line), int(snippetLocation.column)},
@@ -427,6 +421,139 @@ static Result<bool> insertSnippetSilently(const FilePath &cmakeFile,
return true;
}
+CMakeBuildSystem::SnippetAndLocation CMakeBuildSystem::generateSnippetWithTargetPropertyBlock(
+ const QString &projectName, const QString &snippet, const cmListFile &file)
+{
+ SnippetAndLocation result;
+
+ result.snippet = QString("\nset_target_properties(%1 PROPERTIES\n %2)\n").arg(projectName, snippet);
+
+ auto findAddExecutableFunction = [&file]() -> std::optional<cmListFileFunction> {
+ for (const auto &func : file.Functions) {
+ if (func.LowerCaseName() == "qt_add_executable" || func.LowerCaseName() == "add_executable") {
+ return func;
+ }
+ }
+ return std::nullopt;
+ };
+
+ std::optional<cmListFileFunction> projectFunction = findAddExecutableFunction();
+
+ if (projectFunction) {
+ result.line = projectFunction->LineEnd() + 1;
+ result.column = 0;
+ }
+ return result;
+}
+
+static std::vector<cmListFileFunction> findFunctions(
+ const cmListFile& file, const QString& functionName, const std::string condition)
+{
+ std::vector<cmListFileFunction> functions;
+ std::vector<std::string> conditionStack;
+
+ for (const auto& func : file.Functions) {
+
+ if (func.LowerCaseName() == "if") {
+ for (const auto& arg : func.Arguments()) {
+ conditionStack.push_back(arg.Value);
+ }
+ } else if (func.LowerCaseName() == "elseif") {
+ if (!conditionStack.empty())
+ conditionStack.pop_back();
+ for (const auto& arg : func.Arguments()) {
+ conditionStack.push_back(arg.Value);
+ }
+ } else if (func.LowerCaseName() == "else") {
+ if (!conditionStack.empty())
+ conditionStack.pop_back();
+ conditionStack.push_back("else");
+ } else if (func.LowerCaseName() == "endif") {
+ if (!conditionStack.empty())
+ conditionStack.pop_back();
+ }
+
+ if (func.LowerCaseName() == functionName.toLower()) {
+ bool shouldAdd = false;
+
+ if (conditionStack.empty()) {
+ shouldAdd = true;
+ } else {
+ for (const auto& cond : conditionStack) {
+ if (cond == "else" || cond.find(condition) != std::string::npos) {
+ shouldAdd = true;
+ break;
+ }
+ }
+ }
+
+ if (shouldAdd)
+ functions.push_back(func);
+ }
+ }
+
+ return functions;
+}
+
+static CMakeBuildSystem::SnippetAndLocation generateSnippetForExistingTargetPropertyBlock(
+ const QString &snippet, const cmListFileFunction &function)
+{
+ CMakeBuildSystem::SnippetAndLocation result;
+ int insertLine = function.Line();
+
+ if (!function.Arguments().empty()) {
+ const auto &lastArg = function.Arguments().back();
+ insertLine = lastArg.Line - 1;
+ result.column = lastArg.Column + lastArg.Value.length() + 1;
+ }
+
+ result.line = insertLine + 1;
+ result.snippet = "\n" + snippet;
+
+ return result;
+}
+
+bool CMakeBuildSystem::setTargetProperty(
+ ProjectExplorer::Node *context, const QString &property, const QString &value, std::string condition)
+{
+ if (!context)
+ return false;
+
+ auto node = dynamic_cast<CMakeTargetNode *>(context);
+ const QString targetName = node->buildKey();
+
+ const std::optional<Link> cmakeFile = cmakeFileForBuildKey(targetName, buildTargets());
+ if (!cmakeFile)
+ return false;
+
+ std::optional<cmListFile> cmakeListFile = getUncachedCMakeListFile(cmakeFile->targetFilePath);
+ if (!cmakeListFile)
+ return false;
+
+ std::vector<cmListFileFunction> functions = findFunctions(*cmakeListFile, "set_target_properties", condition);
+
+ for (const auto& func : functions) {
+ for (const auto& args : func.Arguments()) {
+ if (args.Value == property) {
+ return false;
+ }
+ }
+ }
+
+ QString snippet;
+ SnippetAndLocation insertLocation;
+
+ snippet = QString("%1 \"%2\"").arg(property, value);
+ if (functions.empty()) {
+ insertLocation = generateSnippetWithTargetPropertyBlock(targetName, snippet, *cmakeListFile);
+ } else {
+ insertLocation = generateSnippetForExistingTargetPropertyBlock(snippet, functions[0]);
+ }
+
+ Result<bool> inserted = insertSnippetSilently(cmakeFile->targetFilePath, insertLocation);
+ return inserted.value_or(false);
+}
+
static void findLastRelevantArgument(const cmListFileFunction &function,
int minimumArgPos,
const QSet<QString> &lowerCaseStopParams,
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
index 422964eaecd..67ca14803cb 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
@@ -55,6 +55,21 @@ public:
bool addFiles(ProjectExplorer::Node *context,
const Utils::FilePaths &filePaths, Utils::FilePaths *) final;
+ struct SnippetAndLocation
+ {
+ QString snippet;
+ long line = -1;
+ long column = -1;
+ };
+
+ SnippetAndLocation generateSnippetWithTargetPropertyBlock(const QString &projectName,
+ const QString &snippet,
+ const cmListFile &file);
+
+ bool setTargetProperty(ProjectExplorer::Node *context, const QString &property, const QString &value,
+ std::string condition = "") final;
+
+
ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *context,
const Utils::FilePaths &filePaths,
Utils::FilePaths *notRemoved
diff --git a/src/plugins/projectexplorer/buildsystem.cpp b/src/plugins/projectexplorer/buildsystem.cpp
index 1fb9048576a..288b0351362 100644
--- a/src/plugins/projectexplorer/buildsystem.cpp
+++ b/src/plugins/projectexplorer/buildsystem.cpp
@@ -188,6 +188,16 @@ bool BuildSystem::addFiles(Node *, const FilePaths &filePaths, FilePaths *notAdd
return false;
}
+bool BuildSystem::setTargetProperty(ProjectExplorer::Node *context, const QString &property,
+ const QString &value, std::string condition)
+{
+ Q_UNUSED(context);
+ Q_UNUSED(property);
+ Q_UNUSED(value);
+ Q_UNUSED(condition);
+ return false;
+}
+
RemovedFilesFromProject BuildSystem::removeFiles(Node *, const FilePaths &filePaths,
FilePaths *notRemoved)
{
diff --git a/src/plugins/projectexplorer/buildsystem.h b/src/plugins/projectexplorer/buildsystem.h
index 77fae0a3f16..c22d44412ca 100644
--- a/src/plugins/projectexplorer/buildsystem.h
+++ b/src/plugins/projectexplorer/buildsystem.h
@@ -178,6 +178,9 @@ public:
void updateQmlCodeModel();
virtual void updateQmlCodeModelInfo(QmlCodeModelInfo &projectInfo);
+ virtual bool setTargetProperty(Node *context, const QString &property, const QString &value,
+ std::string condition);
+
signals:
void parsingStarted();
void parsingFinished(bool success);