sourceFile properties: add property COMPILE_OPTIONS

Add the support of per-source property COMPILE_OPTIONS,
including generator expressions support.

Related: #17507
This commit is contained in:
Marc Chevrier 2017-12-15 12:31:53 +01:00
parent 3f935e690a
commit 78b1c2e09e
15 changed files with 113 additions and 53 deletions

View File

@ -370,6 +370,7 @@ Properties on Source Files
/prop_sf/AUTORCC_OPTIONS /prop_sf/AUTORCC_OPTIONS
/prop_sf/COMPILE_DEFINITIONS /prop_sf/COMPILE_DEFINITIONS
/prop_sf/COMPILE_FLAGS /prop_sf/COMPILE_FLAGS
/prop_sf/COMPILE_OPTIONS
/prop_sf/EXTERNAL_OBJECT /prop_sf/EXTERNAL_OBJECT
/prop_sf/Fortran_FORMAT /prop_sf/Fortran_FORMAT
/prop_sf/GENERATED /prop_sf/GENERATED

View File

@ -0,0 +1,16 @@
COMPILE_OPTIONS
---------------
List of additional options to pass to the compiler.
This property holds a :ref:`;-list <CMake Language Lists>` of options
and will be added to the list of compile flags when this
source file builds. Use :prop_sf:`COMPILE_DEFINITIONS` to pass
additional preprocessor definitions.
Contents of ``COMPILE_OPTIONS`` 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.

View File

@ -0,0 +1,4 @@
sourceFile-new-properties
-------------------------
* The source files learn new property :prop_sf:`COMPILE_OPTIONS`.

View File

@ -361,13 +361,20 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
} }
// Add source file specific flags. // Add source file specific flags.
cmGeneratorExpressionInterpreter genexInterpreter(lg, gtgt, config,
gtgt->GetName(), language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS"); const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) { if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
cmGeneratorExpressionInterpreter genexInterpreter(
lg, gtgt, config, gtgt->GetName(), language);
lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS)); lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
} }
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
}
return flags; return flags;
} }

View File

@ -743,6 +743,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) { if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS)); lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
} }
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
}
// Add per-source definitions. // Add per-source definitions.
BuildObjectListOrString flagsBuild(this, false); BuildObjectListOrString flagsBuild(this, false);

View File

@ -1494,6 +1494,12 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
fc.CompileFlags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS); fc.CompileFlags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
needfc = true; needfc = true;
} }
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
if (const char* coptions = sf.GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
fc.CompileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
needfc = true;
}
if (lg->FortranProject) { if (lg->FortranProject) {
switch (cmOutputConverter::GetFortranFormat( switch (cmOutputConverter::GetFortranFormat(
sf.GetProperty("Fortran_FORMAT"))) { sf.GetProperty("Fortran_FORMAT"))) {

View File

@ -445,6 +445,16 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
<< "\n"; << "\n";
} }
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
if (const char* coptions = source.GetProperty(COMPILE_OPTIONS)) {
const char* evaluatedOptions =
genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS);
this->LocalGenerator->AppendCompileOptions(flags, evaluatedOptions);
*this->FlagFileStream << "# Custom options: " << relativeObj
<< "_OPTIONS = " << evaluatedOptions << "\n"
<< "\n";
}
// Add language-specific defines. // Add language-specific defines.
std::set<std::string> defines; std::set<std::string> defines;

View File

@ -135,16 +135,23 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
} }
// Add source file specific flags. // Add source file specific flags.
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, this->GeneratorTarget,
this->LocalGenerator->GetConfigName(), this->GeneratorTarget->GetName(),
language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS"); const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) { if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, this->GeneratorTarget,
this->LocalGenerator->GetConfigName(), this->GeneratorTarget->GetName(),
language);
this->LocalGenerator->AppendFlags( this->LocalGenerator->AppendFlags(
flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS)); flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
} }
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
this->LocalGenerator->AppendCompileOptions(
flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
}
return flags; return flags;
} }

View File

@ -708,6 +708,11 @@ static Json::Value DumpSourceFilesList(
lg->AppendFlags(compileFlags, lg->AppendFlags(compileFlags,
genexInterpreter.Evaluate(cflags, COMPILE_FLAGS)); genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
} }
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
if (const char* coptions = file->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
compileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
}
fileData.Flags = compileFlags; fileData.Flags = compileFlags;
fileData.IncludePathList = ld.IncludePathList; fileData.IncludePathList = ld.IncludePathList;

View File

