Kaynağa Gözat

Merge topic 'explicit-LANGUAGE-flag'

48aac247e9 Compile with explicit language flag when source LANGUAGE property is set
2e67a75acd Embarcadero: Simplify addition of -P flag for C++

Acked-by: Kitware Robot <[email protected]>
Merge-request: !5522
Brad King 5 yıl önce
ebeveyn
işleme
76685b985d
40 değiştirilmiş dosya ile 203 ekleme ve 9 silme
  1. 1 0
      Help/manual/cmake-policies.7.rst
  2. 36 0
      Help/policy/CMP0119.rst
  3. 7 1
      Help/prop_sf/LANGUAGE.rst
  4. 5 0
      Help/release/dev/explicit-LANGUAGE-flag.rst
  5. 1 0
      Modules/Compiler/AppleClang-C.cmake
  6. 2 0
      Modules/Compiler/AppleClang-CXX.cmake
  7. 2 0
      Modules/Compiler/Clang-C.cmake
  8. 1 0
      Modules/Compiler/Clang-CXX.cmake
  9. 1 0
      Modules/Compiler/GNU-C.cmake
  10. 1 0
      Modules/Compiler/GNU-CXX.cmake
  11. 3 0
      Modules/Compiler/Intel-C.cmake
  12. 2 0
      Modules/Compiler/Intel-CXX.cmake
  13. 1 0
      Modules/Compiler/MSVC-C.cmake
  14. 2 0
      Modules/Compiler/XLClang-C.cmake
  15. 2 0
      Modules/Compiler/XLClang-CXX.cmake
  16. 4 4
      Modules/Platform/Windows-Embarcadero.cmake
  17. 5 0
      Source/cmExtraSublimeTextGenerator.cxx
  18. 24 0
      Source/cmGeneratorTarget.cxx
  19. 3 0
      Source/cmGeneratorTarget.h
  20. 5 0
      Source/cmGlobalXCodeGenerator.cxx
  21. 4 0
      Source/cmMakefileTargetGenerator.cxx
  22. 9 1
      Source/cmNinjaTargetGenerator.cxx
  23. 7 2
      Source/cmPolicies.h
  24. 4 0
      Tests/RunCMake/CMP0119/AltExtC.zzz
  25. 3 0
      Tests/RunCMake/CMP0119/AltExtCXX.zzz
  26. 4 0
      Tests/RunCMake/CMP0119/CMP0119-Common.cmake
  27. 6 0
      Tests/RunCMake/CMP0119/CMP0119-NEW.cmake
  28. 1 0
      Tests/RunCMake/CMP0119/CMP0119-OLD-build-result.txt
  29. 1 0
      Tests/RunCMake/CMP0119/CMP0119-OLD-build-stderr.txt
  30. 2 0
      Tests/RunCMake/CMP0119/CMP0119-OLD.cmake
  31. 1 0
      Tests/RunCMake/CMP0119/CMP0119-WARN-build-result.txt
  32. 1 0
      Tests/RunCMake/CMP0119/CMP0119-WARN-build-stderr.txt
  33. 2 0
      Tests/RunCMake/CMP0119/CMP0119-WARN.cmake
  34. 3 0
      Tests/RunCMake/CMP0119/CMakeLists.txt
  35. 17 0
      Tests/RunCMake/CMP0119/RunCMakeTest.cmake
  36. 1 0
      Tests/RunCMake/CMakeLists.txt
  37. 1 0
      Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
  38. 8 0
      Tests/SetLang/CMakeLists.txt
  39. 13 1
      Tests/SetLang/bar.c
  40. 7 0
      Tests/SetLang/zoom.zzz

+ 1 - 0
Help/manual/cmake-policies.7.rst

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.20
 .. toctree::
    :maxdepth: 1
 
+   CMP0119: LANGUAGE source file property explicitly compiles as language. </policy/CMP0119>
    CMP0118: The GENERATED source file property is now visible in all directories. </policy/CMP0118>
    CMP0117: MSVC RTTI flag /GR is not added to CMAKE_CXX_FLAGS by default. </policy/CMP0117>
    CMP0116: Ninja generators transform DEPFILEs from add_custom_command(). </policy/CMP0116>

