From 2577ce8ba1a69ad716c2fc2a5d0d5cc742c3c4cf Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 18 May 2022 10:40:31 +0200 Subject: [PATCH] CMake: Add 'Profile' configuration Get rid of the hardcoded QML Debugging for Debug & RelWithDebInfo from the project template, because RelWithDebInfo is actually a good configuration for doing releases (we use it for Qt Creator), and enabling QML debugging for releases is a bad idea. Instead enable QML Debugging in Qt Creator for the Debug configuration, and add a 'Profile' configuration that is 'RelWithDebInfo + QML Debugging'. When importing a build, we only set the "QML debugging" option of the build configuration, if it is enabled in the imported build, even if it uses CMAKE_BUILD_TYPE=Debug . One drawback: When not importing a build, but just setting the build directory of a "Profile" or "Debug" configuration to an existing build, Qt Creator asks if it should apply "-DCMAKE_CXX_FLAGS=-DQT_QML_DEBUG". The user can choose not to, but then is asked the next time again, and it is not obvious that the "QML debugging" option is responsible for this. That is somewhat orthogonal to this change though: Even without this change, if the user changes the QML debugging option from "Leave at Default" to "Enable", the same happens, and it is also not clear to the user how to get rid of it. The user might not even have realized that they changed the option (e.g. on platforms where the mouse wheel cycles combo box values). I think the correct solution is to 1. make clearer where the CMake flags came from in that dialog, 2. allow the user to cancel a build from that dialog, 3. allow the user to discard these changes (by changing the setting) from that dialog. But that is for another patch. Amends 3300182d405bffe062a0f2be900f35822a9e20b0 Amends 77fed0b0fdce2a93f465c20cd87c41900117dcda Change-Id: I95de59473b67c5afd6a53ea7f49838dbaef770d4 Reviewed-by: Artem Sokolovskii Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Cristian Adam --- .../qtquickapplication/CMakeLists.6.x.txt | 2 - .../qtquickapplication/CMakeLists.txt | 2 - .../cmakebuildconfiguration.cpp | 52 +++++++++++++------ .../cmakebuildconfiguration.h | 15 +++--- .../cmakeprojectconstants.h | 1 + .../cmakeprojectimporter.cpp | 26 ++++++++-- 6 files changed, 67 insertions(+), 31 deletions(-) diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt index bfe160ea937..d47f49ab3bd 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.6.x.txt @@ -25,7 +25,5 @@ set_target_properties(%{TargetName} PROPERTIES WIN32_EXECUTABLE TRUE ) -target_compile_definitions(%{TargetName} - PRIVATE $<$,$>:QT_QML_DEBUG>) target_link_libraries(%{TargetName} PRIVATE Qt6::Quick) diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt index f814cbcd978..cac41d7c1e7 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt @@ -60,8 +60,6 @@ else() @endif endif() -target_compile_definitions(%{ProjectName} - PRIVATE $<$,$>:QT_QML_DEBUG>) target_link_libraries(%{ProjectName} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 9a364528112..96fc649e28c 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -106,6 +106,7 @@ const char CMAKE_OSX_ARCHITECTURES_FLAG[] = "CMAKE_OSX_ARCHITECTURES:DefaultFlag const char QT_QML_DEBUG_FLAG[] = "Qt:QML_DEBUG_FLAG"; const char CMAKE_QT6_TOOLCHAIN_FILE_ARG[] = "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=%{Qt:QT_INSTALL_PREFIX}/lib/cmake/Qt6/qt.toolchain.cmake"; +const char CMAKE_BUILD_TYPE[] = "CMake.Build.Type"; namespace Internal { @@ -1211,8 +1212,16 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) setInitializer([this, target](const BuildInfo &info) { const Kit *k = target->kit(); const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k); + const QVariantMap extraInfoMap = info.extraInfo.value(); + const QString buildType = extraInfoMap.contains(CMAKE_BUILD_TYPE) + ? extraInfoMap.value(CMAKE_BUILD_TYPE).toString() + : info.typeName; + const TriState qmlDebugging = extraInfoMap.contains(Constants::QML_DEBUG_SETTING) + ? TriState::fromVariant( + extraInfoMap.value(Constants::QML_DEBUG_SETTING)) + : TriState::Default; - CommandLine cmd = defaultInitialCMakeCommand(k, info.typeName); + CommandLine cmd = defaultInitialCMakeCommand(k, buildType); m_buildSystem->setIsMultiConfig(CMakeGeneratorKitAspect::isMultiConfigGenerator(k)); // Android magic: @@ -1292,16 +1301,16 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) info.buildType)); } - if (info.extraInfo.isValid()) { - setSourceDirectory(FilePath::fromVariant( - info.extraInfo.value().value(Constants::CMAKE_HOME_DIR))); - } + if (extraInfoMap.contains(Constants::CMAKE_HOME_DIR)) + setSourceDirectory(FilePath::fromVariant(extraInfoMap.value(Constants::CMAKE_HOME_DIR))); + + aspect()->setValue(qmlDebugging); if (qt && qt->isQmlDebuggingSupported()) cmd.addArg("-DCMAKE_CXX_FLAGS_INIT:STRING=%{" + QLatin1String(QT_QML_DEBUG_FLAG) + "}"); m_buildSystem->setInitialCMakeArguments(cmd.splitArguments()); - m_buildSystem->setCMakeBuildType(info.typeName); + m_buildSystem->setCMakeBuildType(buildType); }); } @@ -1593,15 +1602,7 @@ CMakeBuildConfigurationFactory::BuildType CMakeBuildConfigurationFactory::buildT BuildConfiguration::BuildType CMakeBuildConfigurationFactory::cmakeBuildTypeToBuildType( const CMakeBuildConfigurationFactory::BuildType &in) { - // Cover all common CMake build types - if (in == BuildTypeRelease || in == BuildTypeMinSizeRel) - return BuildConfiguration::Release; - else if (in == BuildTypeDebug) - return BuildConfiguration::Debug; - else if (in == BuildTypeRelWithDebInfo) - return BuildConfiguration::Profile; - else - return BuildConfiguration::Unknown; + return createBuildInfo(in).buildType; } BuildInfo CMakeBuildConfigurationFactory::createBuildInfo(BuildType buildType) @@ -1614,11 +1615,16 @@ BuildInfo CMakeBuildConfigurationFactory::createBuildInfo(BuildType buildType) info.displayName = BuildConfiguration::tr("Build"); info.buildType = BuildConfiguration::Unknown; break; - case BuildTypeDebug: + case BuildTypeDebug: { info.typeName = "Debug"; info.displayName = BuildConfiguration::tr("Debug"); info.buildType = BuildConfiguration::Debug; + QVariantMap extraInfo; + // enable QML debugging by default + extraInfo.insert(Constants::QML_DEBUG_SETTING, TriState::Enabled.toVariant()); + info.extraInfo = extraInfo; break; + } case BuildTypeRelease: info.typeName = "Release"; info.displayName = BuildConfiguration::tr("Release"); @@ -1634,6 +1640,18 @@ BuildInfo CMakeBuildConfigurationFactory::createBuildInfo(BuildType buildType) info.displayName = CMakeBuildConfiguration::tr("Release with Debug Information"); info.buildType = BuildConfiguration::Profile; break; + case BuildTypeProfile: { + info.typeName = "Profile"; + info.displayName = CMakeBuildConfiguration::tr("Profile"); + info.buildType = BuildConfiguration::Profile; + QVariantMap extraInfo; + // override CMake build type, which defaults to info.typeName + extraInfo.insert(CMAKE_BUILD_TYPE, "RelWithDebInfo"); + // enable QML debugging by default + extraInfo.insert(Constants::QML_DEBUG_SETTING, TriState::Enabled.toVariant()); + info.extraInfo = extraInfo; + break; + } default: QTC_CHECK(false); break; @@ -1837,7 +1855,7 @@ SourceDirectoryAspect::SourceDirectoryAspect() // ----------------------------------------------------------------------------- BuildTypeAspect::BuildTypeAspect() { - setSettingsKey("CMake.Build.Type"); + setSettingsKey(CMAKE_BUILD_TYPE); setLabelText(tr("Build type:")); setDisplayStyle(LineEditDisplay); setDefaultValue("Unknown"); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index d23cf0054c4..3121cbcc6fe 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -89,12 +89,15 @@ class CMAKE_EXPORT CMakeBuildConfigurationFactory public: CMakeBuildConfigurationFactory(); - enum BuildType { BuildTypeNone = 0, - BuildTypeDebug = 1, - BuildTypeRelease = 2, - BuildTypeRelWithDebInfo = 3, - BuildTypeMinSizeRel = 4, - BuildTypeLast = 5 }; + enum BuildType { + BuildTypeNone = 0, + BuildTypeDebug = 1, + BuildTypeRelease = 2, + BuildTypeRelWithDebInfo = 3, + BuildTypeProfile = 4, + BuildTypeMinSizeRel = 5, + BuildTypeLast = 6 + }; static BuildType buildTypeFromByteArray(const QByteArray &in); static ProjectExplorer::BuildConfiguration::BuildType cmakeBuildTypeToBuildType(const BuildType &in); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h index 6e1b85d834a..d354076e6d4 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h @@ -38,6 +38,7 @@ const char RUN_CMAKE_CONTEXT_MENU[] = "CMakeProject.RunCMakeContextMenu"; const char BUILD_FILE_CONTEXT_MENU[] = "CMakeProject.BuildFileContextMenu"; const char BUILD_FILE[] = "CMakeProject.BuildFile"; const char CMAKE_HOME_DIR[] = "CMakeProject.HomeDirectory"; +const char QML_DEBUG_SETTING[] = "CMakeProject.EnableQmlDebugging"; // Project const char CMAKE_PROJECT_ID[] = "CMakeProjectManager.CMakeProject"; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index cdc9423d7f9..59f1d3796b0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -63,6 +63,7 @@ struct DirectoryData QByteArray cmakeBuildType; FilePath buildDirectory; FilePath cmakeHomeDirectory; + bool hasQmlDebugging = false; // Kit Stuff FilePath cmakeBinary; @@ -336,6 +337,14 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, canonicalProjectDirectory.toUserOutput()); } + // Determine QML debugging flags. This must match what we do in + // CMakeBuildSettingsWidget::getQmlDebugCxxFlags() + // such that in doubt we leave the QML Debugging setting at "Leave at default" + const QString cxxFlagsInit = config.stringValueOf("CMAKE_CXX_FLAGS_INIT"); + const QString cxxFlags = config.stringValueOf("CMAKE_CXX_FLAGS"); + data->hasQmlDebugging = cxxFlagsInit.contains("-DQT_QML_DEBUG") + && cxxFlags.contains("-DQT_QML_DEBUG"); + data->buildDirectory = importPath; data->cmakeBuildType = buildType; @@ -437,13 +446,22 @@ const QList CMakeProjectImporter::buildInfoList(void *directoryData) auto data = static_cast(directoryData); // create info: - BuildInfo info = CMakeBuildConfigurationFactory::createBuildInfo( - CMakeBuildConfigurationFactory::buildTypeFromByteArray(data->cmakeBuildType)); + CMakeBuildConfigurationFactory::BuildType buildType + = CMakeBuildConfigurationFactory::buildTypeFromByteArray(data->cmakeBuildType); + // RelWithDebInfo + QML Debugging = Profile + if (buildType == CMakeBuildConfigurationFactory::BuildTypeRelWithDebInfo + && data->hasQmlDebugging) + buildType = CMakeBuildConfigurationFactory::BuildTypeProfile; + BuildInfo info = CMakeBuildConfigurationFactory::createBuildInfo(buildType); info.buildDirectory = data->buildDirectory; - info.displayName = info.typeName; - QVariantMap config; + QVariantMap config = info.extraInfo.toMap(); // new empty, or existing one from createBuildInfo config.insert(Constants::CMAKE_HOME_DIR, data->cmakeHomeDirectory.toString()); + // Potentially overwrite the default QML Debugging settings for the build type as set by + // createBuildInfo, in case we are importing a "Debug" CMake configuration without QML Debugging + config.insert(Constants::QML_DEBUG_SETTING, + data->hasQmlDebugging ? TriState::Enabled.toVariant() + : TriState::Default.toVariant()); info.extraInfo = config; qCDebug(cmInputLog) << "BuildInfo configured.";