[Cmake-commits] CMake branch, next, updated. v3.7.1-1505-g37911fe

Brad King brad.king at kitware.com
Mon Dec 5 09:28:55 EST 2016


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  37911fe54ee6e9e566edde7539d619905f9a0c66 (commit)
       via  b4ed74e89e9d1fb7325573b6ac07fb355580c13b (commit)
       via  a5c6b771aa45f23cca8ef51c165475fc88cd60c2 (commit)
       via  10bda09161db81ff54a24698503d0a0596281d7a (commit)
      from  a0df705f16b844da0c8285c2885c75ef4872bf5e (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 -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=37911fe54ee6e9e566edde7539d619905f9a0c66
commit 37911fe54ee6e9e566edde7539d619905f9a0c66
Merge: a0df705 b4ed74e
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Dec 5 09:28:52 2016 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Dec 5 09:28:52 2016 -0500

    Merge topic 'try_compile-lang-std' into next
    
    b4ed74e8 try_compile: Add policy CMP0067 to honor language standards
    a5c6b771 try_compile: Add options to specify language standards
    10bda091 try_compile: Stop processing when test build system fails to generate


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b4ed74e89e9d1fb7325573b6ac07fb355580c13b
commit b4ed74e89e9d1fb7325573b6ac07fb355580c13b
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Dec 1 15:46:34 2016 -0500
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Dec 5 09:27:29 2016 -0500

    try_compile: Add policy CMP0067 to honor language standards
    
    Projects use `try_compile` to check if they will be able to compile some
    particular source code.  When a language standard variable like
    `CMAKE_CXX_STANDARD` is set, then the project intends to compile source
    code using a compiler mode for that standard.  Therefore it makes sense
    for `try_compile` to use that standard in the test project too.
    
    Unfortunately this was not done when support for the
    `CMAKE_CXX_STANDARD` variable was first implemented.  Add a policy to
    introduce the improved behavior in a compatible way.
    
    Closes: #16456

diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 3f16b63..cde3776 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -135,3 +135,17 @@ the type of target used for the source file signature.
 Set the :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable to specify
 variables that must be propagated into the test project.  This variable is
 meant for use only in toolchain files.
+
+If :policy:`CMP0067` is set to ``NEW``, or any of the ``<LANG>_STANDARD``,
+``<LANG>_STANDARD_REQUIRED``, or ``<LANG>_EXTENSIONS`` options are used,
+then the language standard variables are honored:
+
+* :variable:`CMAKE_C_STANDARD`
+* :variable:`CMAKE_C_STANDARD_REQUIRED`
+* :variable:`CMAKE_C_EXTENSIONS`
+* :variable:`CMAKE_CXX_STANDARD`
+* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
+* :variable:`CMAKE_CXX_EXTENSIONS`
+
+Their values are used to set the corresponding target properties in
+the generated project (unless overridden by an explicit option).
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 0cfe983..3266958 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
 to determine whether to report an error on use of deprecated macros or
 functions.
 
+Policies Introduced by CMake 3.8
+================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0067: Honor language standard in try_compile() source-file signature. </policy/CMP0067>
+
 Policies Introduced by CMake 3.7
 ================================
 
diff --git a/Help/policy/CMP0067.rst b/Help/policy/CMP0067.rst
new file mode 100644
index 0000000..d52ba7f
--- /dev/null
+++ b/Help/policy/CMP0067.rst
@@ -0,0 +1,34 @@
+CMP0067
+-------
+
+Honor language standard in :command:`try_compile` source-file signature.
+
+The :command:`try_compile` source file signature is intended to allow
+callers to check whether they will be able to compile a given source file
+with the current toolchain.  In order to match compiler behavior, any
+language standard mode should match.  However, CMake 3.7 and below did not
+do this.  CMake 3.8 and above prefer to honor the language standard settings
+for ``C`` and ``CXX`` (C++) using the values of the variables:
+
+* :variable:`CMAKE_C_STANDARD`
+* :variable:`CMAKE_C_STANDARD_REQUIRED`
+* :variable:`CMAKE_C_EXTENSIONS`
+* :variable:`CMAKE_CXX_STANDARD`
+* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
+* :variable:`CMAKE_CXX_EXTENSIONS`
+
+This policy provides compatibility for projects that do not expect
+the language standard settings to be used automatically.
+
+The ``OLD`` behavior of this policy is to ignore language standard
+setting variables when generating the ``try_compile`` test project.
+The ``NEW`` behavior of this policy is to honor language standard
+setting variables.
+
+This policy was introduced in CMake version 3.8.  Unlike most policies,
+CMake version |release| does *not* warn by default when this policy
+is not set and simply uses OLD behavior.  See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0067 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/try_compile-lang-std.rst b/Help/release/dev/try_compile-lang-std.rst
index 64d082b..849cecc 100644
--- a/Help/release/dev/try_compile-lang-std.rst
+++ b/Help/release/dev/try_compile-lang-std.rst
@@ -3,3 +3,7 @@ try_compile-lang-std
 
 * The :command:`try_compile` command source file signature gained new options
   to specify the language standard to use in the generated test project.
+
+* The :command:`try_compile` command source file signature now honors
+  language standard variables like :variable:`CMAKE_CXX_STANDARD`.
+  See policy :policy:`CMP0067`.
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index 36cf75f..aa23b65 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -17,6 +17,8 @@ warn by default:
   policy :policy:`CMP0065`.
 * ``CMAKE_POLICY_WARNING_CMP0066`` controls the warning for
   policy :policy:`CMP0066`.
+* ``CMAKE_POLICY_WARNING_CMP0067`` controls the warning for
+  policy :policy:`CMP0067`.
 
 This variable should not be set by a project in CMake code.  Project
 developers running CMake may set this variable in their cache to
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 3b72440..1b7180c 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -54,6 +54,17 @@ static void writeProperty(FILE* fout, std::string const& targetName,
           cmOutputConverter::EscapeForCMake(value).c_str());
 }
 
