Просмотр исходного кода

Merge topic 'extend-compile-language-genex'

506fda1c Genex: Enable COMPILE_LANGUAGE for INCLUDE_DIRECTORIES with VS and Xcode
c2f79c98 Genex: Enable COMPILE_LANGUAGE for COMPILE_DEFINITIONS with VS and Xcode
0795d25b cmVisualStudio10TargetGenerator: Factor out include dir computation
1ab4d186 cmLocalVisualStudio7Generator: Clarify variable name of compiled language
07e1a743 cmLocalVisualStudio7Generator: Clarify condition for target that compiles

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1657
Brad King 8 лет назад
Родитель
Сommit
b4dfe1d816
33 измененных файлов с 219 добавлено и 247 удалено
  1. 21 21
      Help/manual/cmake-generator-expressions.7.rst
  2. 11 4
      Help/release/dev/extend-compile-language-genex.rst
  3. 9 28
      Source/cmGeneratorExpressionNode.cxx
  4. 9 3
      Source/cmGlobalXCodeGenerator.cxx
  5. 29 14
      Source/cmLocalVisualStudio7Generator.cxx
  6. 45 22
      Source/cmVisualStudio10TargetGenerator.cxx
  7. 10 12
      Source/cmVisualStudio10TargetGenerator.h
  8. 11 11
      Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
  9. 19 1
      Tests/CMakeCommands/target_compile_definitions/consumer.c
  10. 0 2
      Tests/CMakeCommands/target_compile_definitions/consumer.cpp
  11. 10 10
      Tests/CMakeCommands/target_include_directories/CMakeLists.txt
  12. 9 1
      Tests/CMakeCommands/target_include_directories/consumer.c
  13. 1 5
      Tests/CMakeCommands/target_include_directories/consumer.cpp
  14. 9 2
      Tests/CudaOnly/WithDefs/CMakeLists.txt
  15. 1 0
      Tests/CudaOnly/WithDefs/inc_cuda/inc_cuda.h
  16. 23 6
      Tests/CudaOnly/WithDefs/main.notcu
  17. 2 4
      Tests/GeneratorExpression/CMakeLists.txt
  18. 0 2
      Tests/RunCMake/CMakeLists.txt
  19. 0 3
      Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt
  20. 0 1
      Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt
  21. 0 9
      Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt
  22. 0 9
      Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt
  23. 0 5
      Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake
  24. 0 1
      Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt
  25. 0 9
      Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt
  26. 0 9
      Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt
  27. 0 5
      Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake
  28. 0 1
      Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-result.txt
  29. 0 7
      Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-VS.txt
  30. 0 7
      Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-Xcode.txt
  31. 0 5
      Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions.cmake
  32. 0 23
      Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake
  33. 0 5
      Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp

+ 21 - 21
Help/manual/cmake-generator-expressions.7.rst

@@ -97,21 +97,35 @@ Available logical expressions are:
   compile features and a list of supported compilers.
 ``$<COMPILE_LANGUAGE:lang>``
   ``1`` when the language used for compilation unit matches ``lang``,
-  otherwise ``0``.  This expression may be 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):
+  otherwise ``0``.  This expression may be used to specify compile options,
+  compile definitions, and include directories for source files of a
+  particular language in a target. For example:
 
   .. code-block:: cmake
 
-    add_executable(myapp main.cpp foo.c bar.cpp)
+    add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
     target_compile_options(myapp
       PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
     )
+    target_compile_definitions(myapp
+      PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX>
+              $<$<COMPILE_LANGUAGE:CUDA>:COMPILING_CUDA>
+    )
+    target_include_directories(myapp
+      PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
+    )
+
+  This specifies the use of the ``-fno-exceptions`` compile option,
+  ``COMPILING_CXX`` compile definition, and ``cxx_headers`` include
+  directory for C++ only (compiler id checks elided).  It also specifies
+  a ``COMPILING_CUDA`` compile definition for CUDA.
 
-  Note that with :ref:`Visual Studio Generators` there is no way to represent
+  Note that with :ref:`Visual Studio Generators` and :generator:`Xcode` there
+  is no way to represent target-wide compile definitions or include directories
+  separately for ``C`` and ``CXX`` languages.
+  Also, with :ref:`Visual Studio Generators` there is no way to represent
   target-wide flags separately for ``C`` and ``CXX`` languages.  Under these
