浏览代码

Merge topic 'provide_explicit_source_and_build_command_line_options'

638f00117a Add release note for the -S and -B options.
de962cc00d CMake: Internally uses -S instead of -H to specify source directory
a10d63d578 cmake: -S and -B can be used to specify source and build directories

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2358
Brad King 7 年之前
父节点
当前提交
ec9ef691fe

+ 8 - 0
Help/manual/OPTIONS_BUILD.txt

@@ -1,3 +1,11 @@
+``-S <path-to-source>``
+ Path to root directory of the CMake project to build.
+
+``-B <path-to-build>``
+ Path to directory which CMake will use as the root of build directory.
+
+ If the directory doesn't already exist CMake will make it.
+
 ``-C <initial-cache>``
  Pre-load a script to populate the cache.
 

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

@@ -9,6 +9,7 @@ Synopsis
 .. parsed-literal::
 
  cmake [<options>] {<path-to-source> | <path-to-existing-build>}
+ cmake [<options>] -S <path-to-source> -B <path-to-build>
  cmake [{-D <var>=<value>}...] -P <cmake-script-file>
  cmake --build <dir> [<options>...] [-- <build-tool-options>...]
  cmake --open <dir>

+ 10 - 0
Help/release/dev/cmake-explicit-dirs.rst

@@ -0,0 +1,10 @@
+cmake-explicit-dirs
+-------------------
+
+* The :manual:`cmake <cmake(1)>` command gained the ``-S <source_dir>``
+  command line option to specify the location of the source directory.
+  This option can be used independently of ``-B``.
+
+* The :manual:`cmake <cmake(1)>` command gained the ``-B <build_dir>``
+  command line option to specify the location of the build directory.
+  This option can be used independently of ``-S``.

+ 1 - 1
Source/QtDialog/CMakeSetup.cxx

@@ -150,7 +150,7 @@ int main(int argc, char** argv)
   typedef cmsys::CommandLineArguments argT;
   arg.AddArgument("-B", argT::CONCAT_ARGUMENT, &binaryDirectory,
                   "Binary Directory");
-  arg.AddArgument("-H", argT::CONCAT_ARGUMENT, &sourceDirectory,
+  arg.AddArgument("-S", argT::CONCAT_ARGUMENT, &sourceDirectory,
                   "Source Directory");
   // do not complain about unknown options
   arg.StoreUnusedArguments(true);

+ 2 - 2
Source/cmGlobalGenerator.cxx

@@ -2454,7 +2454,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
   std::string edit_cmd = this->GetEditCacheCommand();
   if (!edit_cmd.empty()) {
     singleLine.push_back(std::move(edit_cmd));
-    singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
+    singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
     singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
     gti.Message = "Running CMake cache editor...";
     gti.UsesTerminal = true;
@@ -2484,7 +2484,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
   gti.UsesTerminal = true;
   cmCustomCommandLine singleLine;
   singleLine.push_back(cmSystemTools::GetCMakeCommand());
-  singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
+  singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
   singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
   gti.CommandLines.push_back(std::move(singleLine));
   targets.push_back(std::move(gti));

+ 1 - 1
Source/cmGlobalNinjaGenerator.cxx

@@ -1340,7 +1340,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
   std::ostringstream cmd;
   cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
                                    cmOutputConverter::SHELL)
-      << " -H"
+      << " -S"
       << lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
                                    cmOutputConverter::SHELL)
       << " -B"

+ 3 - 3
Source/cmGlobalVisualStudio8Generator.cxx

@@ -177,9 +177,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
     // Create a rule to re-run CMake.
     cmCustomCommandLine commandLine;
     commandLine.push_back(cmSystemTools::GetCMakeCommand());
-    std::string argH = "-H";
-    argH += lg->GetSourceDirectory();
-    commandLine.push_back(argH);
+    std::string argS = "-S";
+    argS += lg->GetSourceDirectory();
+    commandLine.push_back(argS);
     std::string argB = "-B";
     argB += lg->GetBinaryDirectory();
     commandLine.push_back(argB);

+ 2 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -773,7 +773,7 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom(
     std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash();
     cmakefileName += "Makefile.cmake";
     std::string runRule =
-      "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
+      "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
     runRule += " --check-build-system ";
     runRule +=
       this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL);
@@ -1683,7 +1683,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
     cmakefileName += "Makefile.cmake";
     {
       std::string runRule =
-        "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
+        "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
       runRule += " --check-build-system ";
       runRule +=
         this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL);