+std::string cmCoreTryCompile::LookupStdVar(std::string const& var,
+                                           bool warnCMP0067)
+{
+  std::string value = this->Makefile->GetSafeDefinition(var);
+  if (warnCMP0067 && !value.empty()) {
+    value.clear();
+    this->WarnCMP0067.push_back(var);
+  }
+  return value;
+}
+
 int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
                                      bool isTryRun)
 {
@@ -620,6 +631,74 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     bool const testC = testLangs.find("C") != testLangs.end();
     bool const testCxx = testLangs.find("CXX") != testLangs.end();
 
+    bool warnCMP0067 = false;
+    bool honorStandard = true;
+
+    if (!didCStandard && !didCxxStandard && !didCStandardRequired &&
+        !didCxxStandardRequired && !didCExtensions && !didCxxExtensions) {
+      switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
+        case cmPolicies::WARN:
+          warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
+            "CMAKE_POLICY_WARNING_CMP0067");
+        case cmPolicies::OLD:
+          // OLD behavior is to not honor the language standard variables.
+          honorStandard = false;
+          break;
+        case cmPolicies::REQUIRED_IF_USED:
+        case cmPolicies::REQUIRED_ALWAYS:
+          this->Makefile->IssueMessage(
+            cmake::FATAL_ERROR,
+            cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0067));
+        case cmPolicies::NEW:
+          // NEW behavior is to honor the language standard variables.
+          // We already initialized honorStandard to true.
+          break;
+      }
+    }
+
+    if (honorStandard || warnCMP0067) {
+      if (testC) {
+        if (!didCStandard) {
+          cStandard = this->LookupStdVar("CMAKE_C_STANDARD", warnCMP0067);
+        }
+        if (!didCStandardRequired) {
+          cStandardRequired =
+            this->LookupStdVar("CMAKE_C_STANDARD_REQUIRED", warnCMP0067);
+        }
+        if (!didCExtensions) {
+          cExtensions = this->LookupStdVar("CMAKE_C_EXTENSIONS", warnCMP0067);
+        }
+      }
+      if (testCxx) {
+        if (!didCxxStandard) {
+          cxxStandard = this->LookupStdVar("CMAKE_CXX_STANDARD", warnCMP0067);
+        }
+        if (!didCxxStandardRequired) {
+          cxxStandardRequired =
+            this->LookupStdVar("CMAKE_CXX_STANDARD_REQUIRED", warnCMP0067);
+        }
+        if (!didCxxExtensions) {
+          cxxExtensions =
+            this->LookupStdVar("CMAKE_CXX_EXTENSIONS", warnCMP0067);
+        }
+      }
+    }
+
+    if (!this->WarnCMP0067.empty()) {
+      std::ostringstream w;
+      /* clang-format off */
+      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0067) << "\n"
+        "For compatibility with older versions of CMake, try_compile "
+        "is not honoring language standard variables in the test project:\n"
+        ;
+      /* clang-format on */
+      for (std::vector<std::string>::iterator vi = this->WarnCMP0067.begin();
+           vi != this->WarnCMP0067.end(); ++vi) {
+        w << "  " << *vi << "\n";
+      }
+      this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+    }
+
     if (testC) {
       if (!cStandard.empty()) {
         writeProperty(fout, targetName, "C_STANDARD", cStandard);
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 1c94f09..4b96aed 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -47,6 +47,10 @@ protected:
   std::string OutputFile;
   std::string FindErrorMessage;
   bool SrcFileSignature;
+
+private:
+  std::vector<std::string> WarnCMP0067;
+  std::string LookupStdVar(std::string const& var, bool warnCMP0067);
 };
 
 #endif
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 9b86435..62e67c7 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -197,7 +197,10 @@ class cmMakefile;
          3, 4, 0, cmPolicies::WARN)                                           \
   SELECT(POLICY, CMP0066,                                                     \
          "Honor per-config flags in try_compile() source-file signature.", 3, \
-         7, 0, cmPolicies::WARN)
+         7, 0, cmPolicies::WARN)                                              \
+  SELECT(POLICY, CMP0067,                                                     \
+         "Honor language standard in try_compile() source-file signature.",   \
+         3, 8, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Tests/RunCMake/try_compile/CMP0067-stderr.txt b/Tests/RunCMake/try_compile/CMP0067-stderr.txt
new file mode 100644
index 0000000..e2677ed
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0067-stderr.txt
@@ -0,0 +1,25 @@
+before try_compile with CMP0067 WARN-enabled but no variables
+after try_compile with CMP0067 WARN-enabled but no variables
+before try_compile with CMP0067 WARN-default
+after try_compile with CMP0067 WARN-default
+before try_compile with CMP0067 WARN-enabled
+CMake Warning \(dev\) at CMP0067.cmake:[0-9]+ \(try_compile\):
+  Policy CMP0067 is not set: Honor language standard in try_compile\(\)
+  source-file signature.  Run "cmake --help-policy CMP0067" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
+
+  For compatibility with older versions of CMake, try_compile is not honoring
+  language standard variables in the test project:
+
+    CMAKE_C_STANDARD
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+after try_compile with CMP0067 WARN-enabled
+before try_compile with CMP0067 OLD
+after try_compile with CMP0067 OLD
+before try_compile with CMP0067 NEW
+after try_compile with CMP0067 NEW
diff --git a/Tests/RunCMake/try_compile/CMP0067.cmake b/Tests/RunCMake/try_compile/CMP0067.cmake
new file mode 100644
index 0000000..dd05d96
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0067.cmake
@@ -0,0 +1,40 @@
+enable_language(C)
+
+set(CMAKE_POLICY_WARNING_CMP0067 ON)
+message("before try_compile with CMP0067 WARN-enabled but no variables")
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  )
+message("after try_compile with CMP0067 WARN-enabled but no variables")
+set(CMAKE_POLICY_WARNING_CMP0067 OFF)
+
+#-----------------------------------------------------------------------------
+
+set(CMAKE_C_STANDARD 90)
+
+message("before try_compile with CMP0067 WARN-default")
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  )
+message("after try_compile with CMP0067 WARN-default")
+
+set(CMAKE_POLICY_WARNING_CMP0067 ON)
+message("before try_compile with CMP0067 WARN-enabled")
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  )
+message("after try_compile with CMP0067 WARN-enabled")
+
+cmake_policy(SET CMP0067 OLD)
+message("before try_compile with CMP0067 OLD")
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  )
+message("after try_compile with CMP0067 OLD")
+
+cmake_policy(SET CMP0066 NEW)
+message("before try_compile with CMP0067 NEW")
+try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  )
+message("after try_compile with CMP0067 NEW")
diff --git a/Tests/RunCMake/try_compile/CStandardGNU.cmake b/Tests/RunCMake/try_compile/CStandardGNU.cmake
index 29ce315..79ae874 100644
--- a/Tests/RunCMake/try_compile/CStandardGNU.cmake
+++ b/Tests/RunCMake/try_compile/CStandardGNU.cmake
@@ -9,3 +9,15 @@ try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
 if(NOT result)
   message(FATAL_ERROR "try_compile failed:\n${out}")
 endif()
