Browse Source

try_run: Allow to set working directory

Fixes: #17634
Asit Dhal 4 years ago
parent
commit
5af38a11ce

+ 7 - 0
Help/command/try_run.rst

@@ -20,6 +20,7 @@ Try Compiling and Running Source Files
           [COMPILE_OUTPUT_VARIABLE <var>]
           [RUN_OUTPUT_VARIABLE <var>]
           [OUTPUT_VARIABLE <var>]
+          [WORKING_DIRECTORY <var>]
           [ARGS <args>...])
 
 Try compiling a ``<srcfile>``.  Returns ``TRUE`` or ``FALSE`` for success
@@ -74,6 +75,12 @@ The options are:
 ``RUN_OUTPUT_VARIABLE <var>``
   Report the output from running the executable in a given variable.
 
+``WORKING_DIRECTORY <var>``
+  .. versionadded:: 3.20
+
+  Run the executable in the given directory. If no ``WORKING_DIRECTORY`` is
+  specified, the executable will run in ``<bindir>``.
+
 Other Behavior Settings
 ^^^^^^^^^^^^^^^^^^^^^^^
 

+ 5 - 0
Help/release/dev/try_run-allow-to-set-working-directory.rst

@@ -0,0 +1,5 @@
+try_run-allow-to-set-working-directory
+--------------------------------------
+
+* The :command:`try_run` command gained a ``WORKING_DIRECTORY`` option to
+  support setting of working directory.

+ 19 - 2
Source/cmTryRunCommand.cxx

@@ -84,6 +84,14 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
         }
         i++;
         this->CompileOutputVariable = argv[i];
+      } else if (argv[i] == "WORKING_DIRECTORY") {
+        if (argv.size() <= (i + 1)) {
+          cmSystemTools::Error(
+            "WORKING_DIRECTORY specified but there is no variable");
+          return false;
+        }
+        i++;
+        this->WorkingDirectory = argv[i];
       } else {
         tryCompile.push_back(argv[i]);
       }
@@ -102,6 +110,14 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
     return false;
   }
 
+  if (!this->WorkingDirectory.empty()) {
+    if (!cmSystemTools::MakeDirectory(this->WorkingDirectory)) {
+      cmSystemTools::Error(cmStrCat("Error creating working directory \"",
+                                    this->WorkingDirectory, "\"."));
+      return false;
+    }
+  }
+
   bool captureRunOutput = false;
   if (!this->OutputVariable.empty()) {
     captureRunOutput = true;
@@ -188,8 +204,9 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
     finalCommand += runArgs;
   }
   bool worked = cmSystemTools::RunSingleCommand(
-    finalCommand, out, out, &retVal, nullptr, cmSystemTools::OUTPUT_NONE,
-    cmDuration::zero());
+    finalCommand, out, out, &retVal,
+    this->WorkingDirectory.empty() ? nullptr : this->WorkingDirectory.c_str(),
+    cmSystemTools::OUTPUT_NONE, cmDuration::zero());
   // set the run var
   char retChar[16];
   const char* retStr;

+ 1 - 0
Source/cmTryRunCommand.h

@@ -49,4 +49,5 @@ private:
   std::string OutputVariable;
   std::string RunOutputVariable;
   std::string CompileOutputVariable;
+  std::string WorkingDirectory;
 };

+ 2 - 0
Tests/RunCMake/try_run/RunCMakeTest.cmake

@@ -8,3 +8,5 @@ if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
   run_cmake(LinkOptions)
   unset (RunCMake_TEST_OPTIONS)
 endif()
+
+run_cmake(WorkingDirArg)

+ 9 - 0
Tests/RunCMake/try_run/WorkingDirArg.cmake

@@ -0,0 +1,9 @@
+try_run(RUN_RESULT COMPILE_RESULT
+  ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+  RUN_OUTPUT_VARIABLE OUTPUT_VARIABLE
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp/workdir
+  )
+
+if(RUN_RESULT)
+  message(SEND_ERROR "try run failed with result: ${RUN_RESULT}")
+endif()