-  generators, target-wide flags for both C and C++ sources will be evaluated
+  generators, expressions for both C and C++ sources will be evaluated
   using ``CXX`` if there are any C++ sources and otherwise using ``C``.
   A workaround is to create separate libraries for each source file language
   instead:
@@ -124,20 +138,6 @@ 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
-  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
 =========================
 

+ 11 - 4
Help/release/dev/extend-compile-language-genex.rst

@@ -1,7 +1,14 @@
 extend-compile-language-genex
 -----------------------------
 
-* The ``COMPILE_LANGUAGE`` :manual:`generator expression
-  <cmake-generator-expressions(7)>` may now be used with
-  :ref:`Visual Studio Generators` in :prop_tgt:`COMPILE_OPTIONS`
-  and :command:`file(GENERATE)`.
+* :ref:`Visual Studio Generators` learned to support the ``COMPILE_LANGUAGE``
+  :manual:`generator expression <cmake-generator-expressions(7)>` in
+  target-wide :prop_tgt:`COMPILE_DEFINITIONS`,
+  :prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_OPTIONS`, and
+  :command:`file(GENERATE)`.
+
+* The :generator:`Xcode` generator learned to support the ``COMPILE_LANGUAGE``
+  :manual:`generator expression <cmake-generator-expressions(7)>` in
+  target-wide :prop_tgt:`COMPILE_DEFINITIONS` and
+  :prop_tgt:`INCLUDE_DIRECTORIES`.  It previously supported only
+  :prop_tgt:`COMPILE_OPTIONS` and :command:`file(GENERATE)`.

+ 9 - 28
Source/cmGeneratorExpressionNode.cxx

@@ -805,7 +805,7 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
     const std::vector<std::string>& parameters,
     cmGeneratorExpressionContext* context,
     const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
     if (context->Language.empty()) {
       reportError(
@@ -827,33 +827,14 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
       return std::string();
     }
     std::string genName = gg->GetName();
-    if (genName.find("Visual Studio") != std::string::npos) {
-      if (dagChecker && (dagChecker->EvaluatingCompileDefinitions() ||
-                         dagChecker->EvaluatingIncludeDirectories())) {
-        reportError(
-          context, content->GetOriginalExpression(),
-          "$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS "
-          "and file(GENERATE) with the Visual Studio generator.");
-        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 for COMPILE_OPTIONS "
-          "and file(GENERATE) 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 (genName.find("Makefiles") == std::string::npos &&
+        genName.find("Ninja") == std::string::npos &&
+        genName.find("Visual Studio") == 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.");
+      return std::string();
     }
     if (parameters.empty()) {
       return context->Language;

+ 9 - 3
Source/cmGlobalXCodeGenerator.cxx

@@ -1703,6 +1703,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
       gtgt->GetName().c_str());
     return;
   }
+  std::string const& langForPreprocessor = llang;
 
   if (gtgt->IsIPOEnabled(llang, configName)) {
     const char* ltoValue =
@@ -1723,7 +1724,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
     this->AppendDefines(ppDefs, exportMacro);
   }
   std::vector<std::string> targetDefines;
-  gtgt->GetCompileDefinitions(targetDefines, configName, "C");
+  if (!langForPreprocessor.empty()) {
+    gtgt->GetCompileDefinitions(targetDefines, configName,
+                                langForPreprocessor);
+  }
   this->AppendDefines(ppDefs, targetDefines);
   buildSettings->AddAttribute("GCC_PREPROCESSOR_DEFINITIONS",
                               ppDefs.CreateList());
@@ -1996,8 +2000,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
   const bool emitSystemIncludes = this->XcodeVersion >= 83;
 
   std::vector<std::string> includes;
-  this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt, "C",
-                                                     configName);
+  if (!langForPreprocessor.empty()) {
+    this->CurrentLocalGenerator->GetIncludeDirectories(
+      includes, gtgt, langForPreprocessor, configName);
+  }
   std::set<std::string> emitted;
   emitted.insert("/System/Library/Frameworks");
 

+ 29 - 14
Source/cmLocalVisualStudio7Generator.cxx

@@ -637,7 +637,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
     configType = projectType;
   }
   std::string flags;
-  if (strcmp(configType, "10") != 0) {
+  std::string langForClCompile;
+  if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
     const std::string& linkLanguage =
       (this->FortranProject ? std::string("Fortran")
                             : target->GetLinkerLanguage(configName));
@@ -647,10 +648,11 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
         target->GetName().c_str());
       return;
     }
-    if (linkLanguage == "C" || linkLanguage == "CXX" ||
-        linkLanguage == "Fortran") {
+    langForClCompile = linkLanguage;
+    if (langForClCompile == "C" || langForClCompile == "CXX" ||
+        langForClCompile == "Fortran") {
       std::string baseFlagVar = "CMAKE_";
-      baseFlagVar += linkLanguage;
+      baseFlagVar += langForClCompile;
       baseFlagVar += "_FLAGS";
       flags = this->Makefile->GetRequiredDefinition(baseFlagVar.c_str());
       std::string flagVar =
@@ -667,7 +669,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
     }
 
     // Add the target-specific flags.
-    this->AddCompileOptions(flags, target, linkLanguage, configName);
+    this->AddCompileOptions(flags, target, langForClCompile, configName);
 
     // Check IPO related warning/error.
     target->IsIPOEnabled(linkLanguage, configName);
@@ -703,7 +705,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
   targetOptions.Parse(defineFlags.c_str());
   targetOptions.ParseFinish();
   std::vector<std::string> targetDefines;
-  target->GetCompileDefinitions(targetDefines, configName, "CXX");
+  if (!langForClCompile.empty()) {
+    target->GetCompileDefinitions(targetDefines, configName, langForClCompile);
+  }
   targetOptions.AddDefines(targetDefines);
   targetOptions.SetVerboseMakefile(
     this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
@@ -792,10 +796,13 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
          << "\\$(ConfigurationName)\"\n";
   }
   fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
-  std::vector<std::string> includes;
-  this->GetIncludeDirectories(includes, target, "C", configName);
-  std::vector<std::string>::iterator i = includes.begin();
-  for (; i != includes.end(); ++i) {
+  std::vector<std::string> includes_cl;
+  if (!langForClCompile.empty()) {
+    this->GetIncludeDirectories(includes_cl, target, langForClCompile,
+                                configName);
+  }
+  std::vector<std::string>::iterator i = includes_cl.begin();
+  for (; i != includes_cl.end(); ++i) {
     // output the include path
     std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
     fout << ipath << ";";
@@ -810,7 +817,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
   }
   fout << "\"\n";
   targetOptions.OutputFlagMap(fout, "\t\t\t\t");
-  targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n", "CXX");
+  targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n",
+                                              langForClCompile);
   fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
   if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
     // Specify the compiler program database file if configured.
@@ -829,9 +837,12 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
       "\t\t\t\tName=\"MASM\"\n"
       "\t\t\t\tIncludePaths=\""
       ;
+    std::vector<std::string> includes_masm;
+    this->GetIncludeDirectories(includes_masm, target, "ASM_MASM",
+                                configName);
     /* clang-format on */
     const char* sep = "";
-    for (i = includes.begin(); i != includes.end(); ++i) {
+    for (i = includes_masm.begin(); i != includes_masm.end(); ++i) {
       std::string inc = *i;
       cmConvertToWindowsSlash(inc);
       fout << sep << this->EscapeForXML(inc);
@@ -859,7 +870,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
   }
   fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
        << "\t\t\t\tAdditionalIncludeDirectories=\"";
-  for (i = includes.begin(); i != includes.end(); ++i) {
+  std::vector<std::string> includes_rc;
+  this->GetIncludeDirectories(includes_rc, target, "RC", configName);
+  for (i = includes_rc.begin(); i != includes_rc.end(); ++i) {
     std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
     fout << ipath << ";";
   }
@@ -873,7 +886,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
   }
   fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
   fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
-  for (i = includes.begin(); i != includes.end(); ++i) {
+  std::vector<std::string> includes_midl;
+  this->GetIncludeDirectories(includes_midl, target, "MIDL", configName);
+  for (i = includes_midl.begin(); i != includes_midl.end(); ++i) {
     std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
     fout << ipath << ";";
   }

+ 45 - 22
Source/cmVisualStudio10TargetGenerator.cxx

@@ -2319,6 +2319,18 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental(
   }
 }
 
+std::vector<std::string> cmVisualStudio10TargetGenerator::GetIncludes(
+  std::string const& config, std::string const& lang) const
+{
+  std::vector<std::string> includes;
+  this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
+                                              lang, config);
+  for (std::string& i : includes) {
+    this->ConvertToWindowsSlash(i);
+  }
+  return includes;
+}
+
 bool cmVisualStudio10TargetGenerator::ComputeClOptions()
 {
   for (std::string const& i : this->Configurations) {
@@ -2379,6 +2391,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
       }
     }
   }
+  this->LangForClCompile = langForClCompile;
   if (!langForClCompile.empty()) {
     std::string baseFlagVar = "CMAKE_";
     baseFlagVar += langForClCompile;
@@ -2422,8 +2435,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   std::vector<std::string> targetDefines;
   switch (this->ProjectType) {
     case vcxproj:
-      this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
-                                                   "CXX");
+      if (!langForClCompile.empty()) {
+        this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
+                                                     langForClCompile);
+      }
       break;
     case csproj:
       this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
@@ -2487,7 +2502,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
 }
 
 void cmVisualStudio10TargetGenerator::WriteClOptions(
-  std::string const& configName, std::vector<std::string> const& includes)
+  std::string const& configName)
 {
   Options& clOptions = *(this->ClOptions[configName]);
   if (this->ProjectType == csproj) {
@@ -2495,12 +2510,16 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
   }
   this->WriteString("<ClCompile>\n", 2);
   clOptions.PrependInheritedString("AdditionalOptions");
-  clOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+  if (!this->LangForClCompile.empty()) {
+    std::vector<std::string> const includes =
+      this->GetIncludes(configName, this->LangForClCompile);
+    clOptions.AppendFlag("AdditionalIncludeDirectories", includes);
+  }
   clOptions.AppendFlag("AdditionalIncludeDirectories",
                        "%(AdditionalIncludeDirectories)");
   clOptions.OutputFlagMap(*this->BuildFileStream, "      ");
   clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, "      ",
-                                          "\n", "CXX");
+                                          "\n", this->LangForClCompile);
 
   if (this->NsightTegra) {
     if (const char* processMax =
@@ -2581,7 +2600,7 @@ bool cmVisualStudio10TargetGenerator::ComputeRcOptions(
 }
 
 void cmVisualStudio10TargetGenerator::WriteRCOptions(
-  std::string const& configName, std::vector<std::string> const& includes)
+  std::string const& configName)
 {
   if (!this->MSTools) {
     return;
@@ -2591,6 +2610,8 @@ void cmVisualStudio10TargetGenerator::WriteRCOptions(
   Options& rcOptions = *(this->RcOptions[configName]);
   rcOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, "      ",
                                           "\n", "RC");
+  std::vector<std::string> const includes =
+    this->GetIncludes(configName, "RC");
   rcOptions.AppendFlag("AdditionalIncludeDirectories", includes);
   rcOptions.AppendFlag("AdditionalIncludeDirectories",
                        "%(AdditionalIncludeDirectories)");
@@ -2701,7 +2722,7 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
 }
 
 void cmVisualStudio10TargetGenerator::WriteCudaOptions(
-  std::string const& configName, std::vector<std::string> const& includes)
+  std::string const& configName)
 {
   if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) {
     return;
@@ -2709,6 +2730,8 @@ void cmVisualStudio10TargetGenerator::WriteCudaOptions(
   this->WriteString("<CudaCompile>\n", 2);
 
   Options& cudaOptions = *(this->CudaOptions[configName]);
+  std::vector<std::string> const includes =
+    this->GetIncludes(configName, "CUDA");
   cudaOptions.AppendFlag("Include", includes);
   cudaOptions.AppendFlag("Include", "%(Include)");
   cudaOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, "      ",
@@ -2823,7 +2846,7 @@ bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
 }
 
 void cmVisualStudio10TargetGenerator::WriteMasmOptions(
-  std::string const& configName, std::vector<std::string> const& includes)
+  std::string const& configName)
 {
   if (!this->MSTools || !this->GlobalGenerator->IsMasmEnabled()) {
     return;
@@ -2836,6 +2859,8 @@ void cmVisualStudio10TargetGenerator::WriteMasmOptions(
                                           "\n", "ASM_MASM");
 
   Options& masmOptions = *(this->MasmOptions[configName]);
+  std::vector<std::string> const includes =
+    this->GetIncludes(configName, "ASM_MASM");
   masmOptions.AppendFlag("IncludePaths", includes);
   masmOptions.AppendFlag("IncludePaths", "%(IncludePaths)");
   masmOptions.PrependInheritedString("AdditionalOptions");
@@ -2880,13 +2905,15 @@ bool cmVisualStudio10TargetGenerator::ComputeNasmOptions(
 }
 
 void cmVisualStudio10TargetGenerator::WriteNasmOptions(
-  std::string const& configName, std::vector<std::string> includes)
+  std::string const& configName)
 {
   if (!this->GlobalGenerator->IsNasmEnabled()) {
     return;
   }
   this->WriteString("<NASM>\n", 2);
 
+  std::vector<std::string> includes =
+    this->GetIncludes(configName, "ASM_NASM");
   Options& nasmOptions = *(this->NasmOptions[configName]);
   for (size_t i = 0; i < includes.size(); i++) {
     includes[i] += "\\";
@@ -3434,7 +3461,7 @@ void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair(
 }
 
 void cmVisualStudio10TargetGenerator::WriteMidlOptions(
-  std::string const& /*config*/, std::vector<std::string> const& includes)
+  std::string const& configName)
 {
   if (!this->MSTools) {
     return;
@@ -3460,6 +3487,8 @@ void cmVisualStudio10TargetGenerator::WriteMidlOptions(
   // on the CMake side?
   this->WriteString("<Midl>\n", 2);
   this->WriteString("<AdditionalIncludeDirectories>", 3);
+  std::vector<std::string> const includes =
+    this->GetIncludes(configName, "MIDL");
   for (std::string const& i : includes) {
     *this->BuildFileStream << cmVS10EscapeXML(i) << ";";
   }
@@ -3484,25 +3513,19 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
     return;
   }
   for (std::string const& i : this->Configurations) {
-    std::vector<std::string> includes;
-    this->LocalGenerator->GetIncludeDirectories(includes,
-                                                this->GeneratorTarget, "C", i);
-    for (std::string& ii : includes) {
-      this->ConvertToWindowsSlash(ii);
-    }
     this->WritePlatformConfigTag("ItemDefinitionGroup", i, 1);
     *this->BuildFileStream << "\n";
     //    output cl compile flags <ClCompile></ClCompile>
     if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
-      this->WriteClOptions(i, includes);
+      this->WriteClOptions(i);
       //    output rc compile flags <ResourceCompile></ResourceCompile>
-      this->WriteRCOptions(i, includes);
-      this->WriteCudaOptions(i, includes);
-      this->WriteMasmOptions(i, includes);
-      this->WriteNasmOptions(i, includes);
+      this->WriteRCOptions(i);
+      this->WriteCudaOptions(i);
+      this->WriteMasmOptions(i);
+      this->WriteNasmOptions(i);
     }
     //    output midl flags       <Midl></Midl>
-    this->WriteMidlOptions(i, includes);
+    this->WriteMidlOptions(i);
     // write events
     if (this->ProjectType != csproj) {
       this->WriteEvents(i);

+ 10 - 12
Source/cmVisualStudio10TargetGenerator.h

@@ -90,18 +90,18 @@ private:
   void WriteTargetSpecificReferences();
   void WriteTargetsFileReferences();
 
+  std::vector<std::string> GetIncludes(std::string const& config,
+                                       std::string const& lang) const;
+
   bool ComputeClOptions();
   bool ComputeClOptions(std::string const& configName);
-  void WriteClOptions(std::string const& config,
-                      std::vector<std::string> const& includes);
+  void WriteClOptions(std::string const& config);
   bool ComputeRcOptions();
   bool ComputeRcOptions(std::string const& config);
-  void WriteRCOptions(std::string const& config,
-                      std::vector<std::string> const& includes);
+  void WriteRCOptions(std::string const& config);
   bool ComputeCudaOptions();
   bool ComputeCudaOptions(std::string const& config);
-  void WriteCudaOptions(std::string const& config,
-                        std::vector<std::string> const& includes);
+  void WriteCudaOptions(std::string const& config);
 
   bool ComputeCudaLinkOptions();
   bool ComputeCudaLinkOptions(std::string const& config);
@@ -109,20 +109,17 @@ private:
 
   bool ComputeMasmOptions();
   bool ComputeMasmOptions(std::string const& config);
-  void WriteMasmOptions(std::string const& config,
-                        std::vector<std::string> const& includes);
+  void WriteMasmOptions(std::string const& config);
   bool ComputeNasmOptions();
   bool ComputeNasmOptions(std::string const& config);
-  void WriteNasmOptions(std::string const& config,
-                        std::vector<std::string> includes);
+  void WriteNasmOptions(std::string const& config);
 
   bool ComputeLinkOptions();
   bool ComputeLinkOptions(std::string const& config);
   bool ComputeLibOptions();
   bool ComputeLibOptions(std::string const& config);
   void WriteLinkOptions(std::string const& config);
-  void WriteMidlOptions(std::string const& config,
-                        std::vector<std::string> const& includes);
+  void WriteMidlOptions(std::string const& config);
   void WriteAntBuildOptions(std::string const& config);
   void OutputLinkIncremental(std::string const& configName);
   void WriteCustomRule(cmSourceFile const* source,
@@ -180,6 +177,7 @@ private:
   OptionsMap MasmOptions;
   OptionsMap NasmOptions;
   OptionsMap LinkOptions;
+  std::string LangForClCompile;
   std::string PathToProjectFile;
   std::string ProjectFileExtension;
   enum VsProjectType

+ 11 - 11
Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt

@@ -26,18 +26,18 @@ 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_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>
+)
+if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
   target_compile_definitions(consumer
-    PRIVATE -DTEST_LANG_DEFINES
+    PRIVATE TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
   )
 endif()
 

+ 19 - 1
Tests/CMakeCommands/target_compile_definitions/consumer.c

@@ -1,5 +1,23 @@
 
-#ifdef TEST_LANG_DEFINES
+// Visual Studio allows only one set of flags for C and C++.
+// In a target using C++ we pick the C++ flags even for C sources.
+#ifdef TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
+#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
+#else
 #ifdef CONSUMER_LANG_CXX
 #error Unexpected CONSUMER_LANG_CXX
 #endif

+ 0 - 2
Tests/CMakeCommands/target_compile_definitions/consumer.cpp

@@ -15,7 +15,6 @@
 #error Expected DASH_D_DEFINE
 #endif
 
-#ifdef TEST_LANG_DEFINES
 #ifndef CONSUMER_LANG_CXX
 #error Expected CONSUMER_LANG_CXX
 #endif
@@ -31,7 +30,6 @@
 #if LANG_IS_C
 #error Unexpected LANG_IS_C
 #endif
-#endif
 
 int main()
 {

+ 10 - 10
Tests/CMakeCommands/target_include_directories/CMakeLists.txt

@@ -42,17 +42,17 @@ 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_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>
+)
+if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
   target_compile_definitions(consumer
-    PRIVATE -DTEST_LANG_DEFINES
+    PRIVATE TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
   )
 endif()
 

+ 9 - 1
Tests/CMakeCommands/target_include_directories/consumer.c

@@ -1,5 +1,13 @@
 
-#ifdef TEST_LANG_DEFINES
+// Visual Studio allows only one set of flags for C and C++.
+// In a target using C++ we pick the C++ flags even for C sources.
+#ifdef TEST_LANG_DEFINES_FOR_VISUAL_STUDIO_OR_XCODE
+#include "cxx_only.h"
+
+#ifndef CXX_ONLY_DEFINE
+#error Expected CXX_ONLY_DEFINE
+#endif
+#else
 #include "c_only.h"
 
 #ifndef C_ONLY_DEFINE

+ 1 - 5
Tests/CMakeCommands/target_include_directories/consumer.cpp

@@ -1,12 +1,10 @@
 
 #include "consumer.h"
 #include "common.h"
+#include "cxx_only.h"
 #include "interfaceinclude.h"
 #include "publicinclude.h"
 #include "relative_dir.h"
-#ifdef TEST_LANG_DEFINES
-#include "cxx_only.h"
-#endif
 
 #ifdef PRIVATEINCLUDE_DEFINE
 #error Unexpected PRIVATEINCLUDE_DEFINE
@@ -32,11 +30,9 @@
 #error Expected CONSUMER_DEFINE
 #endif
 
-#ifdef TEST_LANG_DEFINES
 #ifndef CXX_ONLY_DEFINE
 #error Expected CXX_ONLY_DEFINE
 #endif
-#endif
 
 int main()
 {

+ 9 - 2
Tests/CudaOnly/WithDefs/CMakeLists.txt

@@ -32,8 +32,8 @@ add_executable(CudaOnlyWithDefs ${main})
 
 target_compile_options(CudaOnlyWithDefs
   PRIVATE
-    -DCOMPILE_LANG_$<COMPILE_LANGUAGE>
-    -DLANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
+    -DFLAG_COMPILE_LANG_$<COMPILE_LANGUAGE>
+    -DFLAG_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
     -Xcompiler=-DHOST_DEFINE
     $<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>>
   )
@@ -41,8 +41,15 @@ target_compile_options(CudaOnlyWithDefs
 target_compile_definitions(CudaOnlyWithDefs
   PRIVATE
     $<$<CONFIG:RELEASE>:$<BUILD_INTERFACE:${release_compile_defs}>>
+    -DDEF_COMPILE_LANG_$<COMPILE_LANGUAGE>
+    -DDEF_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
   )
 
+target_include_directories(CudaOnlyWithDefs
+  PRIVATE
+    $<$<COMPILE_LANGUAGE:CUDA>:${CMAKE_CURRENT_SOURCE_DIR}/inc_cuda>
+)
+
 if(APPLE)
   # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
   set_property(TARGET CudaOnlyWithDefs PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})

+ 1 - 0
Tests/CudaOnly/WithDefs/inc_cuda/inc_cuda.h

@@ -0,0 +1 @@
+#define INC_CUDA

+ 23 - 6
Tests/CudaOnly/WithDefs/main.notcu

@@ -2,6 +2,11 @@
 #include <cuda_runtime.h>
 #include <iostream>
 
+#include <inc_cuda.h>
+#ifndef INC_CUDA
+#error "INC_CUDA not defined!"
+#endif
+
 #ifndef HOST_DEFINE
 #error "HOST_DEFINE not defined!"
 #endif
@@ -10,16 +15,28 @@
 #error "PACKED_DEFINE not defined!"
 #endif
 
-#ifndef COMPILE_LANG_CUDA
-#error "COMPILE_LANG_CUDA not defined!"
+#ifndef FLAG_COMPILE_LANG_CUDA
+#error "FLAG_COMPILE_LANG_CUDA not defined!"
+#endif
+
+#ifndef FLAG_LANG_IS_CUDA
+#error "FLAG_LANG_IS_CUDA not defined!"
+#endif
+
+#if !FLAG_LANG_IS_CUDA
+#error "Expected FLAG_LANG_IS_CUDA"
+#endif
+
+#ifndef DEF_COMPILE_LANG_CUDA
+#error "DEF_COMPILE_LANG_CUDA not defined!"
 #endif
 
-#ifndef LANG_IS_CUDA
-#error "LANG_IS_CUDA not defined!"
+#ifndef DEF_LANG_IS_CUDA
+#error "DEF_LANG_IS_CUDA not defined!"
 #endif
 
-#if !LANG_IS_CUDA
-#error "Expected LANG_IS_CUDA"
+#if !DEF_LANG_IS_CUDA
+#error "Expected DEF_LANG_IS_CUDA"
 #endif
 
 static __global__ void DetermineIfValidCudaDevice()

+ 2 - 4
Tests/GeneratorExpression/CMakeLists.txt

@@ -269,10 +269,8 @@ set_property(SOURCE srcgenex_flags_COMPILE_LANGUAGE.c PROPERTY COMPILE_FLAGS "$<
 add_executable(srcgenex_defs srcgenex_defs.c)
 set_property(SOURCE srcgenex_defs.c PROPERTY COMPILE_DEFINITIONS NAME=$<TARGET_PROPERTY:NAME>)
 
-if (CMAKE_GENERATOR MATCHES "Makefiles|Ninja|Watcom WMake")
-  add_executable(srcgenex_defs_COMPILE_LANGUAGE srcgenex_defs_COMPILE_LANGUAGE.c)
-  set_property(SOURCE srcgenex_defs_COMPILE_LANGUAGE.c PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:C>:NAME=$<TARGET_PROPERTY:NAME>>)
-endif()
+add_executable(srcgenex_defs_COMPILE_LANGUAGE srcgenex_defs_COMPILE_LANGUAGE.c)
+set_property(SOURCE srcgenex_defs_COMPILE_LANGUAGE.c PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:C>:NAME=$<TARGET_PROPERTY:NAME>>)
 
 #-----------------------------------------------------------------------------
 # Cover test properties with generator expressions.

+ 0 - 2
Tests/RunCMake/CMakeLists.txt

@@ -351,8 +351,6 @@ add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths)
 set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES)
 add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths)
 
-add_RunCMake_test(COMPILE_LANGUAGE-genex)
-
 # Matlab module related tests
 if(CMake_TEST_FindMatlab)
   add_RunCMake_test(FindMatlab)

+ 0 - 3
Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt

@@ -1,3 +0,0 @@
-cmake_minimum_required(VERSION 3.1)
-project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)

+ 0 - 1
Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt

@@ -1 +0,0 @@
-1

+ 0 - 9
Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt

@@ -1,9 +0,0 @@
-CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
-  Error evaluating generator expression:
-
-    \$<COMPILE_LANGUAGE:CXX>
-
-  \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
-  file\(GENERATE\) with the Visual Studio generator.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)

+ 0 - 9
Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt

@@ -1,9 +0,0 @@
-CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\):
-  Error evaluating generator expression:
-
-    \$<COMPILE_LANGUAGE:CXX>
-
-  \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
-  file\(GENERATE\) with the Xcode generator.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)

+ 0 - 5
Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake

@@ -1,5 +0,0 @@
-
-enable_language(CXX)
-
-add_executable(main main.cpp)
-target_compile_definitions(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>)

+ 0 - 1
Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt

@@ -1 +0,0 @@
-1

+ 0 - 9
Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt

@@ -1,9 +0,0 @@
-CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
-  Error evaluating generator expression:
-
-    \$<COMPILE_LANGUAGE:CXX>
-
-  \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
-  file\(GENERATE\) with the Visual Studio generator.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)

+ 0 - 9
Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt

@@ -1,9 +0,0 @@
-CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\):
-  Error evaluating generator expression:
-
-    \$<COMPILE_LANGUAGE:CXX>
-
-  \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
-  file\(GENERATE\) with the Xcode generator.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)

+ 0 - 5
Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake

@@ -1,5 +0,0 @@
-
-enable_language(CXX)
-
-add_executable(main main.cpp)
-target_include_directories(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:anydir>)

+ 0 - 1
Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-result.txt

@@ -1 +0,0 @@
-1

+ 0 - 7
Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-VS.txt

@@ -1,7 +0,0 @@
-CMake Error:
-  Error evaluating generator expression:
-
-    \$<COMPILE_LANGUAGE:CXX>
-
-  \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
-  file\(GENERATE\) with the Visual Studio generator.

+ 0 - 7
Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions-stderr-Xcode.txt

@@ -1,7 +0,0 @@
-CMake Error:
-  Error evaluating generator expression:
-
-    \$<COMPILE_LANGUAGE:CXX>
-
-  \$<COMPILE_LANGUAGE:...> may only be used for COMPILE_OPTIONS and
-  file\(GENERATE\) with the Xcode generator.

+ 0 - 5
Tests/RunCMake/COMPILE_LANGUAGE-genex/PerSourceCompileDefinitions.cmake

@@ -1,5 +0,0 @@
-
-enable_language(CXX)
-
-add_executable(main main.cpp)
-set_property(SOURCE main.cpp PROPERTY COMPILE_DEFINITIONS $<$<COMPILE_LANGUAGE:CXX>:ANYTHING>)

+ 0 - 23
Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake

@@ -1,23 +0,0 @@
-include(RunCMake)
-
-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()
-if (RunCMake_GENERATOR STREQUAL "Xcode")
-    set(RunCMake-stderr-file PerSourceCompileDefinitions-stderr-Xcode.txt)
-    run_cmake(PerSourceCompileDefinitions)
-elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
-    set(RunCMake-stderr-file PerSourceCompileDefinitions-stderr-VS.txt)
-    run_cmake(PerSourceCompileDefinitions)
-endif()

+ 0 - 5
Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp

@@ -1,5 +0,0 @@
-
-int main()
-{
-  return 0;
-}