+
+cmake_policy(SET CMP0067 NEW)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_C_STANDARD_REQUIRED 1)
+set(CMAKE_C_EXTENSIONS 0)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
+  OUTPUT_VARIABLE out
+  )
+if(NOT result)
+  message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
diff --git a/Tests/RunCMake/try_compile/CxxStandardGNU.cmake b/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
index cc16bea..e714fe4 100644
--- a/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
+++ b/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
@@ -9,3 +9,15 @@ try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
 if(NOT result)
   message(FATAL_ERROR "try_compile failed:\n${out}")
 endif()
+
+cmake_policy(SET CMP0067 NEW)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED 1)
+set(CMAKE_CXX_EXTENSIONS 0)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
+  OUTPUT_VARIABLE out
+  )
+if(NOT result)
+  message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index 74648c9..67068c0 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -44,6 +44,7 @@ endif()
 
 run_cmake(CMP0056)
 run_cmake(CMP0066)
+run_cmake(CMP0067)
 
 if(RunCMake_GENERATOR MATCHES "Make|Ninja")
   # Use a single build tree for a few tests without cleaning.

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a5c6b771aa45f23cca8ef51c165475fc88cd60c2
commit a5c6b771aa45f23cca8ef51c165475fc88cd60c2
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Dec 1 14:24:02 2016 -0500
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Dec 2 11:23:47 2016 -0500

    try_compile: Add options to specify language standards
    
    Give `try_compile` callers a way to control the `CXX_STANDARD`,
    `CXX_STANDARD_REQUIRED`, and `CXX_EXTENSIONS` properties of the
    generated test target (or the `C` equivalents) in order to compile a
    test source for a particular language standard.
    
    Issue: #16456

diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 7830deb..3f16b63 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -35,7 +35,11 @@ Try Compiling Source Files
               [COMPILE_DEFINITIONS <defs>...]
               [LINK_LIBRARIES <libs>...]
               [OUTPUT_VARIABLE <var>]
-              [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]])
+              [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
+              [<LANG>_STANDARD <std>]
+              [<LANG>_STANDARD_REQUIRED <bool>]
+              [<LANG>_EXTENSIONS <bool>]
+              )
 
 Try building an executable from one or more source files.  The success or
 failure of the ``try_compile``, i.e. ``TRUE`` or ``FALSE`` respectively, is
@@ -82,6 +86,18 @@ The options are:
 ``OUTPUT_VARIABLE <var>``
   Store the output from the build process the given variable.
 
+``<LANG>_STANDARD <std>``
+  Specify the :prop_tgt:`C_STANDARD` or :prop_tgt:`CXX_STANDARD`
+  target property of the generated project.
+
+``<LANG>_STANDARD_REQUIRED <bool>``
+  Specify the :prop_tgt:`C_STANDARD_REQUIRED` or
+  :prop_tgt:`CXX_STANDARD_REQUIRED` target property of the generated project.
+
+``<LANG>_EXTENSIONS <bool>``
+  Specify the :prop_tgt:`C_EXTENSIONS` or :prop_tgt:`CXX_EXTENSIONS`
+  target property of the generated project.
+
 In this version all files in ``<bindir>/CMakeFiles/CMakeTmp`` will be
 cleaned automatically.  For debugging, ``--debug-trycompile`` can be
 passed to ``cmake`` to avoid this clean.  However, multiple sequential
diff --git a/Help/release/dev/try_compile-lang-std.rst b/Help/release/dev/try_compile-lang-std.rst
new file mode 100644
index 0000000..64d082b
--- /dev/null
+++ b/Help/release/dev/try_compile-lang-std.rst
@@ -0,0 +1,5 @@
+try_compile-lang-std
+--------------------
+
+* The :command:`try_compile` command source file signature gained new options
+  to specify the language standard to use in the generated test project.
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index fbad778..3b72440 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -46,6 +46,14 @@ static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
   "CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
 static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
 
