summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-03-10 13:12:34 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2015-03-10 13:12:34 (GMT)
commitad6fbb88bbeb4db17f0f060525c638f0b7b01a33 (patch)
tree042b3405a12e583fc496c7be6cdd2af53af8c323
parentcce9671b4fea099c5109569108bca2dafe92a97e (diff)
parent232a6883a1fe480def1743af6d711097b98b026e (diff)
downloadCMake-ad6fbb88bbeb4db17f0f060525c638f0b7b01a33.zip
CMake-ad6fbb88bbeb4db17f0f060525c638f0b7b01a33.tar.gz
CMake-ad6fbb88bbeb4db17f0f060525c638f0b7b01a33.tar.bz2
Merge topic 'target-language-genex'
232a6883 Help: Add release notes for target-language-genex. 9e168941 File(GENERATE): Process genex evaluation files for each language. b734fa44 Genex: Allow COMPILE_LANGUAGE when processing include directories. 0b945ea9 Genex: Allow COMPILE_LANGUAGE when processing compile definitions. 5c559f11 Genex: Enable use of COMPILE_LANGUAGE for compile options. e387ce7d Genex: Add a COMPILE_LANGUAGE generator expression. 4a0128f4 VS6: Compute CMAKE_*_FLAGS and COMPILE_DEFINITIONS* only when needed
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst44
-rw-r--r--Help/release/dev/target-language-genex.rst9
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx2
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx2
-rw-r--r--Source/cmGeneratorExpression.cxx10
-rw-r--r--Source/cmGeneratorExpression.h6
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.cxx51
-rw-r--r--Source/cmGeneratorExpressionEvaluationFile.h2
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx76
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h1
-rw-r--r--Source/cmGeneratorTarget.cxx5
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx2
-rw-r--r--Source/cmLocalGenerator.cxx12
-rw-r--r--Source/cmLocalGenerator.h3
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx50
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx145
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx2
-rw-r--r--Source/cmMakefileTargetGenerator.cxx36
-rw-r--r--Source/cmNinjaTargetGenerator.cxx2
-rw-r--r--Source/cmQtAutoGenerators.cxx2
-rw-r--r--Source/cmTarget.cxx52
-rw-r--r--Source/cmTarget.h9
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx3
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt15
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.c23
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.cpp18
-rw-r--r--Tests/CMakeCommands/target_compile_options/CMakeLists.txt15
-rw-r--r--Tests/CMakeCommands/target_compile_options/consumer.c23
-rw-r--r--Tests/CMakeCommands/target_compile_options/consumer.cpp18
-rw-r--r--Tests/CMakeCommands/target_include_directories/CMakeLists.txt14
-rw-r--r--Tests/CMakeCommands/target_include_directories/c_only/c_only.h2
-rw-r--r--Tests/CMakeCommands/target_include_directories/consumer.c10
-rw-r--r--Tests/CMakeCommands/target_include_directories/consumer.cpp9
-rw-r--r--Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h2
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt8
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt8
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt1
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt8
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt9
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake5
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake20
-rw-r--r--Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp5
-rw-r--r--Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt1
-rw-r--r--Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake12
-rw-r--r--Tests/RunCMake/File_Generate/OutputConflict-stderr.txt2
-rw-r--r--Tests/RunCMake/File_Generate/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/File_Generate/empty.c8
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake8
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake8
80 files changed, 756 insertions, 177 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index c47a7c4..d38cf7e 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -93,6 +93,46 @@ Available logical expressions are:
for the 'head' target, an error is reported. See the
:manual:`cmake-compile-features(7)` manual for information on
compile features.
+``$<COMPILE_LANGUAGE:lang>``
+ ``1`` when the language used for compilation unit matches ``lang``,
+ otherwise ``0``. This expression used to specify compile options for
+ source files of a particular language in a target. For example, to specify
+ the use of the ``-fno-exceptions`` compile option (compiler id checks
+ elided):
+
+ .. code-block:: cmake
+
+ add_executable(myapp main.cpp foo.c bar.cpp)
+ target_compile_options(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
+ )
+
+ This generator expression has limited use because it is not possible to
+ use it with the Visual Studio generators. Portable buildsystems would
+ not use this expression, and would create separate libraries for each
+ source file language instead:
+
+ .. code-block:: cmake
+
+ add_library(myapp_c foo.c)
+ add_library(myapp_cxx foo.c)
+ target_compile_options(myapp_cxx PUBLIC -fno-exceptions)
+ add_executable(myapp main.cpp)
+ target_link_libraries(myapp myapp_c myapp_cxx)
+
+ The ``Makefile`` and ``Ninja`` based generators can also use this
+ expression to specify compile-language specific compile definitions
+ and include directories:
+
+ .. code-block:: cmake
+
+ add_executable(myapp main.cpp foo.c bar.cpp)
+ target_compile_definitions(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
+ )
+ target_include_directories(myapp
+ PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
+ )
Informational Expressions
=========================
@@ -174,6 +214,10 @@ Available informational expressions are:
``$<INSTALL_PREFIX>``
Content of the install prefix when the target is exported via
:command:`install(EXPORT)` and empty otherwise.
+``$<COMPILE_LANGUAGE>``
+ The compile language of source files when evaluating compile options. See
+ the unary version for notes about portability of this generator
+ expression.
Output Expressions
==================
diff --git a/Help/release/dev/target-language-genex.rst b/Help/release/dev/target-language-genex.rst
new file mode 100644
index 0000000..ed4cb5e
--- /dev/null
+++ b/Help/release/dev/target-language-genex.rst
@@ -0,0 +1,9 @@
+target-language-genex
+---------------------
+
+* A new ``COMPILE_LANGUAGE`` generator expression was introduced to
+ allow specification of compile options for target files based on the
+ :prop_sf:`LANGUAGE` of each source file. Due to limitations of the
+ underlying native build tools, this feature has varying support across
+ generators. See the :manual:`cmake-generator-expressions(7)` manual
+ for details.
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index d46d941..554b686 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -604,7 +604,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
// the compilerdefines for this target
std::vector<std::string> cdefs;
- target->GetCompileDefinitions(cdefs, buildType);
+ target->GetCompileDefinitions(cdefs, buildType, "C");
// Expand the list.
for(std::vector<std::string>::const_iterator di = cdefs.begin();
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 5fff0fb..25f9005 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -436,7 +436,7 @@ ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target,
}
// Add preprocessor definitions for this target and configuration.
- lg->AddCompileDefinitions(defines, target, config);
+ lg->AddCompileDefinitions(defines, target, config, language);
lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS"));
{
std::string defPropName = "COMPILE_DEFINITIONS_";
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index bf96951..0a27016 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -52,14 +52,16 @@ cmGeneratorExpression::~cmGeneratorExpression()
const char *cmCompiledGeneratorExpression::Evaluate(
cmMakefile* mf, const std::string& config, bool quiet,
cmTarget const* headTarget,
- cmGeneratorExpressionDAGChecker *dagChecker) const
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& language) const
{
return this->Evaluate(mf,
config,
quiet,
headTarget,
headTarget,
- dagChecker);
+ dagChecker,
+ language);
}
//----------------------------------------------------------------------------
@@ -67,7 +69,8 @@ const char *cmCompiledGeneratorExpression::Evaluate(
cmMakefile* mf, const std::string& config, bool quiet,
cmTarget const* headTarget,
cmTarget const* currentTarget,
- cmGeneratorExpressionDAGChecker *dagChecker) const
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& language) const
{
if (!this->NeedsEvaluation)
{
@@ -93,6 +96,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
context.EvaluateForBuildsystem = this->EvaluateForBuildsystem;
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
context.Backtrace = this->Backtrace;
+ context.Language = language;
for ( ; it != end; ++it)
{
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 57f78c5..55d9691 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -80,11 +80,13 @@ public:
bool quiet = false,
cmTarget const* headTarget = 0,
cmTarget const* currentTarget = 0,
- cmGeneratorExpressionDAGChecker *dagChecker = 0) const;
+ cmGeneratorExpressionDAGChecker *dagChecker = 0,
+ std::string const& language = std::string()) const;
const char* Evaluate(cmMakefile* mf, const std::string& config,
bool quiet,
cmTarget const* headTarget,
- cmGeneratorExpressionDAGChecker *dagChecker) const;
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& language = std::string()) const;
/** Get set of targets found during evaluations. */
std::set<cmTarget*> const& GetTargets() const
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 4e2a868..fa00283 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -38,13 +38,15 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
//----------------------------------------------------------------------------
void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
+ const std::string& lang,
cmCompiledGeneratorExpression* inputExpression,
std::map<std::string, std::string> &outputFiles, mode_t perm)
{
std::string rawCondition = this->Condition->GetInput();
if (!rawCondition.empty())
{
- std::string condResult = this->Condition->Evaluate(this->Makefile, config);
+ std::string condResult = this->Condition->Evaluate(this->Makefile, config,
+ false, 0, 0, 0, lang);
if (condResult == "0")
{
return;
@@ -60,9 +62,11 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
}
const std::string outputFileName
- = this->OutputFileExpr->Evaluate(this->Makefile, config);
+ = this->OutputFileExpr->Evaluate(this->Makefile, config,
+ false, 0, 0, 0, lang);
const std::string outputContent
- = inputExpression->Evaluate(this->Makefile, config);
+ = inputExpression->Evaluate(this->Makefile, config,
+ false, 0, 0, 0, lang);
std::map<std::string, std::string>::iterator it
= outputFiles.find(outputFileName);
@@ -75,7 +79,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
}
std::ostringstream e;
e << "Evaluation file to be written multiple times for different "
- "configurations with different content:\n " << outputFileName;
+ "configurations or languages with different content:\n "
+ << outputFileName;
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
@@ -97,14 +102,22 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config,
void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
std::string const& config)
{
- std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config);
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(name);
- sf->SetProperty("GENERATED", "1");
-
+ std::vector<std::string> enabledLanguages;
cmGlobalGenerator *gg
= this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
- gg->SetFilenameTargetDepends(sf,
+ gg->GetEnabledLanguages(enabledLanguages);
+
+ for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
+ le != enabledLanguages.end(); ++le)
+ {
+ std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config,
+ false, 0, 0, 0, *le);
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(name);
+ sf->SetProperty("GENERATED", "1");
+
+ gg->SetFilenameTargetDepends(sf,
this->OutputFileExpr->GetSourceSensitiveTargets());
+ }
}
//----------------------------------------------------------------------------
@@ -153,13 +166,23 @@ void cmGeneratorExpressionEvaluationFile::Generate()
{
allConfigs.push_back("");
}
- for(std::vector<std::string>::const_iterator li = allConfigs.begin();
- li != allConfigs.end(); ++li)
+
+ std::vector<std::string> enabledLanguages;
+ cmGlobalGenerator *gg
+ = this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
+ gg->GetEnabledLanguages(enabledLanguages);
+
+ for(std::vector<std::string>::const_iterator le = enabledLanguages.begin();
+ le != enabledLanguages.end(); ++le)
{
- this->Generate(*li, inputExpression.get(), outputFiles, perm);
- if(cmSystemTools::GetFatalErrorOccured())
+ for(std::vector<std::string>::const_iterator li = allConfigs.begin();
+ li != allConfigs.end(); ++li)
{
- return;
+ this->Generate(*li, *le, inputExpression.get(), outputFiles, perm);
+ if(cmSystemTools::GetFatalErrorOccured())
+ {
+ return;
+ }
}
}
}
diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h
index 3394ade..4424bec 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.h
+++ b/Source/cmGeneratorExpressionEvaluationFile.h
@@ -34,7 +34,7 @@ public:
void CreateOutputFile(std::string const& config);
private:
- void Generate(const std::string& config,
+ void Generate(const std::string& config, const std::string& lang,
cmCompiledGeneratorExpression* inputExpression,
std::map<std::string, std::string> &outputFiles, mode_t perm);
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index ba18faa..756d932 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -16,6 +16,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpression.h"
#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
#include "cmSourceFile.h"
#include <cmsys/String.h>
@@ -89,7 +90,8 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
context->Quiet,
headTarget,
currentTarget,
- dagChecker);
+ dagChecker,
+ context->Language);
if (cge->GetHadContextSensitiveCondition())
{
context->HadContextSensitiveCondition = true;
@@ -806,6 +808,77 @@ static const struct JoinNode : public cmGeneratorExpressionNode
}
} joinNode;
+static const struct CompileLanguageNode : public cmGeneratorExpressionNode
+{
+ CompileLanguageNode() {}
+
+ virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if(context->Language.empty())
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> may only be used to specify include "
+ "directories compile definitions, compile options and to evaluate "
+ "components of the file(GENERATE) command.");
+ return std::string();
+ }
+
+ std::vector<std::string> enabledLanguages;
+ cmGlobalGenerator* gg
+ = context->Makefile->GetLocalGenerator()->GetGlobalGenerator();
+ gg->GetEnabledLanguages(enabledLanguages);
+ if (!parameters.empty() &&
+ std::find(enabledLanguages.begin(), enabledLanguages.end(),
+ parameters.front()) == enabledLanguages.end())
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> Unknown language.");
+ return std::string();
+ }
+
+ std::string genName = gg->GetName();
+ if (genName.find("Visual Studio") != std::string::npos)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> may not be used with Visual Studio "
+ "generators.");
+ return std::string();
+ }
+ else if (genName.find("Xcode") != std::string::npos)
+ {
+ if (dagChecker && (dagChecker->EvaluatingCompileDefinitions()
+ || dagChecker->EvaluatingIncludeDirectories()))
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS "
+ "with the Xcode generator.");
+ return std::string();
+ }
+ }
+ else
+ {
+ if(genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<COMPILE_LANGUAGE:...> not supported for this generator.");
+ return std::string();
+ }
+ }
+ if (parameters.empty())
+ {
+ return context->Language;
+ }
+ return context->Language == parameters.front() ? "1" : "0";
+ }
+} languageNode;
+
#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \
, "INTERFACE_" #PROPERTY
@@ -1829,6 +1902,7 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
nodeMap["INSTALL_PREFIX"] = &installPrefixNode;
nodeMap["JOIN"] = &joinNode;
nodeMap["LINK_ONLY"] = &linkOnlyNode;
+ nodeMap["COMPILE_LANGUAGE"] = &languageNode;
}
NodeMap::const_iterator i = nodeMap.find(identifier);
if (i == nodeMap.end())
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index 0bf1797..b1fec0b 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -36,6 +36,7 @@ struct cmGeneratorExpressionContext
MaxLanguageStandard;
cmMakefile *Makefile;
std::string Config;
+ std::string Language;
cmTarget const* HeadTarget; // The target whose property is being evaluated.
cmTarget const* CurrentTarget; // The dependent of HeadTarget which appears
// directly or indirectly in the property.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 44c9e9a..b7b2eff 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -960,9 +960,10 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
//----------------------------------------------------------------------------
std::vector<std::string>
-cmGeneratorTarget::GetIncludeDirectories(const std::string& config) const
+cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
+ const std::string& lang) const
{
- return this->Target->GetIncludeDirectories(config);
+ return this->Target->GetIncludeDirectories(config, lang);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 2083b88..c329cf5 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -85,7 +85,7 @@ public:
/** Get the include directories for this target. */
std::vector<std::string> GetIncludeDirectories(
- const std::string& config) const;
+ const std::string& config, const std::string& lang) const;
bool IsSystemIncludeDirectory(const std::string& dir,
const std::string& config) const;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index e89161d..bd8a1f5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1803,7 +1803,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
std::vector<std::string> targetDefines;
- target.GetCompileDefinitions(targetDefines, configName);
+ target.GetCompileDefinitions(targetDefines, configName, "C");
this->AppendDefines(ppDefs, targetDefines);
buildSettings->AddAttribute
("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 7c83f27..37cc2c6 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1428,11 +1428,11 @@ std::string cmLocalGenerator::GetIncludeFlags(
//----------------------------------------------------------------------------
void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines,
cmTarget const* target,
- const std::string& config)
+ const std::string& config,
+ const std::string& lang)
{
std::vector<std::string> targetDefines;
- target->GetCompileDefinitions(targetDefines,
- config);
+ target->GetCompileDefinitions(targetDefines, config, lang);
this->AppendDefines(defines, targetDefines);
}
@@ -1453,7 +1453,7 @@ void cmLocalGenerator::AddCompileOptions(
{
cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
}
- target->GetCompileOptions(opts, config);
+ target->GetCompileOptions(opts, config, lang);
for(std::vector<std::string>::const_iterator i = opts.begin();
i != opts.end(); ++i)
{
@@ -1474,7 +1474,7 @@ void cmLocalGenerator::AddCompileOptions(
this->AppendFlags(flags, targetFlags);
}
std::vector<std::string> opts;
- target->GetCompileOptions(opts, config);
+ target->GetCompileOptions(opts, config, lang);
for(std::vector<std::string>::const_iterator i = opts.begin();
i != opts.end(); ++i)
{
@@ -1600,7 +1600,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
// Get the target-specific include directories.
std::vector<std::string> includes;
- includes = target->GetIncludeDirectories(config);
+ includes = target->GetIncludeDirectories(config, lang);
// Support putting all the in-project include directories first if
// it is requested by the project.
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index d64ae0f..6cdee42 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -239,7 +239,8 @@ public:
const std::string& lang, const std::string& config);
void AddCompileDefinitions(std::set<std::string>& defines,
cmTarget const* target,
- const std::string& config);
+ const std::string& config,
+ const std::string& lang);
/** Compute the language used to compile the given source file. */
std::string GetSourceFileLanguage(const cmSourceFile& source);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 723e39b..5550070 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -2042,23 +2042,49 @@ void cmLocalUnixMakefileGenerator3
<< "set(CMAKE_" << l->first << "_COMPILER_ID \""
<< cid << "\")\n";
}
- }
- // Build a list of preprocessor definitions for the target.
- std::set<std::string> defines;
- this->AddCompileDefinitions(defines, &target,
- this->ConfigurationName);
- if(!defines.empty())
- {
+ // Build a list of preprocessor definitions for the target.
+ std::set<std::string> defines;
+ this->AddCompileDefinitions(defines, &target,
+ this->ConfigurationName, l->first);
+ if(!defines.empty())
+ {
+ cmakefileStream
+ << "\n"
+ << "# Preprocessor definitions for this target.\n"
+ << "set(CMAKE_TARGET_DEFINITIONS_" << l->first << "\n";
+ for(std::set<std::string>::const_iterator di = defines.begin();
+ di != defines.end(); ++di)
+ {
+ cmakefileStream
+ << " " << this->EscapeForCMake(*di) << "\n";
+ }
+ cmakefileStream
+ << " )\n";
+ }
+
+ // Target-specific include directories:
cmakefileStream
<< "\n"
- << "# Preprocessor definitions for this target.\n"
- << "set(CMAKE_TARGET_DEFINITIONS\n";
- for(std::set<std::string>::const_iterator di = defines.begin();
- di != defines.end(); ++di)
+ << "# The include file search paths:\n";
+ cmakefileStream
+ << "set(CMAKE_" << l->first << "_TARGET_INCLUDE_PATH\n";
+ std::vector<std::string> includes;
+
+ cmGeneratorTarget* gt = this->GetGlobalGenerator()
+ ->GetGeneratorTarget(&target);
+
+ const std::string& config =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->GetIncludeDirectories(includes, gt,
+ l->first, config);
+ for(std::vector<std::string>::iterator i = includes.begin();
+ i != includes.end(); ++i)
{
cmakefileStream
- << " " << this->EscapeForCMake(*di) << "\n";
+ << " \""
+ << this->Convert(*i, cmLocalGenerator::HOME_OUTPUT)
+ << "\"\n";
}
cmakefileStream
<< " )\n";
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 1d62093..2b999eb 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -1701,15 +1701,15 @@ void cmLocalVisualStudio6Generator
= this->Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX",
debugPostfix?debugPostfix:"");
- // store flags for each configuration
- std::string flags = " ";
- std::string flagsRelease = " ";
- std::string flagsMinSizeRel = " ";
- std::string flagsDebug = " ";
- std::string flagsRelWithDebInfo = " ";
if(target.GetType() >= cmTarget::EXECUTABLE &&
target.GetType() <= cmTarget::OBJECT_LIBRARY)
{
+ // store flags for each configuration
+ std::string flags = " ";
+ std::string flagsRelease = " ";
+ std::string flagsMinSizeRel = " ";
+ std::string flagsDebug = " ";
+ std::string flagsRelWithDebInfo = " ";
std::vector<std::string> configs;
target.GetMakefile()->GetConfigurations(configs);
std::vector<std::string>::const_iterator it = configs.begin();
@@ -1760,72 +1760,77 @@ void cmLocalVisualStudio6Generator
"MinSizeRel");
this->AddCompileOptions(flagsRelWithDebInfo, &target, linkLanguage,
"RelWithDebInfo");
- }
- // if _UNICODE and _SBCS are not found, then add -D_MBCS
- std::string defs = this->Makefile->GetDefineFlags();
- if(flags.find("D_UNICODE") == flags.npos &&
- defs.find("D_UNICODE") == flags.npos &&
- flags.find("D_SBCS") == flags.npos &&
- defs.find("D_SBCS") == flags.npos)
- {
- flags += " /D \"_MBCS\"";
- }
+ // if _UNICODE and _SBCS are not found, then add -D_MBCS
+ std::string defs = this->Makefile->GetDefineFlags();
+ if(flags.find("D_UNICODE") == flags.npos &&
+ defs.find("D_UNICODE") == flags.npos &&
+ flags.find("D_SBCS") == flags.npos &&
+ defs.find("D_SBCS") == flags.npos)
+ {
+ flags += " /D \"_MBCS\"";
+ }
- // Add per-target and per-configuration preprocessor definitions.
- std::set<std::string> definesSet;
- std::set<std::string> debugDefinesSet;
- std::set<std::string> releaseDefinesSet;
- std::set<std::string> minsizeDefinesSet;
- std::set<std::string> debugrelDefinesSet;
-
- this->AddCompileDefinitions(definesSet, &target, "");
- this->AddCompileDefinitions(debugDefinesSet, &target, "DEBUG");
- this->AddCompileDefinitions(releaseDefinesSet, &target, "RELEASE");
- this->AddCompileDefinitions(minsizeDefinesSet, &target, "MINSIZEREL");
- this->AddCompileDefinitions(debugrelDefinesSet, &target, "RELWITHDEBINFO");
-
- std::string defines = " ";
- std::string debugDefines = " ";
- std::string releaseDefines = " ";
- std::string minsizeDefines = " ";
- std::string debugrelDefines = " ";
-
- this->JoinDefines(definesSet, defines, "");
- this->JoinDefines(debugDefinesSet, debugDefines, "");
- this->JoinDefines(releaseDefinesSet, releaseDefines, "");
- this->JoinDefines(minsizeDefinesSet, minsizeDefines, "");
- this->JoinDefines(debugrelDefinesSet, debugrelDefines, "");
-
- flags += defines;
- flagsDebug += debugDefines;
- flagsRelease += releaseDefines;
- flagsMinSizeRel += minsizeDefines;
- flagsRelWithDebInfo += debugrelDefines;
-
- // The template files have CXX FLAGS in them, that need to be replaced.
- // There are not separate CXX and C template files, so we use the same
- // variable names. The previous code sets up flags* variables to contain
- // the correct C or CXX flags
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL",
- flagsMinSizeRel.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG",
- flagsDebug.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
- flagsRelWithDebInfo.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE",
- flagsRelease.c_str());
- cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str());
-
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL",
- minsizeDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG",
- debugDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO",
- debugrelDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE",
- releaseDefines.c_str());
- cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS", defines.c_str());
+ // Add per-target and per-configuration preprocessor definitions.
+ std::set<std::string> definesSet;
+ std::set<std::string> debugDefinesSet;
+ std::set<std::string> releaseDefinesSet;
+ std::set<std::string> minsizeDefinesSet;
+ std::set<std::string> debugrelDefinesSet;
+
+ this->AddCompileDefinitions(definesSet, &target, "", linkLanguage);
+ this->AddCompileDefinitions(debugDefinesSet, &target,
+ "DEBUG", linkLanguage);
+ this->AddCompileDefinitions(releaseDefinesSet, &target,
+ "RELEASE", linkLanguage);
+ this->AddCompileDefinitions(minsizeDefinesSet, &target,
+ "MINSIZEREL", linkLanguage);
+ this->AddCompileDefinitions(debugrelDefinesSet, &target,
+ "RELWITHDEBINFO", linkLanguage);
+
+ std::string defines = " ";
+ std::string debugDefines = " ";
+ std::string releaseDefines = " ";
+ std::string minsizeDefines = " ";
+ std::string debugrelDefines = " ";
+
+ this->JoinDefines(definesSet, defines, "");
+ this->JoinDefines(debugDefinesSet, debugDefines, "");
+ this->JoinDefines(releaseDefinesSet, releaseDefines, "");
+ this->JoinDefines(minsizeDefinesSet, minsizeDefines, "");
+ this->JoinDefines(debugrelDefinesSet, debugrelDefines, "");
+
+ flags += defines;
+ flagsDebug += debugDefines;
+ flagsRelease += releaseDefines;
+ flagsMinSizeRel += minsizeDefines;
+ flagsRelWithDebInfo += debugrelDefines;
+
+ // The template files have CXX FLAGS in them, that need to be replaced.
+ // There are not separate CXX and C template files, so we use the same
+ // variable names. The previous code sets up flags* variables to
+ // contain the correct C or CXX flags
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL",
+ flagsMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG",
+ flagsDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
+ flagsRelWithDebInfo.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE",
+ flagsRelease.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str());
+
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL",
+ minsizeDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG",
+ debugDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO",
+ debugrelDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE",
+ releaseDefines.c_str());
+ cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS",
+ defines.c_str());
+ }
fout << line.c_str() << std::endl;
}
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index ed560aa..f53f825 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -775,7 +775,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
cmGeneratorTarget* gt =
this->GlobalGenerator->GetGeneratorTarget(&target);
std::vector<std::string> targetDefines;
- target.GetCompileDefinitions(targetDefines, configName);
+ target.GetCompileDefinitions(targetDefines, configName, "CXX");
targetOptions.AddDefines(targetDefines);
targetOptions.SetVerboseMakefile(
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index e751bc1..641cd23 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -329,7 +329,7 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
// Add preprocessor definitions for this target and configuration.
this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
- this->LocalGenerator->ConfigurationName);
+ this->LocalGenerator->ConfigurationName, l);
std::string definesString;
this->LocalGenerator->JoinDefines(defines, definesString, lang);
@@ -1126,40 +1126,6 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
}
- // Target-specific include directories:
- *this->InfoFileStream
- << "\n"
- << "# The include file search paths:\n";
- *this->InfoFileStream
- << "set(CMAKE_C_TARGET_INCLUDE_PATH\n";
- std::vector<std::string> includes;
-
- const std::string& config =
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- this->LocalGenerator->GetIncludeDirectories(includes,
- this->GeneratorTarget,
- "C", config);
- for(std::vector<std::string>::iterator i = includes.begin();
- i != includes.end(); ++i)
- {
- *this->InfoFileStream
- << " \""
- << this->LocalGenerator->Convert(*i,
- cmLocalGenerator::HOME_OUTPUT)
- << "\"\n";
- }
- *this->InfoFileStream
- << " )\n";
- *this->InfoFileStream
- << "set(CMAKE_CXX_TARGET_INCLUDE_PATH "
- << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
- *this->InfoFileStream
- << "set(CMAKE_Fortran_TARGET_INCLUDE_PATH "
- << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
- *this->InfoFileStream
- << "set(CMAKE_ASM_TARGET_INCLUDE_PATH "
- << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
-
// and now write the rule to use it
std::vector<std::string> depends;
std::vector<std::string> commands;
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index cfd8937..92fccd3 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -231,7 +231,7 @@ ComputeDefines(cmSourceFile const* source, const std::string& language)
// Add preprocessor definitions for this target and configuration.
this->LocalGenerator->AddCompileDefinitions(defines, this->Target,
- this->GetConfigName());
+ this->GetConfigName(), language);
this->LocalGenerator->AppendDefines
(defines,
source->GetProperty("COMPILE_DEFINITIONS"));
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index e18e757..844d708 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -507,7 +507,7 @@ static void GetCompileDefinitionsAndDirectories(cmTarget const* target,
incs = cmJoin(includeDirs, ";");
std::set<std::string> defines;
- localGen->AddCompileDefinitions(defines, target, config);
+ localGen->AddCompileDefinitions(defines, target, config, "CXX");
defs += cmJoin(defines, ";");
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e046bef..7a6ad8b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1979,7 +1979,8 @@ static void processIncludeDirectories(cmTarget const* tgt,
std::vector<std::string> &includes,
UNORDERED_SET<std::string> &uniqueIncludes,
cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugIncludes)
+ const std::string& config, bool debugIncludes,
+ const std::string& language)
{
cmMakefile *mf = tgt->GetMakefile();
@@ -1995,7 +1996,7 @@ static void processIncludeDirectories(cmTarget const* tgt,
config,
false,
tgt,
- dagChecker),
+ dagChecker, language),
entryIncludes);
std::string usedIncludes;
@@ -2106,7 +2107,8 @@ static void processIncludeDirectories(cmTarget const* tgt,
//----------------------------------------------------------------------------
std::vector<std::string>
-cmTarget::GetIncludeDirectories(const std::string& config) const
+cmTarget::GetIncludeDirectories(const std::string& config,
+ const std::string& language) const
{
std::vector<std::string> includes;
UNORDERED_SET<std::string> uniqueIncludes;
@@ -2139,7 +2141,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
uniqueIncludes,
&dagChecker,
config,
- debugIncludes);
+ debugIncludes,
+ language);
std::vector<cmTargetInternals::TargetPropertyEntry*>
linkInterfaceIncludeDirectoriesEntries;
@@ -2179,7 +2182,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
uniqueIncludes,
&dagChecker,
config,
- debugIncludes);
+ debugIncludes,
+ language);
deleteAndClear(linkInterfaceIncludeDirectoriesEntries);
@@ -2192,7 +2196,8 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
std::vector<std::string> &options,
UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugOptions, const char *logName)
+ const std::string& config, bool debugOptions, const char *logName,
+ std::string const& language)
{
cmMakefile *mf = tgt->GetMakefile();
@@ -2204,7 +2209,8 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
config,
false,
tgt,
- dagChecker),
+ dagChecker,
+ language),
entryOptions);
std::string usedOptions;
for(std::vector<std::string>::iterator
@@ -2238,10 +2244,12 @@ static void processCompileOptions(cmTarget const* tgt,
std::vector<std::string> &options,
UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugOptions)
+ const std::string& config, bool debugOptions,
+ std::string const& language)
{
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
- dagChecker, config, debugOptions, "options");
+ dagChecker, config, debugOptions, "options",
+ language);
}
//----------------------------------------------------------------------------
@@ -2271,7 +2279,8 @@ void cmTarget::GetAutoUicOptions(std::vector<std::string> &result,
//----------------------------------------------------------------------------
void cmTarget::GetCompileOptions(std::vector<std::string> &result,
- const std::string& config) const
+ const std::string& config,
+ const std::string& language) const
{
UNORDERED_SET<std::string> uniqueOptions;
@@ -2303,7 +2312,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result,
uniqueOptions,
&dagChecker,
config,
- debugOptions);
+ debugOptions,
+ language);
std::vector<cmTargetInternals::TargetPropertyEntry*>
linkInterfaceCompileOptionsEntries;
@@ -2318,7 +2328,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result,
uniqueOptions,
&dagChecker,
config,
- debugOptions);
+ debugOptions,
+ language);
deleteAndClear(linkInterfaceCompileOptionsEntries);
}
@@ -2329,16 +2340,18 @@ static void processCompileDefinitions(cmTarget const* tgt,
std::vector<std::string> &options,
UNORDERED_SET<std::string> &uniqueOptions,
cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string& config, bool debugOptions)
+ const std::string& config, bool debugOptions,
+ std::string const& language)
{
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
dagChecker, config, debugOptions,
- "definitions");
+ "definitions", language);
}
//----------------------------------------------------------------------------
void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
- const std::string& config) const
+ const std::string& config,
+ const std::string& language) const
{
UNORDERED_SET<std::string> uniqueOptions;
@@ -2370,7 +2383,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
uniqueOptions,
&dagChecker,
config,
- debugDefines);
+ debugDefines,
+ language);
std::vector<cmTargetInternals::TargetPropertyEntry*>
linkInterfaceCompileDefinitionsEntries;
@@ -2417,7 +2431,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
uniqueOptions,
&dagChecker,
config,
- debugDefines);
+ debugDefines,
+ language);
deleteAndClear(linkInterfaceCompileDefinitionsEntries);
}
@@ -2431,7 +2446,8 @@ static void processCompileFeatures(cmTarget const* tgt,
const std::string& config, bool debugOptions)
{
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
- dagChecker, config, debugOptions, "features");
+ dagChecker, config, debugOptions, "features",
+ std::string());
}
//----------------------------------------------------------------------------
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index ddd9859..5170b31 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -496,7 +496,8 @@ public:
const char* GetExportMacro() const;
void GetCompileDefinitions(std::vector<std::string> &result,
- const std::string& config) const;
+ const std::string& config,
+ const std::string& language) const;
// Compute the set of languages compiled by the target. This is
// computed every time it is called because the languages can change
@@ -567,7 +568,8 @@ public:
bool contentOnly) const;
std::vector<std::string> GetIncludeDirectories(
- const std::string& config) const;
+ const std::string& config,
+ const std::string& language) const;
void InsertInclude(const cmValueWithOrigin &entry,
bool before = false);
void InsertCompileOption(const cmValueWithOrigin &entry,
@@ -577,7 +579,8 @@ public:
void AppendBuildInterfaceIncludes();
void GetCompileOptions(std::vector<std::string> &result,
- const std::string& config) const;
+ const std::string& config,
+ const std::string& language) const;
void GetAutoUicOptions(std::vector<std::string> &result,
const std::string& config) const;
void GetCompileFeatures(std::vector<std::string> &features,
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 04d1487..19444ed 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1876,7 +1876,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
std::vector<std::string> targetDefines;
- this->Target->GetCompileDefinitions(targetDefines, configName.c_str());
+ this->Target->GetCompileDefinitions(targetDefines,
+ configName.c_str(), "CXX");
clOptions.AddDefines(targetDefines);
if(this->MSTools)
{
diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
index 14d40aa..f96283d 100644
--- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
@@ -26,6 +26,21 @@ target_compile_definitions(consumer
PRIVATE
)
+if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
+ target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+ )
+ target_compile_definitions(consumer
+ PRIVATE
+ CONSUMER_LANG_$<COMPILE_LANGUAGE>
+ LANG_IS_CXX=$<COMPILE_LANGUAGE:CXX>
+ LANG_IS_C=$<COMPILE_LANGUAGE:C>
+ )
+ target_compile_definitions(consumer
+ PRIVATE -DTEST_LANG_DEFINES
+ )
+endif()
+
add_definitions(-DSOME_DEF)
add_library(imp UNKNOWN IMPORTED)
get_target_property(_res imp COMPILE_DEFINITIONS)
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.c b/Tests/CMakeCommands/target_compile_definitions/consumer.c
new file mode 100644
index 0000000..5796d96
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.c
@@ -0,0 +1,23 @@
+
+#ifdef TEST_LANG_DEFINES
+ #ifdef CONSUMER_LANG_CXX
+ #error Unexpected CONSUMER_LANG_CXX
+ #endif
+
+ #ifndef CONSUMER_LANG_C
+ #error Expected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_C
+ #error Expected LANG_IS_C
+ #endif
+
+ #if LANG_IS_CXX
+ #error Unexpected LANG_IS_CXX
+ #endif
+#endif
+
+void consumer_c()
+{
+
+}
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
index a391114..778f57e 100644
--- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
@@ -15,4 +15,22 @@
#error Expected DASH_D_DEFINE
#endif
+#ifdef TEST_LANG_DEFINES
+ #ifndef CONSUMER_LANG_CXX
+ #error Expected CONSUMER_LANG_CXX
+ #endif
+
+ #ifdef CONSUMER_LANG_C
+ #error Unexpected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_CXX
+ #error Expected LANG_IS_CXX
+ #endif
+
+ #if LANG_IS_C
+ #error Unexpected LANG_IS_C
+ #endif
+#endif
+
int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
index 1d04639..35dd276 100644
--- a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt
@@ -23,6 +23,21 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
+if (NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+ )
+ target_compile_options(consumer
+ PRIVATE
+ -DCONSUMER_LANG_$<COMPILE_LANGUAGE>
+ -DLANG_IS_CXX=$<COMPILE_LANGUAGE:CXX>
+ -DLANG_IS_C=$<COMPILE_LANGUAGE:C>
+ )
+ target_compile_definitions(consumer
+ PRIVATE -DTEST_LANG_DEFINES
+ )
+endif()
+
target_compile_options(consumer
PRIVATE $<$<CXX_COMPILER_ID:GNU>:$<TARGET_PROPERTY:target_compile_options,INTERFACE_COMPILE_OPTIONS>>
)
diff --git a/Tests/CMakeCommands/target_compile_options/consumer.c b/Tests/CMakeCommands/target_compile_options/consumer.c
new file mode 100644
index 0000000..5796d96
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_options/consumer.c
@@ -0,0 +1,23 @@
+
+#ifdef TEST_LANG_DEFINES
+ #ifdef CONSUMER_LANG_CXX
+ #error Unexpected CONSUMER_LANG_CXX
+ #endif
+
+ #ifndef CONSUMER_LANG_C
+ #error Expected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_C
+ #error Expected LANG_IS_C
+ #endif
+
+ #if LANG_IS_CXX
+ #error Unexpected LANG_IS_CXX
+ #endif
+#endif
+
+void consumer_c()
+{
+
+}
diff --git a/Tests/CMakeCommands/target_compile_options/consumer.cpp b/Tests/CMakeCommands/target_compile_options/consumer.cpp
index 1299606..c5882a5 100644
--- a/Tests/CMakeCommands/target_compile_options/consumer.cpp
+++ b/Tests/CMakeCommands/target_compile_options/consumer.cpp
@@ -15,4 +15,22 @@
#endif
+#ifdef TEST_LANG_DEFINES
+ #ifndef CONSUMER_LANG_CXX
+ #error Expected CONSUMER_LANG_CXX
+ #endif
+
+ #ifdef CONSUMER_LANG_C
+ #error Unexpected CONSUMER_LANG_C
+ #endif
+
+ #if !LANG_IS_CXX
+ #error Expected LANG_IS_CXX
+ #endif
+
+ #if LANG_IS_C
+ #error Unexpected LANG_IS_C
+ #endif
+#endif
+
int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
index 661bbaa..d57556a 100644
--- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
@@ -42,6 +42,20 @@ add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
+if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
+ target_sources(consumer PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c"
+ )
+ target_include_directories(consumer
+ PRIVATE
+ $<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only>
+ $<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}/c_only>
+ )
+ target_compile_definitions(consumer
+ PRIVATE -DTEST_LANG_DEFINES
+ )
+endif()
+
target_include_directories(consumer
PRIVATE
$<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES>
diff --git a/Tests/CMakeCommands/target_include_directories/c_only/c_only.h b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h
new file mode 100644
index 0000000..29f68ee
--- /dev/null
+++ b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h
@@ -0,0 +1,2 @@
+
+#define C_ONLY_DEFINE
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.c b/Tests/CMakeCommands/target_include_directories/consumer.c
new file mode 100644
index 0000000..8821f5b
--- /dev/null
+++ b/Tests/CMakeCommands/target_include_directories/consumer.c
@@ -0,0 +1,10 @@
+
+#ifdef TEST_LANG_DEFINES
+ #include "c_only.h"
+
+ #ifndef C_ONLY_DEFINE
+ #error Expected C_ONLY_DEFINE
+ #endif
+#endif
+
+int consumer_c() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp
index 7e3443e..649510c 100644
--- a/Tests/CMakeCommands/target_include_directories/consumer.cpp
+++ b/Tests/CMakeCommands/target_include_directories/consumer.cpp
@@ -4,6 +4,9 @@
#include "interfaceinclude.h"
#include "relative_dir.h"
#include "consumer.h"
+#ifdef TEST_LANG_DEFINES
+ #include "cxx_only.h"
+#endif
#ifdef PRIVATEINCLUDE_DEFINE
#error Unexpected PRIVATEINCLUDE_DEFINE
@@ -29,4 +32,10 @@
#error Expected CONSUMER_DEFINE
#endif
+#ifdef TEST_LANG_DEFINES
+ #ifndef CXX_ONLY_DEFINE
+ #error Expected CXX_ONLY_DEFINE
+ #endif
+#endif
+
int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h
new file mode 100644
index 0000000..67289a4
--- /dev/null
+++ b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h
@@ -0,0 +1,2 @@
+
+#define CXX_ONLY_DEFINE
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index eb42057..9f1256e 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -208,3 +208,5 @@ add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths)
if(RPMBUILD_EXECUTABLE)
add_RunCMake_test(CPackRPM)
endif()
+
+add_RunCMake_test(COMPILE_LANGUAGE-genex)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt
new file mode 100644
index 0000000..ef2163c
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt
new file mode 100644
index 0000000..73b66ac
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt
@@ -0,0 +1,8 @@
+CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt
new file mode 100644
index 0000000..a1ed633
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt
@@ -0,0 +1,9 @@
+CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the
+ Xcode generator.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake
new file mode 100644
index 0000000..7935d88
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_executable(main main.cpp)
+target_compile_definitions(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt
new file mode 100644
index 0000000..e9e8e9f
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt
@@ -0,0 +1,8 @@
+CMake Error at CompileOptions.cmake:5 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake
new file mode 100644
index 0000000..6c92abc
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_executable(main main.cpp)
+target_compile_options(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt
new file mode 100644
index 0000000..ec15068
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt
@@ -0,0 +1,8 @@
+CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt
new file mode 100644
index 0000000..fdf92b2
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt
@@ -0,0 +1,9 @@
+CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the
+ Xcode generator.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake
new file mode 100644
index 0000000..31771f6
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake
@@ -0,0 +1,5 @@
+
+enable_language(CXX)
+
+add_executable(main main.cpp)
+target_include_directories(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:anydir>)
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
new file mode 100644
index 0000000..5e0a5f5
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
@@ -0,0 +1,20 @@
+include(RunCMake)
+
+if (RunCMake_GENERATOR MATCHES "Visual Studio")
+ set(RunCMake-stderr-file CompileOptions-stderr-VS.txt)
+ run_cmake(CompileOptions)
+endif()
+if (RunCMake_GENERATOR STREQUAL "Xcode")
+ set(RunCMake-stderr-file CompileDefinitions-stderr-Xcode.txt)
+ run_cmake(CompileDefinitions)
+elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
+ set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt)
+ run_cmake(CompileDefinitions)
+endif()
+if (RunCMake_GENERATOR STREQUAL "Xcode")
+ set(RunCMake-stderr-file IncludeDirectories-stderr-Xcode.txt)
+ run_cmake(IncludeDirectories)
+elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
+ set(RunCMake-stderr-file IncludeDirectories-stderr-VS.txt)
+ run_cmake(IncludeDirectories)
+endif()
diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp
new file mode 100644
index 0000000..31a1337
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake
new file mode 100644
index 0000000..e2b081d
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake
@@ -0,0 +1,12 @@
+
+enable_language(CXX C)
+
+add_library(empty empty.cpp empty.c)
+target_compile_options(empty
+ PRIVATE LANG_IS_$<COMPILE_LANGUAGE>
+)
+
+file(GENERATE
+ OUTPUT opts-$<COMPILE_LANGUAGE>.txt
+ CONTENT "$<TARGET_PROPERTY:empty,COMPILE_OPTIONS>\n"
+)
diff --git a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
index dbd39de..0abb7df 100644
--- a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
+++ b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt
@@ -1,5 +1,5 @@
CMake Error in CMakeLists.txt:
Evaluation file to be written multiple times for different configurations
- with different content:
+ or languages with different content:
.*output.txt
diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
index 97f93d5..db344ef 100644
--- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
@@ -17,6 +17,16 @@ if (NOT file_contents MATCHES "generated.cpp.rule")
message(SEND_ERROR "Rule file not in target sources! ${file_contents}")
endif()
+if (NOT RunCMake_GENERATOR MATCHES "Visual Studio")
+ run_cmake(COMPILE_LANGUAGE-genex)
+ foreach(l CXX C)
+ file(READ "${RunCMake_BINARY_DIR}/COMPILE_LANGUAGE-genex-build/opts-${l}.txt" l_defs)
+ if (NOT l_defs STREQUAL "LANG_IS_${l}\n")
+ message(FATAL_ERROR "File content does not match: ${l_defs}")
+ endif()
+ endforeach()
+endif()
+
set(timeformat "%Y%j%H%M%S")
file(REMOVE "${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt")
diff --git a/Tests/RunCMake/File_Generate/empty.c b/Tests/RunCMake/File_Generate/empty.c
new file mode 100644
index 0000000..563eef0
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/empty.c
@@ -0,0 +1,8 @@
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty_c()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
new file mode 100644
index 0000000..789b4d0
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_custom_command.cmake:6 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake
new file mode 100644
index 0000000..f4ba261
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake
@@ -0,0 +1,8 @@
+
+enable_language(C)
+
+add_library(empty empty.c)
+
+add_custom_command(TARGET empty PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
new file mode 100644
index 0000000..400fbc0
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_custom_target.cmake:4 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake
new file mode 100644
index 0000000..4102623
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake
@@ -0,0 +1,6 @@
+
+enable_language(C)
+
+add_custom_target(empty
+ COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
new file mode 100644
index 0000000..e45bb02
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_executable.cmake:4 \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake
new file mode 100644
index 0000000..5c2ff35
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+
+add_executable(empty empty.$<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
new file mode 100644
index 0000000..c9ee6fe
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_library.cmake:4 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake
new file mode 100644
index 0000000..dd9f824
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+
+add_library(empty empty.$<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
new file mode 100644
index 0000000..9955f5d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-add_test.cmake:5 \(add_test\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake
new file mode 100644
index 0000000..deedf65
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
new file mode 100644
index 0000000..eca700f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake
new file mode 100644
index 0000000..92c20e3
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ empty.$<COMPILE_LANGUAGE>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
new file mode 100644
index 0000000..2d324e2
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at COMPILE_LANGUAGE-target_sources.cmake:5 \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE>
+
+ \$<COMPILE_LANGUAGE:...> may only be used to specify include directories
+ compile definitions, compile options and to evaluate components of the
+ file\(GENERATE\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake
new file mode 100644
index 0000000..0c78acd
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+add_library(empty empty.c)
+target_sources(empty PRIVATE empty.$<COMPILE_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt
new file mode 100644
index 0000000..444da45
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at COMPILE_LANGUAGE-unknown-lang.cmake:4 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<COMPILE_LANGUAGE:CXX>
+
+ \$<COMPILE_LANGUAGE:...> Unknown language.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake
new file mode 100644
index 0000000..cec12a3
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall>)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 6c32393..542b7fc 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -16,6 +16,14 @@ run_cmake(NonValidTarget-C_COMPILER_VERSION)
run_cmake(NonValidTarget-CXX_COMPILER_VERSION)
run_cmake(NonValidTarget-TARGET_PROPERTY)
run_cmake(NonValidTarget-TARGET_POLICY)
+run_cmake(COMPILE_LANGUAGE-add_custom_target)
+run_cmake(COMPILE_LANGUAGE-add_custom_command)
+run_cmake(COMPILE_LANGUAGE-install)
+run_cmake(COMPILE_LANGUAGE-target_sources)
+run_cmake(COMPILE_LANGUAGE-add_executable)
+run_cmake(COMPILE_LANGUAGE-add_library)
+run_cmake(COMPILE_LANGUAGE-add_test)
+run_cmake(COMPILE_LANGUAGE-unknown-lang)
if(LINKER_SUPPORTS_PDB)
run_cmake(NonValidTarget-TARGET_PDB_FILE)