This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  bd86df676c8b19c0f5a4e5d87c0074caf3ebcbe3 (commit)
       via  9e1689413fd1e54e8056b7d369cd508636987072 (commit)
       via  b734fa44719a780683e2eb0dfaabd38d64daa3f6 (commit)
       via  0b945ea9a6a38d1b3ee27cc32afb4268bd571600 (commit)
       via  5c559f11137dcb14113a3c5df99ff896c65c7596 (commit)
      from  60fd5e0a216879aca4f18e840a73e26ad95239d0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd86df676c8b19c0f5a4e5d87c0074caf3ebcbe3
commit bd86df676c8b19c0f5a4e5d87c0074caf3ebcbe3
Merge: 60fd5e0 9e16894
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Mon Mar 9 16:08:11 2015 -0400
Commit:     CMake Topic Stage <kwro...@kitware.com>
CommitDate: Mon Mar 9 16:08:11 2015 -0400

    Merge topic 'target-language-genex' into next
    
    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.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9e1689413fd1e54e8056b7d369cd508636987072
commit 9e1689413fd1e54e8056b7d369cd508636987072
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Sun Feb 22 17:44:59 2015 +0100
Commit:     Stephen Kelly <steve...@gmail.com>
CommitDate: Mon Mar 9 20:49:17 2015 +0100

    File(GENERATE): Process genex evaluation files for each language.

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/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;
+}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b734fa44719a780683e2eb0dfaabd38d64daa3f6
commit b734fa44719a780683e2eb0dfaabd38d64daa3f6
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Wed Mar 4 21:53:15 2015 +0100
Commit:     Stephen Kelly <steve...@gmail.com>
CommitDate: Mon Mar 9 20:49:17 2015 +0100

    Genex: Allow COMPILE_LANGUAGE when processing include directories.
    
    Issue an error if this is encountered by an IDE generator.

diff --git a/Help/manual/cmake-generator-expressions.7.rst 
b/Help/manual/cmake-generator-expressions.7.rst
index b6d97d1..d38cf7e 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -121,7 +121,8 @@ Available logical expressions are:
     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:
+  expression to specify compile-language specific compile definitions
+  and include directories:
 
   .. code-block:: cmake
 
@@ -129,6 +130,9 @@ Available logical expressions are:
     target_compile_definitions(myapp
       PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
     )
+    target_include_directories(myapp
+      PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
+    )
 
 Informational Expressions
 =========================
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx 
b/Source/cmGeneratorExpressionEvaluator.cxx
index 3ec8595..756d932 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -851,7 +851,8 @@ static const struct CompileLanguageNode : public 
cmGeneratorExpressionNode
       }
     else if (genName.find("Xcode") != std::string::npos)
       {
-      if (dagChecker && dagChecker->EvaluatingCompileDefinitions())
+      if (dagChecker && (dagChecker->EvaluatingCompileDefinitions()
+          || dagChecker->EvaluatingIncludeDirectories()))
         {
         reportError(context, content->GetOriginalExpression(),
             "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS "
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/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 735dfa9..37cc2c6 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -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/cmLocalUnixMakefileGenerator3.cxx 
b/Source/cmLocalUnixMakefileGenerator3.cxx
index 9ecb029..50491af 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -2114,6 +2114,32 @@ void cmLocalUnixMakefileGenerator3
       cmakefileStream
         << "  )\n";
       }
+
+    // Target-specific include directories:
+    cmakefileStream
+      << "\n"
+      << "# 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->Convert(*i, cmLocalGenerator::HOME_OUTPUT)
+        << "\"\n";
+      }
+    cmakefileStream
+      << "  )\n";
     }
 
   // Store include transform rule properties.  Write the directory