+ 1 - 1
Source/cmLocalVisualStudio7Generator.cxx

@@ -260,7 +260,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
   std::string comment = "Building Custom Rule ";
   comment += makefileIn;
   std::string args;
-  args = "-H";
+  args = "-S";
   args += this->GetSourceDirectory();
   commandLine.push_back(args);
   args = "-B";

+ 44 - 13
Source/cmake.cxx

@@ -612,19 +612,43 @@ void cmake::SetArgs(const std::vector<std::string>& args,
   bool havePlatform = false;
   for (unsigned int i = 1; i < args.size(); ++i) {
     std::string const& arg = args[i];
-    if (arg.find("-H", 0) == 0) {
+    if (arg.find("-H", 0) == 0 || arg.find("-S", 0) == 0) {
       directoriesSet = true;
       std::string path = arg.substr(2);
+      if (path.empty()) {
+        ++i;
+        if (i >= args.size()) {
+          cmSystemTools::Error("No source directory specified for -S");
+          return;
+        }
+        path = args[i];
+        if (path[0] == '-') {
+          cmSystemTools::Error("No source directory specified for -S");
+          return;
+        }
+      }
+
       path = cmSystemTools::CollapseFullPath(path);
       cmSystemTools::ConvertToUnixSlashes(path);
       this->SetHomeDirectory(path);
-    } else if (arg.find("-S", 0) == 0) {
-      // There is no local generate anymore.  Ignore -S option.
     } else if (arg.find("-O", 0) == 0) {
       // There is no local generate anymore.  Ignore -O option.
     } else if (arg.find("-B", 0) == 0) {
       directoriesSet = true;
       std::string path = arg.substr(2);
+      if (path.empty()) {
+        ++i;
+        if (i >= args.size()) {
+          cmSystemTools::Error("No build directory specified for -B");
+          return;
+        }
+        path = args[i];
+        if (path[0] == '-') {
+          cmSystemTools::Error("No build directory specified for -B");
+          return;
+        }
+      }
+
       path = cmSystemTools::CollapseFullPath(path);
       cmSystemTools::ConvertToUnixSlashes(path);
       this->SetHomeOutputDirectory(path);
@@ -836,20 +860,27 @@ void cmake::SetDirectoriesFromFile(const char* arg)
       this->SetHomeOutputDirectory(listPath);
     } else {
       // Source directory given on command line.  Use current working
-      // directory as build tree.
-      std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-      this->SetHomeOutputDirectory(cwd);
+      // directory as build tree if -B hasn't been given already
+      if (this->GetHomeOutputDirectory().empty()) {
+        std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+        this->SetHomeOutputDirectory(cwd);
+      }
     }
     return;
   }
 
-  // We didn't find a CMakeLists.txt or CMakeCache.txt file from the
-  // argument.  Assume it is the path to the source tree, and use the
-  // current working directory as the build tree.
-  std::string full = cmSystemTools::CollapseFullPath(arg);
-  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
-  this->SetHomeDirectory(full);
-  this->SetHomeOutputDirectory(cwd);
+  if (this->GetHomeDirectory().empty()) {
+    // We didn't find a CMakeLists.txt and it wasn't specified
+    // with -S. Assume it is the path to the source tree
+    std::string full = cmSystemTools::CollapseFullPath(arg);
+    this->SetHomeDirectory(full);
+  }
+  if (this->GetHomeOutputDirectory().empty()) {
+    // We didn't find a CMakeCache.txt and it wasn't specified
+    // with -B. Assume the current working directory as the build tree.
+    std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+    this->SetHomeOutputDirectory(cwd);
+  }
 }
 
 // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the

+ 3 - 1
Source/cmake.h

@@ -556,7 +556,9 @@ private:
 };
 
 #define CMAKE_STANDARD_OPTIONS_TABLE                                          \
-  { "-C <initial-cache>", "Pre-load a script to populate the cache." },       \
+  { "-S <path-to-source>", "Explicitly specify a source directory." },        \
+    { "-B <path-to-build>", "Explicitly specify a build directory." },        \
+    { "-C <initial-cache>", "Pre-load a script to populate the cache." },     \
     { "-D <var>[:<type>]=<value>", "Create or update a cmake cache entry." }, \
     { "-U <globbing_expr>", "Remove matching entries from CMake cache." },    \
     { "-G <generator-name>", "Specify a build system generator." },           \

+ 2 - 1
Source/cmakemain.cxx

