diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2018-01-31 12:54:37 (GMT) |
---|---|---|
committer | Sebastian Holtermann <sebholt@xwmw.org> | 2018-02-02 08:10:40 (GMT) |
commit | a8ee7406a74cbc4d5e341ad33210b8eeb99af48f (patch) | |
tree | 3d13bde5ee4e44cc66eca61faff9007e108f53ad /Source | |
parent | 5a16e762e21e22e7a212acc7e2bc7bd027d66166 (diff) | |
download | CMake-a8ee7406a74cbc4d5e341ad33210b8eeb99af48f.zip CMake-a8ee7406a74cbc4d5e341ad33210b8eeb99af48f.tar.gz CMake-a8ee7406a74cbc4d5e341ad33210b8eeb99af48f.tar.bz2 |
Autogen: Improved multi-config include scheme
For multi configuration generators AUTOMOC generates the
moc files that are included in `mocs_compilation.cpp`
in `AUTOGEN_BUILD_DIR/include_$<CONFIG>/`. By doing so each
configuration reads different moc files when compiling
`mocs_compilation.cpp`. Since we do not (need to) rewrite
`mocs_compilation.cpp` on a configuration change anymore,
the files also does not need to be recompiled anymore.
Not having to rewrite and recompile `mocs_compilation.cpp`
on a configuration change anymore was the main objective of
this patch.
In a similar fashion AUTORCC generates a `qrc_BASE_CMAKE.cpp`
file below `AUTOGEN_BUILD_DIR/include_$<CONFIG>/` and
`qrc_BASE.cpp` becomes a mere wrapper that includes this
actuall rcc output file (when using multi configuration
generators).
The template files `Modules/AutoRccInfo.cmake.in` and
`Modules/AutogenInfo.cmake.in` were removed in favor
of writing the info `.cmake` files manually.
Closes #17230
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmQtAutoGen.cxx | 28 | ||||
-rw-r--r-- | Source/cmQtAutoGen.h | 13 | ||||
-rw-r--r-- | Source/cmQtAutoGenInitializer.cxx | 545 | ||||
-rw-r--r-- | Source/cmQtAutoGenInitializer.h | 25 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorMocUic.cxx | 104 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorMocUic.h | 9 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorRcc.cxx | 150 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorRcc.h | 18 |
8 files changed, 421 insertions, 471 deletions
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index 18ecbe7..6e9ca44 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -17,10 +17,6 @@ std::string const genNameMoc = "AutoMoc"; std::string const genNameUic = "AutoUic"; std::string const genNameRcc = "AutoRcc"; -std::string const mcNameSingle = "SINGLE"; -std::string const mcNameWrapper = "WRAPPER"; -std::string const mcNameMulti = "MULTI"; - // - Static functions /// @brief Merges newOpts into baseOpts @@ -102,30 +98,6 @@ std::string cmQtAutoGen::GeneratorNameUpper(GeneratorT genType) return cmSystemTools::UpperCase(cmQtAutoGen::GeneratorName(genType)); } -std::string const& cmQtAutoGen::MultiConfigName(MultiConfigT config) -{ - switch (config) { - case MultiConfigT::SINGLE: - return mcNameSingle; - case MultiConfigT::WRAPPER: - return mcNameWrapper; - case MultiConfigT::MULTI: - return mcNameMulti; - } - return mcNameWrapper; -} - -cmQtAutoGen::MultiConfigT cmQtAutoGen::MultiConfigType(std::string const& name) -{ - if (name == mcNameSingle) { - return MultiConfigT::SINGLE; - } - if (name == mcNameMulti) { - return MultiConfigT::MULTI; - } - return MultiConfigT::WRAPPER; -} - std::string cmQtAutoGen::Quoted(std::string const& text) { static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a", diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 30ce0f6..67f61b1 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -28,25 +28,12 @@ public: RCC }; - /// @brief Multiconfiguration type - enum class MultiConfigT - { - SINGLE, // Single configuration - WRAPPER, // Multi configuration using wrapper files - MULTI // Multi configuration using per config sources - }; - public: /// @brief Returns the generator name static std::string const& GeneratorName(GeneratorT genType); /// @brief Returns the generator name in upper case static std::string GeneratorNameUpper(GeneratorT genType); - /// @brief Returns the multi configuration name string - static std::string const& MultiConfigName(MultiConfigT config); - /// @brief Returns the multi configuration type - static MultiConfigT MultiConfigType(std::string const& name); - /// @brief Returns a the string escaped and enclosed in quotes static std::string Quoted(std::string const& text); diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 0f3cb23..41142e5 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -68,43 +68,6 @@ static std::size_t GetParallelCPUCount() return count; } -static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, - std::string const& value) -{ - makefile->AddDefinition(key, - cmOutputConverter::EscapeForCMake(value).c_str()); -} - -static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, - const std::vector<std::string>& values) -{ - makefile->AddDefinition( - key, cmOutputConverter::EscapeForCMake(cmJoin(values, ";")).c_str()); -} - -static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, - const std::set<std::string>& values) -{ - makefile->AddDefinition( - key, cmOutputConverter::EscapeForCMake(cmJoin(values, ";")).c_str()); -} - -static void AddDefinitionEscaped( - cmMakefile* makefile, const char* key, - const std::vector<std::vector<std::string>>& lists) -{ - std::vector<std::string> seplist; - for (const std::vector<std::string>& list : lists) { - std::string blist = "{"; - blist += cmJoin(list, ";"); - blist += "}"; - seplist.push_back(std::move(blist)); - } - makefile->AddDefinition(key, cmOutputConverter::EscapeForCMake( - cmJoin(seplist, cmQtAutoGen::ListSep)) - .c_str()); -} - static bool AddToSourceGroup(cmMakefile* makefile, std::string const& fileName, cmQtAutoGen::GeneratorT genType) { @@ -234,8 +197,8 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer( , MocEnabled(mocEnabled) , UicEnabled(uicEnabled) , RccEnabled(rccEnabled) + , MultiConfig(false) , QtVersionMajor(qtVersionMajor) - , MultiConfig(MultiConfigT::WRAPPER) { this->QtVersionMinor = cmQtAutoGenInitializer::GetQtMinorVersion(target, this->QtVersionMajor); @@ -248,30 +211,12 @@ void cmQtAutoGenInitializer::InitCustomTargets() cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator(); // Configurations + this->MultiConfig = globalGen->IsMultiConfig(); this->ConfigDefault = makefile->GetConfigurations(this->ConfigsList); if (this->ConfigsList.empty()) { this->ConfigsList.push_back(this->ConfigDefault); } - // Multi configuration - { - if (!globalGen->IsMultiConfig()) { - this->MultiConfig = MultiConfigT::SINGLE; - } - - // FIXME: Xcode does not support per-config sources, yet. - // (EXCLUDED_SOURCE_FILE_NAMES) - // if (globalGen->GetName().find("Xcode") != std::string::npos) { - // return MultiConfigT::MULTI; - //} - - // FIXME: Visual Studio does not support per-config sources, yet. - // (EXCLUDED_SOURCE_FILE_NAMES) - // if (globalGen->GetName().find("Visual Studio") != std::string::npos) { - // return MultiConfigT::MULTI; - //} - } - // Autogen target name this->AutogenTargetName = this->Target->GetName(); this->AutogenTargetName += "_autogen"; @@ -285,7 +230,7 @@ void cmQtAutoGenInitializer::InitCustomTargets() // Autogen info dir this->DirInfo = cbd; this->DirInfo += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); - this->DirInfo += "/"; + this->DirInfo += '/'; this->DirInfo += this->AutogenTargetName; this->DirInfo += ".dir"; cmSystemTools::ConvertToUnixSlashes(this->DirInfo); @@ -294,7 +239,7 @@ void cmQtAutoGenInitializer::InitCustomTargets() this->DirBuild = GetSafeProperty(this->Target, "AUTOGEN_BUILD_DIR"); if (this->DirBuild.empty()) { this->DirBuild = cbd; - this->DirBuild += "/"; + this->DirBuild += '/'; this->DirBuild += this->AutogenTargetName; } cmSystemTools::ConvertToUnixSlashes(this->DirBuild); @@ -340,32 +285,32 @@ void cmQtAutoGenInitializer::InitCustomTargets() { std::string base = this->DirInfo; base += "/AutogenOldSettings"; - if (this->MultiConfig == MultiConfigT::SINGLE) { - AddCleanFile(makefile, base.append(".cmake")); - } else { + if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { std::string filename = base; - filename += "_"; + filename += '_'; filename += cfg; filename += ".cmake"; AddCleanFile(makefile, filename); } + } else { + AddCleanFile(makefile, base.append(".cmake")); } } // Add moc compilation to generated files list if (this->MocEnabled) { - std::string const mocsComp = this->DirBuild + "/mocs_compilation.cpp"; - auto files = this->AddGeneratedSource(mocsComp, GeneratorT::MOC); - for (std::string& file : files) { - autogenProvides.push_back(std::move(file)); - } + std::string mocsComp = this->DirBuild + "/mocs_compilation.cpp"; + this->AddGeneratedSource(mocsComp, GeneratorT::MOC); + autogenProvides.push_back(std::move(mocsComp)); } // Add autogen includes directory to the origin target INCLUDE_DIRECTORIES - if (this->MocEnabled || this->UicEnabled) { - std::string includeDir = this->DirBuild + "/include"; - if (this->MultiConfig != MultiConfigT::SINGLE) { + if (this->MocEnabled || this->UicEnabled || + (this->RccEnabled && this->MultiConfig)) { + std::string includeDir = this->DirBuild; + includeDir += "/include"; + if (this->MultiConfig) { includeDir += "_$<CONFIG>"; } this->Target->AddIncludeDirectory(includeDir, true); @@ -674,9 +619,10 @@ void cmQtAutoGenInitializer::InitCustomTargets() } for (Qrc& qrc : this->Qrcs) { // Register file at target - std::vector<std::string> const ccOutput = - this->AddGeneratedSource(qrc.RccFile, GeneratorT::RCC); + this->AddGeneratedSource(qrc.RccFile, GeneratorT::RCC); + std::vector<std::string> ccOutput; + ccOutput.push_back(qrc.RccFile); cmCustomCommandLines commandLines; { cmCustomCommandLine currentLine; @@ -905,51 +851,6 @@ void cmQtAutoGenInitializer::SetupCustomTargets() { cmMakefile* makefile = this->Target->Target->GetMakefile(); - // forget the variables added here afterwards again: - cmMakefile::ScopePushPop varScope(makefile); - static_cast<void>(varScope); - - // Configuration suffixes - std::map<std::string, std::string> configSuffixes; - for (std::string const& cfg : this->ConfigsList) { - std::string& suffix = configSuffixes[cfg]; - suffix = "_"; - suffix += cfg; - } - - // Basic setup - AddDefinitionEscaped(makefile, "_multi_config", - MultiConfigName(this->MultiConfig)); - AddDefinitionEscaped(makefile, "_build_dir", this->DirBuild); - { - std::string parallel = GetSafeProperty(this->Target, "AUTOGEN_PARALLEL"); - // Autodetect number of CPUs - if (parallel.empty() || (parallel == "AUTO")) { - parallel = std::to_string(GetParallelCPUCount()); - } - AddDefinitionEscaped(makefile, "_parallel", parallel); - } - - if (this->MocEnabled || this->UicEnabled) { - AddDefinitionEscaped(makefile, "_qt_version_major", this->QtVersionMajor); - AddDefinitionEscaped(makefile, "_settings_file", - this->AutogenSettingsFile); - AddDefinitionEscaped(makefile, "_sources", this->Sources); - AddDefinitionEscaped(makefile, "_headers", this->Headers); - - if (this->MocEnabled) { - this->SetupCustomTargetsMoc(); - } - if (this->UicEnabled) { - this->SetupCustomTargetsUic(); - } - } - if (this->RccEnabled) { - AddDefinitionEscaped(makefile, "_qt_rcc_executable", this->RccExecutable); - AddDefinitionEscaped(makefile, "_qt_rcc_list_options", - this->RccListOptions); - } - // Create info directory on demand if (!cmSystemTools::MakeDirectory(this->DirInfo)) { std::string emsg = ("Could not create directory: "); @@ -957,21 +858,33 @@ void cmQtAutoGenInitializer::SetupCustomTargets() cmSystemTools::Error(emsg.c_str()); } - auto ReOpenInfoFile = [](cmsys::ofstream& ofs, - std::string const& fileName) -> bool { + // Configuration include directories + std::string includeDir = "include"; + std::map<std::string, std::string> includeDirs; + for (std::string const& cfg : this->ConfigsList) { + std::string& dir = includeDirs[cfg]; + dir = "include_"; + dir += cfg; + } + + auto OpenInfoFile = [](cmsys::ofstream& ofs, + std::string const& fileName) -> bool { // Ensure we have write permission - mode_t perm = 0; + if (cmSystemTools::FileExists(fileName)) { + mode_t perm = 0; #if defined(_WIN32) && !defined(__CYGWIN__) - mode_t mode_write = S_IWRITE; + mode_t mode_write = S_IWRITE; #else - mode_t mode_write = S_IWUSR; + mode_t mode_write = S_IWUSR; #endif - cmSystemTools::GetPermissions(fileName, perm); - if (!(perm & mode_write)) { - cmSystemTools::SetPermissions(fileName, perm | mode_write); + cmSystemTools::GetPermissions(fileName, perm); + if (!(perm & mode_write)) { + cmSystemTools::SetPermissions(fileName, perm | mode_write); + } } - ofs.open(fileName.c_str(), std::ios::app); + ofs.open(fileName.c_str(), + (std::ios::out | std::ios::binary | std::ios::trunc)); if (!ofs) { // File open error std::string error = "Internal CMake error when trying to open file: "; @@ -984,88 +897,177 @@ void cmQtAutoGenInitializer::SetupCustomTargets() // Generate autogen target info file if (this->MocEnabled || this->UicEnabled) { - { - std::string infoFileIn = cmSystemTools::GetCMakeRoot(); - infoFileIn += "/Modules/AutogenInfo.cmake.in"; - makefile->ConfigureFile( - infoFileIn.c_str(), this->AutogenInfoFile.c_str(), false, true, false); + if (this->MocEnabled) { + this->SetupCustomTargetsMoc(); + } + if (this->UicEnabled) { + this->SetupCustomTargetsUic(); + } + + // Parallel processing + this->Parallel = GetSafeProperty(this->Target, "AUTOGEN_PARALLEL"); + if (this->Parallel.empty() || (this->Parallel == "AUTO")) { + // Autodetect number of CPUs + this->Parallel = std::to_string(GetParallelCPUCount()); } - // Append custom definitions to info file - // -------------------------------------- cmsys::ofstream ofs; - if (ReOpenInfoFile(ofs, this->AutogenInfoFile)) { - auto OfsWriteMap = [&ofs]( - const char* key, std::map<std::string, std::string> const& map) { + if (OpenInfoFile(ofs, this->AutogenInfoFile)) { + // Utility lambdas + auto CWrite = [&ofs](const char* key, std::string const& value) { + ofs << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value) + << ")\n"; + }; + auto CWriteList = [&CWrite](const char* key, + std::vector<std::string> const& list) { + CWrite(key, cmJoin(list, ";")); + }; + auto CWriteNestedLists = [&CWrite]( + const char* key, std::vector<std::vector<std::string>> const& lists) { + std::vector<std::string> seplist; + for (const std::vector<std::string>& list : lists) { + std::string blist = "{"; + blist += cmJoin(list, ";"); + blist += "}"; + seplist.push_back(std::move(blist)); + } + CWrite(key, cmJoin(seplist, cmQtAutoGen::ListSep)); + }; + auto CWriteSet = [&CWrite](const char* key, + std::set<std::string> const& list) { + CWrite(key, cmJoin(list, ";")); + }; + auto CWriteMap = [&ofs](const char* key, + std::map<std::string, std::string> const& map) { for (auto const& item : map) { ofs << "set(" << key << "_" << item.first << " " << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; } }; - ofs << "# Configurations options\n"; - OfsWriteMap("AM_CONFIG_SUFFIX", configSuffixes); - OfsWriteMap("AM_MOC_DEFINITIONS", this->ConfigMocDefines); - OfsWriteMap("AM_MOC_INCLUDES", this->ConfigMocIncludes); - OfsWriteMap("AM_UIC_TARGET_OPTIONS", this->ConfigUicOptions); - // Settings files (only require for multi configuration generators) - if (this->MultiConfig != MultiConfigT::SINGLE) { + auto MfDef = [makefile](const char* key) { + return std::string(makefile->GetSafeDefinition(key)); + }; + + // Write + ofs << "# Meta\n"; + CWrite("AM_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); + CWrite("AM_PARALLEL", this->Parallel); + + ofs << "# Directories\n"; + CWrite("AM_CMAKE_SOURCE_DIR", MfDef("CMAKE_SOURCE_DIR")); + CWrite("AM_CMAKE_BINARY_DIR", MfDef("CMAKE_BINARY_DIR")); + CWrite("AM_CMAKE_CURRENT_SOURCE_DIR", MfDef("CMAKE_CURRENT_SOURCE_DIR")); + CWrite("AM_CMAKE_CURRENT_BINARY_DIR", MfDef("CMAKE_CURRENT_BINARY_DIR")); + CWrite("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", + MfDef("CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE")); + CWrite("AM_BUILD_DIR", this->DirBuild); + if (this->MultiConfig) { + CWriteMap("AM_INCLUDE_DIR", includeDirs); + } else { + CWrite("AM_INCLUDE_DIR", includeDir); + } + + ofs << "# Files\n"; + CWriteList("AM_SOURCES", this->Sources); + CWriteList("AM_HEADERS", this->Headers); + if (this->MultiConfig) { std::map<std::string, std::string> settingsFiles; for (std::string const& cfg : this->ConfigsList) { settingsFiles[cfg] = AppendFilenameSuffix(this->AutogenSettingsFile, "_" + cfg); } - OfsWriteMap("AM_SETTINGS_FILE", settingsFiles); + CWriteMap("AM_SETTINGS_FILE", settingsFiles); + } else { + CWrite("AM_SETTINGS_FILE", this->AutogenSettingsFile); + } + + ofs << "# Qt\n"; + CWrite("AM_QT_VERSION_MAJOR", this->QtVersionMajor); + CWrite("AM_QT_MOC_EXECUTABLE", this->MocExecutable); + CWrite("AM_QT_UIC_EXECUTABLE", this->UicExecutable); + + if (this->MocEnabled) { + ofs << "# MOC settings\n"; + CWriteSet("AM_MOC_SKIP", this->MocSkip); + CWrite("AM_MOC_DEFINITIONS", this->MocDefines); + CWriteMap("AM_MOC_DEFINITIONS", this->MocDefinesConfig); + CWrite("AM_MOC_INCLUDES", this->MocIncludes); + CWriteMap("AM_MOC_INCLUDES", this->MocIncludesConfig); + CWrite("AM_MOC_OPTIONS", + GetSafeProperty(this->Target, "AUTOMOC_MOC_OPTIONS")); + CWrite("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE")); + CWrite("AM_MOC_MACRO_NAMES", + GetSafeProperty(this->Target, "AUTOMOC_MACRO_NAMES")); + CWrite("AM_MOC_DEPEND_FILTERS", + GetSafeProperty(this->Target, "AUTOMOC_DEPEND_FILTERS")); + CWrite("AM_MOC_PREDEFS_CMD", this->MocPredefsCmd); + } + + if (this->UicEnabled) { + ofs << "# UIC settings\n"; + CWriteSet("AM_UIC_SKIP", this->UicSkip); + CWrite("AM_UIC_TARGET_OPTIONS", this->UicOptions); + CWriteMap("AM_UIC_TARGET_OPTIONS", this->UicOptionsConfig); + CWriteList("AM_UIC_OPTIONS_FILES", this->UicFileFiles); + CWriteNestedLists("AM_UIC_OPTIONS_OPTIONS", this->UicFileOptions); + CWriteList("AM_UIC_SEARCH_PATHS", this->UicSearchPaths); } } } // Generate auto RCC info files if (this->RccEnabled) { - std::string infoFileIn = cmSystemTools::GetCMakeRoot(); - infoFileIn += "/Modules/AutoRccInfo.cmake.in"; for (Qrc const& qrc : this->Qrcs) { - // Configure info file - makefile->ConfigureFile(infoFileIn.c_str(), qrc.InfoFile.c_str(), false, - true, false); - - // Append custom definitions to info file - // -------------------------------------- cmsys::ofstream ofs; - if (ReOpenInfoFile(ofs, qrc.InfoFile)) { - { - ofs << "# Job\n"; - auto OfsWrite = [&ofs](const char* key, std::string const& value) { - ofs << "set(" << key << " " - << cmOutputConverter::EscapeForCMake(value) << ")\n"; - - }; - OfsWrite("ARCC_SETTINGS_FILE", qrc.SettingsFile); - OfsWrite("ARCC_SOURCE", qrc.QrcFile); - OfsWrite("ARCC_OUTPUT", qrc.RccFile); - OfsWrite("ARCC_OPTIONS", cmJoin(qrc.Options, ";")); - OfsWrite("ARCC_INPUTS", cmJoin(qrc.Resources, ";")); - } - { - ofs << "# Configurations options\n"; - auto OfsWriteMap = [&ofs]( - const char* key, std::map<std::string, std::string> const& map) { - for (auto const& item : map) { - ofs << "set(" << key << "_" << item.first << " " - << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; - } - }; - OfsWriteMap("ARCC_CONFIG_SUFFIX", configSuffixes); - - // Settings files (only require for multi configuration generators) - if (this->MultiConfig != MultiConfigT::SINGLE) { - std::map<std::string, std::string> settingsFiles; - for (std::string const& cfg : this->ConfigsList) { - settingsFiles[cfg] = - AppendFilenameSuffix(qrc.SettingsFile, "_" + cfg); - } - OfsWriteMap("ARCC_SETTINGS_FILE", settingsFiles); + if (OpenInfoFile(ofs, qrc.InfoFile)) { + // Utility lambdas + auto CWrite = [&ofs](const char* key, std::string const& value) { + ofs << "set(" << key << " " + << cmOutputConverter::EscapeForCMake(value) << ")\n"; + }; + auto CWriteMap = [&ofs]( + const char* key, std::map<std::string, std::string> const& map) { + for (auto const& item : map) { + ofs << "set(" << key << "_" << item.first << " " + << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; + } + }; + + // Write + ofs << "# Configurations\n"; + CWrite("ARCC_MULTI_CONFIG", this->MultiConfig ? "TRUE" : "FALSE"); + + ofs << "# Settings file\n"; + if (this->MultiConfig) { + std::map<std::string, std::string> settingsFiles; + for (std::string const& cfg : this->ConfigsList) { + settingsFiles[cfg] = + AppendFilenameSuffix(qrc.SettingsFile, "_" + cfg); } + CWriteMap("ARCC_SETTINGS_FILE", settingsFiles); + } else { + CWrite("ARCC_SETTINGS_FILE", qrc.SettingsFile); } + + ofs << "# Directories\n"; + CWrite("ARCC_BUILD_DIR", this->DirBuild); + if (this->MultiConfig) { + CWriteMap("ARCC_INCLUDE_DIR", includeDirs); + } else { + CWrite("ARCC_INCLUDE_DIR", includeDir); + } + + ofs << "# Rcc executable\n"; + CWrite("ARCC_RCC_EXECUTABLE", this->RccExecutable); + CWrite("ARCC_RCC_LIST_OPTIONS", cmJoin(this->RccListOptions, ";")); + + ofs << "# Rcc job\n"; + CWrite("ARCC_SOURCE", qrc.QrcFile); + CWrite("ARCC_OUTPUT_CHECKSUM", qrc.PathChecksum); + CWrite("ARCC_OUTPUT_NAME", + cmSystemTools::GetFilenameName(qrc.RccFile)); + CWrite("ARCC_OPTIONS", cmJoin(qrc.Options, ";")); + CWrite("ARCC_INPUTS", cmJoin(qrc.Resources, ";")); } else { break; } @@ -1078,25 +1080,13 @@ void cmQtAutoGenInitializer::SetupCustomTargetsMoc() cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); cmMakefile* makefile = this->Target->Target->GetMakefile(); - AddDefinitionEscaped(makefile, "_moc_skip", this->MocSkip); - AddDefinitionEscaped(makefile, "_moc_options", - GetSafeProperty(this->Target, "AUTOMOC_MOC_OPTIONS")); - AddDefinitionEscaped(makefile, "_moc_relaxed_mode", - makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE") ? "TRUE" - : "FALSE"); - AddDefinitionEscaped(makefile, "_moc_macro_names", - GetSafeProperty(this->Target, "AUTOMOC_MACRO_NAMES")); - AddDefinitionEscaped( - makefile, "_moc_depend_filters", - GetSafeProperty(this->Target, "AUTOMOC_DEPEND_FILTERS")); - - // Compiler predefines + // Moc predefs command if (this->Target->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") && this->QtVersionGreaterOrEqual(5, 8)) { - AddDefinitionEscaped( - makefile, "_moc_predefs_cmd", - makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND")); + this->MocPredefsCmd = + makefile->GetSafeDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"); } + // Moc includes and compile definitions { auto GetIncludeDirs = [this, @@ -1117,25 +1107,23 @@ void cmQtAutoGenInitializer::SetupCustomTargetsMoc() }; // Default configuration settings - std::string const includeDirs = GetIncludeDirs(this->ConfigDefault); - std::string const compileDefs = GetCompileDefinitions(this->ConfigDefault); + this->MocIncludes = GetIncludeDirs(this->ConfigDefault); + this->MocDefines = GetCompileDefinitions(this->ConfigDefault); // Other configuration settings for (std::string const& cfg : this->ConfigsList) { { std::string const configIncludeDirs = GetIncludeDirs(cfg); - if (configIncludeDirs != includeDirs) { - this->ConfigMocIncludes[cfg] = configIncludeDirs; + if (configIncludeDirs != this->MocIncludes) { + this->MocIncludesConfig[cfg] = configIncludeDirs; } } { std::string const configCompileDefs = GetCompileDefinitions(cfg); - if (configCompileDefs != compileDefs) { - this->ConfigMocDefines[cfg] = configCompileDefs; + if (configCompileDefs != this->MocDefines) { + this->MocDefinesConfig[cfg] = configCompileDefs; } } } - AddDefinitionEscaped(makefile, "_moc_include_dirs", includeDirs); - AddDefinitionEscaped(makefile, "_moc_compile_defs", compileDefs); } // Moc executable @@ -1162,7 +1150,7 @@ void cmQtAutoGenInitializer::SetupCustomTargetsMoc() } if (err.empty()) { - AddDefinitionEscaped(makefile, "_qt_moc_executable", mocExec); + this->MocExecutable = mocExec; } else { err += " ("; err += this->Target->GetName(); @@ -1178,19 +1166,15 @@ void cmQtAutoGenInitializer::SetupCustomTargetsUic() // Uic search paths { - std::vector<std::string> uicSearchPaths; - { - std::string const usp = - GetSafeProperty(this->Target, "AUTOUIC_SEARCH_PATHS"); - if (!usp.empty()) { - cmSystemTools::ExpandListArgument(usp, uicSearchPaths); - std::string const srcDir = makefile->GetCurrentSourceDirectory(); - for (std::string& path : uicSearchPaths) { - path = cmSystemTools::CollapseFullPath(path, srcDir); - } + std::string const usp = + GetSafeProperty(this->Target, "AUTOUIC_SEARCH_PATHS"); + if (!usp.empty()) { + cmSystemTools::ExpandListArgument(usp, this->UicSearchPaths); + std::string const srcDir = makefile->GetCurrentSourceDirectory(); + for (std::string& path : this->UicSearchPaths) { + path = cmSystemTools::CollapseFullPath(path, srcDir); } } - AddDefinitionEscaped(makefile, "_uic_search_paths", uicSearchPaths); } // Uic target options { @@ -1201,60 +1185,51 @@ void cmQtAutoGenInitializer::SetupCustomTargetsUic() }; // Default settings - std::string const uicOpts = UicGetOpts(this->ConfigDefault); - AddDefinitionEscaped(makefile, "_uic_target_options", uicOpts); + this->UicOptions = UicGetOpts(this->ConfigDefault); // Configuration specific settings for (std::string const& cfg : this->ConfigsList) { std::string const configUicOpts = UicGetOpts(cfg); - if (configUicOpts != uicOpts) { - this->ConfigUicOptions[cfg] = configUicOpts; + if (configUicOpts != this->UicOptions) { + this->UicOptionsConfig[cfg] = configUicOpts; } } } // .ui files skip and options { - std::vector<std::string> uiFileFiles; - std::vector<std::vector<std::string>> uiFileOptions; - { - std::string const uiExt = "ui"; - std::string pathError; - for (cmSourceFile* sf : makefile->GetSourceFiles()) { - // sf->GetExtension() is only valid after sf->GetFullPath() ... - // Since we're iterating over source files that might be not in the - // target we need to check for path errors (not existing files). - std::string const& fPath = sf->GetFullPath(&pathError); - if (!pathError.empty()) { - pathError.clear(); - continue; + std::string const uiExt = "ui"; + std::string pathError; + for (cmSourceFile* sf : makefile->GetSourceFiles()) { + // sf->GetExtension() is only valid after sf->GetFullPath() ... + // Since we're iterating over source files that might be not in the + // target we need to check for path errors (not existing files). + std::string const& fPath = sf->GetFullPath(&pathError); + if (!pathError.empty()) { + pathError.clear(); + continue; + } + if (sf->GetExtension() == uiExt) { + std::string const absFile = cmSystemTools::GetRealPath(fPath); + // Check if the .ui file should be skipped + if (sf->GetPropertyAsBool("SKIP_AUTOUIC") || + sf->GetPropertyAsBool("SKIP_AUTOGEN")) { + this->UicSkip.insert(absFile); } - if (sf->GetExtension() == uiExt) { - std::string const absFile = cmSystemTools::GetRealPath(fPath); - // Check if the .ui file should be skipped - if (sf->GetPropertyAsBool("SKIP_AUTOUIC") || - sf->GetPropertyAsBool("SKIP_AUTOGEN")) { - this->UicSkip.insert(absFile); - } - // Check if the .ui file has uic options - std::string const uicOpts = GetSafeProperty(sf, "AUTOUIC_OPTIONS"); - if (!uicOpts.empty()) { - // Check if file isn't skipped - if (this->UicSkip.count(absFile) == 0) { - uiFileFiles.push_back(absFile); - std::vector<std::string> optsVec; - cmSystemTools::ExpandListArgument(uicOpts, optsVec); - uiFileOptions.push_back(std::move(optsVec)); - } + // Check if the .ui file has uic options + std::string const uicOpts = GetSafeProperty(sf, "AUTOUIC_OPTIONS"); + if (!uicOpts.empty()) { + // Check if file isn't skipped + if (this->UicSkip.count(absFile) == 0) { + this->UicFileFiles.push_back(absFile); + std::vector<std::string> optsVec; + cmSystemTools::ExpandListArgument(uicOpts, optsVec); + this->UicFileOptions.push_back(std::move(optsVec)); } } } } - AddDefinitionEscaped(makefile, "_qt_uic_options_files", uiFileFiles); - AddDefinitionEscaped(makefile, "_qt_uic_options_options", uiFileOptions); } - AddDefinitionEscaped(makefile, "_uic_skip", this->UicSkip); - // Uic executable { std::string err; @@ -1280,7 +1255,7 @@ void cmQtAutoGenInitializer::SetupCustomTargetsUic() } if (err.empty()) { - AddDefinitionEscaped(makefile, "_qt_uic_executable", uicExec); + this->UicExecutable = uicExec; } else { err += " ("; err += this->Target->GetName(); @@ -1290,45 +1265,22 @@ void cmQtAutoGenInitializer::SetupCustomTargetsUic() } } -std::vector<std::string> cmQtAutoGenInitializer::AddGeneratedSource( - std::string const& filename, GeneratorT genType) +void cmQtAutoGenInitializer::AddGeneratedSource(std::string const& filename, + GeneratorT genType) { - std::vector<std::string> genFiles; - // Register source file in makefile and source group - if (this->MultiConfig != MultiConfigT::MULTI) { - genFiles.push_back(filename); - } else { - for (std::string const& cfg : this->ConfigsList) { - genFiles.push_back(AppendFilenameSuffix(filename, "_" + cfg)); - } - } + // Register source file in makefile + cmMakefile* makefile = this->Target->Target->GetMakefile(); { - cmMakefile* makefile = this->Target->Target->GetMakefile(); - for (std::string const& genFile : genFiles) { - { - cmSourceFile* gFile = makefile->GetOrCreateSource(genFile, true); - gFile->SetProperty("GENERATED", "1"); - gFile->SetProperty("SKIP_AUTOGEN", "On"); - } - AddToSourceGroup(makefile, genFile, genType); - } + cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true); + gFile->SetProperty("GENERATED", "1"); + gFile->SetProperty("SKIP_AUTOGEN", "On"); } - // Add source file to target - if (this->MultiConfig != MultiConfigT::MULTI) { - this->Target->AddSource(filename); - } else { - for (std::string const& cfg : this->ConfigsList) { - std::string src = "$<$<CONFIG:"; - src += cfg; - src += ">:"; - src += AppendFilenameSuffix(filename, "_" + cfg); - src += ">"; - this->Target->AddSource(src); - } - } + // Add source file to source group + AddToSourceGroup(makefile, filename, genType); - return genFiles; + // Add source file to target + this->Target->AddSource(filename); } std::string cmQtAutoGenInitializer::GetQtMajorVersion( @@ -1400,7 +1352,8 @@ bool cmQtAutoGenInitializer::RccListInputs(std::string const& fileName, return false; } - // Run rcc list command in the directory of the qrc file with the pathless + // Run rcc list command in the directory of the qrc file with the + // pathless // qrc file name argument. This way rcc prints relative paths. // This avoids issues on Windows when the qrc file is in a path that // contains non-ASCII characters. diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index a667017..2a47e46 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -21,6 +21,7 @@ public: static std::string GetQtMinorVersion(cmGeneratorTarget const* target, std::string const& qtVersionMajor); + /// @brief Rcc job information class Qrc { public: @@ -55,8 +56,7 @@ private: void SetupCustomTargetsMoc(); void SetupCustomTargetsUic(); - std::vector<std::string> AddGeneratedSource(std::string const& filename, - GeneratorT genType); + void AddGeneratedSource(std::string const& filename, GeneratorT genType); bool QtVersionGreaterOrEqual(unsigned long requestMajor, unsigned long requestMinor) const; @@ -70,15 +70,18 @@ private: bool MocEnabled; bool UicEnabled; bool RccEnabled; + bool MultiConfig; // Qt std::string QtVersionMajor; std::string QtVersionMinor; + std::string MocExecutable; + std::string UicExecutable; std::string RccExecutable; std::vector<std::string> RccListOptions; // Configurations std::string ConfigDefault; std::vector<std::string> ConfigsList; - MultiConfigT MultiConfig; + std::string Parallel; // Names std::string AutogenTargetName; std::string AutogenFolder; @@ -91,11 +94,21 @@ private: // Sources std::vector<std::string> Headers; std::vector<std::string> Sources; + // Moc + std::string MocPredefsCmd; std::set<std::string> MocSkip; + std::string MocIncludes; + std::map<std::string, std::string> MocIncludesConfig; + std::string MocDefines; + std::map<std::string, std::string> MocDefinesConfig; + // Uic std::set<std::string> UicSkip; - std::map<std::string, std::string> ConfigMocIncludes; - std::map<std::string, std::string> ConfigMocDefines; - std::map<std::string, std::string> ConfigUicOptions; + std::vector<std::string> UicSearchPaths; + std::string UicOptions; + std::map<std::string, std::string> UicOptionsConfig; + std::vector<std::string> UicFileFiles; + std::vector<std::vector<std::string>> UicFileOptions; + // Rcc std::vector<Qrc> Qrcs; }; diff --git a/Source/cmQtAutoGeneratorMocUic.cxx b/Source/cmQtAutoGeneratorMocUic.cxx index 037279a..6be65ee 100644 --- a/Source/cmQtAutoGeneratorMocUic.cxx +++ b/Source/cmQtAutoGeneratorMocUic.cxx @@ -672,19 +672,24 @@ void cmQtAutoGeneratorMocUic::JobMocT::Process(WorkerT& wrk) { // Compute build file name if (!IncludeString.empty()) { - BuildFile = wrk.Base().AutogenIncludeDirAbs; + BuildFile = wrk.Base().AutogenIncludeDir; + BuildFile += '/'; BuildFile += IncludeString; } else { - std::string buildRel = wrk.Base().FilePathChecksum.getPart(SourceFile); - buildRel += '/'; - buildRel += "moc_"; - buildRel += cmSystemTools::GetFilenameWithoutLastExtension(SourceFile); - if (wrk.Base().MultiConfig != MultiConfigT::SINGLE) { - buildRel += wrk.Base().ConfigSuffix; + std::string rel = wrk.Base().FilePathChecksum.getPart(SourceFile); + rel += "/moc_"; + rel += cmSystemTools::GetFilenameWithoutLastExtension(SourceFile); + rel += ".cpp"; + // Register relative file path + wrk.Gen().ParallelMocAutoRegister(rel); + // Absolute build path + if (wrk.Base().MultiConfig) { + BuildFile = wrk.Base().AutogenIncludeDir; + BuildFile += '/'; + BuildFile += rel; + } else { + BuildFile = wrk.Base().AbsoluteBuildPath(rel); } - buildRel += ".cpp"; - wrk.Gen().ParallelMocAutoRegister(buildRel); - BuildFile = wrk.Base().AbsoluteBuildPath(buildRel); } if (UpdateRequired(wrk)) { @@ -871,7 +876,8 @@ void cmQtAutoGeneratorMocUic::JobMocT::GenerateMoc(WorkerT& wrk) void cmQtAutoGeneratorMocUic::JobUicT::Process(WorkerT& wrk) { // Compute build file name - BuildFile = wrk.Base().AutogenIncludeDirAbs; + BuildFile = wrk.Base().AutogenIncludeDir; + BuildFile += '/'; BuildFile += IncludeString; if (UpdateRequired(wrk)) { @@ -1208,20 +1214,7 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile) } // -- Meta - Base_.MultiConfig = MultiConfigType(InfoGet("AM_MULTI_CONFIG")); - - Base_.ConfigSuffix = InfoGetConfig("AM_CONFIG_SUFFIX"); - if (Base_.ConfigSuffix.empty()) { - Base_.ConfigSuffix = "_"; - Base_.ConfigSuffix += InfoConfig(); - } - - SettingsFile_ = InfoGetConfig("AM_SETTINGS_FILE"); - if (SettingsFile_.empty()) { - Log().ErrorFile(GeneratorT::GEN, InfoFile(), "Settings file name missing"); - return false; - } - + Base_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG"); { unsigned long num = Base_.NumThreads; if (cmSystemTools::StringToULong(InfoGet("AM_PARALLEL"), &num)) { @@ -1244,6 +1237,23 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile) "Autogen build directory missing"); return false; } + // include directory + { + std::string dirRel = InfoGetConfig("AM_INCLUDE_DIR"); + if (dirRel.empty()) { + Log().ErrorFile(GeneratorT::GEN, InfoFile(), + "Autogen include directory missing"); + return false; + } + Base_.AutogenIncludeDir = Base_.AbsoluteBuildPath(dirRel); + } + + // - Files + SettingsFile_ = InfoGetConfig("AM_SETTINGS_FILE"); + if (SettingsFile_.empty()) { + Log().ErrorFile(GeneratorT::GEN, InfoFile(), "Settings file name missing"); + return false; + } // - Qt environment { @@ -1438,30 +1448,17 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile) Base().CurrentSourceDir, Base().CurrentBinaryDir, Base().ProjectSourceDir, Base().ProjectBinaryDir); - // include directory - Base_.AutogenIncludeDirRel = "include"; - if (Base().MultiConfig != MultiConfigT::SINGLE) { - Base_.AutogenIncludeDirRel += Base().ConfigSuffix; - } - Base_.AutogenIncludeDirRel += "/"; - Base_.AutogenIncludeDirAbs = - Base_.AbsoluteBuildPath(Base().AutogenIncludeDirRel); - // Moc variables if (Moc().Enabled) { // Mocs compilation file - Moc_.CompFileRel = "mocs_compilation"; - if (Base_.MultiConfig == MultiConfigT::MULTI) { - Moc_.CompFileRel += Base().ConfigSuffix; - } - Moc_.CompFileRel += ".cpp"; - Moc_.CompFileAbs = Base_.AbsoluteBuildPath(Moc().CompFileRel); + Moc_.CompFileAbs = Base().AbsoluteBuildPath("mocs_compilation.cpp"); // Moc predefs file if (!Moc_.PredefsCmd.empty()) { Moc_.PredefsFileRel = "moc_predefs"; - if (Base_.MultiConfig != MultiConfigT::SINGLE) { - Moc_.PredefsFileRel += Base().ConfigSuffix; + if (Base_.MultiConfig) { + Moc_.PredefsFileRel += '_'; + Moc_.PredefsFileRel += InfoConfig(); } Moc_.PredefsFileRel += ".h"; Moc_.PredefsFileAbs = Base_.AbsoluteBuildPath(Moc().PredefsFileRel); @@ -1731,7 +1728,7 @@ void cmQtAutoGeneratorMocUic::SettingsFileWrite() void cmQtAutoGeneratorMocUic::CreateDirectories() { // Create AUTOGEN include directory - if (!FileSys().MakeDirectory(GeneratorT::GEN, Base().AutogenIncludeDirAbs)) { + if (!FileSys().MakeDirectory(GeneratorT::GEN, Base().AutogenIncludeDir)) { RegisterJobError(); } } @@ -1980,9 +1977,10 @@ void cmQtAutoGeneratorMocUic::ParallelMocAutoUpdated() void cmQtAutoGeneratorMocUic::MocGenerateCompilation() { std::lock_guard<std::mutex> mocLock(JobsMutex_); - if (!JobThreadsAbort_ && Moc().Enabled) { - // Compose mocs compilation file content + if (!JobError_ && Moc().Enabled) { + // Write mocs compilation build file { + // Compose mocs compilation file content std::string content = "// This file is autogenerated. Changes will be overwritten.\n"; if (MocAutoFiles_.empty()) { @@ -1992,19 +1990,22 @@ void cmQtAutoGeneratorMocUic::MocGenerateCompilation() content += "enum some_compilers { need_more_than_nothing };\n"; } else { // Valid content + char const sbeg = Base().MultiConfig ? '<' : '"'; + char const send = Base().MultiConfig ? '>' : '"'; for (std::string const& mocfile : MocAutoFiles_) { - content += "#include \""; + content += "#include "; + content += sbeg; content += mocfile; - content += "\"\n"; + content += send; + content += '\n'; } } - std::string const& compRel = Moc().CompFileRel; std::string const& compAbs = Moc().CompFileAbs; if (FileSys().FileDiffers(compAbs, content)) { // Actually write mocs compilation file if (Log().Verbose()) { - Log().Info(GeneratorT::MOC, "Generating MOC compilation " + compRel); + Log().Info(GeneratorT::MOC, "Generating MOC compilation " + compAbs); } if (!FileSys().FileWrite(GeneratorT::MOC, compAbs, content)) { Log().ErrorFile(GeneratorT::MOC, compAbs, @@ -2015,10 +2016,13 @@ void cmQtAutoGeneratorMocUic::MocGenerateCompilation() } else if (MocAutoFileUpdated_) { // Only touch mocs compilation file if (Log().Verbose()) { - Log().Info(GeneratorT::MOC, "Touching mocs compilation " + compRel); + Log().Info(GeneratorT::MOC, "Touching mocs compilation " + compAbs); } FileSys().Touch(compAbs); } } + // Write mocs compilation wrapper file + if (Base().MultiConfig) { + } } } diff --git a/Source/cmQtAutoGeneratorMocUic.h b/Source/cmQtAutoGeneratorMocUic.h index 215e25a..696d5bd 100644 --- a/Source/cmQtAutoGeneratorMocUic.h +++ b/Source/cmQtAutoGeneratorMocUic.h @@ -68,7 +68,7 @@ public: public: // -- Volatile methods BaseSettingsT(FileSystem* fileSystem) - : MultiConfig(MultiConfigT::WRAPPER) + : MultiConfig(false) , IncludeProjectDirsBefore(false) , QtVersionMajor(4) , NumThreads(1) @@ -83,8 +83,7 @@ public: // -- Attributes // - Config - std::string ConfigSuffix; - MultiConfigT MultiConfig; + bool MultiConfig; bool IncludeProjectDirsBefore; unsigned int QtVersionMajor; unsigned int NumThreads; @@ -94,8 +93,7 @@ public: std::string CurrentSourceDir; std::string CurrentBinaryDir; std::string AutogenBuildDir; - std::string AutogenIncludeDirRel; - std::string AutogenIncludeDirAbs; + std::string AutogenIncludeDir; // - Files cmFilePathChecksum FilePathChecksum; std::vector<std::string> HeaderExtensions; @@ -128,7 +126,6 @@ public: bool SettingsChanged = false; bool RelaxedMode = false; std::string Executable; - std::string CompFileRel; std::string CompFileAbs; std::string PredefsFileRel; std::string PredefsFileAbs; diff --git a/Source/cmQtAutoGeneratorRcc.cxx b/Source/cmQtAutoGeneratorRcc.cxx index e8ff75a..2bf00f7 100644 --- a/Source/cmQtAutoGeneratorRcc.cxx +++ b/Source/cmQtAutoGeneratorRcc.cxx @@ -14,8 +14,8 @@ // -- Class methods cmQtAutoGeneratorRcc::cmQtAutoGeneratorRcc() - : SettingsChanged_(false) - , MultiConfig_(MultiConfigT::WRAPPER) + : MultiConfig_(false) + , SettingsChanged_(false) , Stage_(StageT::SETTINGS_READ) , Error_(false) , Generate_(false) @@ -31,16 +31,18 @@ cmQtAutoGeneratorRcc::~cmQtAutoGeneratorRcc() bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) { - // Utility lambdas - auto InfoGet = [makefile](const char* key) { + // -- Utility lambdas + auto InfoGet = [makefile](std::string const& key) { return makefile->GetSafeDefinition(key); }; - auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> { + auto InfoGetList = + [makefile](std::string const& key) -> std::vector<std::string> { std::vector<std::string> list; cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list); return list; }; - auto InfoGetConfig = [makefile, this](const char* key) -> std::string { + auto InfoGetConfig = [makefile, + this](std::string const& key) -> std::string { const char* valueConf = nullptr; { std::string keyConf = key; @@ -54,7 +56,7 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) return std::string(valueConf); }; auto InfoGetConfigList = - [&InfoGetConfig](const char* key) -> std::vector<std::string> { + [&InfoGetConfig](std::string const& key) -> std::vector<std::string> { std::vector<std::string> list; cmSystemTools::ExpandListArgument(InfoGetConfig(key), list); return list; @@ -66,20 +68,23 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) return false; } - // -- Meta - MultiConfig_ = MultiConfigType(InfoGet("ARCC_MULTI_CONFIG")); - ConfigSuffix_ = InfoGetConfig("ARCC_CONFIG_SUFFIX"); - if (ConfigSuffix_.empty()) { - ConfigSuffix_ = "_"; - ConfigSuffix_ += InfoConfig(); - } - - SettingsFile_ = InfoGetConfig("ARCC_SETTINGS_FILE"); + // - Configurations + MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG"); - // - Files and directories + // - Directories AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR"); + if (AutogenBuildDir_.empty()) { + Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Build directory empty"); + return false; + } - // - Qt environment + IncludeDir_ = InfoGetConfig("ARCC_INCLUDE_DIR"); + if (IncludeDir_.empty()) { + Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Include directory empty"); + return false; + } + + // - Rcc executable RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE"); RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS"); @@ -87,10 +92,14 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) QrcFile_ = InfoGet("ARCC_SOURCE"); QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_); QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_); - RccFile_ = InfoGet("ARCC_OUTPUT"); + RccPathChecksum_ = InfoGet("ARCC_OUTPUT_CHECKSUM"); + RccFileName_ = InfoGet("ARCC_OUTPUT_NAME"); Options_ = InfoGetConfigList("ARCC_OPTIONS"); Inputs_ = InfoGetList("ARCC_INPUTS"); + // - Settings file + SettingsFile_ = InfoGetConfig("ARCC_SETTINGS_FILE"); + // - Validity checks if (SettingsFile_.empty()) { Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Settings file name missing"); @@ -109,7 +118,7 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) Log().ErrorFile(GeneratorT::RCC, InfoFile(), "rcc input file missing"); return false; } - if (RccFile_.empty()) { + if (RccFileName_.empty()) { Log().ErrorFile(GeneratorT::RCC, InfoFile(), "rcc output file missing"); return false; } @@ -117,22 +126,21 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) // Init derived information // ------------------------ + RccFilePublic_ = AutogenBuildDir_; + RccFilePublic_ += '/'; + RccFilePublic_ += RccPathChecksum_; + RccFilePublic_ += '/'; + RccFilePublic_ += RccFileName_; + // Compute rcc output file name - { - std::string suffix; - switch (MultiConfig_) { - case MultiConfigT::SINGLE: - break; - case MultiConfigT::WRAPPER: - suffix = "_CMAKE"; - suffix += ConfigSuffix_; - suffix += "_"; - break; - case MultiConfigT::MULTI: - suffix = ConfigSuffix_; - break; - } - RccFileBuild_ = AppendFilenameSuffix(RccFile_, suffix); + if (IsMultiConfig()) { + RccFileOutput_ = AutogenBuildDir_; + RccFileOutput_ += '/'; + RccFileOutput_ += IncludeDir_; + RccFileOutput_ += '/'; + RccFileOutput_ += MultiConfigOutput(); + } else { + RccFileOutput_ = RccFilePublic_; } return true; @@ -234,6 +242,16 @@ void cmQtAutoGeneratorRcc::SetStage(StageT stage) } } +std::string cmQtAutoGeneratorRcc::MultiConfigOutput() const +{ + static std::string const suffix = "_CMAKE_"; + std::string res; + res += RccPathChecksum_; + res += '/'; + res += AppendFilenameSuffix(RccFileName_, suffix); + return res; +} + void cmQtAutoGeneratorRcc::SettingsFileRead() { // Compose current settings strings @@ -248,7 +266,9 @@ void cmQtAutoGeneratorRcc::SettingsFileRead() str += sep; str += QrcFile_; str += sep; - str += RccFile_; + str += RccPathChecksum_; + str += sep; + str += RccFileName_; str += sep; str += cmJoin(Options_, ";"); str += sep; @@ -302,10 +322,10 @@ bool cmQtAutoGeneratorRcc::TestQrcRccFiles() // Do basic checks if rcc generation is required // Test if the rcc output file exists - if (!FileSys().FileExists(RccFileBuild_)) { + if (!FileSys().FileExists(RccFileOutput_)) { if (Log().Verbose()) { std::string reason = "Generating "; - reason += Quoted(RccFileBuild_); + reason += Quoted(RccFileOutput_); reason += " from its source file "; reason += Quoted(QrcFile_); reason += " because it doesn't exist"; @@ -319,7 +339,7 @@ bool cmQtAutoGeneratorRcc::TestQrcRccFiles() if (SettingsChanged_) { if (Log().Verbose()) { std::string reason = "Generating "; - reason += Quoted(RccFileBuild_); + reason += Quoted(RccFileOutput_); reason += " from "; reason += Quoted(QrcFile_); reason += " because the RCC settings changed"; @@ -334,7 +354,7 @@ bool cmQtAutoGeneratorRcc::TestQrcRccFiles() bool isOlder = false; { std::string error; - isOlder = FileSys().FileIsOlderThan(RccFileBuild_, QrcFile_, &error); + isOlder = FileSys().FileIsOlderThan(RccFileOutput_, QrcFile_, &error); if (!error.empty()) { Log().ErrorFile(GeneratorT::RCC, QrcFile_, error); Error_ = true; @@ -343,7 +363,7 @@ bool cmQtAutoGeneratorRcc::TestQrcRccFiles() if (isOlder) { if (Log().Verbose()) { std::string reason = "Generating "; - reason += Quoted(RccFileBuild_); + reason += Quoted(RccFileOutput_); reason += " because it is older than "; reason += Quoted(QrcFile_); Log().Info(GeneratorT::RCC, reason); @@ -437,10 +457,10 @@ bool cmQtAutoGeneratorRcc::TestResources() break; } // Check if the resource file is newer than the build file - if (FileSys().FileIsOlderThan(RccFileBuild_, resFile, &error)) { + if (FileSys().FileIsOlderThan(RccFileOutput_, resFile, &error)) { if (Log().Verbose()) { std::string reason = "Generating "; - reason += Quoted(RccFileBuild_); + reason += Quoted(RccFileOutput_); reason += " from "; reason += Quoted(QrcFile_); reason += " because it is older than "; @@ -469,7 +489,7 @@ void cmQtAutoGeneratorRcc::TestInfoFile() bool isOlder = false; { std::string error; - isOlder = FileSys().FileIsOlderThan(RccFileBuild_, InfoFile(), &error); + isOlder = FileSys().FileIsOlderThan(RccFileOutput_, InfoFile(), &error); if (!error.empty()) { Log().ErrorFile(GeneratorT::RCC, QrcFile_, error); Error_ = true; @@ -478,13 +498,13 @@ void cmQtAutoGeneratorRcc::TestInfoFile() if (isOlder) { if (Log().Verbose()) { std::string reason = "Touching "; - reason += Quoted(RccFileBuild_); + reason += Quoted(RccFileOutput_); reason += " because it is older than "; reason += Quoted(InfoFile()); Log().Info(GeneratorT::RCC, reason); } // Touch build file - FileSys().Touch(RccFileBuild_); + FileSys().Touch(RccFileOutput_); BuildFileChanged_ = true; } } @@ -493,7 +513,7 @@ void cmQtAutoGeneratorRcc::TestInfoFile() void cmQtAutoGeneratorRcc::GenerateParentDir() { // Make sure the parent directory exists - if (!FileSys().MakeParentDirectory(GeneratorT::RCC, RccFileBuild_)) { + if (!FileSys().MakeParentDirectory(GeneratorT::RCC, RccFileOutput_)) { Error_ = true; } } @@ -521,7 +541,7 @@ bool cmQtAutoGeneratorRcc::GenerateRcc() std::string emsg = "The rcc process failed to compile\n "; emsg += Quoted(QrcFile_); emsg += "\ninto\n "; - emsg += Quoted(RccFileBuild_); + emsg += Quoted(RccFileOutput_); if (ProcessResult_.error()) { emsg += "\n"; emsg += ProcessResult_.ErrorMessage; @@ -529,7 +549,7 @@ bool cmQtAutoGeneratorRcc::GenerateRcc() Log().ErrorCommand(GeneratorT::RCC, emsg, Process_->Setup().Command, ProcessResult_.StdOut); } - FileSys().FileRemove(RccFileBuild_); + FileSys().FileRemove(RccFileOutput_); Error_ = true; } // Clean up @@ -545,7 +565,7 @@ bool cmQtAutoGeneratorRcc::GenerateRcc() cmd.push_back(RccExecutable_); cmd.insert(cmd.end(), Options_.begin(), Options_.end()); cmd.push_back("-o"); - cmd.push_back(RccFileBuild_); + cmd.push_back(RccFileOutput_); cmd.push_back(QrcFile_); // We're done here if the process fails to start return !StartProcess(AutogenBuildDir_, cmd, true); @@ -557,32 +577,34 @@ bool cmQtAutoGeneratorRcc::GenerateRcc() void cmQtAutoGeneratorRcc::GenerateWrapper() { // Generate a wrapper source file on demand - if (MultiConfig_ == MultiConfigT::WRAPPER) { - // Wrapper file name - std::string const& wrapperAbs = RccFile_; + if (IsMultiConfig()) { // Wrapper file content - std::string content = "// This is an autogenerated configuration " - "wrapper file. Changes will be overwritten.\n" - "#include \""; - content += cmSystemTools::GetFilenameName(RccFileBuild_); - content += "\"\n"; + std::string content; + content += "// This is an autogenerated configuration wrapper file.\n"; + content += "// Changes will be overwritten.\n"; + content += "#include <"; + content += MultiConfigOutput(); + content += ">\n"; + // Write content to file - if (FileSys().FileDiffers(wrapperAbs, content)) { + if (FileSys().FileDiffers(RccFilePublic_, content)) { // Write new wrapper file if (Log().Verbose()) { - Log().Info(GeneratorT::RCC, "Generating RCC wrapper " + wrapperAbs); + Log().Info(GeneratorT::RCC, + "Generating RCC wrapper file " + RccFilePublic_); } - if (!FileSys().FileWrite(GeneratorT::RCC, wrapperAbs, content)) { - Log().ErrorFile(GeneratorT::RCC, wrapperAbs, + if (!FileSys().FileWrite(GeneratorT::RCC, RccFilePublic_, content)) { + Log().ErrorFile(GeneratorT::RCC, RccFilePublic_, "RCC wrapper file writing failed"); Error_ = true; } } else if (BuildFileChanged_) { // Just touch the wrapper file if (Log().Verbose()) { - Log().Info(GeneratorT::RCC, "Touching RCC wrapper " + wrapperAbs); + Log().Info(GeneratorT::RCC, + "Touching RCC wrapper file " + RccFilePublic_); } - FileSys().Touch(wrapperAbs); + FileSys().Touch(RccFilePublic_); } } } diff --git a/Source/cmQtAutoGeneratorRcc.h b/Source/cmQtAutoGeneratorRcc.h index 8a69c6c..55e0998 100644 --- a/Source/cmQtAutoGeneratorRcc.h +++ b/Source/cmQtAutoGeneratorRcc.h @@ -5,7 +5,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmQtAutoGen.h" #include "cmQtAutoGenerator.h" #include "cm_uv.h" @@ -26,7 +25,7 @@ private: // -- Types /// @brief Processing stage - enum class StageT + enum class StageT : unsigned char { SETTINGS_READ, TEST_QRC_RCC_FILES, @@ -62,17 +61,18 @@ private: void GenerateWrapper(); // -- Utility + bool IsMultiConfig() const { return MultiConfig_; } + std::string MultiConfigOutput() const; bool StartProcess(std::string const& workingDirectory, std::vector<std::string> const& command, bool mergedOutput); private: // -- Config settings - bool SettingsChanged_; - std::string ConfigSuffix_; - MultiConfigT MultiConfig_; + bool MultiConfig_; // -- Directories std::string AutogenBuildDir_; + std::string IncludeDir_; // -- Qt environment std::string RccExecutable_; std::vector<std::string> RccListOptions_; @@ -80,9 +80,10 @@ private: std::string QrcFile_; std::string QrcFileName_; std::string QrcFileDir_; - std::string RccFile_; - std::string RccFileWrapper_; - std::string RccFileBuild_; + std::string RccPathChecksum_; + std::string RccFileName_; + std::string RccFileOutput_; + std::string RccFilePublic_; std::vector<std::string> Options_; std::vector<std::string> Inputs_; // -- Subprocess @@ -91,6 +92,7 @@ private: // -- Settings file std::string SettingsFile_; std::string SettingsString_; + bool SettingsChanged_; // -- libuv loop StageT Stage_; bool Error_; |