diff --git a/Source/cmMakefileTargetGenerator.cxx 
b/Source/cmMakefileTargetGenerator.cxx
index 57c49f1..c7a7110 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1056,40 +1056,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/cmTarget.cxx b/Source/cmTarget.cxx
index 87dcc99..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);
 
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 0356c1e..5170b31 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -568,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,
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/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
index 8a32aef..5e0a5f5 100644
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
@@ -11,3 +11,10 @@ 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()

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0b945ea9a6a38d1b3ee27cc32afb4268bd571600
commit 0b945ea9a6a38d1b3ee27cc32afb4268bd571600
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Wed Mar 4 21:46:42 2015 +0100
Commit:     Stephen Kelly <steve...@gmail.com>
CommitDate: Mon Mar 9 20:49:16 2015 +0100

    Genex: Allow COMPILE_LANGUAGE when processing compile definitions.
    
    Issue an error if this is encountered by an IDE generator.

diff --git a/Help/manual/cmake-generator-expressions.7.rst 
b/Help/manual/cmake-generator-expressions.7.rst
index b1b1102..b6d97d1 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -120,6 +120,16 @@ Available logical expressions are:
     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:
+
+  .. code-block:: cmake
+
+    add_executable(myapp main.cpp foo.c bar.cpp)
+    target_compile_definitions(myapp
+      PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
+    )
+
 Informational Expressions
 =========================
 
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx 
b/Source/cmExtraCodeBlocksGenerator.cxx
index 69857ef..614e7d9 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -599,7 +599,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/cmGeneratorExpressionEvaluator.cxx 
b/Source/cmGeneratorExpressionEvaluator.cxx
index 6a9f251..3ec8595 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -817,7 +817,7 @@ static const struct CompileLanguageNode : public 
cmGeneratorExpressionNode
   std::string Evaluate(const std::vector<std::string> &parameters,
                        cmGeneratorExpressionContext *context,
                        const GeneratorExpressionContent *content,
-                       cmGeneratorExpressionDAGChecker *) const
+                       cmGeneratorExpressionDAGChecker *dagChecker) const
   {
     if(context->Language.empty())
       {
@@ -849,12 +849,21 @@ static const struct CompileLanguageNode : public 
cmGeneratorExpressionNode
           "generators.");
       return std::string();
       }
+    else if (genName.find("Xcode") != std::string::npos)
+      {
+      if (dagChecker && dagChecker->EvaluatingCompileDefinitions())
+        {
+        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 &&
-              genName.find("Xcode") == std::string::npos)
+              genName.find("Watcom WMake") == std::string::npos)
         {
         reportError(context, content->GetOriginalExpression(),
             "$<COMPILE_LANGUAGE:...> not supported for this generator.");
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 be82085..735dfa9 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);
 }
 
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 3a9d5be..f1f0da1 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 432cb3a..9ecb029 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -2094,26 +2094,26 @@ 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())
-    {
-    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)
+    // 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
-        << "  " << this->EscapeForCMake(*di) << "\n";
+        << "\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";
       }
-    cmakefileStream
-      << "  )\n";
     }
 
   // Store include transform rule properties.  Write the directory
diff --git a/Source/cmLocalVisualStudio6Generator.cxx 
b/Source/cmLocalVisualStudio6Generator.cxx
index 0848b03..2b999eb 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -1778,15 +1778,15 @@ void cmLocalVisualStudio6Generator
       std::set<std::string> minsizeDefinesSet;
       std::set<std::string> debugrelDefinesSet;
 
-      this->AddCompileDefinitions(definesSet, &target, "");
+      this->AddCompileDefinitions(definesSet, &target, "", linkLanguage);
       this->AddCompileDefinitions(debugDefinesSet, &target,
-                                  "DEBUG");
+                                  "DEBUG", linkLanguage);
       this->AddCompileDefinitions(releaseDefinesSet, &target,
-                                  "RELEASE");
+                                  "RELEASE", linkLanguage);
       this->AddCompileDefinitions(minsizeDefinesSet, &target,
-                                  "MINSIZEREL");
+                                  "MINSIZEREL", linkLanguage);
       this->AddCompileDefinitions(debugrelDefinesSet, &target,
-                                  "RELWITHDEBINFO");
+                                  "RELWITHDEBINFO", linkLanguage);
 
       std::string defines = " ";
       std::string debugDefines = " ";
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 20207f5..57c49f1 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);
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 c54d694..87dcc99 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2336,16 +2336,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", std::string());
+                                "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;
 