+ 36 - 0
Help/policy/CMP0119.rst

@@ -0,0 +1,36 @@
+CMP0119
+-------
+
+.. versionadded:: 3.20
+
+:prop_sf:`LANGUAGE` source file property explicitly compiles as specified
+language.
+
+The :prop_sf:`LANGUAGE` source file property is documented to mean that the
+source file is written in the specified language.  In CMake 3.19 and below,
+setting this property causes CMake to compile the source file using the
+compiler for the specified language.  However, it only passes an explicit
+flag to tell the compiler to treat the source as the specified language
+for MSVC-like, XL, and Embarcadero compilers for the ``CXX`` language.
+CMake 3.20 and above prefer to also explicitly tell the compiler to use
+the specified language using a flag such as ``-x c`` on all compilers
+for which such flags are known.
+
+This policy provides compatibility for projects that have not been updated
+to expect this behavior.  For example, some projects were setting the
+``LANGUAGE`` property to ``C`` on assembly-language ``.S`` source files
+in order to compile them using the C compiler.  Such projects should be
+updated to use ``enable_language(ASM)``, for which CMake will often choose
+the C compiler as the assembler on relevant platforms anyway.
+
+The ``OLD`` behavior for this policy is to interpret the ``LANGUAGE <LANG>``
+property using its undocumented meaning to "use the ``<LANG>`` compiler".
+The ``NEW`` behavior for this policy is to interpret the ``LANGUAGE <LANG>``
+property using its documented meaning to "compile as a ``<LANG>`` source".
+
+This policy was introduced in CMake version 3.20.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt

+ 7 - 1
Help/prop_sf/LANGUAGE.rst

@@ -1,7 +1,7 @@
 LANGUAGE
 --------
 
-What programming language is the file.
+Specify the programming language in which a source file is written.
 
 A property that can be set to indicate what programming language the
 source file is.  If it is not set the language is determined based on
@@ -9,3 +9,9 @@ the file extension.  Typical values are ``CXX`` (i.e.  C++), ``C``,
 ``CSharp``, ``CUDA``, ``Fortran``, ``ISPC``, and ``ASM``.  Setting this
 property for a file means this file will be compiled.  Do not set this
 for headers or files that should not be compiled.
+
+.. versionchanged:: 3.20
+  Setting this property causes the source file to be compiled as the
+  specified language, using explicit flags if possible.  Previously it
+  only caused the specified language's compiler to be used.
+  See policy :policy:`CMP0119`.

+ 5 - 0
Help/release/dev/explicit-LANGUAGE-flag.rst

@@ -0,0 +1,5 @@
+explicit-LANGUAGE-flag
+----------------------
+
+* The :prop_sf:`LANGUAGE` source file property now forces compilation
+  as the specified language.  See policy :policy:`CMP0119`.

+ 1 - 0
Modules/Compiler/AppleClang-C.cmake

@@ -12,6 +12,7 @@ if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
   endif()
 endif()
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
 
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")

+ 2 - 0
Modules/Compiler/AppleClang-CXX.cmake

@@ -1,6 +1,8 @@
 include(Compiler/Clang)
 __compiler_clang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
   if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
       AND CMAKE_GENERATOR MATCHES "Makefiles"

+ 2 - 0
Modules/Compiler/Clang-C.cmake

@@ -7,6 +7,7 @@ if(APPLE AND NOT appleClangPolicy STREQUAL NEW)
 endif()
 
 if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -TC)
   set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
   if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
       AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
@@ -14,6 +15,7 @@ if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
     set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
   endif()
 elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
   if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
       AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
       AND CMAKE_DEPFILE_FLAGS_C)

+ 1 - 0
Modules/Compiler/Clang-CXX.cmake

@@ -11,6 +11,7 @@ if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
     set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
   endif()
 
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
   set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
 endif()
 

