diff options
author | Brad King <brad.king@kitware.com> | 2017-08-07 14:34:45 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2017-08-07 14:34:48 (GMT) |
commit | 3a0ef7ac1a50383331f92a19926682d5c1f2682a (patch) | |
tree | 5665133e96c4ac72bd51d13c4a9257abc9cbeee1 | |
parent | 1f20aff2a69160c36002781ed91b6998fc4587ac (diff) | |
parent | 5150c3527df55f84e896177f6bbec0315d6c1349 (diff) | |
download | CMake-3a0ef7ac1a50383331f92a19926682d5c1f2682a.zip CMake-3a0ef7ac1a50383331f92a19926682d5c1f2682a.tar.gz CMake-3a0ef7ac1a50383331f92a19926682d5c1f2682a.tar.bz2 |
Merge topic 'autogen-configs'
5150c352 Autogen: Add release notes for per-config include dir
ccc98b5c Autogen: Update documentation for per-config include dir
a13716a5 Autogen: Enable per-config support
6d83757f Autogen: Generate rcc wrapper file on demand
74a1b8eb Autogen: Fix configuration suffix initialization
ddd6f0db Autogen: Add per-config suffix to moc_predefs.h
e2c9cf12 Autogen: Remove per-config suffix for mocs_compilations.cpp
3a4840e0 Autogen: Make test per-config include directory compatible
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1107
-rw-r--r-- | Help/manual/cmake-qt.7.rst | 6 | ||||
-rw-r--r-- | Help/prop_tgt/AUTOMOC.rst | 3 | ||||
-rw-r--r-- | Help/prop_tgt/AUTOUIC.rst | 3 | ||||
-rw-r--r-- | Help/release/dev/autogen-configs.rst | 8 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 79 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 54 | ||||
-rw-r--r-- | Tests/QtAutoUicInterface/CMakeLists.txt | 5 | ||||
-rw-r--r-- | Tests/QtAutogen/mocInclude/shared.cmake | 6 |
8 files changed, 91 insertions, 73 deletions
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index 00d6e6e..b3b09d1 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -72,6 +72,9 @@ Included ``moc_*.cpp`` and ``*.moc`` files will be generated in the automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. (This differs from CMake 3.7 and below; see their documentation for details.) +* For multi configuration generators, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. Not included ``moc_<basename>.cpp`` files will be generated in custom @@ -117,6 +120,9 @@ The generated generated ``ui_*.h`` files are placed in the automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. (This differs from CMake 3.7 and below; see their documentation for details.) +* For multi configuration generators, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. The :prop_tgt:`AUTOUIC` target property may be pre-set for all following diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 0171d20..e70fe0d 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -20,6 +20,9 @@ source files at build time and invoke moc accordingly. This allows the compiler to find the included ``moc_<basename>.cpp`` file regardless of the location the original source. + * For multi configuration generators, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. * If an ``#include`` statement like ``#include "<basename>.moc"`` is found, diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 6493bbc..2fc2167 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -17,6 +17,9 @@ optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target. ``<AUTOGEN_BUILD_DIR>/include``, which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. +* For multi configuration generators, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. This property is initialized by the value of the :variable:`CMAKE_AUTOUIC` diff --git a/Help/release/dev/autogen-configs.rst b/Help/release/dev/autogen-configs.rst new file mode 100644 index 0000000..7613c68 --- /dev/null +++ b/Help/release/dev/autogen-configs.rst @@ -0,0 +1,8 @@ +autogen-configs +--------------- + +* When using :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` with a + multi configuration generator (e.g. :generator:`Xcode`), + included ``*.moc``, ``moc_*.cpp`` and ``ui_*.h`` files are generated in + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>`` instead of + ``<AUTOGEN_BUILD_DIR>/include``. diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 108241a..5a06730 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -158,16 +158,6 @@ static void GetCompileDefinitionsAndDirectories( static bool IsMultiConfig(cmGlobalGenerator* globalGen) { - // FIXME: Xcode does not support per-config sources, yet. - // (EXCLUDED_SOURCE_FILE_NAMES) - // Treat it as a single configuration generator meanwhile. - if (globalGen->GetName().find("Xcode") != std::string::npos) { - return false; - } - // FIXME: Visual Studio does not fully support per-config sources yet. - if (globalGen->GetName().find("Visual Studio") != std::string::npos) { - return false; - } return globalGen->IsMultiConfig(); } @@ -707,24 +697,11 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenSources( { if (target->GetPropertyAsBool("AUTOMOC")) { cmMakefile* makefile = target->Target->GetMakefile(); - const std::vector<std::string> suffixes = - GetConfigurationSuffixes(makefile); - // Get build directory - const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); - // Register all compilation files as generated - for (std::vector<std::string>::const_iterator it = suffixes.begin(); - it != suffixes.end(); ++it) { - std::string mcFile = autogenBuildDir + "/mocs_compilation"; - mcFile += *it; - mcFile += ".cpp"; - AddGeneratedSource(makefile, mcFile, cmQtAutoGeneratorCommon::MOC); - } // Mocs compilation file - if (IsMultiConfig(target->GetGlobalGenerator())) { - target->AddSource(autogenBuildDir + "/mocs_compilation_$<CONFIG>.cpp"); - } else { - target->AddSource(autogenBuildDir + "/mocs_compilation.cpp"); - } + const std::string mocsComp = + GetAutogenTargetBuildDir(target) + "/mocs_compilation.cpp"; + AddGeneratedSource(makefile, mocsComp, cmQtAutoGeneratorCommon::MOC); + target->AddSource(mocsComp); } } @@ -803,24 +780,17 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Add moc compilation to generated files list if (mocEnabled) { - for (std::vector<std::string>::const_iterator it = suffixes.begin(); - it != suffixes.end(); ++it) { - std::string mcFile = autogenBuildDir + "/mocs_compilation"; - mcFile += *it; - mcFile += ".cpp"; - autogenProvides.push_back(mcFile); - } + const std::string mocsComp = autogenBuildDir + "/mocs_compilation.cpp"; + autogenProvides.push_back(mocsComp); } // Add autogen includes directory to the origin target INCLUDE_DIRECTORIES if (mocEnabled || uicEnabled) { + std::string includeDir = autogenBuildDir + "/include"; if (multiConfig) { - target->AddIncludeDirectory(autogenBuildDir + "/include_$<CONFIG>", - true); - - } else { - target->AddIncludeDirectory(autogenBuildDir + "/include", true); + includeDir += "_$<CONFIG>"; } + target->AddIncludeDirectory(includeDir, true); } #if defined(_WIN32) && !defined(__CYGWIN__) @@ -902,29 +872,20 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Compose rcc output file name { - std::string rccOutBase = autogenBuildDir + "/"; - rccOutBase += fpathCheckSum.getPart(absFile); - rccOutBase += "/qrc_"; - rccOutBase += + std::string rccBuildFile = autogenBuildDir + "/"; + rccBuildFile += fpathCheckSum.getPart(absFile); + rccBuildFile += "/qrc_"; + rccBuildFile += cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile); + rccBuildFile += ".cpp"; // Register rcc ouput file as generated - for (std::vector<std::string>::const_iterator it = - suffixes.begin(); - it != suffixes.end(); ++it) { - std::string rccOutCfg = rccOutBase; - rccOutCfg += *it; - rccOutCfg += ".cpp"; - AddGeneratedSource(makefile, rccOutCfg, - cmQtAutoGeneratorCommon::RCC); - autogenProvides.push_back(rccOutCfg); - } + AddGeneratedSource(makefile, rccBuildFile, + cmQtAutoGeneratorCommon::RCC); // Add rcc output file to origin target sources - if (multiConfig) { - target->AddSource(rccOutBase + "_$<CONFIG>.cpp"); - } else { - target->AddSource(rccOutBase + ".cpp"); - } + target->AddSource(rccBuildFile); + // Register rcc ouput file as generated by the _autogen target + autogenProvides.push_back(rccBuildFile); } if (PropertyEnabled(sf, "GENERATED")) { @@ -1035,7 +996,7 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( if (IsMultiConfig(target->GetGlobalGenerator())) { for (std::vector<std::string>::const_iterator it = configs.begin(); it != configs.end(); ++it) { - configSuffix[*it] = "_" + *it; + configSuffix[*it] = cmOutputConverter::EscapeForCMake("_" + *it); } } diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index feec735..bdf682a 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -366,6 +366,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( return false; } + // -- Meta + InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix); + // - Old settings file { this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory); @@ -375,9 +378,6 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( this->SettingsFile += ".cmake"; } - // -- Meta - InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix); - // - Files and directories InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir); InfoGet(makefile, "AM_CMAKE_BINARY_DIR", this->ProjectBinaryDir); @@ -636,9 +636,7 @@ bool cmQtAutoGenerators::SettingsFileWrite() void cmQtAutoGenerators::Init(cmMakefile* makefile) { // Mocs compilation file - this->MocCompFileRel = "mocs_compilation"; - this->MocCompFileRel += this->ConfigSuffix; - this->MocCompFileRel += ".cpp"; + this->MocCompFileRel = "mocs_compilation.cpp"; this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath( this->AutogenBuildDir, this->MocCompFileRel); @@ -649,7 +647,9 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile) // Moc predefs file if (!this->MocPredefsCmd.empty()) { - this->MocPredefsFileRel = "moc_predefs.h"; + this->MocPredefsFileRel = "moc_predefs"; + this->MocPredefsFileRel += this->ConfigSuffix; + this->MocPredefsFileRel += ".h"; this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath( this->AutogenBuildDir, this->MocPredefsFileRel); } @@ -724,10 +724,10 @@ bool cmQtAutoGenerators::RunAutogen() // the program goes through all .cpp files to see which moc files are // included. It is not really interesting how the moc file is named, but // what file the moc is created from. Once a moc is included the same moc - // may not be included in the mocs_compilation_$<CONFIG>.cpp file anymore. + // may not be included in the mocs_compilation.cpp file anymore. // OTOH if there's a header containing Q_OBJECT where no corresponding // moc file is included anywhere a moc_<filename>.cpp file is created and - // included in the mocs_compilation_$<CONFIG>.cpp file. + // included in the mocs_compilation.cpp file. // key = moc source filepath, value = moc output filepath std::map<std::string, std::string> mocsIncluded; @@ -1664,10 +1664,10 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, { bool rccGenerated = false; bool generateRcc = this->RccSettingsChanged; - const std::string rccBuildFile = cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile); + // Check if regeneration is required if (!generateRcc) { // Test if the resources list file is newer than build file generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile); @@ -1700,6 +1700,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, } } } + // Regenerate on demand if (generateRcc) { // Log this->LogBold("Generating RCC source " + rccOutputFile); @@ -1755,6 +1756,39 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, this->RccRunFailed = true; } } + // For a multi configuration generator generate a wrapper file + if (!this->ConfigSuffix.empty() && !this->RccRunFailed) { + // Wrapper file name + const std::string cppSuffix = ".cpp"; + const size_t suffixLength = this->ConfigSuffix.size() + cppSuffix.size(); + const std::string wrapperFileRel = + rccOutputFile.substr(0, rccOutputFile.size() - suffixLength) + cppSuffix; + const std::string wrapperFileAbs = cmSystemTools::CollapseCombinedPath( + this->AutogenBuildDir, wrapperFileRel); + // Wrapper file content + std::string content = + "// This is an autogenerated configuration wrapper file. Do not edit.\n" + "#include \""; + content += cmsys::SystemTools::GetFilenameName(rccBuildFile); + content += "\"\n"; + // Write content to file + if (this->FileDiffers(wrapperFileAbs, content)) { + // Write new wrapper file if the content differs + this->LogBold("Generating RCC wrapper " + wrapperFileRel); + if (!this->FileWrite("AutoRcc", wrapperFileAbs, content)) { + // Error + rccGenerated = false; + this->RccRunFailed = true; + } + } else if (rccGenerated) { + // Only touch wrapper file if the content matches + if (this->Verbose) { + this->LogInfo("Touching RCC wrapper " + wrapperFileRel); + } + cmSystemTools::Touch(wrapperFileAbs, false); + } + } + return rccGenerated; } diff --git a/Tests/QtAutoUicInterface/CMakeLists.txt b/Tests/QtAutoUicInterface/CMakeLists.txt index 3ea1294..a5c2d99 100644 --- a/Tests/QtAutoUicInterface/CMakeLists.txt +++ b/Tests/QtAutoUicInterface/CMakeLists.txt @@ -53,8 +53,9 @@ set_property(TARGET KI18n APPEND PROPERTY # END upstream -if(${CMAKE_GENERATOR} MATCHES "Visual Studio") -set(INC_DIR "include_${CMAKE_BUILD_TYPE}" ) +get_property(_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(_GENERATOR_IS_MULTI_CONFIG) +set(INC_DIR "include_$<CONFIG>" ) else() set(INC_DIR "include" ) endif() diff --git a/Tests/QtAutogen/mocInclude/shared.cmake b/Tests/QtAutogen/mocInclude/shared.cmake index c426050..d05f27c 100644 --- a/Tests/QtAutogen/mocInclude/shared.cmake +++ b/Tests/QtAutogen/mocInclude/shared.cmake @@ -29,9 +29,11 @@ set_property(SOURCE ${CMAKE_CURRENT_BINARY_DIR}/SObjB.cpp PROPERTY SKIP_AUTOMOC qtx_generate_moc( ${CMAKE_CURRENT_SOURCE_DIR}/../mocInclude/SObjCExtra.hpp ${CMAKE_CURRENT_BINARY_DIR}/SObjCExtra_extMoc.cpp) -set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../mocInclude/SObjCExtra.hpp PROPERTY SKIP_AUTOMOC ON) +set_property( + SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../mocInclude/SObjCExtra.hpp + PROPERTY SKIP_AUTOMOC ON) # Custom target to depend on -set(SOBJC_MOC ${CMAKE_CURRENT_BINARY_DIR}/${MOC_INCLUDE_NAME}_autogen/include/moc_SObjCExtra.cpp) +set(SOBJC_MOC ${CMAKE_CURRENT_BINARY_DIR}/moc_SObjCExtra.cpp) add_custom_target("${MOC_INCLUDE_NAME}_SOBJC" DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SObjCExtra_extMoc.cpp BYPRODUCTS ${SOBJC_MOC} |