summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestGIT.cxx9
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx4
-rw-r--r--Source/cmCMakeLanguageCommand.cxx26
-rw-r--r--Source/cmComputeLinkInformation.cxx3
-rw-r--r--Source/cmConfigure.cmake.h.in7
-rw-r--r--Source/cmDebuggerExceptionManager.cxx2
-rw-r--r--Source/cmExecuteProcessCommand.cxx7
-rw-r--r--Source/cmExecutionStatus.h8
-rw-r--r--Source/cmExportBuildFileGenerator.cxx31
-rw-r--r--Source/cmExportBuildFileGenerator.h6
-rw-r--r--Source/cmExportFileGenerator.cxx9
-rw-r--r--Source/cmExportFileGenerator.h5
-rw-r--r--Source/cmExportInstallFileGenerator.cxx15
-rw-r--r--Source/cmExportInstallFileGenerator.h6
-rw-r--r--Source/cmExportTryCompileFileGenerator.h5
-rw-r--r--Source/cmGeneratorTarget.cxx8
-rw-r--r--Source/cmImportedCxxModuleInfo.cxx7
-rw-r--r--Source/cmInstallExportGenerator.cxx5
-rw-r--r--Source/cmMakefile.cxx15
-rw-r--r--Source/cmQtAutoGen.h17
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx91
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.h11
-rw-r--r--Source/cmQtAutoGenInitializer.cxx372
-rw-r--r--Source/cmQtAutoGenInitializer.h35
-rw-r--r--Source/cmQtAutoGenerator.cxx4
-rw-r--r--Source/cmQtAutoGenerator.h8
-rw-r--r--Source/cmQtAutoMocUic.cxx56
-rw-r--r--Source/cmQtAutoMocUic.h3
-rw-r--r--Source/cmQtAutoRcc.cxx58
-rw-r--r--Source/cmQtAutoRcc.h3
-rw-r--r--Source/cmRST.cxx5
-rw-r--r--Source/cmStringAlgorithms.h5
-rw-r--r--Source/cmStringCommand.cxx3
-rw-r--r--Source/cmSystemTools.cxx8
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmXMLParser.cxx6
-rw-r--r--Source/cmXMLParser.h4
-rw-r--r--Source/cmake.cxx2
-rw-r--r--Source/cmake.h6
-rw-r--r--Source/cmakemain.cxx11
-rw-r--r--Source/cmcmd.cxx8
42 files changed, 652 insertions, 245 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 9202d03..d77680c 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 28)
-set(CMake_VERSION_PATCH 20240116)
+set(CMake_VERSION_PATCH 20240124)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 984c837..99c5a2b 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestGIT.h"
-#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <ctime>
@@ -414,14 +413,14 @@ protected:
const char* ConsumeSpace(const char* c)
{
- while (*c && isspace(*c)) {
+ while (*c && cmIsSpace(*c)) {
++c;
}
return c;
}
const char* ConsumeField(const char* c)
{
- while (*c && !isspace(*c)) {
+ while (*c && !cmIsSpace(*c)) {
++c;
}
return c;
@@ -481,7 +480,7 @@ private:
{
// Person Name <person@domain.com> 1234567890 +0000
const char* c = str;
- while (*c && isspace(*c)) {
+ while (*c && cmIsSpace(*c)) {
++c;
}
@@ -490,7 +489,7 @@ private:
++c;
}
const char* name_last = c;
- while (name_last != name_first && isspace(*(name_last - 1))) {
+ while (name_last != name_first && cmIsSpace(*(name_last - 1))) {
--name_last;
}
person.Name.assign(name_first, name_last - name_first);
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 699e23b..e4160a1 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -178,7 +178,7 @@ cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine(
if (std::isalpha(ch) || ch == '_') {
key += ch;
state = PARSE_KEY;
- } else if (!std::isspace(ch)) {
+ } else if (!cmIsSpace(ch)) {
state = IGNORE_REST;
}
break;
@@ -238,7 +238,7 @@ cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine(
break;
case PARSE_VALUE:
- if (ch == '#' || std::isspace(ch)) {
+ if (ch == '#' || cmIsSpace(ch)) {
state = IGNORE_REST;
} else {
value += ch;
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index 329427c..9ffc363 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -398,6 +398,32 @@ bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
if (!moreArgs()) {
return FatalError(status, "called with incorrect number of arguments");
}
+ if (expArgs[expArg] == "EXIT"_s) {
+ ++expArg; // consume "EXIT".
+
+ if (!moreArgs()) {
+ return FatalError(status, "EXIT requires one argument");
+ }
+
+ auto workingMode =
+ status.GetMakefile().GetCMakeInstance()->GetWorkingMode();
+ if (workingMode != cmake::SCRIPT_MODE) {
+ return FatalError(status, "EXIT can be used only in SCRIPT mode");
+ }
+
+ long retCode = 0;
+
+ if (!cmStrToLong(expArgs[expArg], &retCode)) {
+ return FatalError(status,
+ cmStrCat("EXIT requires one integral argument, got \"",
+ expArgs[expArg], '\"'));
+ }
+
+ if (workingMode == cmake::SCRIPT_MODE) {
+ status.SetExitCode(static_cast<int>(retCode));
+ }
+ return true;
+ }
if (expArgs[expArg] == "SET_DEPENDENCY_PROVIDER"_s) {
finishArgs();
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 40eb902..c985767 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -553,7 +553,8 @@ bool cmComputeLinkInformation::Compute()
this->Target->GetType() == cmStateEnums::MODULE_LIBRARY ||
this->Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
(this->Target->CanCompileSources() &&
- (this->Target->HaveCxx20ModuleSources() ||
+ (this->Target->HaveCxxModuleSupport(this->Config) ==
+ cmGeneratorTarget::Cxx20SupportLevel::Supported ||
this->Target->HaveFortranSources())))) {
return false;
}
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index de74716..23e4846 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -14,8 +14,13 @@
#pragma warning(disable : 1572) /* floating-point equality test */
#endif
-#if defined(__LCC__) && defined(__EDG__) && (__LCC__ == 123)
+#if defined(__LCC__) && defined(__EDG__)
+#if __LCC__ == 123
#pragma diag_suppress 2910 /* excess -Wunused-function in 1.23.x */
+#elif __LCC__ == 121
+#pragma diag_suppress 2727 /* excess -Wunused-function in 1.21.x */
+#include <limits.h> /* ..._MIN, ..._MAX constants */
+#endif
#endif
#cmakedefine HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE
diff --git a/Source/cmDebuggerExceptionManager.cxx b/Source/cmDebuggerExceptionManager.cxx
index a27426c..470e44c 100644
--- a/Source/cmDebuggerExceptionManager.cxx
+++ b/Source/cmDebuggerExceptionManager.cxx
@@ -78,7 +78,7 @@ cmDebuggerExceptionManager::HandleExceptionInfoRequest()
response.exceptionId = TheException->Id;
response.breakMode = "always";
response.description = TheException->Description;
- TheException = {};
+ TheException = cm::nullopt;
}
return response;
}
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 483a601..da6def9 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExecuteProcessCommand.h"
-#include <cctype> /* isspace */
#include <cstdint>
#include <cstdio>
#include <iostream>
@@ -35,11 +34,7 @@
namespace {
bool cmExecuteProcessCommandIsWhitespace(char c)
{
- // isspace takes 'int' but documents that the value must be representable
- // by 'unsigned char', or EOF. Cast to 'unsigned char' to avoid sign
- // extension while casting to 'int'.
- return (isspace(static_cast<int>(static_cast<unsigned char>(c))) ||
- c == '\n' || c == '\r');
+ return (cmIsSpace(c) || c == '\n' || c == '\r');
}
void cmExecuteProcessCommandFixText(std::vector<char>& output,
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index ced3548..e023971 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -7,6 +7,8 @@
#include <string>
#include <vector>
+#include <cm/optional>
+
class cmMakefile;
/** \class cmExecutionStatus
@@ -53,6 +55,11 @@ public:
void SetNestedError() { this->NestedError = true; }
bool GetNestedError() const { return this->NestedError; }
+ void SetExitCode(int code) noexcept { this->ExitCode = code; }
+ bool HasExitCode() const noexcept { return this->ExitCode.has_value(); }
+ void CleanExitCode() noexcept { this->ExitCode.reset(); }
+ int GetExitCode() const noexcept { return this->ExitCode.value_or(-1); }
+
private:
cmMakefile& Makefile;
std::string Error;
@@ -60,5 +67,6 @@ private:
bool BreakInvoked = false;
bool ContinueInvoked = false;
bool NestedError = false;
+ cm::optional<int> ExitCode;
std::vector<std::string> Variables;
};
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 8ba8d97..81e3d54 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmExportBuildFileGenerator.h"
#include <algorithm>
+#include <cstddef>
#include <map>
#include <memory>
#include <set>
@@ -12,6 +13,7 @@
#include <cm/string_view>
#include <cmext/string_view>
+#include "cmCryptoHash.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
@@ -156,7 +158,19 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateTargetFileSets(gte, os);
}
- this->GenerateCxxModuleInformation(os);
+ std::string cxx_modules_name;
+ if (this->ExportSet) {
+ cxx_modules_name = this->ExportSet->GetName();
+ } else {
+ cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
+ constexpr std::size_t HASH_TRUNCATION = 12;
+ for (auto const& target : this->Targets) {
+ hasher.Append(target.Name);
+ }
+ cxx_modules_name = hasher.FinalizeHex().substr(0, HASH_TRUNCATION);
+ }
+
+ this->GenerateCxxModuleInformation(cxx_modules_name, os);
// Generate import file content for each configuration.
for (std::string const& c : this->Configurations) {
@@ -165,7 +179,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
// Generate import file content for each configuration.
for (std::string const& c : this->Configurations) {
- this->GenerateImportCxxModuleConfigTargetInclusion(c);
+ this->GenerateImportCxxModuleConfigTargetInclusion(cxx_modules_name, c);
}
this->GenerateMissingTargetsCheckCode(os);
@@ -526,7 +540,7 @@ std::string cmExportBuildFileGenerator::GetCxxModulesDirectory() const
}
void cmExportBuildFileGenerator::GenerateCxxModuleConfigInformation(
- std::ostream& os) const
+ std::string const& name, std::ostream& os) const
{
const char* opt = "";
if (this->Configurations.size() > 1) {
@@ -539,13 +553,13 @@ void cmExportBuildFileGenerator::GenerateCxxModuleConfigInformation(
if (c.empty()) {
c = "noconfig";
}
- os << "include(\"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << c << ".cmake\""
- << opt << ")\n";
+ os << "include(\"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << name << '-'
+ << c << ".cmake\"" << opt << ")\n";
}
}
bool cmExportBuildFileGenerator::GenerateImportCxxModuleConfigTargetInclusion(
- std::string config) const
+ std::string const& name, std::string config) const
{
auto cxx_modules_dirname = this->GetCxxModulesDirectory();
if (cxx_modules_dirname.empty()) {
@@ -556,8 +570,9 @@ bool cmExportBuildFileGenerator::GenerateImportCxxModuleConfigTargetInclusion(
config = "noconfig";
}
- std::string fileName = cmStrCat(this->FileDir, '/', cxx_modules_dirname,
- "/cxx-modules-", config, ".cmake");
+ std::string fileName =
+ cmStrCat(this->FileDir, '/', cxx_modules_dirname, "/cxx-modules-", name,
+ '-', config, ".cmake");
cmGeneratedFileStream os(fileName, true);
if (!os) {
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 9f11d13..ee4779f 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -105,8 +105,10 @@ protected:
cmExportSet* GetExportSet() const override { return this->ExportSet; }
std::string GetCxxModulesDirectory() const override;
- void GenerateCxxModuleConfigInformation(std::ostream&) const override;
- bool GenerateImportCxxModuleConfigTargetInclusion(std::string) const;
+ void GenerateCxxModuleConfigInformation(std::string const&,
+ std::ostream&) const override;
+ bool GenerateImportCxxModuleConfigTargetInclusion(std::string const&,
+ std::string) const;
std::pair<std::vector<std::string>, std::string> FindBuildExportInfo(
cmGlobalGenerator* gg, const std::string& name);
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index e2c3edd..f332007 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -1587,7 +1587,8 @@ void cmExportFileGenerator::GenerateTargetFileSets(cmGeneratorTarget* gte,
}
}
-void cmExportFileGenerator::GenerateCxxModuleInformation(std::ostream& os)
+void cmExportFileGenerator::GenerateCxxModuleInformation(
+ std::string const& name, std::ostream& os)
{
auto const cxx_module_dirname = this->GetCxxModulesDirectory();
if (cxx_module_dirname.empty()) {
@@ -1597,19 +1598,19 @@ void cmExportFileGenerator::GenerateCxxModuleInformation(std::ostream& os)
// Write the include.
os << "# Include C++ module properties\n"
<< "include(\"${CMAKE_CURRENT_LIST_DIR}/" << cxx_module_dirname
- << "/cxx-modules.cmake\")\n\n";
+ << "/cxx-modules-" << name << ".cmake\")\n\n";
// Get the path to the file we're going to write.
std::string path = this->MainImportFile;
path = cmSystemTools::GetFilenamePath(path);
auto trampoline_path =
- cmStrCat(path, '/', cxx_module_dirname, "/cxx-modules.cmake");
+ cmStrCat(path, '/', cxx_module_dirname, "/cxx-modules-", name, ".cmake");
// Include all configuration-specific include files.
cmGeneratedFileStream ap(trampoline_path, true);
ap.SetCopyIfDifferent(true);
- this->GenerateCxxModuleConfigInformation(ap);
+ this->GenerateCxxModuleConfigInformation(name, ap);
}
void cmExportFileGenerator::SetRequiredCMakeVersion(unsigned int major,
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 554dd4a..f619576 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -192,7 +192,7 @@ protected:
void GenerateTargetFileSets(cmGeneratorTarget* gte, std::ostream& os,
cmTargetExport* te = nullptr);
- void GenerateCxxModuleInformation(std::ostream& os);
+ void GenerateCxxModuleInformation(std::string const& name, std::ostream& os);
virtual std::string GetFileSetDirectories(cmGeneratorTarget* gte,
cmFileSet* fileSet,
@@ -253,5 +253,6 @@ private:
const std::string& config) = 0;
virtual std::string GetCxxModulesDirectory() const = 0;
- virtual void GenerateCxxModuleConfigInformation(std::ostream& os) const = 0;
+ virtual void GenerateCxxModuleConfigInformation(std::string const&,
+ std::ostream& os) const = 0;
};
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 64e694c..c5b9dc9 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -170,10 +170,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
bool result = true;
- this->GenerateCxxModuleInformation(os);
+ std::string cxx_modules_name = this->IEGen->GetExportSet()->GetName();
+ this->GenerateCxxModuleInformation(cxx_modules_name, os);
if (requiresConfigFiles) {
for (std::string const& c : this->Configurations) {
- if (!this->GenerateImportCxxModuleConfigTargetInclusion(c)) {
+ if (!this->GenerateImportCxxModuleConfigTargetInclusion(cxx_modules_name,
+ c)) {
result = false;
}
}
@@ -724,12 +726,12 @@ std::string cmExportInstallFileGenerator::GetCxxModulesDirectory() const
}
void cmExportInstallFileGenerator::GenerateCxxModuleConfigInformation(
- std::ostream& os) const
+ std::string const& name, std::ostream& os) const
{
// Now load per-configuration properties for them.
/* clang-format off */
os << "# Load information for each installed configuration.\n"
- "file(GLOB _cmake_cxx_module_includes \"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-*.cmake\")\n"
+ "file(GLOB _cmake_cxx_module_includes \"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << name << "-*.cmake\")\n"
"foreach(_cmake_cxx_module_include IN LISTS _cmake_cxx_module_includes)\n"
" include(\"${_cmake_cxx_module_include}\")\n"
"endforeach()\n"
@@ -739,7 +741,8 @@ void cmExportInstallFileGenerator::GenerateCxxModuleConfigInformation(
}
bool cmExportInstallFileGenerator::
- GenerateImportCxxModuleConfigTargetInclusion(std::string const& config)
+ GenerateImportCxxModuleConfigTargetInclusion(std::string const& name,
+ std::string const& config)
{
auto cxx_modules_dirname = this->GetCxxModulesDirectory();
if (cxx_modules_dirname.empty()) {
@@ -754,7 +757,7 @@ bool cmExportInstallFileGenerator::
std::string const dest =
cmStrCat(this->FileDir, '/', cxx_modules_dirname, '/');
std::string fileName =
- cmStrCat(dest, "cxx-modules-", filename_config, ".cmake");
+ cmStrCat(dest, "cxx-modules-", name, '-', filename_config, ".cmake");
cmGeneratedFileStream os(fileName, true);
if (!os) {
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 9de0c8e..7a72584 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -119,8 +119,10 @@ protected:
cmTargetExport* te) override;
std::string GetCxxModulesDirectory() const override;
- void GenerateCxxModuleConfigInformation(std::ostream&) const override;
- bool GenerateImportCxxModuleConfigTargetInclusion(std::string const&);
+ void GenerateCxxModuleConfigInformation(std::string const&,
+ std::ostream&) const override;
+ bool GenerateImportCxxModuleConfigTargetInclusion(std::string const&,
+ std::string const&);
cmExportSet* GetExportSet() const override
{
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 5c34fad..4c7d287 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -56,7 +56,10 @@ protected:
cmTargetExport* te) override;
std::string GetCxxModulesDirectory() const override { return {}; }
- void GenerateCxxModuleConfigInformation(std::ostream&) const override {}
+ void GenerateCxxModuleConfigInformation(std::string const&,
+ std::ostream&) const override
+ {
+ }
private:
std::string FindTargets(const std::string& prop,
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 11253db..ac8bc67 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -3578,7 +3578,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlagsImpl(cmBuildStep compileOrLink,
flags += "]\"";
}
- } else if (compiler == "Clang") {
+ } else if (compiler == "Clang" && compileOrLink == cmBuildStep::Compile) {
for (CudaArchitecture& architecture : architectures) {
flags += " --cuda-gpu-arch=sm_" + architecture.name;
@@ -8417,14 +8417,14 @@ bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
}
if (gt->HaveCxx20ModuleSources()) {
- auto hasher = cmCryptoHash::New("SHA3_512");
+ cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
constexpr size_t HASH_TRUNCATION = 12;
- auto dirhash = hasher->HashString(
+ auto dirhash = hasher.HashString(
gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
std::string safeName = gt->GetName();
cmSystemTools::ReplaceString(safeName, ":", "_");
auto targetIdent =
- hasher->HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
+ hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
std::string targetName =
cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION));
diff --git a/Source/cmImportedCxxModuleInfo.cxx b/Source/cmImportedCxxModuleInfo.cxx
index 9e3ac9a..c54b265 100644
--- a/Source/cmImportedCxxModuleInfo.cxx
+++ b/Source/cmImportedCxxModuleInfo.cxx
@@ -4,7 +4,6 @@
#include "cmImportedCxxModuleInfo.h"
#include <cstddef>
-#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -60,13 +59,13 @@ std::string ImportedCxxModuleLookup::BmiNameForSource(std::string const& path)
auto importit = this->ImportedInfo.find(path);
std::string bmiName;
- auto hasher = cmCryptoHash::New("SHA3_512");
+ cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
constexpr size_t HASH_TRUNCATION = 12;
if (importit != this->ImportedInfo.end()) {
- auto safename = hasher->HashString(importit->second.Name);
+ auto safename = hasher.HashString(importit->second.Name);
bmiName = cmStrCat(safename.substr(0, HASH_TRUNCATION), ".bmi");
} else {
- auto dirhash = hasher->HashString(path);
+ auto dirhash = hasher.HashString(path);
bmiName = cmStrCat(dirhash.substr(0, HASH_TRUNCATION), ".bmi");
}
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 72f0ac7..2f3da3e 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -160,10 +160,11 @@ void cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
// Remove old per-configuration export files if the main changes.
std::string installedDir = cmStrCat(
"$ENV{DESTDIR}", ConvertToAbsoluteDestination(cxx_module_dest), '/');
- std::string installedFile = cmStrCat(installedDir, "/cxx-modules.cmake");
+ std::string installedFile = cmStrCat(installedDir, "/cxx-modules-",
+ this->ExportSet->GetName(), ".cmake");
std::string toInstallFile =
cmStrCat(cmSystemTools::GetFilenamePath(config_file_example),
- "/cxx-modules.cmake");
+ "/cxx-modules-", this->ExportSet->GetName(), ".cmake");
os << indent << "if(EXISTS \"" << installedFile << "\")\n";
Indent indentN = indent.Next();
Indent indentNN = indentN.Next();
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 936b282..2687afa 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -529,6 +529,12 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
cmSystemTools::SetFatalErrorOccurred();
}
}
+ if (this->GetCMakeInstance()->HasScriptModeExitCode() &&
+ this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE) {
+ // pass-through the exit code from inner cmake_language(EXIT) ,
+ // possibly from include() or similar command...
+ status.SetExitCode(this->GetCMakeInstance()->GetScriptModeExitCode());
+ }
}
} else {
if (!cmSystemTools::GetFatalErrorOccurred()) {
@@ -898,6 +904,11 @@ void cmMakefile::RunListFile(cmListFile const& listFile,
if (cmSystemTools::GetFatalErrorOccurred()) {
break;
}
+ if (status.HasExitCode()) {
+ // cmake_language EXIT was requested, early break.
+ this->GetCMakeInstance()->SetScriptModeExitCode(status.GetExitCode());
+ break;
+ }
if (status.GetReturnInvoked()) {
this->RaiseScope(status.GetReturnVariables());
// Exit early due to return command.
@@ -1427,8 +1438,8 @@ static void s_RemoveDefineFlag(std::string const& flag, std::string& dflags)
for (std::string::size_type lpos = dflags.find(flag, 0);
lpos != std::string::npos; lpos = dflags.find(flag, lpos)) {
std::string::size_type rpos = lpos + len;
- if ((lpos <= 0 || isspace(dflags[lpos - 1])) &&
- (rpos >= dflags.size() || isspace(dflags[rpos]))) {
+ if ((lpos <= 0 || cmIsSpace(dflags[lpos - 1])) &&
+ (rpos >= dflags.size() || cmIsSpace(dflags[rpos]))) {
dflags.erase(lpos, len);
} else {
++lpos;
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index 5a23ae9..b302403 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -6,6 +6,7 @@
#include <memory>
#include <string>
+#include <unordered_map>
#include <vector>
#include <cm/string_view>
@@ -16,6 +17,22 @@
class cmQtAutoGen
{
public:
+ /** String value with per configuration variants. */
+ class ConfigString
+ {
+ public:
+ std::string Default;
+ std::unordered_map<std::string, std::string> Config;
+ };
+
+ /** String values with per configuration variants. */
+ template <typename C>
+ class ConfigStrings
+ {
+ public:
+ C Default;
+ std::unordered_map<std::string, C> Config;
+ };
/** Integer version. */
struct IntegerVersion
{
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 1da8847..5e2f99f 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -213,24 +213,81 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc(
}
}
-cmQtAutoGen::CompilerFeaturesHandle
+cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle>
cmQtAutoGenGlobalInitializer::GetCompilerFeatures(
- std::string const& generator, std::string const& executable,
- std::string& error)
+ std::string const& generator, cmQtAutoGen::ConfigString const& executable,
+ std::string& error, bool const isMultiConfig, bool UseBetterGraph)
{
+ cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle> res;
+ if (isMultiConfig && UseBetterGraph) {
+ for (auto const& config : executable.Config) {
+ auto const exe = config.second;
+ // Check if we have cached features
+ {
+ auto it = this->CompilerFeatures_.Config[config.first].find(exe);
+ if (it != this->CompilerFeatures_.Config[config.first].end()) {
+ res.Config[config.first] = it->second;
+ continue;
+ }
+ }
+
+ // Check if the executable exists
+ if (!cmSystemTools::FileExists(exe, true)) {
+ error = cmStrCat("The \"", generator, "\" executable ",
+ cmQtAutoGen::Quoted(exe), " does not exist.");
+ res.Config[config.first] = {};
+ continue;
+ }
+
+ // Test the executable
+ std::string stdOut;
+ {
+ std::string stdErr;
+ std::vector<std::string> command;
+ command.emplace_back(exe);
+ command.emplace_back("-h");
+ int retVal = 0;
+ const bool runResult = cmSystemTools::RunSingleCommand(
+ command, &stdOut, &stdErr, &retVal, nullptr,
+ cmSystemTools::OUTPUT_NONE, cmDuration::zero(),
+ cmProcessOutput::Auto);
+ if (!runResult) {
+ error = cmStrCat("Test run of \"", generator, "\" executable ",
+ cmQtAutoGen::Quoted(exe), " failed.\n",
+ cmQtAutoGen::QuotedCommand(command), '\n', stdOut,
+ '\n', stdErr);
+ res.Config[config.first] = {};
+ continue;
+ }
+ }
+
+ // Create valid handle
+ res.Config[config.first] =
+ std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ res.Config[config.first]->HelpOutput = std::move(stdOut);
+
+ // Register compiler features
+ this->CompilerFeatures_.Config[config.first].emplace(
+ exe, res.Config[config.first]);
+ }
+ return res;
+ }
+
// Check if we have cached features
{
- auto it = this->CompilerFeatures_.find(executable);
- if (it != this->CompilerFeatures_.end()) {
- return it->second;
+ auto it = this->CompilerFeatures_.Default.find(executable.Default);
+ if (it != this->CompilerFeatures_.Default.end()) {
+ res.Default = it->second;
+ return res;
}
}
// Check if the executable exists
- if (!cmSystemTools::FileExists(executable, true)) {
- error = cmStrCat("The \"", generator, "\" executable ",
- cmQtAutoGen::Quoted(executable), " does not exist.");
- return cmQtAutoGen::CompilerFeaturesHandle();
+ if (!cmSystemTools::FileExists(executable.Default, true)) {
+ error =
+ cmStrCat("The \"", generator, "\" executable ",
+ cmQtAutoGen::Quoted(executable.Default), " does not exist.");
+ return cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle>();
}
// Test the executable
@@ -238,7 +295,7 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures(
{
std::string stdErr;
std::vector<std::string> command;
- command.emplace_back(executable);
+ command.emplace_back(executable.Default);
command.emplace_back("-h");
int retVal = 0;
const bool runResult = cmSystemTools::RunSingleCommand(
@@ -246,20 +303,18 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures(
cmDuration::zero(), cmProcessOutput::Auto);
if (!runResult) {
error = cmStrCat("Test run of \"", generator, "\" executable ",
- cmQtAutoGen::Quoted(executable), " failed.\n",
+ cmQtAutoGen::Quoted(executable.Default), " failed.\n",
cmQtAutoGen::QuotedCommand(command), '\n', stdOut, '\n',
stdErr);
- return cmQtAutoGen::CompilerFeaturesHandle();
+ return cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle>();
}
}
- // Create valid handle
- cmQtAutoGen::CompilerFeaturesHandle res =
- std::make_shared<cmQtAutoGen::CompilerFeatures>();
- res->HelpOutput = std::move(stdOut);
+ res.Default = std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ res.Default->HelpOutput = std::move(stdOut);
// Register compiler features
- this->CompilerFeatures_.emplace(executable, res);
+ this->CompilerFeatures_.Default.emplace(executable.Default, res.Default);
return res;
}
diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h
index e8569a5..c1c4758 100644
--- a/Source/cmQtAutoGenGlobalInitializer.h
+++ b/Source/cmQtAutoGenGlobalInitializer.h
@@ -66,14 +66,17 @@ private:
void AddToGlobalAutoRcc(cmLocalGenerator* localGen,
std::string const& targetName);
- cmQtAutoGen::CompilerFeaturesHandle GetCompilerFeatures(
- std::string const& generator, std::string const& executable,
- std::string& error);
+ cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle>
+ GetCompilerFeatures(std::string const& generator,
+ cmQtAutoGen::ConfigString const& executable,
+ std::string& error, bool isMultiConfig,
+ bool UseBetterGraph);
std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_;
std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_;
std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_;
- std::unordered_map<std::string, cmQtAutoGen::CompilerFeaturesHandle>
+ cmQtAutoGen::ConfigStrings<
+ std::unordered_map<std::string, cmQtAutoGen::CompilerFeaturesHandle>>
CompilerFeatures_;
Keywords const Keywords_;
};
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 8213274..ff6be2a 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenInitializer.h"
+#include <array>
#include <cstddef>
#include <deque>
#include <initializer_list>
@@ -17,6 +18,7 @@
#include <cm/algorithm>
#include <cm/iterator>
#include <cm/memory>
+#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -301,15 +303,22 @@ bool InfoWriter::Save(std::string const& filename)
return fileStream.Close();
}
-void AddAutogenExecutableToDependencies(
- cmQtAutoGenInitializer::GenVarsT const& genVars,
- std::vector<std::string>& dependencies)
+cmQtAutoGen::ConfigStrings<std::vector<std::string>> generateListOptions(
+ cmQtAutoGen::ConfigStrings<cmQtAutoGen::CompilerFeaturesHandle> const&
+ executableFeatures,
+ bool IsMultiConfig)
{
- if (genVars.ExecutableTarget != nullptr) {
- dependencies.push_back(genVars.ExecutableTarget->Target->GetName());
- } else if (!genVars.Executable.empty()) {
- dependencies.push_back(genVars.Executable);
+ cmQtAutoGen::ConfigStrings<std::vector<std::string>> tempListOptions;
+ if (IsMultiConfig) {
+ for (auto const& executableFeature : executableFeatures.Config) {
+ tempListOptions.Config[executableFeature.first] =
+ executableFeature.second->ListOptions;
+ }
+ } else {
+ tempListOptions.Default = executableFeatures.Default->ListOptions;
}
+
+ return tempListOptions;
}
} // End of unnamed namespace
@@ -334,6 +343,42 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer(
this->Rcc.GlobalTarget = globalAutoRccTarget;
this->CrossConfig =
!this->Makefile->GetSafeDefinition("CMAKE_CROSS_CONFIGS").empty();
+ this->UseBetterGraph =
+ this->GenTarget->GetProperty("AUTOGEN_BETTER_GRAPH_MULTI_CONFIG").IsSet()
+ ? this->GenTarget->GetProperty("AUTOGEN_BETTER_GRAPH_MULTI_CONFIG").IsOn()
+ : (this->QtVersion >= IntegerVersion(6, 8));
+ // AUTOGEN_BETTER_GRAPH_MULTI_CONFIG is set explicitly because it is read by
+ // the qt library
+ this->GenTarget->Target->SetProperty("AUTOGEN_BETTER_GRAPH_MULTI_CONFIG",
+ this->UseBetterGraph ? "ON" : "OFF");
+}
+
+void cmQtAutoGenInitializer::AddAutogenExecutableToDependencies(
+ cmQtAutoGenInitializer::GenVarsT const& genVars,
+ std::vector<std::string>& dependencies) const
+{
+ if (genVars.ExecutableTarget != nullptr) {
+ dependencies.push_back(genVars.ExecutableTarget->Target->GetName());
+ } else if (this->MultiConfig && this->UseBetterGraph) {
+ cm::string_view const& configGenexWithCommandConfig =
+ "$<COMMAND_CONFIG:$<$<CONFIG:";
+ cm::string_view const& configGenex = "$<$<CONFIG:";
+ cm::string_view const& configGenexEnd = ">";
+ cm::string_view const& configGenexEndWithCommandConfig = ">>";
+ auto genexBegin =
+ this->CrossConfig ? configGenexWithCommandConfig : configGenex;
+ auto genexEnd =
+ this->CrossConfig ? configGenexEndWithCommandConfig : configGenexEnd;
+ for (auto const& config : genVars.Executable.Config) {
+ auto executableWithConfig =
+ cmStrCat(genexBegin, config.first, ">:", config.second, genexEnd);
+ dependencies.emplace_back(std::move(executableWithConfig));
+ }
+ } else {
+ if (!genVars.Executable.Default.empty()) {
+ dependencies.push_back(genVars.Executable.Default);
+ }
+ }
}
bool cmQtAutoGenInitializer::InitCustomTargets()
@@ -811,18 +856,30 @@ bool cmQtAutoGenInitializer::InitRcc()
return false;
}
// Evaluate test output on demand
- CompilerFeatures& features = *this->Rcc.ExecutableFeatures;
- if (!features.Evaluated) {
- // Look for list options
- if (this->QtVersion.Major == 5 || this->QtVersion.Major == 6) {
- if (features.HelpOutput.find("--list") != std::string::npos) {
- features.ListOptions.emplace_back("--list");
- } else if (features.HelpOutput.find("-list") != std::string::npos) {
- features.ListOptions.emplace_back("-list");
+ auto& features = this->Rcc.ExecutableFeatures;
+ auto checkAndAddOptions = [this](CompilerFeaturesHandle& feature) {
+ if (!feature->Evaluated) {
+ // Look for list options
+ if (this->QtVersion.Major == 5 || this->QtVersion.Major == 6) {
+ static std::array<std::string, 2> const listOptions{ { "--list",
+ "-list" } };
+ for (std::string const& opt : listOptions) {
+ if (feature->HelpOutput.find(opt) != std::string::npos) {
+ feature->ListOptions.emplace_back(opt);
+ break;
+ }
+ }
}
+ // Evaluation finished
+ feature->Evaluated = true;
}
- // Evaluation finished
- features.Evaluated = true;
+ };
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ checkAndAddOptions(features.Config[config]);
+ }
+ } else {
+ checkAndAddOptions(features.Default);
}
}
@@ -1158,8 +1215,14 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Path checksum
qrc.QrcPathChecksum = this->PathCheckSum.getPart(qrc.QrcFile);
// Output file name
- qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
- "/qrc_", qrc.QrcName, ".cpp");
+ if (this->MultiConfig && !this->GlobalGen->IsXcode() &&
+ this->UseBetterGraph) {
+ qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
+ "_$<CONFIG>", "/qrc_", qrc.QrcName, ".cpp");
+ } else {
+ qrc.OutputFile = cmStrCat(this->Dir.Build, '/', qrc.QrcPathChecksum,
+ "/qrc_", qrc.QrcName, ".cpp");
+ }
std::string const base = cmStrCat(this->Dir.Info, "/AutoRcc_",
qrc.QrcName, '_', qrc.QrcPathChecksum);
qrc.LockFile = cmStrCat(base, "_Lock.lock");
@@ -1191,11 +1254,25 @@ bool cmQtAutoGenInitializer::InitScanFiles()
for (Qrc& qrc : this->Rcc.Qrcs) {
if (!qrc.Generated) {
std::string error;
- RccLister const lister(this->Rcc.Executable,
- this->Rcc.ExecutableFeatures->ListOptions);
- if (!lister.list(qrc.QrcFile, qrc.Resources, error)) {
- cmSystemTools::Error(error);
- return false;
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ RccLister const lister(
+ this->Rcc.Executable.Config[config],
+ this->Rcc.ExecutableFeatures.Config[config]->ListOptions);
+ if (!lister.list(qrc.QrcFile, qrc.Resources.Config[config],
+ error)) {
+ cmSystemTools::Error(error);
+ return false;
+ }
+ }
+ } else {
+ RccLister const lister(
+ this->Rcc.Executable.Default,
+ this->Rcc.ExecutableFeatures.Default->ListOptions);
+ if (!lister.list(qrc.QrcFile, qrc.Resources.Default, error)) {
+ cmSystemTools::Error(error);
+ return false;
+ }
}
}
}
@@ -1223,8 +1300,9 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
if (this->Moc.Enabled) {
this->AddGeneratedSource(this->Moc.CompilationFile, this->Moc, true);
if (useDepfile) {
- if (this->MultiConfig && this->CrossConfig &&
- this->GlobalGen->GetName().find("Ninja") != std::string::npos) {
+ if (this->CrossConfig &&
+ this->GlobalGen->GetName().find("Ninja") != std::string::npos &&
+ !this->UseBetterGraph) {
// Make all mocs_compilation_<CONFIG>.cpp files byproducts of the
// ${target}_autogen/timestamp custom command.
// We cannot just use Moc.CompilationFileGenex here, because that
@@ -1267,28 +1345,11 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// Compose command lines
// FIXME: Take advantage of our per-config mocs_compilation_$<CONFIG>.cpp
// instead of fiddling with the include directories
- std::vector<std::string> configs;
- this->GlobalGen->GetQtAutoGenConfigs(configs);
+
bool constexpr stdPipesUTF8 = true;
cmCustomCommandLines commandLines;
- if (!this->CrossConfig) {
- std::string autogenInfoFileConfig;
- if (this->MultiConfig) {
- autogenInfoFileConfig = "$<CONFIG>";
- } else {
- autogenInfoFileConfig = configs[0];
- }
- commandLines.push_back(cmMakeCommandLine(
- { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
- this->AutogenTarget.InfoFile, autogenInfoFileConfig }));
-
- } else {
- for (auto const& config : configs) {
- commandLines.push_back(cmMakeCommandLine(
- { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
- this->AutogenTarget.InfoFile, config }));
- }
- }
+ AddCMakeProcessToCommandLines(this->AutogenTarget.InfoFile, "cmake_autogen",
+ commandLines);
// Use PRE_BUILD on demand
bool usePRE_BUILD = false;
@@ -1456,18 +1517,47 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
AddAutogenExecutableToDependencies(this->Moc, dependencies);
AddAutogenExecutableToDependencies(this->Uic, dependencies);
-
+ std::string outputFile;
+ std::string depFile;
// Create the custom command that outputs the timestamp file.
- const char timestampFileName[] = "timestamp";
- const std::string outputFile =
- cmStrCat(this->Dir.Build, "/", timestampFileName);
- this->AutogenTarget.DepFile = cmStrCat(this->Dir.Build, "/deps");
- this->AutogenTarget.DepFileRuleName =
- cmStrCat(this->Dir.RelativeBuild, "/", timestampFileName);
- commandLines.push_back(cmMakeCommandLine(
- { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
-
- this->AddGeneratedSource(outputFile, this->Moc);
+ if (this->MultiConfig && this->UseBetterGraph) {
+ // create timestamp file with $<CONFIG> in the name so that
+ // every cmake_autogen target has its own timestamp file
+ std::string const configView = "$<CONFIG>";
+ std::string const timestampFileWithoutConfig = "timestamp_";
+ std::string const depFileWithoutConfig =
+ cmStrCat(this->Dir.Build, "/deps_");
+ std::string const timestampFileName =
+ timestampFileWithoutConfig + configView;
+ outputFile = cmStrCat(this->Dir.Build, "/", timestampFileName);
+ auto const depFileWithConfig =
+ cmStrCat(depFileWithoutConfig, configView);
+ depFile = depFileWithConfig;
+ commandLines.push_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
+
+ ConfigString outputFileWithConfig;
+ for (std::string const& config : this->ConfigsList) {
+ auto tempTimestampFileName = timestampFileWithoutConfig + config;
+ auto tempDepFile = depFileWithoutConfig + config;
+ outputFileWithConfig.Config[config] = tempTimestampFileName;
+ this->AutogenTarget.DepFileRuleName.Config[config] =
+ cmStrCat(this->Dir.RelativeBuild, "/", tempTimestampFileName);
+ this->AutogenTarget.DepFile.Config[config] = tempDepFile;
+ }
+ this->AddGeneratedSource(outputFileWithConfig, this->Moc);
+ } else {
+ cm::string_view const timestampFileName = "timestamp";
+ outputFile = cmStrCat(this->Dir.Build, "/", timestampFileName);
+ this->AutogenTarget.DepFile.Default =
+ cmStrCat(this->Dir.Build, "/deps");
+ depFile = this->AutogenTarget.DepFile.Default;
+ this->AutogenTarget.DepFileRuleName.Default =
+ cmStrCat(this->Dir.RelativeBuild, "/", timestampFileName);
+ commandLines.push_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
+ this->AddGeneratedSource(outputFile, this->Moc);
+ }
cc = cm::make_unique<cmCustomCommand>();
cc->SetOutputs(outputFile);
cc->SetByproducts(timestampByproducts);
@@ -1476,14 +1566,11 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
cc->SetComment(autogenComment.c_str());
cc->SetWorkingDirectory(this->Dir.Work.c_str());
cc->SetEscapeOldStyle(false);
- cc->SetDepfile(this->AutogenTarget.DepFile);
+ cc->SetDepfile(depFile);
cc->SetStdPipesUTF8(stdPipesUTF8);
this->LocalGen->AddCustomCommandToOutput(std::move(cc));
-
- // Alter variables for the autogen target which now merely wraps the
- // custom command
dependencies.clear();
- dependencies.emplace_back(outputFile);
+ dependencies.emplace_back(std::move(outputFile));
commandLines.clear();
autogenComment.clear();
}
@@ -1535,6 +1622,36 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
return true;
}
+void cmQtAutoGenInitializer::AddCMakeProcessToCommandLines(
+ std::string const& infoFile, std::string const& processName,
+ cmCustomCommandLines& commandLines)
+{
+ if (this->CrossConfig && this->UseBetterGraph) {
+ commandLines.push_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", processName, infoFile,
+ "$<CONFIG>", "$<COMMAND_CONFIG:$<CONFIG>>" }));
+ } else if ((this->MultiConfig && this->GlobalGen->IsXcode()) ||
+ this->CrossConfig) {
+ for (std::string const& config : this->ConfigsList) {
+ commandLines.push_back(
+ cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E",
+ processName, infoFile, config }));
+ }
+ } else {
+ std::string autoInfoFileConfig;
+ if (this->MultiConfig) {
+ autoInfoFileConfig = "$<CONFIG>";
+ } else {
+ std::vector<std::string> configs;
+ this->GlobalGen->GetQtAutoGenConfigs(configs);
+ autoInfoFileConfig = configs[0];
+ }
+ commandLines.push_back(
+ cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E", processName,
+ infoFile, autoInfoFileConfig }));
+ }
+}
+
bool cmQtAutoGenInitializer::InitRccTargets()
{
for (Qrc const& qrc : this->Rcc.Qrcs) {
@@ -1555,18 +1672,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
ccDepends.push_back(qrc.InfoFile);
cmCustomCommandLines commandLines;
- if (this->MultiConfig) {
- // Build for all configurations
- for (std::string const& config : this->ConfigsList) {
- commandLines.push_back(
- cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E",
- "cmake_autorcc", qrc.InfoFile, config }));
- }
- } else {
- commandLines.push_back(
- cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E",
- "cmake_autorcc", qrc.InfoFile, "$<CONFIG>" }));
- }
+ AddCMakeProcessToCommandLines(qrc.InfoFile, "cmake_autorcc", commandLines);
std::string const ccComment =
cmStrCat("Automatic RCC for ",
@@ -1617,13 +1723,28 @@ bool cmQtAutoGenInitializer::InitRccTargets()
// Create custom rcc command
{
// Add the resource files to the dependencies
- for (std::string const& fileName : qrc.Resources) {
- // Add resource file to the custom command dependencies
- ccDepends.push_back(fileName);
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ // Add resource file to the custom command dependencies
+ auto resourceFilesWithConfig = cmStrCat(
+ "$<$<CONFIG:", config,
+ ">:", cmList{ qrc.Resources.Config.at(config) }.to_string(),
+ ">");
+ ccDepends.emplace_back(std::move(resourceFilesWithConfig));
+ }
+ } else {
+ for (std::string const& fileName : qrc.Resources.Default) {
+ // Add resource file to the custom command dependencies
+ ccDepends.push_back(fileName);
+ }
}
+
if (!this->Rcc.ExecutableTargetName.empty()) {
ccDepends.push_back(this->Rcc.ExecutableTargetName);
}
+
+ AddAutogenExecutableToDependencies(this->Rcc, ccDepends);
+
cc->SetOutputs(ccOutput);
cc->SetDepends(ccDepends);
this->LocalGen->AddCustomCommandToOutput(std::move(cc));
@@ -1723,6 +1844,8 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
// General
info.SetBool("MULTI_CONFIG", this->MultiConfig);
+ info.SetBool("CROSS_CONFIG", this->CrossConfig);
+ info.SetBool("USE_BETTER_GRAPH", this->UseBetterGraph);
info.SetUInt("PARALLEL", this->AutogenTarget.Parallel);
#ifdef _WIN32
info.SetUInt("AUTOGEN_COMMAND_LINE_LENGTH_MAX",
@@ -1740,14 +1863,14 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major);
info.SetUInt("QT_VERSION_MINOR", this->QtVersion.Minor);
- info.Set("QT_MOC_EXECUTABLE", this->Moc.Executable);
- info.Set("QT_UIC_EXECUTABLE", this->Uic.Executable);
+ info.SetConfig("QT_MOC_EXECUTABLE", this->Moc.Executable);
+ info.SetConfig("QT_UIC_EXECUTABLE", this->Uic.Executable);
info.Set("CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
info.SetConfig("SETTINGS_FILE", this->AutogenTarget.SettingsFile);
info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
- info.Set("DEP_FILE", this->AutogenTarget.DepFile);
- info.Set("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName);
+ info.SetConfig("DEP_FILE", this->AutogenTarget.DepFile);
+ info.SetConfig("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName);
info.SetArray("CMAKE_LIST_FILES", this->Makefile->GetListFiles());
info.SetArray("HEADER_EXTENSIONS",
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
@@ -1874,6 +1997,8 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
// General
info.SetBool("MULTI_CONFIG", this->MultiConfig);
+ info.SetBool("CROSS_CONFIG", this->CrossConfig);
+ info.SetBool("USE_BETTER_GRAPH", this->UseBetterGraph);
info.SetUInt("VERBOSITY", this->Verbosity);
info.Set("GENERATOR", this->GlobalGen->GetName());
@@ -1890,16 +2015,17 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo()
info.SetConfig("INCLUDE_DIR", this->Dir.Include);
// rcc executable
- info.Set("RCC_EXECUTABLE", this->Rcc.Executable);
- info.SetArray("RCC_LIST_OPTIONS",
- this->Rcc.ExecutableFeatures->ListOptions);
+ info.SetConfig("RCC_EXECUTABLE", this->Rcc.Executable);
+ info.SetConfigArray(
+ "RCC_LIST_OPTIONS",
+ generateListOptions(this->Rcc.ExecutableFeatures, this->MultiConfig));
// qrc file
info.Set("SOURCE", qrc.QrcFile);
info.Set("OUTPUT_CHECKSUM", qrc.QrcPathChecksum);
info.Set("OUTPUT_NAME", cmSystemTools::GetFilenameName(qrc.OutputFile));
info.SetArray("OPTIONS", qrc.Options);
- info.SetArray("INPUTS", qrc.Resources);
+ info.SetConfigArray("INPUTS", qrc.Resources);
info.Save(qrc.InfoFile);
}
@@ -2244,16 +2370,32 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmGeneratorExpression ge(*this->Makefile->GetCMakeInstance(), lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(val);
- genVars.Executable = cge->Evaluate(this->LocalGen, "");
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ genVars.Executable.Config[config] =
+ cge->Evaluate(this->LocalGen, config);
+ }
+ } else {
+ genVars.Executable.Default = cge->Evaluate(this->LocalGen, "");
+ }
}
- if (genVars.Executable.empty() && !ignoreMissingTarget) {
+
+ if (genVars.Executable.Default.empty() &&
+ genVars.Executable.Config.empty() && !ignoreMissingTarget) {
print_err(prop + " evaluates to an empty value");
return false;
}
// Create empty compiler features.
- genVars.ExecutableFeatures =
- std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ genVars.ExecutableFeatures.Config[config] =
+ std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ }
+ } else {
+ genVars.ExecutableFeatures.Default =
+ std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ }
return true;
}
}
@@ -2278,15 +2420,39 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
genVars.ExecutableTargetName = targetName;
genVars.ExecutableTarget = genTarget;
if (genTarget->IsImported()) {
- genVars.Executable = genTarget->ImportedGetLocation("");
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ genVars.Executable.Config[config] =
+ genTarget->ImportedGetLocation(config);
+ }
+ } else {
+ genVars.Executable.Default =
+ genTarget->ImportedGetLocation(this->ConfigDefault);
+ }
+
} else {
- genVars.Executable = genTarget->GetLocation("");
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ genVars.Executable.Config[config] = genTarget->GetLocation(config);
+ }
+ } else {
+ genVars.Executable.Default =
+ genTarget->GetLocation(this->ConfigDefault);
+ }
}
} else {
if (ignoreMissingTarget) {
// Create empty compiler features.
- genVars.ExecutableFeatures =
- std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ genVars.ExecutableFeatures.Config[config] =
+ std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ }
+ } else {
+ genVars.ExecutableFeatures.Default =
+ std::make_shared<cmQtAutoGen::CompilerFeatures>();
+ }
+
return true;
}
print_err(cmStrCat("Could not find ", executable, " executable target ",
@@ -2299,10 +2465,22 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
{
std::string err;
genVars.ExecutableFeatures = this->GlobalInitializer->GetCompilerFeatures(
- executable, genVars.Executable, err);
- if (!genVars.ExecutableFeatures) {
- print_err(err);
- return false;
+ executable, genVars.Executable, err, this->MultiConfig,
+ this->UseBetterGraph);
+ if (this->MultiConfig && this->UseBetterGraph) {
+ for (auto const& config : this->ConfigsList) {
+ if (!genVars.ExecutableFeatures.Config[config]) {
+ if (!genVars.ExecutableFeatures.Config[config]) {
+ print_err(err);
+ return false;
+ }
+ }
+ }
+ } else {
+ if (!genVars.ExecutableFeatures.Default) {
+ print_err(err);
+ return false;
+ }
}
}
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 3f7ab9f..1ab038b 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -19,6 +19,7 @@
#include "cmFilePathChecksum.h"
#include "cmQtAutoGen.h"
+class cmCustomCommandLines;
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmLocalGenerator;
@@ -33,23 +34,6 @@ class cmTarget;
class cmQtAutoGenInitializer : public cmQtAutoGen
{
public:
- /** String value with per configuration variants. */
- class ConfigString
- {
- public:
- std::string Default;
- std::unordered_map<std::string, std::string> Config;
- };
-
- /** String values with per configuration variants. */
- template <typename C>
- class ConfigStrings
- {
- public:
- C Default;
- std::unordered_map<std::string, C> Config;
- };
-
/** rcc job. */
class Qrc
{
@@ -64,7 +48,7 @@ public:
bool Generated = false;
bool Unique = false;
std::vector<std::string> Options;
- std::vector<std::string> Resources;
+ ConfigStrings<std::vector<std::string>> Resources;
};
/** moc and/or uic file. */
@@ -91,8 +75,8 @@ public:
// Executable
std::string ExecutableTargetName;
cmGeneratorTarget* ExecutableTarget = nullptr;
- std::string Executable;
- CompilerFeaturesHandle ExecutableFeatures;
+ ConfigString Executable;
+ ConfigStrings<CompilerFeaturesHandle> ExecutableFeatures;
GenVarsT(GenT gen)
: Gen(gen)
@@ -142,6 +126,9 @@ private:
GenVarsT const& genVars, bool prepend = false);
void AddToSourceGroup(std::string const& fileName,
cm::string_view genNameUpper);
+ void AddCMakeProcessToCommandLines(std::string const& infoFile,
+ std::string const& processName,
+ cmCustomCommandLines& commandLines);
void AddCleanFile(std::string const& fileName);
void ConfigFileNames(ConfigString& configString, cm::string_view prefix,
@@ -156,6 +143,9 @@ private:
bool ignoreMissingTarget) const;
void handleSkipPch(cmSourceFile* sf);
+ void AddAutogenExecutableToDependencies(
+ cmQtAutoGenInitializer::GenVarsT const& genVars,
+ std::vector<std::string>& dependencies) const;
cmQtAutoGenGlobalInitializer* GlobalInitializer = nullptr;
cmGeneratorTarget* GenTarget = nullptr;
@@ -169,6 +159,7 @@ private:
unsigned int Verbosity = 0;
bool MultiConfig = false;
bool CrossConfig = false;
+ bool UseBetterGraph = false;
bool CMP0071Accept = false;
bool CMP0071Warn = false;
bool CMP0100Accept = false;
@@ -205,8 +196,8 @@ private:
bool DependOrigin = false;
std::set<std::string> DependFiles;
std::set<cmTarget*> DependTargets;
- std::string DepFile;
- std::string DepFileRuleName;
+ ConfigString DepFile;
+ ConfigString DepFileRuleName;
// Sources to process
std::unordered_map<cmSourceFile*, MUFileHandle> Headers;
std::unordered_map<cmSourceFile*, MUFileHandle> Sources;
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index c048312..ebdec12 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -430,10 +430,12 @@ std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const
return cmQtAutoGen::Quoted(res);
}
-bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config)
+bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config,
+ cm::string_view executableConfig)
{
// Info config
this->InfoConfig_ = std::string(config);
+ this->ExecutableConfig_ = std::string(executableConfig);
// Info file
this->InfoFile_ = std::string(infoFile);
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index 5c3a8ad..4b15fc7 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -90,6 +90,10 @@ public:
std::string const& InfoDir() const { return this->InfoDir_; }
cmFileTime const& InfoFileTime() const { return this->InfoFileTime_; }
std::string const& InfoConfig() const { return this->InfoConfig_; }
+ std::string const& ExecutableConfig() const
+ {
+ return this->ExecutableConfig_;
+ }
// -- Info file parsing
/** Info file reader class. */
@@ -151,7 +155,8 @@ public:
std::string MessagePath(cm::string_view path) const;
// -- Run
- bool Run(cm::string_view infoFile, cm::string_view config);
+ bool Run(cm::string_view infoFile, cm::string_view config,
+ cm::string_view executableConfig);
protected:
// -- Abstract processing interface
@@ -170,6 +175,7 @@ private:
std::string InfoDir_;
cmFileTime InfoFileTime_;
std::string InfoConfig_;
+ std::string ExecutableConfig_;
// -- Directories
ProjectDirsT ProjectDirs_;
};
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index a49125e..408a22c 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -171,6 +171,8 @@ public:
// -- Attributes
// - Config
bool MultiConfig = false;
+ bool CrossConfig = false;
+ bool UseBetterGraph = false;
IntegerVersion QtVersion = { 4, 0 };
unsigned int ThreadCount = 0;
unsigned int MaxCommandLineLength =
@@ -2380,6 +2382,9 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
{
// -- Required settings
if (!info.GetBool("MULTI_CONFIG", this->BaseConst_.MultiConfig, true) ||
+ !info.GetBool("CROSS_CONFIG", this->BaseConst_.CrossConfig, true) ||
+ !info.GetBool("USE_BETTER_GRAPH", this->BaseConst_.UseBetterGraph,
+ true) ||
!info.GetUInt("QT_VERSION_MAJOR", this->BaseConst_.QtVersion.Major,
true) ||
!info.GetUInt("QT_VERSION_MINOR", this->BaseConst_.QtVersion.Minor,
@@ -2396,19 +2401,49 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
true) ||
!info.GetStringConfig("PARSE_CACHE_FILE",
this->BaseConst_.ParseCacheFile, true) ||
- !info.GetString("DEP_FILE", this->BaseConst_.DepFile, false) ||
- !info.GetString("DEP_FILE_RULE_NAME", this->BaseConst_.DepFileRuleName,
- false) ||
!info.GetStringConfig("SETTINGS_FILE", this->SettingsFile_, true) ||
!info.GetArray("CMAKE_LIST_FILES", this->BaseConst_.ListFiles, true) ||
!info.GetArray("HEADER_EXTENSIONS", this->BaseConst_.HeaderExtensions,
- true) ||
- !info.GetString("QT_MOC_EXECUTABLE", this->MocConst_.Executable,
- false) ||
- !info.GetString("QT_UIC_EXECUTABLE", this->UicConst_.Executable,
- false)) {
+ true)) {
return false;
}
+ if (this->BaseConst().UseBetterGraph) {
+ if (!info.GetStringConfig("DEP_FILE", this->BaseConst_.DepFile, false) ||
+ !info.GetStringConfig("DEP_FILE_RULE_NAME",
+ this->BaseConst_.DepFileRuleName, false)) {
+ return false;
+ }
+
+ if (this->BaseConst_.CrossConfig) {
+ std::string const mocExecutableWithConfig =
+ "QT_MOC_EXECUTABLE_" + this->ExecutableConfig();
+ std::string const uicExecutableWithConfig =
+ "QT_UIC_EXECUTABLE_" + this->ExecutableConfig();
+ if (!info.GetString(mocExecutableWithConfig, this->MocConst_.Executable,
+ false) ||
+ !info.GetString(uicExecutableWithConfig, this->UicConst_.Executable,
+ false)) {
+ return false;
+ }
+ } else {
+ if (!info.GetStringConfig("QT_MOC_EXECUTABLE",
+ this->MocConst_.Executable, false) ||
+ !info.GetStringConfig("QT_UIC_EXECUTABLE",
+ this->UicConst_.Executable, false)) {
+ return false;
+ }
+ }
+ } else {
+ if (!info.GetString("QT_MOC_EXECUTABLE", this->MocConst_.Executable,
+ false) ||
+ !info.GetString("QT_UIC_EXECUTABLE", this->UicConst_.Executable,
+ false) ||
+ !info.GetString("DEP_FILE", this->BaseConst_.DepFile, false) ||
+ !info.GetString("DEP_FILE_RULE_NAME", this->BaseConst_.DepFileRuleName,
+ false)) {
+ return false;
+ }
+ }
// -- Checks
if (!this->BaseConst_.CMakeExecutableTime.Load(
@@ -3075,7 +3110,8 @@ std::string cmQtAutoMocUicT::AbsoluteIncludePath(
} // End of unnamed namespace
-bool cmQtAutoMocUic(cm::string_view infoFile, cm::string_view config)
+bool cmQtAutoMocUic(cm::string_view infoFile, cm::string_view config,
+ cm::string_view executableConfig)
{
- return cmQtAutoMocUicT().Run(infoFile, config);
+ return cmQtAutoMocUicT().Run(infoFile, config, executableConfig);
}
diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h
index 20f9d6e..5cb4ff1 100644
--- a/Source/cmQtAutoMocUic.h
+++ b/Source/cmQtAutoMocUic.h
@@ -10,4 +10,5 @@
* Process AUTOMOC and AUTOUIC
* @return true on success
*/
-bool cmQtAutoMocUic(cm::string_view infoFile, cm::string_view config);
+bool cmQtAutoMocUic(cm::string_view infoFile, cm::string_view config,
+ cm::string_view executableConfig);
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index e288645..605dad5 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -35,6 +35,11 @@ public:
private:
// -- Utility
bool IsMultiConfig() const { return this->MultiConfig_; }
+ std::string const& GetGenerator() const { return this->Generator_; }
+ bool IsXcode() const
+ {
+ return this->GetGenerator().find("Xcode") != std::string::npos;
+ }
std::string MultiConfigOutput() const;
// -- Abstract processing interface
@@ -53,6 +58,9 @@ private:
// -- Config settings
bool MultiConfig_ = false;
+ bool CrossConfig_ = false;
+ bool UseBetterGraph_ = false;
+ std::string Generator_;
// -- Directories
std::string AutogenBuildDir_;
std::string IncludeDir_;
@@ -92,26 +100,57 @@ bool cmQtAutoRccT::InitFromInfo(InfoT const& info)
{
// -- Required settings
if (!info.GetBool("MULTI_CONFIG", this->MultiConfig_, true) ||
+ !info.GetString("GENERATOR", this->Generator_, true) ||
+ !info.GetBool("CROSS_CONFIG", this->CrossConfig_, true) ||
+ !info.GetBool("USE_BETTER_GRAPH", this->UseBetterGraph_, true) ||
!info.GetString("BUILD_DIR", this->AutogenBuildDir_, true) ||
!info.GetStringConfig("INCLUDE_DIR", this->IncludeDir_, true) ||
- !info.GetString("RCC_EXECUTABLE", this->RccExecutable_, true) ||
- !info.GetArray("RCC_LIST_OPTIONS", this->RccListOptions_, false) ||
+ !info.GetArrayConfig("RCC_LIST_OPTIONS", this->RccListOptions_, false) ||
!info.GetString("LOCK_FILE", this->LockFile_, true) ||
!info.GetStringConfig("SETTINGS_FILE", this->SettingsFile_, true) ||
!info.GetString("SOURCE", this->QrcFile_, true) ||
!info.GetString("OUTPUT_CHECKSUM", this->RccPathChecksum_, true) ||
!info.GetString("OUTPUT_NAME", this->RccFileName_, true) ||
- !info.GetArray("OPTIONS", this->Options_, false) ||
- !info.GetArray("INPUTS", this->Inputs_, false)) {
+ !info.GetArray("OPTIONS", this->Options_, false)) {
return false;
}
+ if (this->UseBetterGraph_) {
+ if (!info.GetArrayConfig("INPUTS", this->Inputs_, false)) {
+ return false;
+ }
+ if (this->CrossConfig_) {
+ std::string const rccExecutableWithConfig =
+ "RCC_EXECUTABLE_" + this->ExecutableConfig();
+ if (!info.GetString(rccExecutableWithConfig, this->RccExecutable_,
+ true)) {
+ return false;
+ }
+ } else {
+ if (!info.GetStringConfig("RCC_EXECUTABLE", this->RccExecutable_,
+ true)) {
+ return false;
+ }
+ }
+ } else {
+ if (!info.GetString("RCC_EXECUTABLE", this->RccExecutable_, true) ||
+ !info.GetArray("RCC_LIST_OPTIONS", this->RccListOptions_, false) ||
+ !info.GetArray("INPUTS", this->Inputs_, false)) {
+ return false;
+ }
+ }
// -- Derive information
this->QrcFileName_ = cmSystemTools::GetFilenameName(this->QrcFile_);
this->QrcFileDir_ = cmSystemTools::GetFilenamePath(this->QrcFile_);
- this->RccFilePublic_ =
- cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, '/',
- this->RccFileName_);
+ if (IsMultiConfig() && !this->IsXcode() && this->UseBetterGraph_) {
+ this->RccFilePublic_ =
+ cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, "_",
+ this->InfoConfig(), '/', this->RccFileName_);
+ } else {
+ this->RccFilePublic_ =
+ cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, '/',
+ this->RccFileName_);
+ }
// rcc output file name
if (this->IsMultiConfig()) {
@@ -520,7 +559,8 @@ bool cmQtAutoRccT::GenerateWrapper()
} // End of unnamed namespace
-bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config)
+bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config,
+ cm::string_view executableConfig)
{
- return cmQtAutoRccT().Run(infoFile, config);
+ return cmQtAutoRccT().Run(infoFile, config, executableConfig);
}
diff --git a/Source/cmQtAutoRcc.h b/Source/cmQtAutoRcc.h
index d525efa..9c0a4e9 100644
--- a/Source/cmQtAutoRcc.h
+++ b/Source/cmQtAutoRcc.h
@@ -10,4 +10,5 @@
* Process AUTORCC
* @return true on success
*/
-bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config);
+bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config,
+ cm::string_view executableConfig);
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index f48330d..3934a29 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -3,7 +3,6 @@
#include "cmRST.h"
#include <algorithm>
-#include <cctype>
#include <cstddef>
#include <iterator>
#include <utility>
@@ -159,7 +158,7 @@ void cmRST::ProcessLine(std::string const& line)
// A line starting in .. is an explicit markup start.
if (line == ".." ||
(line.size() >= 3 && line[0] == '.' && line[1] == '.' &&
- isspace(line[2]))) {
+ cmIsSpace(line[2]))) {
this->Reset();
this->MarkupType =
(line.find_first_not_of(" \t", 2) == std::string::npos ? Markup::Empty
@@ -219,7 +218,7 @@ void cmRST::ProcessLine(std::string const& line)
}
// Indented lines following an explicit markup start are explicit markup.
else if (this->MarkupType != Markup::None &&
- (line.empty() || isspace(line[0]))) {
+ (line.empty() || cmIsSpace(line[0]))) {
this->MarkupType = Markup::Normal;
// Record markup lines if the start line was recorded.
if (!this->MarkupLines.empty()) {
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 4a9840b..55a1e46 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -44,7 +44,10 @@ private:
/** Returns true if the character @a ch is a whitespace character. **/
inline bool cmIsSpace(char ch)
{
- return ((ch & 0x80) == 0) && std::isspace(ch);
+ // isspace takes 'int' but documents that the value must be representable
+ // by 'unsigned char', or be EOF. Cast to 'unsigned char' to avoid sign
+ // extension while converting to 'int'.
+ return std::isspace(static_cast<unsigned char>(ch));
}
/** Returns a string that has whitespace removed from the start and the end. */
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 5a64588..ab87f34 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -6,7 +6,6 @@
#include "cmStringCommand.h"
#include <algorithm>
-#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <limits>
@@ -660,7 +659,7 @@ bool HandleStripCommand(std::vector<std::string> const& args,
const char* ptr = stringValue.c_str();
size_t cc;
for (cc = 0; cc < inStringLength; ++cc) {
- if (!isspace(*ptr)) {
+ if (!cmIsSpace(*ptr)) {
if (startPos > inStringLength) {
startPos = cc;
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index f606c22..fca8186 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -486,7 +486,7 @@ bool cmSystemTools::SplitProgramFromArgs(std::string const& command,
const char* c = command.c_str();
// Skip leading whitespace.
- while (isspace(static_cast<unsigned char>(*c))) {
+ while (cmIsSpace(*c)) {
++c;
}
@@ -516,7 +516,7 @@ bool cmSystemTools::SplitProgramFromArgs(std::string const& command,
in_double = true;
} else if (*c == '\'') {
in_single = true;
- } else if (isspace(static_cast<unsigned char>(*c))) {
+ } else if (cmIsSpace(*c)) {
break;
} else {
program += *c;
@@ -1673,7 +1673,7 @@ void cmSystemTools::EnvDiff::PutEnv(const std::string& env)
void cmSystemTools::EnvDiff::UnPutEnv(const std::string& env)
{
- diff[env] = {};
+ diff[env] = cm::nullopt;
}
bool cmSystemTools::EnvDiff::ParseOperation(const std::string& envmod)
@@ -1728,7 +1728,7 @@ bool cmSystemTools::EnvDiff::ParseOperation(const std::string& envmod)
} else if (op == "set"_s) {
diff[name] = value;
} else if (op == "unset"_s) {
- diff[name] = {};
+ diff[name] = cm::nullopt;
} else if (op == "string_append"_s) {
apply_diff(name, [&value](std::string& output) { output += value; });
} else if (op == "string_prepend"_s) {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index a365cd1..e6e1ac4 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -557,6 +557,7 @@ TargetProperty const StaticTargetProperties[] = {
{ "AUTOGEN_ORIGIN_DEPENDS"_s, IC::CanCompileSources },
{ "AUTOGEN_PARALLEL"_s, IC::CanCompileSources },
{ "AUTOGEN_USE_SYSTEM_INCLUDE"_s, IC::CanCompileSources },
+ { "AUTOGEN_BETTER_GRAPH_MULTI_CONFIG"_s, IC::CanCompileSources },
// -- moc
{ "AUTOMOC_DEPEND_FILTERS"_s, IC::CanCompileSources },
// -- C++
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
index 24da8c6..f4433e3 100644
--- a/Source/cmXMLParser.cxx
+++ b/Source/cmXMLParser.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmXMLParser.h"
-#include <cctype>
#include <cstring>
#include <iostream>
#include <sstream>
@@ -143,11 +142,6 @@ void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
{
}
-int cmXMLParser::IsSpace(char c)
-{
- return isspace(c);
-}
-
const char* cmXMLParser::FindAttribute(const char** atts,
const char* attribute)
{
diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h
index 176252d..d35e44f 100644
--- a/Source/cmXMLParser.h
+++ b/Source/cmXMLParser.h
@@ -89,10 +89,6 @@ protected:
/** Called by ReportXmlParseError with basic error info. */
virtual void ReportError(int line, int column, const char* msg);
- //! Utility for convenience of subclasses. Wraps isspace C library
- // routine.
- static int IsSpace(char c);
-
//! Send the given buffer to the XML parser.
virtual int ParseBuffer(const char* buffer, std::string::size_type length);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 32064b4..7ab7600 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2820,7 +2820,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
if (cmSystemTools::GetErrorOccurredFlag()) {
return -1;
}
- return 0;
+ return this->HasScriptModeExitCode() ? this->GetScriptModeExitCode() : 0;
}
// If MAKEFLAGS are given in the environment, remove the environment
diff --git a/Source/cmake.h b/Source/cmake.h
index 58f90c9..ccf5154 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -835,7 +835,13 @@ private:
std::string DebuggerDapLogFile;
#endif
+ cm::optional<int> ScriptModeExitCode;
+
public:
+ bool HasScriptModeExitCode() const { return ScriptModeExitCode.has_value(); }
+ void SetScriptModeExitCode(int code) { ScriptModeExitCode = code; }
+ int GetScriptModeExitCode() const { return ScriptModeExitCode.value_or(-1); }
+
static cmDocumentationEntry CMAKE_STANDARD_OPTIONS_TABLE[18];
};
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index ced83dc..8462734 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -389,13 +389,16 @@ int do_cmake(int ac, char const* const* av)
}
}
- // Always return a non-negative value. Windows tools do not always
- // interpret negative return values as errors.
+ // Always return a non-negative value (except exit code from SCRIPT_MODE).
+ // Windows tools do not always interpret negative return values as errors.
if (res != 0) {
+ auto scriptModeExitCode =
+ cm.HasScriptModeExitCode() ? cm.GetScriptModeExitCode() : 0;
+ res = scriptModeExitCode ? scriptModeExitCode : 1;
#ifdef CMake_ENABLE_DEBUGGER
- cm.StopDebuggerIfNeeded(1);
+ cm.StopDebuggerIfNeeded(res);
#endif
- return 1;
+ return res;
}
#ifdef CMake_ENABLE_DEBUGGER
cm.StopDebuggerIfNeeded(0);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 93b0086..bcf7462 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1443,13 +1443,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
if ((args[1] == "cmake_autogen") && (args.size() >= 4)) {
cm::string_view const infoFile = args[2];
cm::string_view const config = args[3];
- return cmQtAutoMocUic(infoFile, config) ? 0 : 1;
+ cm::string_view const executableConfig =
+ (args.size() >= 5) ? cm::string_view(args[4]) : cm::string_view();
+ return cmQtAutoMocUic(infoFile, config, executableConfig) ? 0 : 1;
}
if ((args[1] == "cmake_autorcc") && (args.size() >= 3)) {
cm::string_view const infoFile = args[2];
cm::string_view const config =
(args.size() > 3) ? cm::string_view(args[3]) : cm::string_view();
- return cmQtAutoRcc(infoFile, config) ? 0 : 1;
+ cm::string_view const executableConfig =
+ (args.size() >= 5) ? cm::string_view(args[4]) : cm::string_view();
+ return cmQtAutoRcc(infoFile, config, executableConfig) ? 0 : 1;
}
#endif