+ 1 - 0
Modules/Compiler/GNU-C.cmake

@@ -10,6 +10,7 @@ if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
   set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
 endif()
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
 
 if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")

+ 1 - 0
Modules/Compiler/GNU-CXX.cmake

@@ -10,6 +10,7 @@ if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
   set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
 endif()
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
 
 if (WIN32)
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)

+ 3 - 0
Modules/Compiler/Intel-C.cmake

@@ -15,6 +15,7 @@ endif()
 
 if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
 
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -TC)
   set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
 
   if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 16.0.0)
@@ -34,6 +35,8 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
 
 else()
 
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
   if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.0)
     set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
     set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")

+ 2 - 0
Modules/Compiler/Intel-CXX.cmake

@@ -48,6 +48,8 @@ if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
 
 else()
 
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
   if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0)
     set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++20")
     set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++20")

+ 1 - 0
Modules/Compiler/MSVC-C.cmake

@@ -27,6 +27,7 @@ else()
   set(CMAKE_C_STANDARD_DEFAULT "")
 endif()
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -TC)
 set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
 
 # There are no C compiler modes so we hard-code the known compiler supported

+ 2 - 0
Modules/Compiler/XLClang-C.cmake

@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION  "-std=c89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89")

+ 2 - 0
Modules/Compiler/XLClang-CXX.cmake

@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_CXX98_STANDARD_COMPILE_OPTION  "")
   set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")

+ 4 - 4
Modules/Platform/Windows-Embarcadero.cmake

@@ -35,8 +35,8 @@ else()
   set(_tR "-tR") # Target uses the dynamic RTL
   set(_tW "-tW") # Target is a Windows application
 endif()
-set(_COMPILE_C "-c")
-set(_COMPILE_CXX "-P -c")
+set(_COMPILE_C "")
+set(_COMPILE_CXX " -P")
 
 set(CMAKE_LIBRARY_PATH_FLAG "-L")
 set(CMAKE_LINK_LIBRARY_FLAG "")
@@ -87,7 +87,7 @@ macro(__embarcadero_language lang)
   # place <DEFINES> outside the response file because Borland refuses
   # to parse quotes from the response file.
   set(CMAKE_${lang}_COMPILE_OBJECT
-    "<CMAKE_${lang}_COMPILER> ${_tR} -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<OBJECT> ${_COMPILE_${lang}} <SOURCE>"
+    "<CMAKE_${lang}_COMPILER> ${_tR} -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<OBJECT>${_COMPILE_${lang}} -c <SOURCE>"
     )
 
   set(CMAKE_${lang}_LINK_EXECUTABLE
@@ -98,7 +98,7 @@ macro(__embarcadero_language lang)
   # place <DEFINES> outside the response file because Borland refuses
   # to parse quotes from the response file.
   set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
-    "cpp32 -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>"
+    "cpp32 -DWIN32 <DEFINES> <INCLUDES> <FLAGS> -o<PREPROCESSED_SOURCE>${_COMPILE_${lang}} -c <SOURCE>"
     )
   # Borland >= 5.6 allows -P option for cpp32, <= 5.5 does not
 

+ 5 - 0
Source/cmExtraSublimeTextGenerator.cxx

@@ -349,6 +349,11 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
   if (language.empty()) {
     language = "C";
   }
+
+  // Explicitly add the explicit language flag before any other flag
+  // so user flags can override it.
+  gtgt->AddExplicitLanguageFlags(flags, *source);
+
   std::string const& config =
     lg->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
 

+ 24 - 0
Source/cmGeneratorTarget.cxx

@@ -3155,6 +3155,30 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
   }
 }
 
