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
This commit is contained in:
Brad King 2017-08-07 14:34:45 +00:00 committed by Kitware Robot
commit 3a0ef7ac1a
8 changed files with 91 additions and 73 deletions

View File

@ -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

View File

@ -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,

View File

@ -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`

View File

@ -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``.

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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()

View File

@ -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}