+static void writeProperty(FILE* fout, std::string const& targetName,
+                          std::string const& prop, std::string const& value)
+{
+  fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n", targetName.c_str(),
+          cmOutputConverter::EscapeForCMake(prop).c_str(),
+          cmOutputConverter::EscapeForCMake(value).c_str());
+}
+
 int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
                                      bool isTryRun)
 {
@@ -87,6 +95,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
   std::string outputVariable;
   std::string copyFile;
   std::string copyFileError;
+  std::string cStandard;
+  std::string cxxStandard;
+  std::string cStandardRequired;
+  std::string cxxStandardRequired;
+  std::string cExtensions;
+  std::string cxxExtensions;
   std::vector<std::string> targets;
   std::string libsToLink = " ";
   bool useOldLinkLibs = true;
@@ -94,6 +108,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
   bool didOutputVariable = false;
   bool didCopyFile = false;
   bool didCopyFileError = false;
+  bool didCStandard = false;
+  bool didCxxStandard = false;
+  bool didCStandardRequired = false;
+  bool didCxxStandardRequired = false;
+  bool didCExtensions = false;
+  bool didCxxExtensions = false;
   bool useSources = argv[2] == "SOURCES";
   std::vector<std::string> sources;
 
@@ -106,6 +126,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     DoingOutputVariable,
     DoingCopyFile,
     DoingCopyFileError,
+    DoingCStandard,
+    DoingCxxStandard,
+    DoingCStandardRequired,
+    DoingCxxStandardRequired,
+    DoingCExtensions,
+    DoingCxxExtensions,
     DoingSources
   };
   Doing doing = useSources ? DoingSources : DoingNone;
@@ -126,6 +152,24 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (argv[i] == "COPY_FILE_ERROR") {
       doing = DoingCopyFileError;
       didCopyFileError = true;
+    } else if (argv[i] == "C_STANDARD") {
+      doing = DoingCStandard;
+      didCStandard = true;
+    } else if (argv[i] == "CXX_STANDARD") {
+      doing = DoingCxxStandard;
+      didCxxStandard = true;
+    } else if (argv[i] == "C_STANDARD_REQUIRED") {
+      doing = DoingCStandardRequired;
+      didCStandardRequired = true;
+    } else if (argv[i] == "CXX_STANDARD_REQUIRED") {
+      doing = DoingCxxStandardRequired;
+      didCxxStandardRequired = true;
+    } else if (argv[i] == "C_EXTENSIONS") {
+      doing = DoingCExtensions;
+      didCExtensions = true;
+    } else if (argv[i] == "CXX_EXTENSIONS") {
+      doing = DoingCxxExtensions;
+      didCxxExtensions = true;
     } else if (doing == DoingCMakeFlags) {
       cmakeFlags.push_back(argv[i]);
     } else if (doing == DoingCompileDefinitions) {
@@ -166,6 +210,24 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (doing == DoingCopyFileError) {
       copyFileError = argv[i];
       doing = DoingNone;
+    } else if (doing == DoingCStandard) {
+      cStandard = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingCxxStandard) {
+      cxxStandard = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingCStandardRequired) {
+      cStandardRequired = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingCxxStandardRequired) {
+      cxxStandardRequired = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingCExtensions) {
+      cExtensions = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingCxxExtensions) {
+      cxxExtensions = argv[i];
+      doing = DoingNone;
     } else if (doing == DoingSources) {
       sources.push_back(argv[i]);
     } else if (i == 3) {
@@ -213,6 +275,42 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     return -1;
   }
 
+  if (didCStandard && !this->SrcFileSignature) {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR, "C_STANDARD allowed only in source file signature.");
+    return -1;
+  }
+  if (didCxxStandard && !this->SrcFileSignature) {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR,
+      "CXX_STANDARD allowed only in source file signature.");
+    return -1;
+  }
+  if (didCStandardRequired && !this->SrcFileSignature) {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR,
+      "C_STANDARD_REQUIRED allowed only in source file signature.");
+    return -1;
+  }
+  if (didCxxStandardRequired && !this->SrcFileSignature) {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR,
+      "CXX_STANDARD_REQUIRED allowed only in source file signature.");
+    return -1;
+  }
+  if (didCExtensions && !this->SrcFileSignature) {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR,
+      "C_EXTENSIONS allowed only in source file signature.");
+    return -1;
+  }
+  if (didCxxExtensions && !this->SrcFileSignature) {
+    this->Makefile->IssueMessage(
+      cmake::FATAL_ERROR,
+      "CXX_EXTENSIONS allowed only in source file signature.");
+    return -1;
+  }
+
   // compute the binary dir when TRY_COMPILE is called with a src file
   // signature
   if (this->SrcFileSignature) {
@@ -518,6 +616,36 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
       }
     }
     fprintf(fout, ")\n");