+void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags,
+                                                 cmSourceFile const& sf) const
+{
+  cmProp lang = sf.GetProperty("LANGUAGE");
+  if (!lang) {
+    return;
+  }
+
+  switch (this->GetPolicyStatusCMP0119()) {
+    case cmPolicies::WARN:
+    case cmPolicies::OLD:
+      // The OLD behavior is to not add explicit language flags.
+      return;
+    case cmPolicies::REQUIRED_ALWAYS:
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::NEW:
+      // The NEW behavior is to add explicit language flags.
+      break;
+  }
+
+  this->LocalGenerator->AppendFeatureOptions(flags, *lang,
+                                             "EXPLICIT_LANGUAGE");
+}
+
 void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
 {
   const std::string& property = this->GetSafeProperty("CUDA_ARCHITECTURES");

+ 3 - 0
Source/cmGeneratorTarget.h

@@ -447,6 +447,9 @@ public:
   void GetAppleArchs(const std::string& config,
                      std::vector<std::string>& archVec) const;
 
+  void AddExplicitLanguageFlags(std::string& flags,
+                                cmSourceFile const& sf) const;
+
   void AddCUDAArchitectureFlags(std::string& flags) const;
   void AddCUDAToolkitFlags(std::string& flags) const;
 

+ 5 - 0
Source/cmGlobalXCodeGenerator.cxx

@@ -938,6 +938,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
     default:
       break;
   }
+
+  // Explicitly add the explicit language flag before any other flag
+  // so user flags can override it.
+  gtgt->AddExplicitLanguageFlags(flags, *sf);
+
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
   if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
     lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));

+ 4 - 0
Source/cmMakefileTargetGenerator.cxx

@@ -622,6 +622,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
   // Build the set of compiler flags.
   std::string flags;
 
+  // Explicitly add the explicit language flag before any other flag
+  // so user flags can override it.
+  this->GeneratorTarget->AddExplicitLanguageFlags(flags, source);
+
   // Add language-specific flags.
   std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
   this->LocalGenerator->AppendFlags(flags, langFlags);

+ 9 - 1
Source/cmNinjaTargetGenerator.cxx

@@ -185,7 +185,15 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
     }
   }
 
