Pārlūkot izejas kodu

cmake-presets: Make generator and binaryDir fields optional

In v3 of the presets, generator and buildDir can be omitted to fall
back to regular cmake behavior when these values are not explicitly
provided by the user.

Fixes: #21987
friendlyanon 4 gadi atpakaļ
vecāks
revīzija
06e6981336

+ 5 - 2
Help/manual/cmake-presets.7.rst

@@ -145,7 +145,9 @@ that may contain the following fields:
 
 
   An optional string representing the generator to use for the preset. If
   An optional string representing the generator to use for the preset. If
   ``generator`` is not specified, it must be inherited from the
   ``generator`` is not specified, it must be inherited from the
-  ``inherits`` preset (unless this preset is ``hidden``).
+  ``inherits`` preset (unless this preset is ``hidden``). In version ``3``
+  or above, this field may be omitted to fall back to regular generator
+  discovery procedure.
 
 
   Note that for Visual Studio generators, unlike in the command line ``-G``
   Note that for Visual Studio generators, unlike in the command line ``-G``
   argument, you cannot include the platform name in the generator name. Use
   argument, you cannot include the platform name in the generator name. Use
@@ -186,7 +188,8 @@ that may contain the following fields:
   This field supports `macro expansion`_. If a relative path is specified,
   This field supports `macro expansion`_. If a relative path is specified,
   it is calculated relative to the source directory. If ``binaryDir`` is not
   it is calculated relative to the source directory. If ``binaryDir`` is not
   specified, it must be inherited from the ``inherits`` preset (unless this
   specified, it must be inherited from the ``inherits`` preset (unless this
-  preset is ``hidden``).
+  preset is ``hidden``). In version ``3`` or above, this field may be
+  omitted.
 
 
 ``installDir``
 ``installDir``
 
 

+ 8 - 0
Help/manual/presets/schema.json