+
+    bool const testC = testLangs.find("C") != testLangs.end();
+    bool const testCxx = testLangs.find("CXX") != testLangs.end();
+
+    if (testC) {
+      if (!cStandard.empty()) {
+        writeProperty(fout, targetName, "C_STANDARD", cStandard);
+      }
+      if (!cStandardRequired.empty()) {
+        writeProperty(fout, targetName, "C_STANDARD_REQUIRED",
+                      cStandardRequired);
+      }
+      if (!cExtensions.empty()) {
+        writeProperty(fout, targetName, "C_EXTENSIONS", cExtensions);
+      }
+    }
+
+    if (testCxx) {
+      if (!cxxStandard.empty()) {
+        writeProperty(fout, targetName, "CXX_STANDARD", cxxStandard);
+      }
+      if (!cxxStandardRequired.empty()) {
+        writeProperty(fout, targetName, "CXX_STANDARD_REQUIRED",
+                      cxxStandardRequired);
+      }
+      if (!cxxExtensions.empty()) {
+        writeProperty(fout, targetName, "CXX_EXTENSIONS", cxxExtensions);
+      }
+    }
+
     if (useOldLinkLibs) {
       fprintf(fout, "target_link_libraries(%s ${LINK_LIBRARIES})\n",
               targetName.c_str());
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index c02b917..5eb39bb 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -215,7 +215,14 @@ add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES})
 add_RunCMake_test(return)
 add_RunCMake_test(set_property)
 add_RunCMake_test(string)
-add_RunCMake_test(try_compile)
+add_RunCMake_test(try_compile
+  -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+  -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}
+  -DCMAKE_C_STANDARD_DEFAULT=${CMAKE_C_STANDARD_DEFAULT}
+  -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
+  -DCMAKE_CXX_COMPILER_VERSION=${CMAKE_CXX_COMPILER_VERSION}
+  -DCMAKE_CXX_STANDARD_DEFAULT=${CMAKE_CXX_STANDARD_DEFAULT}
+  )
 add_RunCMake_test(try_run)
 add_RunCMake_test(set)
 add_RunCMake_test(variable_watch)