-  std::string flags = this->GetFlags(language, config, filterArch);
+  std::string flags;
+  // Explicitly add the explicit language flag before any other flag
+  // so user flags can override it.
+  this->GeneratorTarget->AddExplicitLanguageFlags(flags, *source);
+
+  if (!flags.empty()) {
+    flags += " ";
+  }
+  flags += this->GetFlags(language, config, filterArch);
 
   // Add Fortran format flags.
   if (language == "Fortran") {

+ 7 - 2
Source/cmPolicies.h

@@ -352,7 +352,11 @@ class cmMakefile;
   SELECT(                                                                     \
     POLICY, CMP0118,                                                          \
     "The GENERATED source file property is now visible in all directories.",  \
-    3, 20, 0, cmPolicies::WARN)
+    3, 20, 0, cmPolicies::WARN)                                               \
+  SELECT(POLICY, CMP0119,                                                     \
+         "LANGUAGE source file property explicitly compiles as specified "    \
+         "language.",                                                         \
+         3, 20, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
@@ -387,7 +391,8 @@ class cmMakefile;
   F(CMP0105)                                                                  \
   F(CMP0108)                                                                  \
   F(CMP0112)                                                                  \
-  F(CMP0113)
+  F(CMP0113)                                                                  \
+  F(CMP0119)
 
 /** \class cmPolicies
  * \brief Handles changes in CMake behavior and policies

+ 4 - 0
Tests/RunCMake/CMP0119/AltExtC.zzz

@@ -0,0 +1,4 @@
+int main(void) {
+  int class = 0;
+  return class;
+}

+ 3 - 0
Tests/RunCMake/CMP0119/AltExtCXX.zzz

@@ -0,0 +1,3 @@
+int main() {
+  return static_cast<int>(0);
+}

+ 4 - 0
Tests/RunCMake/CMP0119/CMP0119-Common.cmake

@@ -0,0 +1,4 @@
+enable_language(C)
+
+add_executable(AltExtC AltExtC.zzz)
+set_property(SOURCE AltExtC.zzz PROPERTY LANGUAGE C)

+ 6 - 0
Tests/RunCMake/CMP0119/CMP0119-NEW.cmake

@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0119 NEW)
+include(CMP0119-Common.cmake)
+
+enable_language(CXX)
+add_executable(AltExtCXX AltExtCXX.zzz)
+set_property(SOURCE AltExtCXX.zzz PROPERTY LANGUAGE CXX)

+ 1 - 0
Tests/RunCMake/CMP0119/CMP0119-OLD-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/CMP0119/CMP0119-OLD-build-stderr.txt

@@ -0,0 +1 @@
+.*

+ 2 - 0
Tests/RunCMake/CMP0119/CMP0119-OLD.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0119 OLD)
+include(CMP0119-Common.cmake)

+ 1 - 0
Tests/RunCMake/CMP0119/CMP0119-WARN-build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/CMP0119/CMP0119-WARN-build-stderr.txt

@@ -0,0 +1 @@
+.*

+ 2 - 0
Tests/RunCMake/CMP0119/CMP0119-WARN.cmake

@@ -0,0 +1,2 @@
+
+include(CMP0119-Common.cmake)

+ 3 - 0
Tests/RunCMake/CMP0119/CMakeLists.txt

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

+ 17 - 0
Tests/RunCMake/CMP0119/RunCMakeTest.cmake

@@ -0,0 +1,17 @@
+include(RunCMake)
+
+function(run_CMP0119 status)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0119-${status}-build)
+  run_cmake(CMP0119-${status})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(CMP0119-${status}-build "${CMAKE_COMMAND}" --build . --config Debug)
+endfunction()
+
+if(NOT RunCMake_GENERATOR MATCHES "Visual Studio|Xcode" AND
+    NOT CMAKE_C_COMPILER_ID MATCHES "(Borland|Embarcadero|Watcom)")
+  run_CMP0119(WARN)
+  run_CMP0119(OLD)
+endif()
+if((CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang|MSVC|Borland|Embarcadero|Intel|TI)"))
+  run_CMP0119(NEW)
+endif()

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -130,6 +130,7 @@ if(CMAKE_GENERATOR MATCHES "Ninja")
   add_RunCMake_test(CMP0116)
 endif()
 add_RunCMake_test(CMP0118)
+add_RunCMake_test(CMP0119 -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
 
 # The test for Policy 65 requires the use of the
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode

+ 1 - 0
Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt

@@ -34,6 +34,7 @@
    \* CMP0108
    \* CMP0112
    \* CMP0113
+   \* CMP0119
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)

+ 8 - 0
Tests/SetLang/CMakeLists.txt

@@ -15,3 +15,11 @@ if(CMAKE_GENERATOR MATCHES "^Visual Studio" AND "x${CMAKE_C_COMPILER_ID}" STREQU
   add_library(stay stay_c.c stay_cxx.cxx)
   set_property(TARGET stay PROPERTY COMPILE_OPTIONS "-TP")
 endif()
+
+if((CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang|MSVC|Borland|Embarcadero|Intel|TI|XL)"))
+  cmake_policy(SET CMP0119 NEW)
+  add_library(zoom zoom.zzz)
+  set_source_files_properties(zoom.zzz PROPERTIES LANGUAGE CXX)
+  target_link_libraries(SetLang zoom)
+  target_compile_definitions(SetLang PRIVATE WITH_ZOOM)
+endif()

+ 13 - 1
Tests/SetLang/bar.c

@@ -1,10 +1,22 @@
 #include <stdio.h>
 
 int foo();
+
+#ifdef WITH_ZOOM
+int zoom();
+#endif
+
 class A
 {
 public:
-  A() { this->i = foo(); }
+  A()
+  {
+    this->i = foo();
+#ifdef WITH_ZOOM
+    i += zoom();
+    i -= zoom();
+#endif
+  }
   int i;
 };
 

+ 7 - 0
Tests/SetLang/zoom.zzz

@@ -0,0 +1,7 @@
+int zoom()
+{
+  int r = 10;
+  r++;
+  int ret = r + 10;
+  return ret;
+}