@@ -79,6 +79,14 @@
         "type": "object",
         "type": "object",
         "description": "A configure preset object.",
         "description": "A configure preset object.",
         "properties": {
         "properties": {
+          "binaryDir": {
+            "type": "string",
+            "description": "An optional string representing the path to the output binary directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory. If binaryDir is not specified, the path is calculated using regular methods."
+          },
+          "generator": {
+            "type": "string",
+            "description": "An optional string representing the generator to use for the preset. If generator is not specified, the normal generator discovery procedure is used. Note that for Visual Studio generators, unlike in the command line -G argument, you cannot include the platform name in the generator name. Use the architecture field instead."
+          },
           "installDir": {
           "installDir": {
             "type": "string",
             "type": "string",
             "description": "An optional string representing the path to the output binary directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory. If binaryDir is not specified, it must be inherited from the inherits preset (unless this preset is hidden)."
             "description": "An optional string representing the path to the output binary directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory. If binaryDir is not specified, it must be inherited from the inherits preset (unless this preset is hidden)."

+ 5 - 0
Help/release/dev/cmake-presets-optional-generator-and-binarydir.rst

@@ -0,0 +1,5 @@
+cmake-presets-optional-generator-and-binarydir
+----------------------------------------------
+
+* :manual:`cmake-presets(7)` now support omitting the ``generator`` and
+  ``binaryDir`` fields.

+ 1 - 1
Source/QtDialog/QCMake.cxx

@@ -160,7 +160,7 @@ void QCMake::setPreset(const QString& name, bool setBinary)
       auto const& expandedPreset =
       auto const& expandedPreset =
         this->CMakePresetsFile.ConfigurePresets[presetName].Expanded;
         this->CMakePresetsFile.ConfigurePresets[presetName].Expanded;
       if (expandedPreset) {
       if (expandedPreset) {
-        if (setBinary) {
+        if (setBinary && !expandedPreset->BinaryDir.empty()) {
           QString binaryDir =
           QString binaryDir =
             QString::fromLocal8Bit(expandedPreset->BinaryDir.data());
             QString::fromLocal8Bit(expandedPreset->BinaryDir.data());
           this->setBinaryDirectory(binaryDir);
           this->setBinaryDirectory(binaryDir);

+ 22 - 16
Source/cmCMakePresetsFile.cxx

@@ -78,7 +78,7 @@ void InheritVector(std::vector<T>& child, const std::vector<T>& parent)
 template <class T>
 template <class T>
 ReadFileResult VisitPreset(
 ReadFileResult VisitPreset(
   T& preset, std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets,
   T& preset, std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets,
-  std::map<std::string, CycleStatus> cycleStatus)
+  std::map<std::string, CycleStatus> cycleStatus, int version)
 {
 {
   switch (cycleStatus[preset.Name]) {
   switch (cycleStatus[preset.Name]) {
     case CycleStatus::InProgress:
     case CycleStatus::InProgress:
@@ -108,7 +108,7 @@ ReadFileResult VisitPreset(
       return ReadFileResult::USER_PRESET_INHERITANCE;
       return ReadFileResult::USER_PRESET_INHERITANCE;
     }
     }
 
 
-    auto result = VisitPreset(parentPreset, presets, cycleStatus);
+    auto result = VisitPreset(parentPreset, presets, cycleStatus, version);
     if (result != ReadFileResult::READ_OK) {
     if (result != ReadFileResult::READ_OK) {
       return result;
       return result;
     }
     }
@@ -128,7 +128,7 @@ ReadFileResult VisitPreset(
     preset.ConditionEvaluator.reset();
     preset.ConditionEvaluator.reset();
   }
   }
 
 
-  CHECK_OK(preset.VisitPresetAfterInherit())
+  CHECK_OK(preset.VisitPresetAfterInherit(version))
 
 
   cycleStatus[preset.Name] = CycleStatus::Verified;
   cycleStatus[preset.Name] = CycleStatus::Verified;
   return ReadFileResult::READ_OK;
   return ReadFileResult::READ_OK;
@@ -136,7 +136,8 @@ ReadFileResult VisitPreset(
 
 
 template <class T>
 template <class T>
 ReadFileResult ComputePresetInheritance(
 ReadFileResult ComputePresetInheritance(
-  std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets)
+  std::map<std::string, cmCMakePresetsFile::PresetPair<T>>& presets,
+  const cmCMakePresetsFile& file)
 {
 {
   std::map<std::string, CycleStatus> cycleStatus;
   std::map<std::string, CycleStatus> cycleStatus;
   for (auto const& it : presets) {
   for (auto const& it : presets) {
@@ -144,7 +145,9 @@ ReadFileResult ComputePresetInheritance(
   }
   }
 
 
   for (auto& it : presets) {
   for (auto& it : presets) {
-    auto result = VisitPreset<T>(it.second.Unexpanded, presets, cycleStatus);
+    auto& preset = it.second.Unexpanded;
+    auto result =
+      VisitPreset<T>(preset, presets, cycleStatus, file.GetVersion(preset));
     if (result != ReadFileResult::READ_OK) {
     if (result != ReadFileResult::READ_OK) {
       return result;
       return result;
     }
     }
@@ -667,16 +670,19 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetBeforeInherit()
 }
 }
 
 
 cmCMakePresetsFile::ReadFileResult
 cmCMakePresetsFile::ReadFileResult
-cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit()
+cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit(int version)
 {
 {
   auto& preset = *this;
   auto& preset = *this;
   if (!preset.Hidden) {
   if (!preset.Hidden) {
-    if (preset.Generator.empty()) {
-      return ReadFileResult::INVALID_PRESET;
-    }
-    if (preset.BinaryDir.empty()) {
-      return ReadFileResult::INVALID_PRESET;
+    if (version < 3) {
+      if (preset.Generator.empty()) {
+        return ReadFileResult::INVALID_PRESET;
+      }
+      if (preset.BinaryDir.empty()) {
+        return ReadFileResult::INVALID_PRESET;
+      }
     }
     }
+
     if (preset.WarnDev == false && preset.ErrorDev == true) {
     if (preset.WarnDev == false && preset.ErrorDev == true) {
       return ReadFileResult::INVALID_PRESET;
       return ReadFileResult::INVALID_PRESET;
     }
     }
@@ -712,7 +718,7 @@ cmCMakePresetsFile::BuildPreset::VisitPresetInherit(
 }
 }
 
 
 cmCMakePresetsFile::ReadFileResult
 cmCMakePresetsFile::ReadFileResult
-cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit()
+cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit(int /* version */)
 {
 {
   auto& preset = *this;
   auto& preset = *this;
   if (!preset.Hidden && preset.ConfigurePreset.empty()) {
   if (!preset.Hidden && preset.ConfigurePreset.empty()) {
@@ -822,7 +828,7 @@ cmCMakePresetsFile::TestPreset::VisitPresetInherit(
 }
 }
 
 
 cmCMakePresetsFile::ReadFileResult
 cmCMakePresetsFile::ReadFileResult
-cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit()
+cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit(int /* version */)
 {
 {
   auto& preset = *this;
   auto& preset = *this;
   if (!preset.Hidden && preset.ConfigurePreset.empty()) {
   if (!preset.Hidden && preset.ConfigurePreset.empty()) {
@@ -883,9 +889,9 @@ cmCMakePresetsFile::ReadProjectPresetsInternal(bool allowNoFiles)
                         : ReadFileResult::FILE_NOT_FOUND;
                         : ReadFileResult::FILE_NOT_FOUND;
   }
   }
 
 
-  CHECK_OK(ComputePresetInheritance(this->ConfigurePresets))
-  CHECK_OK(ComputePresetInheritance(this->BuildPresets))
-  CHECK_OK(ComputePresetInheritance(this->TestPresets))
+  CHECK_OK(ComputePresetInheritance(this->ConfigurePresets, *this))
+  CHECK_OK(ComputePresetInheritance(this->BuildPresets, *this))
+  CHECK_OK(ComputePresetInheritance(this->TestPresets, *this))
 
 
   for (auto& it : this->ConfigurePresets) {
   for (auto& it : this->ConfigurePresets) {
     if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
     if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {

+ 4 - 4
Source/cmCMakePresetsFile.h

@@ -89,7 +89,7 @@ public:
       return ReadFileResult::READ_OK;
       return ReadFileResult::READ_OK;
     }
     }
 
 
-    virtual ReadFileResult VisitPresetAfterInherit()
+    virtual ReadFileResult VisitPresetAfterInherit(int /* version */)
     {
     {
       return ReadFileResult::READ_OK;
       return ReadFileResult::READ_OK;
     }
     }
@@ -132,7 +132,7 @@ public:
 
 
     ReadFileResult VisitPresetInherit(const Preset& parent) override;
     ReadFileResult VisitPresetInherit(const Preset& parent) override;
     ReadFileResult VisitPresetBeforeInherit() override;
     ReadFileResult VisitPresetBeforeInherit() override;
-    ReadFileResult VisitPresetAfterInherit() override;
+    ReadFileResult VisitPresetAfterInherit(int version) override;
   };
   };
 
 
   class BuildPreset : public Preset
   class BuildPreset : public Preset
@@ -158,7 +158,7 @@ public:
     std::vector<std::string> NativeToolOptions;
     std::vector<std::string> NativeToolOptions;
 
 
     ReadFileResult VisitPresetInherit(const Preset& parent) override;
     ReadFileResult VisitPresetInherit(const Preset& parent) override;
-    ReadFileResult VisitPresetAfterInherit() override;
+    ReadFileResult VisitPresetAfterInherit(int /* version */) override;
   };
   };
 
 
   class TestPreset : public Preset
   class TestPreset : public Preset
@@ -285,7 +285,7 @@ public:
     cm::optional<ExecutionOptions> Execution;
     cm::optional<ExecutionOptions> Execution;
 
 
     ReadFileResult VisitPresetInherit(const Preset& parent) override;
     ReadFileResult VisitPresetInherit(const Preset& parent) override;
-    ReadFileResult VisitPresetAfterInherit() override;
+    ReadFileResult VisitPresetAfterInherit(int /* version */) override;
   };
   };
 
 
   template <class T>
   template <class T>

+ 6 - 3
Source/cmake.cxx

@@ -1223,10 +1223,11 @@ void cmake::SetArgs(const std::vector<std::string>& args)
       return;
       return;
     }
     }
 
 
-    if (!this->State->IsCacheLoaded() && !haveBArg) {
+    if (!this->State->IsCacheLoaded() && !haveBArg &&
+        !expandedPreset->BinaryDir.empty()) {
       this->SetHomeOutputDirectory(expandedPreset->BinaryDir);
       this->SetHomeOutputDirectory(expandedPreset->BinaryDir);
     }
     }
-    if (!this->GlobalGenerator) {
+    if (!this->GlobalGenerator && !expandedPreset->Generator.empty()) {
       if (!this->CreateAndSetGlobalGenerator(expandedPreset->Generator,
       if (!this->CreateAndSetGlobalGenerator(expandedPreset->Generator,
                                              false)) {
                                              false)) {
         return;
         return;
@@ -3203,7 +3204,9 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
       return 1;
       return 1;
     }
     }
 
 
-    dir = expandedConfigurePreset->BinaryDir;
+    if (!expandedConfigurePreset->BinaryDir.empty()) {
+      dir = expandedConfigurePreset->BinaryDir;
+    }
 
 
     this->UnprocessedPresetEnvironment = expandedPreset->Environment;
     this->UnprocessedPresetEnvironment = expandedPreset->Environment;
     this->ProcessPresetEnvironment();
     this->ProcessPresetEnvironment();

+ 3 - 0
Tests/RunCMake/CMakePresets/OptionalBinaryDirField.cmake

@@ -0,0 +1,3 @@
+include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake)
+
+test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build")

+ 9 - 0
Tests/RunCMake/CMakePresets/OptionalBinaryDirField.json.in

@@ -0,0 +1,9 @@
+{
+  "version": 3,
+  "configurePresets": [
+    {
+      "name": "OptionalBinaryDirField",
+      "generator": "@RunCMake_GENERATOR@"
+    }
+  ]
+}

+ 3 - 0
Tests/RunCMake/CMakePresets/OptionalGeneratorField.cmake

@@ -0,0 +1,3 @@
+include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake)
+
+test_variable(CMAKE_GENERATOR "" "${RunCMake_GENERATOR}")

+ 9 - 0
Tests/RunCMake/CMakePresets/OptionalGeneratorField.json.in

@@ -0,0 +1,9 @@
+{
+  "version": 3,
+  "configurePresets": [
+    {
+      "name": "OptionalGeneratorField",
+      "binaryDir": "${sourceDir}/build"
+    }
+  ]
+}

+ 5 - 0
Tests/RunCMake/CMakePresets/RunCMakeTest.cmake

@@ -275,6 +275,11 @@ set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Conditions.json.in")
 run_cmake_presets(ListConditions --list-presets)
 run_cmake_presets(ListConditions --list-presets)
 run_cmake_presets(SimpleTrue)
 run_cmake_presets(SimpleTrue)
 run_cmake_presets(SimpleFalse)
 run_cmake_presets(SimpleFalse)
+unset(CMakePresets_FILE)
+
+# Test optional generator and buildDir fields
+run_cmake_presets(OptionalBinaryDirField -B "${RunCMake_BINARY_DIR}/OptionalBinaryDirField/build")
+run_cmake_presets(OptionalGeneratorField -G "${RunCMake_GENERATOR}")
 
 
 # Test the example from the documentation
 # Test the example from the documentation
 file(READ "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/example.json" _example)
 file(READ "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/example.json" _example)