diff --git a/Tests/RunCMake/try_compile/CStandard-result.txt b/Tests/RunCMake/try_compile/CStandard-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CStandard-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_compile/CStandard-stderr.txt b/Tests/RunCMake/try_compile/CStandard-stderr.txt
new file mode 100644
index 0000000..209afcc
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CStandard-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at .*/Tests/RunCMake/try_compile/CStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+  C_STANDARD is set to invalid value '3'
++
+CMake Error at CStandard.cmake:[0-9]+ \(try_compile\):
+  Failed to generate test project build system.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_compile/CStandard.cmake b/Tests/RunCMake/try_compile/CStandard.cmake
new file mode 100644
index 0000000..2849ed4
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CStandard.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  C_STANDARD 3
+  OUTPUT_VARIABLE out
+  )
+message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/CStandardGNU.c b/Tests/RunCMake/try_compile/CStandardGNU.c
new file mode 100644
index 0000000..ac26c15
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CStandardGNU.c
@@ -0,0 +1,10 @@
+#if __STDC_VERSION__ != 199901L
+#error "Not GNU C 99 mode!"
+#endif
+#ifndef __STRICT_ANSI__
+#error "Not GNU C strict ANSI!"
+#endif
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/try_compile/CStandardGNU.cmake b/Tests/RunCMake/try_compile/CStandardGNU.cmake
new file mode 100644
index 0000000..29ce315
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CStandardGNU.cmake
@@ -0,0 +1,11 @@
+enable_language(C)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
+  C_STANDARD 99
+  C_STANDARD_REQUIRED 1
+  C_EXTENSIONS 0
+  OUTPUT_VARIABLE out
+  )
+if(NOT result)
+  message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
diff --git a/Tests/RunCMake/try_compile/CStandardNoDefault.cmake b/Tests/RunCMake/try_compile/CStandardNoDefault.cmake
new file mode 100644
index 0000000..97e72ea
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CStandardNoDefault.cmake
@@ -0,0 +1,9 @@
+enable_language(C)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  C_STANDARD 3 # bogus, but not used
+  OUTPUT_VARIABLE out
+  )
+if(NOT result)
+  message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
diff --git a/Tests/RunCMake/try_compile/CxxStandard-result.txt b/Tests/RunCMake/try_compile/CxxStandard-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CxxStandard-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_compile/CxxStandard-stderr.txt b/Tests/RunCMake/try_compile/CxxStandard-stderr.txt
new file mode 100644
index 0000000..ec7245f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CxxStandard-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at .*/Tests/RunCMake/try_compile/CxxStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+  CXX_STANDARD is set to invalid value '3'
++
+CMake Error at CxxStandard.cmake:[0-9]+ \(try_compile\):
+  Failed to generate test project build system.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_compile/CxxStandard.cmake b/Tests/RunCMake/try_compile/CxxStandard.cmake
new file mode 100644
index 0000000..bcb49b9
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CxxStandard.cmake
@@ -0,0 +1,7 @@
+enable_language(CXX)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
+  CXX_STANDARD 3
+  OUTPUT_VARIABLE out
+  )
+message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/CxxStandardGNU.cmake b/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
new file mode 100644
index 0000000..cc16bea
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
@@ -0,0 +1,11 @@
+enable_language(CXX)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
+  CXX_STANDARD 11
+  CXX_STANDARD_REQUIRED 1
+  CXX_EXTENSIONS 0
+  OUTPUT_VARIABLE out
+  )
+if(NOT result)
+  message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
diff --git a/Tests/RunCMake/try_compile/CxxStandardGNU.cxx b/Tests/RunCMake/try_compile/CxxStandardGNU.cxx
new file mode 100644
index 0000000..6ea1792
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CxxStandardGNU.cxx
@@ -0,0 +1,10 @@
+#if __cplusplus != 201103L
+#error "Not GNU C++ 11 mode!"
+#endif
+#ifndef __STRICT_ANSI__
+#error "Not GNU C++ strict ANSI!"
+#endif
+int main()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake b/Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake
new file mode 100644
index 0000000..35caa9d
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake
@@ -0,0 +1,9 @@
+enable_language(CXX)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
+  CXX_STANDARD 3 # bogus, but not used
+  OUTPUT_VARIABLE out
+  )
+if(NOT result)
+  message(FATAL_ERROR "try_compile failed:\n${out}")
+endif()
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index 4934bcd..74648c9 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -25,6 +25,23 @@ run_cmake(TargetTypeExe)
 run_cmake(TargetTypeInvalid)
 run_cmake(TargetTypeStatic)
 
+if(CMAKE_C_STANDARD_DEFAULT)
+  run_cmake(CStandard)
+else()
+  run_cmake(CStandardNoDefault)
+endif()
+if(CMAKE_CXX_STANDARD_DEFAULT)
+  run_cmake(CxxStandard)
+else()
+  run_cmake(CxxStandardNoDefault)
+endif()
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+  run_cmake(CStandardGNU)
+endif()
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
+  run_cmake(CxxStandardGNU)
+endif()
+
 run_cmake(CMP0056)
 run_cmake(CMP0066)
 
diff --git a/Tests/RunCMake/try_compile/src.cxx b/Tests/RunCMake/try_compile/src.cxx
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/RunCMake/try_compile/src.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=10bda09161db81ff54a24698503d0a0596281d7a
commit 10bda09161db81ff54a24698503d0a0596281d7a
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Dec 2 10:47:37 2016 -0500
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Dec 2 10:50:09 2016 -0500

    try_compile: Stop processing when test build system fails to generate
    
    Failing to generate the build system of the test project is a failure to
    compute the result of the test compilation, and so must be treated as
    any other CMake Error and stop processing.

diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index fecc983..a42c8c9 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3158,8 +3158,10 @@ int cmMakefile::TryCompile(const std::string& srcdir,
   cmGlobalGenerator* gg =
     cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
   if (!gg) {
-    cmSystemTools::Error(
-      "Internal CMake error, TryCompile bad GlobalGenerator");
+    this->IssueMessage(cmake::INTERNAL_ERROR, "Global generator '" +
+                         this->GetGlobalGenerator()->GetName() +
+                         "' could not be created.");
+    cmSystemTools::SetFatalErrorOccured();
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd);
     this->IsSourceFileTryCompile = false;
@@ -3222,8 +3224,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
                      cmStateEnums::INTERNAL);
   }
   if (cm.Configure() != 0) {
-    cmSystemTools::Error(
-      "Internal CMake error, TryCompile configure of cmake failed");
+    this->IssueMessage(cmake::FATAL_ERROR,
+                       "Failed to configure test project build system.");
+    cmSystemTools::SetFatalErrorOccured();
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd);
     this->IsSourceFileTryCompile = false;