@ -2036,6 +2036,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
} }
std::string flags; std::string flags;
bool configDependentFlags = false; bool configDependentFlags = false;
std::string options;
bool configDependentOptions = false;
std::string defines; std::string defines;
bool configDependentDefines = false; bool configDependentDefines = false;
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) { if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
@ -2043,6 +2045,11 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmGeneratorExpression::Find(cflags) != std::string::npos; cmGeneratorExpression::Find(cflags) != std::string::npos;
flags += cflags; flags += cflags;
} }
if (const char* coptions = sf.GetProperty("COMPILE_OPTIONS")) {
configDependentOptions =
cmGeneratorExpression::Find(coptions) != std::string::npos;
options += coptions;
}
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) { if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
configDependentDefines = configDependentDefines =
cmGeneratorExpression::Find(cdefs) != std::string::npos; cmGeneratorExpression::Find(cdefs) != std::string::npos;
@ -2099,7 +2106,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() || !options.empty() || !configDefines.empty() ||
compileAs || noWinRT) {
(*this->BuildFileStream) << firstString; (*this->BuildFileStream) << firstString;
firstString = ""; // only do firstString once firstString = ""; // only do firstString once
hasFlags = true; hasFlags = true;
@ -2137,6 +2145,17 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
} else { } else {
clOptions.Parse(flags.c_str()); clOptions.Parse(flags.c_str());
} }
if (!options.empty()) {
std::string expandedOptions;
if (configDependentOptions) {
this->LocalGenerator->AppendCompileOptions(
expandedOptions,
genexInterpreter.Evaluate(options, "COMPILE_OPTIONS"));
} else {
this->LocalGenerator->AppendCompileOptions(expandedOptions, options);
}
clOptions.Parse(expandedOptions.c_str());
}
if (clOptions.HasFlag("AdditionalIncludeDirectories")) { if (clOptions.HasFlag("AdditionalIncludeDirectories")) {
clOptions.AppendFlag("AdditionalIncludeDirectories", clOptions.AppendFlag("AdditionalIncludeDirectories",
"%(AdditionalIncludeDirectories)"); "%(AdditionalIncludeDirectories)");

View File

@ -260,17 +260,33 @@ add_custom_target(check-part4 ALL
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Cover source file properties with generator expressions. # Cover source file properties with generator expressions.
add_executable(srcgenex_flags srcgenex_flags.c) ## generate various source files
set_property(SOURCE srcgenex_flags.c PROPERTY COMPILE_FLAGS "-DNAME=$<TARGET_PROPERTY:NAME>") foreach (item IN ITEMS flags flags_COMPILE_LANGUAGE
options options_COMPILE_LANGUAGE
defs defs_COMPILE_LANGUAGE)
set(TARGET_NAME srcgenex_${item})
configure_file(srcgenex.c.in ${TARGET_NAME}.c @ONLY)
endforeach()
add_executable(srcgenex_flags "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_flags.c")
set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_flags.c"
PROPERTY COMPILE_FLAGS "-DNAME=$<TARGET_PROPERTY:NAME>")
add_executable(srcgenex_flags_COMPILE_LANGUAGE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_flags_COMPILE_LANGUAGE.c")
set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_flags_COMPILE_LANGUAGE.c"
PROPERTY COMPILE_FLAGS "$<$<COMPILE_LANGUAGE:C>:-DNAME=$<TARGET_PROPERTY:NAME>>")
add_executable(srcgenex_flags_COMPILE_LANGUAGE srcgenex_flags_COMPILE_LANGUAGE.c) add_executable(srcgenex_options "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_options.c")
set_property(SOURCE srcgenex_flags_COMPILE_LANGUAGE.c PROPERTY COMPILE_FLAGS "$<$<COMPILE_LANGUAGE:C>:-DNAME=$<TARGET_PROPERTY:NAME>>") set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_options.c"
PROPERTY COMPILE_OPTIONS -DUNUSED -DNAME=$<TARGET_PROPERTY:NAME>)
add_executable(srcgenex_options_COMPILE_LANGUAGE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_options_COMPILE_LANGUAGE.c")
set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_options_COMPILE_LANGUAGE.c"
PROPERTY COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:C>:-DNAME=$<TARGET_PROPERTY:NAME>>)
add_executable(srcgenex_defs srcgenex_defs.c) add_executable(srcgenex_defs "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_defs.c")
set_property(SOURCE srcgenex_defs.c PROPERTY COMPILE_DEFINITIONS NAME=$<TARGET_PROPERTY:NAME>) set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_defs.c"
PROPERTY COMPILE_DEFINITIONS NAME=$<TARGET_PROPERTY:NAME>)
add_executable(srcgenex_defs_COMPILE_LANGUAGE srcgenex_defs_COMPILE_LANGUAGE.c) add_executable(srcgenex_defs_COMPILE_LANGUAGE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_defs_COMPILE_LANGUAGE.c")
set_property(SOURCE srcgenex_defs_COMPILE_LANGUAGE.c PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:C>:NAME=$<TARGET_PROPERTY:NAME>>) set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/srcgenex_defs_COMPILE_LANGUAGE.c"
PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:C>:NAME=$<TARGET_PROPERTY:NAME>>)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Cover test properties with generator expressions. # Cover test properties with generator expressions.

View File

@ -1,4 +1,4 @@
int srcgenex_defs(void) int @TARGET_NAME@(void)
{ {
return 0; return 0;
} }

View File

@ -1,12 +0,0 @@
int srcgenex_defs_COMPILE_LANGUAGE(void)
{
return 0;
}
int main(int argc, char* argv[])
{
#ifndef NAME
#error NAME not defined
#endif
return NAME();
}

View File

@ -1,12 +0,0 @@
int srcgenex_flags(void)
{
return 0;
}
int main(int argc, char* argv[])
{
#ifndef NAME
#error NAME not defined
#endif
return NAME();
}

View File

@ -1,12 +0,0 @@
int srcgenex_flags_COMPILE_LANGUAGE(void)
{
return 0;
}
int main(int argc, char* argv[])
{
#ifndef NAME
#error NAME not defined
#endif
return NAME();
}