Преглед изворни кода

Merge topic 'try_compile-no-cache'

09b3051524 try_compile: Add NO_CACHE option (also try_run)

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !7723
Brad King пре 3 година
родитељ
комит
cadcb6a5f0

+ 26 - 1
Help/command/try_compile.rst

@@ -18,6 +18,7 @@ Try Compiling Whole Projects
               SOURCE_DIR <srcdir>
               [BINARY_DIR <bindir>]
               [TARGET <targetName>]
+              [NO_CACHE]
               [CMAKE_FLAGS <flags>...]
               [OUTPUT_VARIABLE <var>])
 
@@ -45,7 +46,9 @@ which was present in older versions of CMake:
 .. code-block:: cmake
 
   try_compile(<resultVar> <bindir> <srcdir>
-              <projectName> [<targetName>] [CMAKE_FLAGS <flags>...]
+              <projectName> [<targetName>]
+              [NO_CACHE]
+              [CMAKE_FLAGS <flags>...]
               [OUTPUT_VARIABLE <var>])
 
 .. _`Try Compiling Source Files`:
@@ -60,6 +63,7 @@ Try Compiling Source Files
                SOURCE_FROM_ARG <name> <content>] |
                SOURCE_FROM_VAR <name> <var>]     |
                SOURCE_FROM_FILE <name> <path>    >...
+              [NO_CACHE]
               [CMAKE_FLAGS <flags>...]
               [COMPILE_DEFINITIONS <defs>...]
               [LINK_OPTIONS <options>...]
@@ -111,6 +115,7 @@ which was present in older versions of CMake:
 .. code-block:: cmake
 
   try_compile(<resultVar> <bindir> <srcfile|SOURCES srcfile...>
+              [NO_CACHE]
               [CMAKE_FLAGS <flags>...]
               [COMPILE_DEFINITIONS <defs>...]
               [LINK_OPTIONS <options>...]
@@ -166,6 +171,26 @@ The options are:
   set the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property in the generated
   project, depending on the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable.
 
+``NO_CACHE``
+  .. versionadded:: 3.25
+
+  The result will be stored in a normal variable rather than a cache entry.
+
+  The result variable is normally cached so that a simple pattern can be used
+  to avoid repeating the test on subsequent executions of CMake:
+
+  .. code-block:: cmake
+
+    if(NOT DEFINED RESULTVAR)
+      # ...(check-specific setup code)...
+      try_compile(RESULTVAR ...)
+      # ...(check-specific logging and cleanup code)...
+    endif()
+
+  If the guard variable and result variable are not the same (for example, if
+  the test is part of a larger inspection), ``NO_CACHE`` may be useful to avoid
+  leaking the intermediate result variable into the cache.
+
 ``OUTPUT_VARIABLE <var>``
   Store the output from the build process in the given variable.
 

+ 2 - 0
Help/command/try_run.rst

@@ -17,6 +17,7 @@ Try Compiling and Running Source Files
            SOURCE_FROM_ARG <name> <content>] |
            SOURCE_FROM_VAR <name> <var>]     |
            SOURCE_FROM_FILE <name> <path>    >...
+          [NO_CACHE]
           [CMAKE_FLAGS <flags>...]
           [COMPILE_DEFINITIONS <defs>...]
           [LINK_OPTIONS <options>...]
@@ -54,6 +55,7 @@ which was present in older versions of CMake:
 
   try_run(<runResultVar> <compileResultVar>
           <bindir> <srcfile|SOURCES srcfile...>
+          [NO_CACHE]
           [CMAKE_FLAGS <flags>...]
           [COMPILE_DEFINITIONS <defs>...]
           [LINK_OPTIONS <options>...]

+ 5 - 0
Help/release/dev/try_compile-no_cache.rst

@@ -0,0 +1,5 @@
+try_compile-no_cache
+--------------------
+
+* The :command:`try_compile` and :command:`try_run` commands gained the option
+  ``NO_CACHE`` to store results in normal variables.

+ 9 - 3
Source/cmCoreTryCompile.cxx

@@ -149,6 +149,7 @@ cmArgumentParser<Arguments> makeTryRunParser(
 auto const TryCompileBaseArgParser =
   cmArgumentParser<Arguments>{}
     .Bind(0, &Arguments::CompileResultVariable)
+    .Bind("NO_CACHE"_s, &Arguments::NoCache)
     .Bind("CMAKE_FLAGS"_s, &Arguments::CMakeFlags)
     .Bind("__CMAKE_INTERNAL"_s, &Arguments::CMakeInternal)
   /* keep semicolon on own line */;
@@ -1061,9 +1062,14 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
   }
 
   // set the result var to the return value to indicate success or failure
-  this->Makefile->AddCacheDefinition(
-    *arguments.CompileResultVariable, (res == 0 ? "TRUE" : "FALSE"),
-    "Result of TRY_COMPILE", cmStateEnums::INTERNAL);
+  if (arguments.NoCache) {
+    this->Makefile->AddDefinition(*arguments.CompileResultVariable,
+                                  (res == 0 ? "TRUE" : "FALSE"));
+  } else {
+    this->Makefile->AddCacheDefinition(
+      *arguments.CompileResultVariable, (res == 0 ? "TRUE" : "FALSE"),
+      "Result of TRY_COMPILE", cmStateEnums::INTERNAL);
+  }
 
   if (arguments.OutputVariable) {
     this->Makefile->AddDefinition(*arguments.OutputVariable, output);

+ 1 - 0
Source/cmCoreTryCompile.h

@@ -58,6 +58,7 @@ public:
     cm::optional<std::string> OutputVariable;
     cm::optional<std::string> CopyFileTo;
     cm::optional<std::string> CopyFileError;
+    bool NoCache = false;
 
     // Argument for try_run only.
     // Keep in sync with warnings in cmCoreTryCompile::ParseArgs.

+ 9 - 3
Source/cmTryRunCommand.cxx

@@ -46,6 +46,7 @@ public:
                           std::string* runOutputStdOutContents,
                           std::string* runOutputStdErrContents);
 
+  bool NoCache;
   std::string RunResultVariable;
 };
 
