QtAutomoc: Use config-dependent compile definitions and includes.

Instead of always using the includes and defines which are not
config-specific, ensure that the config specific ones can be used.

Task-number: #13589
This commit is contained in:
Stephen Kelly 2013-06-11 15:52:48 +02:00
parent 67f6cebb1e
commit ea4d7848e5
3 changed files with 143 additions and 42 deletions

View File

@ -152,10 +152,44 @@ bool cmQtAutomoc::InitializeMocSourceFile(cmTarget* target)
return true;
}
void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
static void GetCompileDefinitionsAndDirectories(cmTarget *target,
const char * config,
std::string &incs,
std::string &defs)
{
cmMakefile* makefile = target->GetMakefile();
cmLocalGenerator* localGen = makefile->GetLocalGenerator();
std::vector<std::string> includeDirs;
cmGeneratorTarget gtgt(target);
// Get the include dirs for this target, without stripping the implicit
// include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
localGen->GetIncludeDirectories(includeDirs, &gtgt, "CXX", config, false);
const char* sep = "";
incs = "";
for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin();
incDirIt != includeDirs.end();
++incDirIt)
{
incs += sep;
sep = ";";
incs += *incDirIt;
}
defs = target->GetCompileDefinitions(config);
const char *tmp = makefile->GetProperty("COMPILE_DEFINITIONS");
sep = "";
if (tmp)
{
defs += sep;
sep = ";";
defs += tmp;
}
}
void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
{
cmMakefile* makefile = target->GetMakefile();
const char* targetName = target->GetName();
bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
@ -175,6 +209,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
currentLine.push_back("-E");
currentLine.push_back("cmake_automoc");
currentLine.push_back(targetDir);
currentLine.push_back("$<CONFIGURATION>");
cmCustomCommandLines commandLines;
commandLines.push_back(currentLine);
@ -188,6 +223,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
#if defined(_WIN32) && !defined(__CYGWIN__)
bool usePRE_BUILD = false;
cmLocalGenerator* localGen = makefile->GetLocalGenerator();
cmGlobalGenerator* gg = localGen->GetGlobalGenerator();
if(strstr(gg->GetName(), "Visual Studio"))
{
@ -263,34 +299,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
}
}
std::vector<std::string> includeDirs;
cmGeneratorTarget gtgt(target);
// Get the include dirs for this target, without stripping the implicit
// include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
localGen->GetIncludeDirectories(includeDirs, &gtgt, "CXX", 0, false);
std::string _moc_incs = "";
const char* sep = "";
for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin();
incDirIt != includeDirs.end();
++incDirIt)
{
_moc_incs += sep;
sep = ";";
_moc_incs += *incDirIt;
}
std::string _moc_compile_defs = target->GetCompileDefinitions(0);
const char* tmp = makefile->GetProperty("COMPILE_DEFINITIONS");
sep = "";
if (tmp)
{
_moc_compile_defs += sep;
sep = ";";
_moc_compile_defs += tmp;
}
tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
std::string _moc_options = (tmp!=0 ? tmp : "");
// forget the variables added here afterwards again:
@ -299,10 +308,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
makefile->AddDefinition("_moc_target_name",
cmLocalGenerator::EscapeForCMake(automocTargetName.c_str()).c_str());
makefile->AddDefinition("_moc_incs",
cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str());
makefile->AddDefinition("_moc_compile_defs",
cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str());
makefile->AddDefinition("_moc_options",
cmLocalGenerator::EscapeForCMake(_moc_options.c_str()).c_str());
makefile->AddDefinition("_moc_files",
@ -311,6 +316,49 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str());
makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");
std::string _moc_incs;
std::string _moc_compile_defs;
std::vector<std::string> configs;
const char *config = makefile->GetConfigurations(configs);
GetCompileDefinitionsAndDirectories(target, config,
_moc_incs, _moc_compile_defs);
makefile->AddDefinition("_moc_incs",
cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str());
makefile->AddDefinition("_moc_compile_defs",
cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str());
std::map<std::string, std::string> configIncludes;
std::map<std::string, std::string> configDefines;
for (std::vector<std::string>::const_iterator li = configs.begin();
li != configs.end(); ++li)
{
std::string config_moc_incs;
std::string config_moc_compile_defs;
GetCompileDefinitionsAndDirectories(target, li->c_str(),
config_moc_incs,
config_moc_compile_defs);
if (config_moc_incs != _moc_incs)
{
configIncludes["_moc_incs_" + *li] =
cmLocalGenerator::EscapeForCMake(config_moc_incs.c_str());
if(_moc_incs.empty())
{
_moc_incs = config_moc_incs;
}
}
if (config_moc_compile_defs != _moc_compile_defs)
{
configDefines["_moc_compile_defs_" + *li] =
cmLocalGenerator::EscapeForCMake(config_moc_compile_defs.c_str());
if(_moc_compile_defs.empty())
{
_moc_compile_defs = config_moc_compile_defs;
}
}
}
const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
if (!qtVersion)
{
@ -358,17 +406,50 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
outputFile += "/AutomocInfo.cmake";
makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
false, true, false);
if (!configDefines.empty() || !configIncludes.empty())
{
std::ofstream infoFile(outputFile.c_str(), std::ios::app);
if ( !infoFile )
{
std::string error = "Internal CMake error when trying to open file: ";
error += outputFile.c_str();
error += " for writing.";
cmSystemTools::Error(error.c_str());
return;
}
if (!configDefines.empty())
{
for (std::map<std::string, std::string>::iterator
it = configDefines.begin(), end = configDefines.end();
it != end; ++it)
{
infoFile << "SET(AM_MOC_COMPILE_DEFINITIONS_" << it->first <<
" " << it->second << ")\n";
}
}
if (!configIncludes.empty())
{
for (std::map<std::string, std::string>::iterator
it = configIncludes.begin(), end = configIncludes.end();
it != end; ++it)
{
infoFile << "SET(AM_MOC_INCLUDES_" << it->first <<
" " << it->second << ")\n";
}
}
}
}
bool cmQtAutomoc::Run(const char* targetDirectory)
bool cmQtAutomoc::Run(const char* targetDirectory, const char *config)
{
bool success = true;
cmake cm;
cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory);
cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile();
this->ReadAutomocInfoFile(makefile, targetDirectory);
this->ReadAutomocInfoFile(makefile, targetDirectory, config);
this->ReadOldMocDefinitionsFile(makefile, targetDirectory);
this->Init();
@ -405,7 +486,8 @@ cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm,
bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile,
const char* targetDirectory)
const char* targetDirectory,
const char *config)
{
std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
cmSystemTools::ConvertToUnixSlashes(filename);
@ -430,9 +512,26 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile,
this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_BINARY_DIR");
this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
this->MocCompileDefinitionsStr = makefile->GetSafeDefinition(
"AM_MOC_COMPILE_DEFINITIONS");
this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES");
std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS";
std::string compileDefsProp = compileDefsPropOrig;
if(config)
{
compileDefsProp += "_";
compileDefsProp += config;
}
const char *compileDefs = makefile->GetDefinition(compileDefsProp.c_str());
this->MocCompileDefinitionsStr = compileDefs ? compileDefs
: makefile->GetSafeDefinition(compileDefsPropOrig.c_str());
std::string includesPropOrig = "AM_MOC_INCLUDES";
std::string includesProp = includesPropOrig;
if(config)
{
includesProp += "_";
includesProp += config;
}
const char *includes = makefile->GetDefinition(includesProp.c_str());
this->MocIncludesStr = includes ? includes
: makefile->GetSafeDefinition(includesPropOrig.c_str());
this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS");
this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR");

View File

@ -21,7 +21,7 @@ class cmQtAutomoc
{
public:
cmQtAutomoc();
bool Run(const char* targetDirectory);
bool Run(const char* targetDirectory, const char *config);
bool InitializeMocSourceFile(cmTarget* target);
void SetupAutomocTarget(cmTarget* target);
@ -31,7 +31,8 @@ private:
const char* targetDirectory);
bool ReadAutomocInfoFile(cmMakefile* makefile,
const char* targetDirectory);
const char* targetDirectory,
const char *config);
bool ReadOldMocDefinitionsFile(cmMakefile* makefile,
const char* targetDirectory);
void WriteOldMocDefinitionsFile(const char* targetDirectory);

View File

@ -1737,7 +1737,8 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
else if (args[1] == "cmake_automoc")
{
cmQtAutomoc automoc;
bool automocSuccess = automoc.Run(args[2].c_str());
const char *config = args[3].empty() ? 0 : args[3].c_str();
bool automocSuccess = automoc.Run(args[2].c_str(), config);
return automocSuccess ? 0 : 1;
}
#endif