mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-15 20:46:37 +08:00
Add generator expression support to per-source COMPILE_FLAGS
This allows users to specify different genex-based compile flags for each file in a target, e.g. compiling just a single file with `Od/Ox` in release builds on Visual Studio.
This commit is contained in:
@@ -6,3 +6,10 @@ Additional flags to be added when compiling this source file.
|
|||||||
These flags will be added to the list of compile flags when this
|
These flags will be added to the list of compile flags when this
|
||||||
source file builds. Use :prop_sf:`COMPILE_DEFINITIONS` to pass
|
source file builds. Use :prop_sf:`COMPILE_DEFINITIONS` to pass
|
||||||
additional preprocessor definitions.
|
additional preprocessor definitions.
|
||||||
|
|
||||||
|
Contents of ``COMPILE_FLAGS`` may use "generator expressions"
|
||||||
|
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
|
||||||
|
manual for available expressions. However, :generator:`Xcode`
|
||||||
|
does not support per-config per-source settings, so expressions
|
||||||
|
that depend on the build configuration are not allowed with that
|
||||||
|
generator.
|
||||||
|
5
Help/release/dev/src-COMPILE_FLAGS-genex.rst
Normal file
5
Help/release/dev/src-COMPILE_FLAGS-genex.rst
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
src-COMPILE_FLAGS-genex
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* The :prop_sf:`COMPILE_FLAGS` source file property learned to support
|
||||||
|
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
@@ -341,7 +341,11 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add source file specific flags.
|
// Add source file specific flags.
|
||||||
lg->AppendFlags(flags, source->GetProperty("COMPILE_FLAGS"));
|
if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
|
||||||
|
cmGeneratorExpression ge;
|
||||||
|
const char* processed = ge.Parse(cflags)->Evaluate(lg, config);
|
||||||
|
lg->AppendFlags(flags, processed);
|
||||||
|
}
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
@@ -675,7 +675,24 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lg->AppendFlags(flags, sf->GetProperty("COMPILE_FLAGS"));
|
if (const char* cflags = sf->GetProperty("COMPILE_FLAGS")) {
|
||||||
|
cmGeneratorExpression ge;
|
||||||
|
std::string configName = "NO-PER-CONFIG-SUPPORT-IN-XCODE";
|
||||||
|
CM_AUTO_PTR<cmCompiledGeneratorExpression> compiledExpr = ge.Parse(cflags);
|
||||||
|
const char* processed = compiledExpr->Evaluate(lg, configName);
|
||||||
|
if (compiledExpr->GetHadContextSensitiveCondition()) {
|
||||||
|
std::ostringstream e;
|
||||||
|
/* clang-format off */
|
||||||
|
e <<
|
||||||
|
"Xcode does not support per-config per-source COMPILE_FLAGS:\n"
|
||||||
|
" " << cflags << "\n"
|
||||||
|
"specified for source:\n"
|
||||||
|
" " << sf->GetFullPath() << "\n";
|
||||||
|
/* clang-format on */
|
||||||
|
lg->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||||
|
}
|
||||||
|
lg->AppendFlags(flags, processed);
|
||||||
|
}
|
||||||
|
|
||||||
// Add per-source definitions.
|
// Add per-source definitions.
|
||||||
BuildObjectListOrString flagsBuild(this, false);
|
BuildObjectListOrString flagsBuild(this, false);
|
||||||
|
@@ -1464,7 +1464,9 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
|
|||||||
needfc = true;
|
needfc = true;
|
||||||
}
|
}
|
||||||
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
|
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
|
||||||
fc.CompileFlags = cflags;
|
cmGeneratorExpression ge;
|
||||||
|
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
|
||||||
|
fc.CompileFlags = cge->Evaluate(lg, *i);
|
||||||
needfc = true;
|
needfc = true;
|
||||||
}
|
}
|
||||||
if (lg->FortranProject) {
|
if (lg->FortranProject) {
|
||||||
|
@@ -437,8 +437,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
|
|||||||
langFlags += "_FLAGS)";
|
langFlags += "_FLAGS)";
|
||||||
this->LocalGenerator->AppendFlags(flags, langFlags);
|
this->LocalGenerator->AppendFlags(flags, langFlags);
|
||||||
|
|
||||||
std::string configUpper =
|
std::string config = this->LocalGenerator->GetConfigName();
|
||||||
cmSystemTools::UpperCase(this->LocalGenerator->GetConfigName());
|
std::string configUpper = cmSystemTools::UpperCase(config);
|
||||||
|
|
||||||
// Add Fortran format flags.
|
// Add Fortran format flags.
|
||||||
if (lang == "Fortran") {
|
if (lang == "Fortran") {
|
||||||
@@ -446,12 +446,14 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add flags from source file properties.
|
// Add flags from source file properties.
|
||||||
if (source.GetProperty("COMPILE_FLAGS")) {
|
if (const char* cflags = source.GetProperty("COMPILE_FLAGS")) {
|
||||||
this->LocalGenerator->AppendFlags(flags,
|
cmGeneratorExpression ge;
|
||||||
source.GetProperty("COMPILE_FLAGS"));
|
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
|
||||||
|
const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
|
||||||
|
false, this->GeneratorTarget);
|
||||||
|
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
|
||||||
*this->FlagFileStream << "# Custom flags: " << relativeObj
|
*this->FlagFileStream << "# Custom flags: " << relativeObj
|
||||||
<< "_FLAGS = " << source.GetProperty("COMPILE_FLAGS")
|
<< "_FLAGS = " << evaluatedFlags << "\n"
|
||||||
<< "\n"
|
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -132,8 +132,14 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add source file specific flags.
|
// Add source file specific flags.
|
||||||
this->LocalGenerator->AppendFlags(flags,
|
if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
|
||||||
source->GetProperty("COMPILE_FLAGS"));
|
std::string config = this->LocalGenerator->GetConfigName();
|
||||||
|
cmGeneratorExpression ge;
|
||||||
|
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
|
||||||
|
const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
|
||||||
|
false, this->GeneratorTarget);
|
||||||
|
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
|
||||||
|
}
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
@@ -686,7 +686,12 @@ static Json::Value DumpSourceFilesList(
|
|||||||
cmLocalGenerator* lg = target->GetLocalGenerator();
|
cmLocalGenerator* lg = target->GetLocalGenerator();
|
||||||
|
|
||||||
std::string compileFlags = ld.Flags;
|
std::string compileFlags = ld.Flags;
|
||||||
lg->AppendFlags(compileFlags, file->GetProperty("COMPILE_FLAGS"));
|
if (const char* cflags = file->GetProperty("COMPILE_FLAGS")) {
|
||||||
|
cmGeneratorExpression ge;
|
||||||
|
const char* processed =
|
||||||
|
ge.Parse(cflags)->Evaluate(target->GetLocalGenerator(), config);
|
||||||
|
lg->AppendFlags(compileFlags, processed);
|
||||||
|
}
|
||||||
fileData.Flags = compileFlags;
|
fileData.Flags = compileFlags;
|
||||||
|
|
||||||
fileData.IncludePathList = ld.IncludePathList;
|
fileData.IncludePathList = ld.IncludePathList;
|
||||||
|
@@ -1355,8 +1355,13 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
|||||||
objectName = this->GeneratorTarget->GetObjectName(&sf);
|
objectName = this->GeneratorTarget->GetObjectName(&sf);
|
||||||
}
|
}
|
||||||
std::string flags;
|
std::string flags;
|
||||||
|
bool configDependentFlags = false;
|
||||||
std::string defines;
|
std::string defines;
|
||||||
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
|
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
|
||||||
|
|
||||||
|
if (cmGeneratorExpression::Find(cflags) != std::string::npos) {
|
||||||
|
configDependentFlags = true;
|
||||||
|
}
|
||||||
flags += cflags;
|
flags += cflags;
|
||||||
}
|
}
|
||||||
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
|
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
|
||||||
@@ -1412,7 +1417,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
|||||||
}
|
}
|
||||||
// if we have flags or defines for this config then
|
// if we have flags or defines for this config then
|
||||||
// use them
|
// use them
|
||||||
if (!flags.empty() || !configDefines.empty() || compileAs || noWinRT) {
|
if (!flags.empty() || configDependentFlags || !configDefines.empty() ||
|
||||||
|
compileAs || noWinRT) {
|
||||||
(*this->BuildFileStream) << firstString;
|
(*this->BuildFileStream) << firstString;
|
||||||
firstString = ""; // only do firstString once
|
firstString = ""; // only do firstString once
|
||||||
hasFlags = true;
|
hasFlags = true;
|
||||||
@@ -1427,7 +1433,15 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
|||||||
if (noWinRT) {
|
if (noWinRT) {
|
||||||
clOptions.AddFlag("CompileAsWinRT", "false");
|
clOptions.AddFlag("CompileAsWinRT", "false");
|
||||||
}
|
}
|
||||||
clOptions.Parse(flags.c_str());
|
if (configDependentFlags) {
|
||||||
|
cmGeneratorExpression ge;
|
||||||
|
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(flags);
|
||||||
|
std::string evaluatedFlags =
|
||||||
|
cge->Evaluate(this->LocalGenerator, *config);
|
||||||
|
clOptions.Parse(evaluatedFlags.c_str());
|
||||||
|
} else {
|
||||||
|
clOptions.Parse(flags.c_str());
|
||||||
|
}
|
||||||
if (clOptions.HasFlag("AdditionalIncludeDirectories")) {
|
if (clOptions.HasFlag("AdditionalIncludeDirectories")) {
|
||||||
clOptions.AppendFlag("AdditionalIncludeDirectories",
|
clOptions.AppendFlag("AdditionalIncludeDirectories",
|
||||||
"%(AdditionalIncludeDirectories)");
|
"%(AdditionalIncludeDirectories)");
|
||||||
|
@@ -257,6 +257,7 @@ add_custom_target(check-part4 ALL
|
|||||||
# Cover test properties with generator expressions.
|
# Cover test properties with generator expressions.
|
||||||
add_executable(echo echo.c)
|
add_executable(echo echo.c)
|
||||||
add_executable(pwd pwd.c)
|
add_executable(pwd pwd.c)
|
||||||
|
set_property(SOURCE echo.c PROPERTY COMPILE_FLAGS $<1:-DSRC_GENEX_WORKS>)
|
||||||
|
|
||||||
add_test(NAME echo-configuration COMMAND echo $<CONFIGURATION>)
|
add_test(NAME echo-configuration COMMAND echo $<CONFIGURATION>)
|
||||||
set_property(TEST echo-configuration PROPERTY
|
set_property(TEST echo-configuration PROPERTY
|
||||||
|
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
#ifndef SRC_GENEX_WORKS
|
||||||
|
#error SRC_GENEX_WORKS not defined
|
||||||
|
#endif
|
||||||
printf("%s\n", argv[1]);
|
printf("%s\n", argv[1]);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user