@@ -38,7 +38,8 @@ static const char* cmDocumentationName[][2] = {
 static const char* cmDocumentationUsage[][2] = {
   { nullptr,
     "  cmake [options] <path-to-source>\n"
-    "  cmake [options] <path-to-existing-build>" },
+    "  cmake [options] <path-to-existing-build>\n"
+    "  cmake [options] -S <path-to-source> -B <path-to-build>" },
   { nullptr,
     "Specify a source directory to (re-)generate a build system for "
     "it in the current working directory.  Specify an existing build "

+ 1 - 0
Tests/RunCMake/CommandLine/B-no-arg-result.txt

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

+ 1 - 0
Tests/RunCMake/CommandLine/B-no-arg-stderr.txt

@@ -0,0 +1 @@
+CMake Error: No build directory specified for -B

+ 1 - 0
Tests/RunCMake/CommandLine/B-no-arg2-result.txt

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

+ 1 - 0
Tests/RunCMake/CommandLine/B-no-arg2-stderr.txt

@@ -0,0 +1 @@
+CMake Error: No build directory specified for -B

+ 8 - 0
Tests/RunCMake/CommandLine/ExplicitDirs/CMakeLists.txt

@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+add_custom_command(
+  OUTPUT output.txt
+  COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt
+  )
+add_custom_target(CustomTarget ALL DEPENDS output.txt)
+add_custom_target(CustomTarget2 ALL DEPENDS output.txt)
+add_custom_target(CustomTarget3 ALL DEPENDS output.txt)

+ 1 - 0
Tests/RunCMake/CommandLine/NoArgs-stdout.txt

@@ -2,6 +2,7 @@
 
   cmake \[options\] <path-to-source>
   cmake \[options\] <path-to-existing-build>
+  cmake \[options\] -S <path-to-source> -B <path-to-build>
 
 Specify a source directory to \(re-\)generate a build system for it in the
 current working directory.  Specify an existing build directory to

+ 25 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -48,6 +48,31 @@ run_cmake_command(cache-bad-entry
 run_cmake_command(cache-empty-entry
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-empty-entry/)
 
+function(run_ExplicitDirs)
+  set(source_dir ${RunCMake_SOURCE_DIR}/ExplicitDirs)
+  set(binary_dir ${RunCMake_BINARY_DIR}/ExplicitDirs-build)
+
+  file(REMOVE_RECURSE "${binary_dir}")
+  file(MAKE_DIRECTORY "${binary_dir}")
+  run_cmake_command(S-arg ${CMAKE_COMMAND} -S ${source_dir} ${binary_dir})
+  run_cmake_command(S-arg-reverse-order ${CMAKE_COMMAND} ${binary_dir} -S${source_dir} )
+  run_cmake_command(S-no-arg ${CMAKE_COMMAND} -S )
+  run_cmake_command(S-no-arg2 ${CMAKE_COMMAND} -S -T)
+  run_cmake_command(S-B ${CMAKE_COMMAND} -S ${source_dir} -B ${binary_dir})
+
+  # make sure that -B can explicitly construct build directories
+  file(REMOVE_RECURSE "${binary_dir}")
+  run_cmake_command(B-arg ${CMAKE_COMMAND} -B ${binary_dir} ${source_dir})
+  file(REMOVE_RECURSE "${binary_dir}")
+  run_cmake_command(B-arg-reverse-order ${CMAKE_COMMAND} ${source_dir} -B${binary_dir})
+  run_cmake_command(B-no-arg ${CMAKE_COMMAND} -B )
+  run_cmake_command(B-no-arg2 ${CMAKE_COMMAND} -B -T)
+  file(REMOVE_RECURSE "${binary_dir}")
+  run_cmake_command(B-S ${CMAKE_COMMAND} -B${binary_dir} -S${source_dir})
+
+endfunction()
+run_ExplicitDirs()
+
 function(run_BuildDir)
   # Use a single build tree for a few tests without cleaning.
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BuildDir-build)

+ 1 - 0
Tests/RunCMake/CommandLine/S-no-arg-result.txt

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

+ 1 - 0
Tests/RunCMake/CommandLine/S-no-arg-stderr.txt

@@ -0,0 +1 @@
+CMake Error: No source directory specified for -S

+ 1 - 0
Tests/RunCMake/CommandLine/S-no-arg2-result.txt

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

+ 1 - 0
Tests/RunCMake/CommandLine/S-no-arg2-stderr.txt

@@ -0,0 +1 @@
+CMake Error: No source directory specified for -S