@@ -2377,7 +2379,8 @@ void 
cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
                             uniqueOptions,
                             &dagChecker,
                             config,
-                            debugDefines);
+                            debugDefines,
+                            language);
 
   std::vector<cmTargetInternals::TargetPropertyEntry*>
     linkInterfaceCompileDefinitionsEntries;
@@ -2424,7 +2427,8 @@ void 
cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
                             uniqueOptions,
                             &dagChecker,
                             config,
-                            debugDefines);
+                            debugDefines,
+                            language);
 
   deleteAndClear(linkInterfaceCompileDefinitionsEntries);
 }
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 56db22e..0356c1e 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
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/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/RunCMakeTest.cmake 
b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
index 2c5d9ae..8a32aef 100644
--- a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
@@ -4,3 +4,10 @@ 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()

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5c559f11137dcb14113a3c5df99ff896c65c7596
commit 5c559f11137dcb14113a3c5df99ff896c65c7596
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Tue Nov 25 22:47:44 2014 +0100
Commit:     Stephen Kelly <steve...@gmail.com>
CommitDate: Mon Mar 9 20:48:57 2015 +0100

    Genex: Enable use of COMPILE_LANGUAGE for compile options.
    
    Follow-ups will allow the use of the generator expression
    for compile definitions and include directories for non-IDE
    generators.

diff --git a/Help/manual/cmake-generator-expressions.7.rst 
b/Help/manual/cmake-generator-expressions.7.rst
index c47a7c4..b1b1102 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -93,6 +93,32 @@ 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)
 
 Informational Expressions
 =========================
@@ -174,6 +200,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/Source/cmGeneratorExpressionEvaluator.cxx 
b/Source/cmGeneratorExpressionEvaluator.cxx
index 63a46f2..6a9f251 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -827,6 +827,40 @@ static const struct CompileLanguageNode : public 
cmGeneratorExpressionNode
           "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("Makefiles") == std::string::npos &&
+              genName.find("Ninja") == std::string::npos &&
+              genName.find("Watcom WMake") == std::string::npos &&
+              genName.find("Xcode") == std::string::npos)
+        {
+        reportError(context, content->GetOriginalExpression(),
+            "$<COMPILE_LANGUAGE:...> not supported for this generator.");
+        return std::string();
+        }
+      }
     if (parameters.empty())
       {
       return context->Language;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 7c83f27..be82085 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -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)
       {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e046bef..c54d694 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2192,7 +2192,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 +2205,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 +2240,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 +2275,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 +2308,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> 
&result,
                             uniqueOptions,
                             &dagChecker,
                             config,
-                            debugOptions);
+                            debugOptions,
+                            language);
 
   std::vector<cmTargetInternals::TargetPropertyEntry*>
     linkInterfaceCompileOptionsEntries;
@@ -2318,7 +2324,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> 
&result,
                             uniqueOptions,
                             &dagChecker,
                             config,
-                            debugOptions);
+                            debugOptions,
+                            language);
 
   deleteAndClear(linkInterfaceCompileOptionsEntries);
 }
@@ -2333,7 +2340,7 @@ static void processCompileDefinitions(cmTarget const* tgt,
 {
   processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
                                 dagChecker, config, debugOptions,
-                                "definitions");
+                                "definitions", std::string());
 }
 
 //----------------------------------------------------------------------------
@@ -2431,7 +2438,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..56db22e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -577,7 +577,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/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/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/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/RunCMakeTest.cmake 
b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
new file mode 100644
index 0000000..2c5d9ae
--- /dev/null
+++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+if (RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake-stderr-file CompileOptions-stderr-VS.txt)
+    run_cmake(CompileOptions)
+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/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 f591c3d..542b7fc 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -23,6 +23,7 @@ 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)

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
http://public.kitware.com/mailman/listinfo/cmake-commits

Reply via email to