@@ -3231,8 +3234,9 @@ int cmMakefile::TryCompile(const std::string& srcdir,
   }
 
   if (cm.Generate() != 0) {
-    cmSystemTools::Error(
-      "Internal CMake error, TryCompile generation of cmake failed");
+    this->IssueMessage(cmake::FATAL_ERROR,
+                       "Failed to generate test project build system.");
+    cmSystemTools::SetFatalErrorOccured();
     // return to the original directory
     cmSystemTools::ChangeDirectory(cwd);
     this->IsSourceFileTryCompile = false;

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

Summary of changes:
 Help/command/try_compile.rst                       |   32 ++-
 Help/manual/cmake-policies.7.rst                   |    8 +
 Help/policy/CMP0067.rst                            |   34 ++++
 Help/release/dev/try_compile-lang-std.rst          |    9 +
 Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst     |    2 +
 Source/cmCoreTryCompile.cxx                        |  207 ++++++++++++++++++++
 Source/cmCoreTryCompile.h                          |    4 +
 Source/cmMakefile.cxx                              |   16 +-
 Source/cmPolicies.h                                |    5 +-
 Tests/RunCMake/CMakeLists.txt                      |    9 +-
 Tests/RunCMake/try_compile/CMP0067-stderr.txt      |   25 +++
 Tests/RunCMake/try_compile/CMP0067.cmake           |   40 ++++
 .../CStandard-result.txt}                          |    0
 Tests/RunCMake/try_compile/CStandard-stderr.txt    |    7 +
 Tests/RunCMake/try_compile/CStandard.cmake         |    7 +
 Tests/RunCMake/try_compile/CStandardGNU.c          |   10 +
 Tests/RunCMake/try_compile/CStandardGNU.cmake      |   23 +++
 ...argetTypeExe.cmake => CStandardNoDefault.cmake} |    7 +-
 .../CxxStandard-result.txt}                        |    0
 Tests/RunCMake/try_compile/CxxStandard-stderr.txt  |    7 +
 Tests/RunCMake/try_compile/CxxStandard.cmake       |    7 +
 Tests/RunCMake/try_compile/CxxStandardGNU.cmake    |   23 +++
 Tests/RunCMake/try_compile/CxxStandardGNU.cxx      |   10 +
 .../try_compile/CxxStandardNoDefault.cmake         |    9 +
 Tests/RunCMake/try_compile/RunCMakeTest.cmake      |   18 ++
 .../RunCMake/try_compile/src.cxx                   |    0
 26 files changed, 504 insertions(+), 15 deletions(-)
 create mode 100644 Help/policy/CMP0067.rst
 create mode 100644 Help/release/dev/try_compile-lang-std.rst
 create mode 100644 Tests/RunCMake/try_compile/CMP0067-stderr.txt
 create mode 100644 Tests/RunCMake/try_compile/CMP0067.cmake
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => try_compile/CStandard-result.txt} (100%)
 create mode 100644 Tests/RunCMake/try_compile/CStandard-stderr.txt
 create mode 100644 Tests/RunCMake/try_compile/CStandard.cmake
 create mode 100644 Tests/RunCMake/try_compile/CStandardGNU.c
 create mode 100644 Tests/RunCMake/try_compile/CStandardGNU.cmake
 copy Tests/RunCMake/try_compile/{TargetTypeExe.cmake => CStandardNoDefault.cmake} (50%)
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => try_compile/CxxStandard-result.txt} (100%)
 create mode 100644 Tests/RunCMake/try_compile/CxxStandard-stderr.txt
 create mode 100644 Tests/RunCMake/try_compile/CxxStandard.cmake
 create mode 100644 Tests/RunCMake/try_compile/CxxStandardGNU.cmake
 create mode 100644 Tests/RunCMake/try_compile/CxxStandardGNU.cxx
 create mode 100644 Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake
 copy Modules/DummyCXXFile.cxx => Tests/RunCMake/try_compile/src.cxx (100%)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list