@@ -57,6 +58,7 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
   if (!arguments) {
     return true;
   }
+  this->NoCache = arguments.NoCache;
 
   // although they could be used together, don't allow it, because
   // using OUTPUT_VARIABLE makes crosscompiling harder
@@ -222,9 +224,13 @@ void TryRunCommandImpl::RunExecutable(const std::string& runArgs,
   } else {
     retStr = "FAILED_TO_RUN";
   }
-  this->Makefile->AddCacheDefinition(this->RunResultVariable, retStr,
-                                     "Result of try_run()",
-                                     cmStateEnums::INTERNAL);
+  if (this->NoCache) {
+    this->Makefile->AddDefinition(this->RunResultVariable, retStr);
+  } else {
+    this->Makefile->AddCacheDefinition(this->RunResultVariable, retStr,
+                                       "Result of try_run()",
+                                       cmStateEnums::INTERNAL);
+  }
 }
 
 /* This is only used when cross compiling. Instead of running the

+ 52 - 0
Tests/TryCompile/old_and_new_signature_tests.cmake

@@ -140,6 +140,28 @@ if(APPLE)
   EXPECT_FAIL(SHOULD_FAIL "${TRY_OUT}")
 endif()
 
+# check that try_compile honors NO_CACHE
+function(try_compile_scope_test)
+  try_compile(
+    CACHED_RESULT
+    ${try_compile_bindir_or_SOURCES}
+    ${TryCompile_SOURCE_DIR}/pass.c)
+  try_compile(
+    SHOULD_NOT_ESCAPE_SCOPE_RESULT
+    ${try_compile_bindir_or_SOURCES}
+    ${TryCompile_SOURCE_DIR}/pass.c
+    NO_CACHE)
+endfunction()
+
+try_compile_scope_test()
+
+if(NOT DEFINED CACHE{CACHED_RESULT})
+  message(SEND_ERROR " Result from try_compile was not cached")
+endif()
+if(DEFINED SHOULD_NOT_ESCAPE_SCOPE_RESULT)
+  message(SEND_ERROR " Result from try_compile(NO_CACHE) leaked")
+endif()
+
 ######################################
 
 # now test try_run()
@@ -222,3 +244,33 @@ endif()
 if(NOT "${RUN_OUTPUT_STDERR}" MATCHES "error")
   message(SEND_ERROR " RUN_OUTPUT_STDERR didn't contain \"error\": \"${RUN_OUTPUT_STDERR}\"")
 endif()
+
+# check that try_run honors NO_CACHE
+function(try_run_scope_test)
+  try_run(
+    CACHED_RUN_RESULT
+    CACHED_COMPILE_RESULT
+    ${try_compile_bindir_or_SOURCES}
+    ${TryCompile_SOURCE_DIR}/exit_success.c)
+  try_run(
+    SHOULD_NOT_ESCAPE_SCOPE_RUN_RESULT
+    SHOULD_NOT_ESCAPE_SCOPE_COMPILE_RESULT
+    ${try_compile_bindir_or_SOURCES}
+    ${TryCompile_SOURCE_DIR}/exit_success.c
+    NO_CACHE)
+endfunction()
+
+try_run_scope_test()
+
+if(NOT DEFINED CACHE{CACHED_COMPILE_RESULT})
+  message(SEND_ERROR " Compile result from try_run was not cached")
+endif()
+if(NOT DEFINED CACHE{CACHED_RUN_RESULT})
+  message(SEND_ERROR " Run result from try_run was not cached")
+endif()
+if(DEFINED SHOULD_NOT_ESCAPE_SCOPE_COMPILE_RESULT)
+  message(SEND_ERROR " Compile result from try_run(NO_CACHE) leaked")
+endif()
+if(DEFINED SHOULD_NOT_ESCAPE_SCOPE_RUN_RESULT)
+  message(SEND_ERROR " Run result from try_run(NO_CACHE) leaked")
+endif()