diff options
280 files changed, 5185 insertions, 83 deletions
@@ -5,6 +5,7 @@ *.pyc Testing +CMakeUserPresets.json # Visual Studio work directory .vs/ diff --git a/Help/manual/cmake-gui.1.rst b/Help/manual/cmake-gui.1.rst index ff8311b..d9c8ed7 100644 --- a/Help/manual/cmake-gui.1.rst +++ b/Help/manual/cmake-gui.1.rst @@ -11,6 +11,7 @@ Synopsis cmake-gui [<options>] cmake-gui [<options>] {<path-to-source> | <path-to-existing-build>} cmake-gui [<options>] -S <path-to-source> -B <path-to-build> + cmake-gui [<options>] -S <path-to-source> --preset=<preset-name> Description =========== @@ -36,6 +37,10 @@ Options If the directory doesn't already exist CMake will make it. +``--preset=<preset-name>`` + Name of the preset to use from the project's ``CMakePresets.json`` file, if it + has one. + .. include:: OPTIONS_HELP.txt See Also diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 9850116..764f61e 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -12,6 +12,7 @@ Synopsis cmake [<options>] <path-to-source> cmake [<options>] <path-to-existing-build> cmake [<options>] -S <path-to-source> -B <path-to-build> + cmake [<options>] -S <path-to-source> --preset=<preset-name> `Build a Project`_ cmake --build <dir> [<options>] [-- <build-tool-options>] @@ -148,6 +149,368 @@ source and build trees and generate a buildsystem: $ cmake -S src -B build +``cmake [<options>] -S <path-to-source> --preset=<preset-name>`` + Uses ``<path-to-source>`` as the source tree and reads a preset from + ``<path-to-source>/CMakePresets.json`` and + ``<path-to-source>/CMakeUserPresets.json``. The preset specifies the + generator and the build directory, and optionally a list of variables and + other arguments to pass to CMake. The :manual:`CMake GUI <cmake-gui(1)>` can + also recognize ``CMakePresets.json`` and ``CMakeUserPresets.json`` files. + + ``CMakePresets.json`` and ``CMakeUserPresets.json`` have exactly the same + format, and both are optional (though at least one must be present if + ``--preset`` is specified.) ``CMakePresets.json`` is meant to save + project-wide builds, while ``CMakeUserPresets.json`` is meant for developers + to save their own local builds. ``CMakePresets.json`` may be checked into a + version control system, and ``CMakeUserPresets.json`` should NOT be checked + in. For example, if a project is using Git, ``CMakePresets.json`` may be + tracked, and ``CMakeUserPresets.json`` should be added to the ``.gitignore``. + + The presets are read before all other command line options. The options + specified by the preset (variables, generator, etc.) can all be overridden by + manually specifying them on the command line. For example, if the preset sets + a variable called ``MYVAR`` to ``1``, but the user sets it to ``2`` with a + ``-D`` argument, the value ``2`` is preferred. + + The files are a JSON document with an object as the root: + + .. code-block:: json + + { + "version": 1, + "cmakeMinimumRequired": { + "major": 3, + "minor": 19, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "displayName": "Default Config", + "description": "Default build using Ninja generator", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/default", + "cacheVariables": [ + { + "name": "MY_CACHE_VARIABLE", + "type": "BOOL", + "value": "OFF" + } + ] + } + ] + } + + The root object recognizes the following fields: + + ``version`` + + A required integer representing the version of the JSON schema. Currently, + the only supported version is 1. + + ``cmakeMinimumRequired`` + + An optional object representing the minimum version of CMake needed to + build this project. This object consists of the following fields: + + ``major`` + + An optional integer representing the major version. + + ``minor`` + + An optional integer representing the minor version. + + ``patch`` + + An optional integer representing the patch version. + + ``vendor`` + + An optional map containing vendor-specific information. CMake does not + interpret the contents of this field except to verify that it is a map if + it does exist. However, the keys should be a vendor-specific domain name + followed by a ``/``-separated path. For example, the Example IDE 1.0 could + use ``example.com/ExampleIDE/1.0``. The value of each field can be anything + desired by the vendor, though will typically be a map. For example: + + .. code-block:: json + + { + "version": 1, + "vendor": { + "example.com/ExampleIDE/1.0": { + "autoFormat": true + } + }, + "configurePresets": [] + } + + ``configurePresets`` + + An optional array of configure preset objects. Each preset may contain the + following fields: + + ``name`` + + A required string representing the machine-friendly name of the preset. + This identifier is used in the ``--preset`` argument. There must not be + two presets in the union of ``CMakePresets.json`` and + ``CMakeUserPresets.json`` in the same directory with the same name. + + ``hidden`` + + An optional boolean specifying whether or not a preset should be hidden. + If a preset is hidden, it cannot be used in the ``--preset=`` argument, + will not show up in the :manual:`CMake GUI <cmake-gui(1)>`, and does not + have to have a valid ``generator`` or ``binaryDir``, even from + inheritance. ``hidden`` presets are intended to be used as a base for + other presets to inherit via the ``inherits`` field. + + ``inherits`` + + An optional array of strings representing the names of presets to inherit + from. The preset will inherit all of the fields from the ``inherits`` + presets by default (except ``name``, ``hidden``, ``inherits``, + ``description``, and ``longDescription``), but can override them as + desired. If multiple ``inherits`` presets provide conflicting values for + the same field, the earlier preset in the ``inherits`` list will be + preferred. Presets in ``CMakePresets.json`` may not inherit from presets + in ``CMakeUserPresets.json``. + + This field can also be a string, which is equivalent to an array + containing one string. + + ``vendor`` + + An optional map containing vendor-specific information. CMake does not + interpret the contents of this field except to verify that it is a map + if it does exist. However, it should follow the same conventions as the + root-level ``vendor`` field. If vendors use their own per-preset + ``vendor`` field, they should implement inheritance in a sensible manner + when appropriate. + + ``displayName`` + + An optional string with a human-friendly name of the preset. + + ``description`` + + An optional string with a human-friendly description of the preset. + + ``generator`` + + An optional string representing the generator to use for the preset. If + ``generator`` is not specified, it must be inherited from the + ``inherits`` preset (unless this preset is ``hidden``). + + 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. + + ``architecture`` + + An optional string representing the platform name to use for Visual + Studio generators. + + ``toolset`` + + An optional string representing the toolset name to use for Visual Studio + generators. + + ``cmakeGeneratorConfig`` + + An optional string telling CMake how to handle the ``architecture`` and + ``toolset`` fields. Valid values are: + + ``"default"`` + + Set the platform and toolset using the ``architecture`` and ``toolset`` + fields respectively. On non-Visual Studio generators, this will result + in an error if ``architecture`` or ``toolset`` are set. + + ``"ignore"`` + + Do not set the platform or toolset at all, even on Visual Studio + generators. This is useful if, for example, a preset uses the Ninja + generator, and an IDE knows how to set up the Visual C++ environment + from the ``architecture`` and ``toolset`` fields. In that case, CMake + will ignore ``architecture`` and ``toolset``, but the IDE can use them + to set up the environment before invoking CMake. + + ``binaryDir`` + + 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``). + + ``cmakeExecutable`` + + An optional string representing the path to the CMake executable to use + for this preset. This is reserved for use by IDEs, and is not used by + CMake itself. IDEs that use this field should expand any macros in it. + + ``cacheVariables`` + + An optional map of cache variables. The key is the variable name, and the + value is either ``null``, a string representing the value of the variable + (which supports macro expansion), or an object with the following fields: + + ``type`` + + An optional string representing the type of the variable. + + ``value`` + + A required string representing the value of the variable. This field + supports macro expansion. + + Cache variables are inherited through the ``inherits`` field, and the + preset's variables will be the union of its own ``cacheVariables`` and + the ``cacheVariables`` from all its parents. If multiple presets in this + union define the same variable, the standard rules of ``inherits`` are + applied. Setting a variable to ``null`` causes it to not be set, even if + a value was inherited from another preset. + + ``environment`` + + An optional map of environment variables. The key is the variable name, + and the value is either ``null`` or a string representing the value of + the variable. Each variable is set regardless of whether or not a value + was given to it by the process's environment. This field supports macro + expansion, and environment variables in this map may reference each + other, and may be listed in any order, as long as such references do not + cause a cycle (for example, if ``ENV_1`` is ``$env{ENV_2}``, ``ENV_2`` + may not be ``$env{ENV_1}``.) + + Environment variables are inherited through the ``inherits`` field, and + the preset's environment will be the union of its own ``environment`` and + the ``environment`` from all its parents. If multiple presets in this + union define the same variable, the standard rules of ``inherits`` are + applied. Setting a variable to ``null`` causes it to not be set, even if + a value was inherited from another preset. + + ``warnings`` + + An optional object specifying warnings. The object may contain the + following fields: + + ``dev`` + + An optional boolean. Equivalent to passing ``-Wdev`` or ``-Wno-dev`` + on the command line. This may not be set to ``false`` if ``errors.dev`` + is set to ``true``. + + ``deprecated`` + + An optional boolean. Equivalent to passing ``-Wdeprecated`` or + ``-Wno-deprecated`` on the command line. This may not be set to + ``false`` if ``errors.deprecated`` is set to ``true``. + + ``uninitialized`` + + An optional boolean. Setting this to ``true`` is equivalent to passing + ``--warn-uninitialized`` on the command line. + + ``unusedVars`` + + An optional boolean. Setting this to ``false`` is equivalent to passing + ``--no-warn-unused-cli`` on the command line. + + ``systemVars`` + + An optional boolean. Setting this to ``true`` is equivalent to passing + ``--check-system-vars`` on the command line. + + ``errors`` + + An optional object specifying errors. The object may contain the + following fields: + + ``dev`` + + An optional boolean. Equivalent to passing ``-Werror=dev`` or + ``-Wno-error=dev`` on the command line. This may not be set to ``true`` + if ``warnings.dev`` is set to ``false``. + + ``deprecated`` + + An optional boolean. Equivalent to passing ``-Werror=deprecated`` or + ``-Wno-error=deprecated`` on the command line. This may not be set to + ``true`` if ``warnings.deprecated`` is set to ``false``. + + As mentioned above, some fields support macro expansion. Macros are + recognized in the form ``$<macro-namespace>{<macro-name>}``. All macros are + evaluated in the context of the preset being used, even if the macro is in a + field that was inherited from another preset. For example, if the ``Base`` + preset sets variable ``PRESET_NAME`` to ``${presetName}``, and the + ``Derived`` preset inherits from ``Base``, ``PRESET_NAME`` will be set to + ``Derived``. + + It is an error to not put a closing brace at the end of a macro name. For + example, ``${sourceDir`` is invalid. A dollar sign (``$``) followed by + anything other than a left curly brace (``{``) with a possible namespace is + interpreted as a literal dollar sign. + + Recognized macros include: + + ``${sourceDir}`` + + Path to the project source directory. + + ``${sourceParentDir}`` + + Path to the project source directory's parent directory. + + ``${presetName}`` + + Name specified in the preset's ``name`` field. + + ``${generator}`` + + Generator specified in the preset's ``generator`` field. + + ``${dollar}`` + + A literal dollar sign (``$``). + + ``$env{<variable-name>}`` + + Environment variable with name ``<variable-name>``. If the variable is + defined in the ``environment`` field, that value is used instead of the + value from the parent environment. If the environment variable is not + defined, this evaluates as an empty string. + + Note that while Windows environment variable names are case-insensitive, + variable names within a preset are still case-sensitive. This may lead to + unexpected results when using inconsistent casing. For best results, keep + the casing of environment variable names consistent. + + ``$penv{<variable-name>}`` + + Similar to ``$env{<variable-name>}``, except that the value only comes from + the parent environment, and never from the ``environment`` field. This + allows you to prepend or append values to existing environment variables. + For example, setting ``PATH`` to ``/path/to/ninja/bin:$penv{PATH}`` will + prepend ``/path/to/ninja/bin`` to the ``PATH`` environment variable. This + is needed because ``$env{<variable-name>}`` does not allow circular + references. + + ``$vendor{<macro-name>}`` + + An extension point for vendors to insert their own macros. CMake will not + be able to use presets which have a ``$vendor{<macro-name>}`` macro, and + effectively ignores such presets. However, it will still be able to use + other presets from the same file. + + CMake does not make any attempt to interpret ``$vendor{<macro-name>}`` + macros. However, to avoid name collisions, IDE vendors should prefix + ``<macro-name>`` with a very short (preferably <= 4 characters) vendor + identifier prefix, followed by a ``.``, followed by the macro name. For + example, the Example IDE could have ``$vendor{xide.ideInstallDir}``. + In all cases the ``<options>`` may be zero or more of the `Options`_ below. After generating a buildsystem one may use the corresponding native @@ -813,6 +1176,11 @@ with one of the following options: .. include:: OPTIONS_HELP.txt +To view the presets available for a project, use + +.. code-block::shell + + cmake <source-dir> --list-presets See Also ======== diff --git a/Help/release/dev/cmake-presets.rst b/Help/release/dev/cmake-presets.rst new file mode 100644 index 0000000..a901f10 --- /dev/null +++ b/Help/release/dev/cmake-presets.rst @@ -0,0 +1,5 @@ +cmake-presets +------------- + +* :manual:`cmake(1)` and :manual:`cmake-gui(1)` now recognize + ``CMakePresets.json`` and ``CMakeUserPresets.json`` files. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index d0d9459..1e16e17 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -184,6 +184,8 @@ set(SRCS cmCLocaleEnvironmentScope.cxx cmCMakePath.h cmCMakePath.cxx + cmCMakePresetsFile.cxx + cmCMakePresetsFile.h cmCommandArgumentParserHelper.cxx cmCommonTargetGenerator.cxx cmCommonTargetGenerator.h diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 5fd0e89..394762a 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -92,6 +92,12 @@ set(SRCS QCMake.h QCMakeCacheView.cxx QCMakeCacheView.h + QCMakePreset.cxx + QCMakePreset.h + QCMakePresetComboBox.cxx + QCMakePresetComboBox.h + QCMakePresetItemModel.cxx + QCMakePresetItemModel.h QCMakeWidgets.cxx QCMakeWidgets.h RegexExplorer.cxx @@ -116,6 +122,8 @@ qt5_wrap_cpp(MOC_SRCS FirstConfigure.h QCMake.h QCMakeCacheView.h + QCMakePresetComboBox.h + QCMakePresetItemModel.h QCMakeWidgets.h RegexExplorer.h WarningMessagesDialog.h diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 37c1f15..a5b2f34 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -32,7 +32,8 @@ static const char* cmDocumentationUsage[][2] = { " cmake-gui [options]\n" " cmake-gui [options] <path-to-source>\n" " cmake-gui [options] <path-to-existing-build>\n" - " cmake-gui [options] -S <path-to-source> -B <path-to-build>\n" }, + " cmake-gui [options] -S <path-to-source> -B <path-to-build>\n" + " cmake-gui [options] -S <path-to-source> --preset=<preset-name>\n" }, { nullptr, nullptr } }; @@ -147,6 +148,7 @@ int main(int argc, char** argv) QStringList args = QApplication::arguments(); std::string binaryDirectory; std::string sourceDirectory; + std::string presetName; for (int i = 1; i < args.size(); ++i) { const QString& arg = args[i]; if (arg.startsWith("-S")) { @@ -185,11 +187,28 @@ int main(int argc, char** argv) binaryDirectory = cmSystemTools::CollapseFullPath(path.toLocal8Bit().data()); cmSystemTools::ConvertToUnixSlashes(binaryDirectory); + } else if (arg.startsWith("--preset=")) { + QString preset = arg.mid(cmStrLen("--preset=")); + if (preset.isEmpty()) { + std::cerr << "No preset specified for --preset" << std::endl; + return 1; + } + presetName = preset.toLocal8Bit().data(); } } - if (!sourceDirectory.empty() && !binaryDirectory.empty()) { + if (!sourceDirectory.empty() && + (!binaryDirectory.empty() || !presetName.empty())) { dialog.setSourceDirectory(QString::fromLocal8Bit(sourceDirectory.c_str())); - dialog.setBinaryDirectory(QString::fromLocal8Bit(binaryDirectory.c_str())); + if (!binaryDirectory.empty()) { + dialog.setBinaryDirectory( + QString::fromLocal8Bit(binaryDirectory.c_str())); + if (!presetName.empty()) { + dialog.setStartupBinaryDirectory(true); + } + } + if (!presetName.empty()) { + dialog.setDeferredPreset(QString::fromLocal8Bit(presetName.c_str())); + } } else { if (args.count() == 2) { std::string filePath = diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index df22028..acd32ec 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -21,8 +21,10 @@ #include <QSettings> #include <QShortcut> #include <QStatusBar> +#include <QString> #include <QToolButton> #include <QUrl> +#include <QVector> #ifdef QT_WINEXTRAS # include <QWinTaskbarButton> @@ -263,6 +265,8 @@ void CMakeSetupDialog::initialize() &CMakeSetupDialog::onBinaryDirectoryChanged); QObject::connect(this->SourceDirectory, &QLineEdit::textChanged, this, &CMakeSetupDialog::onSourceDirectoryChanged); + QObject::connect(this->Preset, &QCMakePresetComboBox::presetChanged, this, + &CMakeSetupDialog::onBuildPresetChanged); QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::sourceDirChanged, this, @@ -270,6 +274,13 @@ void CMakeSetupDialog::initialize() QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::binaryDirChanged, this, &CMakeSetupDialog::updateBinaryDirectory); + QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::presetsChanged, + this, &CMakeSetupDialog::updatePresets); + QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::presetChanged, + this, &CMakeSetupDialog::updatePreset); + QObject::connect(this->CMakeThread->cmakeInstance(), + &QCMake::presetLoadError, this, + &CMakeSetupDialog::showPresetLoadError); QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::progressChanged, this, @@ -314,9 +325,15 @@ void CMakeSetupDialog::initialize() QObject::connect(this->WarnUninitializedAction, &QAction::triggered, this->CMakeThread->cmakeInstance(), &QCMake::setWarnUninitializedMode); + QObject::connect(this->CMakeThread->cmakeInstance(), + &QCMake::warnUninitializedModeChanged, + this->WarnUninitializedAction, &QAction::setChecked); - if (!this->SourceDirectory->text().isEmpty() || - !this->BinaryDirectory->lineEdit()->text().isEmpty()) { + if (!this->SourceDirectory->text().isEmpty() && + !this->DeferredPreset.isNull()) { + this->onSourceDirectoryChanged(this->SourceDirectory->text()); + } else if (!this->SourceDirectory->text().isEmpty() || + !this->BinaryDirectory->lineEdit()->text().isEmpty()) { this->onSourceDirectoryChanged(this->SourceDirectory->text()); this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text()); } else { @@ -671,6 +688,41 @@ void CMakeSetupDialog::updateBinaryDirectory(const QString& dir) } } +void CMakeSetupDialog::updatePresets(const QVector<QCMakePreset>& presets) +{ + if (this->Preset->presets() != presets) { + this->Preset->blockSignals(true); + this->Preset->setPresets(presets); + this->Preset->blockSignals(false); + } + + this->Preset->setHidden(presets.isEmpty()); + this->PresetLabel->setHidden(presets.isEmpty()); + + if (!this->DeferredPreset.isNull()) { + this->Preset->setPresetName(this->DeferredPreset); + this->DeferredPreset = QString{}; + } +} + +void CMakeSetupDialog::updatePreset(const QString& name) +{ + if (this->Preset->presetName() != name) { + this->Preset->blockSignals(true); + this->Preset->setPresetName(name); + this->Preset->blockSignals(false); + } +} + +void CMakeSetupDialog::showPresetLoadError( + const QString& dir, cmCMakePresetsFile::ReadFileResult result) +{ + QMessageBox::warning( + this, "Error Reading CMake Presets", + QString::fromLocal8Bit("Could not read presets from %1: %2") + .arg(dir, cmCMakePresetsFile::ResultToString(result))); +} + void CMakeSetupDialog::doBinaryBrowse() { QString dir = QFileDialog::getExistingDirectory( @@ -686,6 +738,11 @@ void CMakeSetupDialog::setBinaryDirectory(const QString& dir) this->BinaryDirectory->setEditText(dir); } +void CMakeSetupDialog::setStartupBinaryDirectory(bool startup) +{ + this->StartupBinaryDirectory = startup; +} + void CMakeSetupDialog::onSourceDirectoryChanged(const QString& dir) { this->Output->clear(); @@ -711,11 +768,24 @@ void CMakeSetupDialog::onBinaryDirectoryChanged(const QString& dir) Q_ARG(QString, dir)); } +void CMakeSetupDialog::onBuildPresetChanged(const QString& name) +{ + QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(), "setPreset", + Qt::QueuedConnection, Q_ARG(QString, name), + Q_ARG(bool, !this->StartupBinaryDirectory)); + this->StartupBinaryDirectory = false; +} + void CMakeSetupDialog::setSourceDirectory(const QString& dir) { this->SourceDirectory->setText(dir); } +void CMakeSetupDialog::setDeferredPreset(const QString& preset) +{ + this->DeferredPreset = preset; +} + void CMakeSetupDialog::showProgress(const QString& /*msg*/, float percent) { percent = (percent * ProgressFactor) + ProgressOffset; @@ -753,6 +823,7 @@ void CMakeSetupDialog::setEnabledState(bool enabled) this->CacheValues->cacheModel()->setEditEnabled(enabled); this->SourceDirectory->setEnabled(enabled); this->BrowseSourceDirectoryButton->setEnabled(enabled); + this->Preset->setEnabled(enabled); this->BinaryDirectory->setEnabled(enabled); this->BrowseBinaryDirectoryButton->setEnabled(enabled); this->ReloadCacheAction->setEnabled(enabled); @@ -777,6 +848,17 @@ bool CMakeSetupDialog::setupFirstConfigure() // restore from settings dialog.loadFromSettings(); + auto presetData = this->Preset->currentData(); + if (presetData.isValid()) { + auto preset = presetData.value<QCMakePreset>(); + dialog.setCurrentGenerator(preset.generator); + if (preset.setGenConfig) { + dialog.setPlatform(preset.architecture); + dialog.setToolset(preset.toolset); + } + dialog.setCompilerOption(CompilerOption::DefaultNative); + } + if (dialog.exec() == QDialog::Accepted) { dialog.saveToSettings(); this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator()); diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index d752ef2..f0cc929 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -5,12 +5,15 @@ #include <memory> #include "QCMake.h" +#include "QCMakePreset.h" #include <QEventLoop> #include <QMainWindow> #include <QThread> +#include <QVector> #include "ui_CMakeSetupDialog.h" +class QCMakePresetItemModel; class QCMakeThread; class CMakeCacheModel; class QProgressBar; @@ -33,6 +36,8 @@ public: public slots: void setBinaryDirectory(const QString& dir); void setSourceDirectory(const QString& dir); + void setDeferredPreset(const QString& preset); + void setStartupBinaryDirectory(bool startup); protected slots: void initialize(); @@ -52,6 +57,10 @@ protected slots: void doDeleteCache(); void updateSourceDirectory(const QString& dir); void updateBinaryDirectory(const QString& dir); + void updatePresets(const QVector<QCMakePreset>& presets); + void updatePreset(const QString& name); + void showPresetLoadError(const QString& dir, + cmCMakePresetsFile::ReadFileResult result); void showProgress(const QString& msg, float percent); void setEnabledState(bool); bool setupFirstConfigure(); @@ -62,6 +71,7 @@ protected slots: void saveBuildPaths(const QStringList&); void onBinaryDirectoryChanged(const QString& dir); void onSourceDirectoryChanged(const QString& dir); + void onBuildPresetChanged(const QString& name); void setCacheModified(); void removeSelectedCacheEntries(); void selectionChanged(); @@ -113,6 +123,8 @@ protected: QAction* WarnUninitializedAction; QAction* InstallForCommandLineAction; State CurrentState; + QString DeferredPreset; + bool StartupBinaryDirectory = false; QTextCharFormat ErrorFormat; QTextCharFormat MessageFormat; diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui index 5feee91..afb25eb 100644 --- a/Source/QtDialog/CMakeSetupDialog.ui +++ b/Source/QtDialog/CMakeSetupDialog.ui @@ -44,7 +44,7 @@ <number>6</number> </property> <item row="0" column="0"> - <widget class="QLabel" name="label"> + <widget class="QLabel" name="SourceLabel"> <property name="text"> <string>Where is the source code:</string> </property> @@ -61,13 +61,23 @@ </widget> </item> <item row="1" column="0"> - <widget class="QLabel" name="label_2"> + <widget class="QLabel" name="PresetLabel"> <property name="text"> - <string>Where to build the binaries:</string> + <string>Preset:</string> </property> </widget> </item> <item row="1" column="1"> + <widget class="QCMakePresetComboBox" name="Preset"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="BinaryLabel"> + <property name="text"> + <string>Where to build the binaries:</string> + </property> + </widget> + </item> + <item row="2" column="1"> <widget class="QComboBox" name="BinaryDirectory"> <property name="sizePolicy"> <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> @@ -83,7 +93,7 @@ </property> </widget> </item> - <item row="1" column="2"> + <item row="2" column="2"> <widget class="QPushButton" name="BrowseBinaryDirectoryButton"> <property name="text"> <string>Browse &Build...</string> @@ -367,6 +377,11 @@ <extends>QTreeView</extends> <header>QCMakeCacheView.h</header> </customwidget> + <customwidget> + <class>QCMakePresetComboBox</class> + <extends>QComboBox</extends> + <header>QCMakePresetComboBox.h</header> + </customwidget> </customwidgets> <resources> <include location="CMakeSetup.qrc"/> diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index 918f137..10360bb 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -145,6 +145,36 @@ void StartCompilerSetup::setCurrentGenerator(const QString& gen) } } +void StartCompilerSetup::setPlatform(const QString& platform) +{ + this->PlatformOptions->setCurrentText(platform); +} + +void StartCompilerSetup::setToolset(const QString& toolset) +{ + this->Toolset->setText(toolset); +} + +void StartCompilerSetup::setCompilerOption(CompilerOption option) +{ + std::size_t index = 0; + switch (option) { + case CompilerOption::DefaultNative: + index = 0; + break; + case CompilerOption::SpecifyNative: + index = 1; + break; + case CompilerOption::ToolchainFile: + index = 2; + break; + case CompilerOption::Options: + index = 3; + break; + } + this->CompilerSetupOptions[index]->setChecked(true); +} + QString StartCompilerSetup::getGenerator() const { return this->GeneratorOptions->currentText(); @@ -482,6 +512,26 @@ void FirstConfigure::setGenerators( this->mStartCompilerSetupPage->setGenerators(gens); } +void FirstConfigure::setCurrentGenerator(const QString& gen) +{ + this->mStartCompilerSetupPage->setCurrentGenerator(gen); +} + +void FirstConfigure::setPlatform(const QString& platform) +{ + this->mStartCompilerSetupPage->setPlatform(platform); +} + +void FirstConfigure::setToolset(const QString& toolset) +{ + this->mStartCompilerSetupPage->setToolset(toolset); +} + +void FirstConfigure::setCompilerOption(CompilerOption option) +{ + this->mStartCompilerSetupPage->setCompilerOption(option); +} + QString FirstConfigure::getGenerator() const { return this->mStartCompilerSetupPage->getGenerator(); @@ -503,7 +553,7 @@ void FirstConfigure::loadFromSettings() // restore generator settings.beginGroup("Settings/StartPath"); QString lastGen = settings.value("LastGenerator").toString(); - this->mStartCompilerSetupPage->setCurrentGenerator(lastGen); + this->setCurrentGenerator(lastGen); settings.endGroup(); // restore compiler setup @@ -550,7 +600,7 @@ void FirstConfigure::loadFromSettings() // this prevents them from being taken from environment, while the // generator is taken from application settings if (!mDefaultGenerator.isEmpty()) { - this->mStartCompilerSetupPage->setCurrentGenerator(mDefaultGenerator); + this->setCurrentGenerator(mDefaultGenerator); } } diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h index ca5f52e..5844f3a 100644 --- a/Source/QtDialog/FirstConfigure.h +++ b/Source/QtDialog/FirstConfigure.h @@ -22,6 +22,14 @@ enum FirstConfigurePages Done }; +enum class CompilerOption +{ + DefaultNative, + SpecifyNative, + ToolchainFile, + Options, +}; + //! the first page that gives basic options for what compilers setup to choose //! from class StartCompilerSetup : public QWizardPage @@ -33,6 +41,9 @@ public: ~StartCompilerSetup(); void setGenerators(std::vector<cmake::GeneratorInfo> const& gens); void setCurrentGenerator(const QString& gen); + void setToolset(const QString& toolset); + void setPlatform(const QString& platform); + void setCompilerOption(CompilerOption option); QString getGenerator() const; QString getToolset() const; QString getPlatform() const; @@ -167,6 +178,10 @@ public: ~FirstConfigure(); void setGenerators(std::vector<cmake::GeneratorInfo> const& gens); + void setCurrentGenerator(const QString& gen); + void setToolset(const QString& toolset); + void setPlatform(const QString& platform); + void setCompilerOption(CompilerOption option); QString getGenerator() const; QString getPlatform() const; QString getToolset() const; diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 974c545..9017a63 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -2,10 +2,14 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "QCMake.h" +#include <algorithm> + #include <cm/memory> #include <QCoreApplication> #include <QDir> +#include <QString> +#include <QVector> #include "cmExternalMakefileProjectGenerator.h" #include "cmGlobalGenerator.h" @@ -19,12 +23,15 @@ QCMake::QCMake(QObject* p) : QObject(p) + , StartEnvironment(QProcessEnvironment::systemEnvironment()) , Environment(QProcessEnvironment::systemEnvironment()) { this->WarnUninitializedMode = false; qRegisterMetaType<QCMakeProperty>(); qRegisterMetaType<QCMakePropertyList>(); qRegisterMetaType<QProcessEnvironment>(); + qRegisterMetaType<QVector<QCMakePreset>>(); + qRegisterMetaType<cmCMakePresetsFile::ReadFileResult>(); cmSystemTools::DisableRunCommandOutput(); cmSystemTools::SetRunCommandHideConsole(true); @@ -57,6 +64,17 @@ QCMake::QCMake(QObject* p) for (cmake::GeneratorInfo const& gen : generators) { this->AvailableGenerators.push_back(gen); } + + connect(&this->LoadPresetsTimer, &QTimer::timeout, this, [this]() { + this->loadPresets(); + if (!this->PresetName.isEmpty() && + this->CMakePresetsFile.Presets.find( + std::string(this->PresetName.toLocal8Bit())) == + this->CMakePresetsFile.Presets.end()) { + this->setPreset(QString{}); + } + }); + this->LoadPresetsTimer.start(1000); } QCMake::~QCMake() = default; @@ -73,6 +91,8 @@ void QCMake::setSourceDirectory(const QString& _dir) if (this->SourceDirectory != dir) { this->SourceDirectory = QDir::fromNativeSeparators(dir); emit this->sourceDirChanged(this->SourceDirectory); + this->loadPresets(); + this->setPreset(QString{}); } } @@ -129,6 +149,56 @@ void QCMake::setBinaryDirectory(const QString& _dir) } } +void QCMake::setPreset(const QString& name, bool setBinary) +{ + if (this->PresetName != name) { + this->PresetName = name; + emit this->presetChanged(this->PresetName); + + if (!name.isNull()) { + std::string presetName(name.toLocal8Bit()); + auto const& preset = this->CMakePresetsFile.Presets[presetName]; + auto expandedPreset = this->CMakePresetsFile.ExpandMacros(preset); + if (expandedPreset) { + if (setBinary) { + QString binaryDir = + QString::fromLocal8Bit(expandedPreset->BinaryDir.data()); + this->setBinaryDirectory(binaryDir); + } + if (expandedPreset->WarnDev) { + this->CMakeInstance->SetSuppressDevWarnings( + !*expandedPreset->WarnDev); + } + if (expandedPreset->ErrorDev) { + this->CMakeInstance->SetDevWarningsAsErrors( + *expandedPreset->ErrorDev); + } + if (expandedPreset->WarnDeprecated) { + this->CMakeInstance->SetSuppressDeprecatedWarnings( + !*expandedPreset->WarnDeprecated); + } + if (expandedPreset->ErrorDeprecated) { + this->CMakeInstance->SetDeprecatedWarningsAsErrors( + *expandedPreset->ErrorDeprecated); + } + if (expandedPreset->WarnUninitialized) { + this->WarnUninitializedMode = *expandedPreset->WarnUninitialized; + emit this->warnUninitializedModeChanged( + *expandedPreset->WarnUninitialized); + } + this->Environment = this->StartEnvironment; + for (auto const& v : expandedPreset->Environment) { + if (v.second) { + this->Environment.insert(QString::fromLocal8Bit(v.first.data()), + QString::fromLocal8Bit(v.second->data())); + } + } + } + } + emit this->propertiesChanged(this->properties()); + } +} + void QCMake::setGenerator(const QString& gen) { if (this->Generator != gen) { @@ -348,6 +418,56 @@ QCMakePropertyList QCMake::properties() const ret.append(prop); } + if (!this->PresetName.isNull()) { + std::string presetName(this->PresetName.toLocal8Bit()); + auto p = this->CMakePresetsFile.ExpandMacros( + this->CMakePresetsFile.Presets.at(presetName)); + if (p) { + for (auto const& v : p->CacheVariables) { + if (!v.second) { + continue; + } + QCMakeProperty prop; + prop.Key = QString::fromLocal8Bit(v.first.data()); + prop.Value = QString::fromLocal8Bit(v.second->Value.data()); + prop.Type = QCMakeProperty::STRING; + if (!v.second->Type.empty()) { + auto type = cmState::StringToCacheEntryType(v.second->Type); + switch (type) { + case cmStateEnums::BOOL: + prop.Type = QCMakeProperty::BOOL; + prop.Value = cmIsOn(v.second->Value); + break; + case cmStateEnums::PATH: + prop.Type = QCMakeProperty::PATH; + break; + case cmStateEnums::FILEPATH: + prop.Type = QCMakeProperty::FILEPATH; + break; + default: + prop.Type = QCMakeProperty::STRING; + break; + } + } + + // QCMakeCacheModel prefers variables earlier in the list rather than + // later, so overwrite them if they already exist rather than simply + // appending + bool found = false; + for (auto& orig : ret) { + if (orig.Key == prop.Key) { + orig = prop; + found = true; + break; + } + } + if (!found) { + ret.append(prop); + } + } + } + } + return ret; } @@ -405,6 +525,46 @@ void QCMake::setUpEnvironment() const } } +void QCMake::loadPresets() +{ + auto result = this->CMakePresetsFile.ReadProjectPresets( + this->SourceDirectory.toLocal8Bit().data(), true); + if (result != this->LastLoadPresetsResult && + result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + emit this->presetLoadError(this->SourceDirectory, result); + } + this->LastLoadPresetsResult = result; + + QVector<QCMakePreset> presets; + for (auto const& name : this->CMakePresetsFile.PresetOrder) { + auto const& p = this->CMakePresetsFile.Presets[name]; + if (p.Hidden) { + continue; + } + + QCMakePreset preset; + preset.name = std::move(QString::fromLocal8Bit(p.Name.data())); + preset.displayName = + std::move(QString::fromLocal8Bit(p.DisplayName.data())); + preset.description = + std::move(QString::fromLocal8Bit(p.Description.data())); + preset.generator = std::move(QString::fromLocal8Bit(p.Generator.data())); + preset.architecture = + std::move(QString::fromLocal8Bit(p.Architecture.data())); + preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data())); + preset.setGenConfig = !p.GeneratorConfig || + p.GeneratorConfig == cmCMakePresetsFile::CMakeGeneratorConfig::Default; + preset.enabled = std::find_if(this->AvailableGenerators.begin(), + this->AvailableGenerators.end(), + [&p](const cmake::GeneratorInfo& g) { + return g.name == p.Generator; + }) != this->AvailableGenerators.end() && + this->CMakePresetsFile.ExpandMacros(p); + presets.push_back(preset); + } + emit this->presetsChanged(presets); +} + QString QCMake::binaryDirectory() const { return this->BinaryDirectory; diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index f569951..a6751b0 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -4,6 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmCMakePresetsFile.h" #include "cmake.h" #ifdef _MSC_VER @@ -14,6 +15,7 @@ #include <memory> #include <vector> +#include "QCMakePreset.h" #include <QAtomicInt> #include <QList> #include <QMetaType> @@ -21,6 +23,7 @@ #include <QProcessEnvironment> #include <QString> #include <QStringList> +#include <QTimer> #include <QVariant> /// struct to represent cmake properties in Qt @@ -57,6 +60,7 @@ using QCMakePropertyList = QList<QCMakeProperty>; Q_DECLARE_METATYPE(QCMakeProperty) Q_DECLARE_METATYPE(QCMakePropertyList) Q_DECLARE_METATYPE(QProcessEnvironment) +Q_DECLARE_METATYPE(cmCMakePresetsFile::ReadFileResult) /// Qt API for CMake library. /// Wrapper like class allows for easier integration with @@ -74,6 +78,8 @@ public slots: void setSourceDirectory(const QString& dir); /// set the binary directory to build in void setBinaryDirectory(const QString& dir); + /// set the preset name to use + void setPreset(const QString& name, bool setBinary = true); /// set the desired generator to use void setGenerator(const QString& generator); /// set the desired generator to use @@ -147,6 +153,15 @@ signals: void sourceDirChanged(const QString& dir); /// signal when the binary directory changes void binaryDirChanged(const QString& dir); + /// signal when the preset list changes + void presetsChanged(const QVector<QCMakePreset>& presets); + /// signal when the selected preset changes + void presetChanged(const QString& name); + /// signal when there's an error reading the presets files + void presetLoadError(const QString& dir, + cmCMakePresetsFile::ReadFileResult error); + /// signal when uninitialized warning changes + void warnUninitializedModeChanged(bool value); /// signal for progress events void progressChanged(const QString& msg, float percent); /// signal when configure is done @@ -178,6 +193,8 @@ protected: void stderrCallback(std::string const& msg); void setUpEnvironment() const; + void loadPresets(); + bool WarnUninitializedMode; QString SourceDirectory; QString BinaryDirectory; @@ -185,7 +202,13 @@ protected: QString Platform; QString Toolset; std::vector<cmake::GeneratorInfo> AvailableGenerators; + cmCMakePresetsFile CMakePresetsFile; + cmCMakePresetsFile::ReadFileResult LastLoadPresetsResult = + cmCMakePresetsFile::ReadFileResult::READ_OK; + QString PresetName; QString CMakeExecutable; QAtomicInt InterruptFlag; + QProcessEnvironment StartEnvironment; QProcessEnvironment Environment; + QTimer LoadPresetsTimer; }; diff --git a/Source/QtDialog/QCMakePreset.cxx b/Source/QtDialog/QCMakePreset.cxx new file mode 100644 index 0000000..b10cf07 --- /dev/null +++ b/Source/QtDialog/QCMakePreset.cxx @@ -0,0 +1,50 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "QCMakePreset.h" + +bool operator==(const QCMakePreset& lhs, const QCMakePreset& rhs) +{ + return lhs.name == rhs.name && lhs.displayName == rhs.displayName && + lhs.description == rhs.description && lhs.generator == rhs.generator && + lhs.architecture == rhs.architecture && lhs.toolset == rhs.toolset && + lhs.setGenConfig == rhs.setGenConfig && lhs.enabled == rhs.enabled; +} + +bool operator!=(const QCMakePreset& lhs, const QCMakePreset& rhs) +{ + return !(lhs == rhs); +} + +bool operator<(const QCMakePreset& lhs, const QCMakePreset& rhs) +{ + return lhs.name < rhs.name || + (lhs.name == rhs.name && + (lhs.displayName < rhs.displayName || + (lhs.displayName == rhs.displayName && + (lhs.description < rhs.description || + (lhs.description == rhs.description && + (lhs.generator < rhs.generator || + (lhs.generator == rhs.generator && + (lhs.architecture < rhs.architecture || + (lhs.architecture == rhs.architecture && + (lhs.toolset < rhs.toolset || + (lhs.toolset == rhs.toolset && + (lhs.setGenConfig < rhs.setGenConfig || + (lhs.setGenConfig == rhs.setGenConfig && + (lhs.enabled < rhs.enabled)))))))))))))); +} + +bool operator<=(const QCMakePreset& lhs, const QCMakePreset& rhs) +{ + return rhs >= lhs; +} + +bool operator>(const QCMakePreset& lhs, const QCMakePreset& rhs) +{ + return rhs < lhs; +} + +bool operator>=(const QCMakePreset& lhs, const QCMakePreset& rhs) +{ + return !(lhs < rhs); +} diff --git a/Source/QtDialog/QCMakePreset.h b/Source/QtDialog/QCMakePreset.h new file mode 100644 index 0000000..93d70d8 --- /dev/null +++ b/Source/QtDialog/QCMakePreset.h @@ -0,0 +1,30 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include <QString> +#include <QVariant> + +#include "cmCMakePresetsFile.h" + +class QCMakePreset +{ +public: + QString name; + QString displayName; + QString description; + QString generator; + QString architecture; + QString toolset; + bool setGenConfig; + bool enabled; +}; + +bool operator==(const QCMakePreset& lhs, const QCMakePreset& rhs); +bool operator!=(const QCMakePreset& lhs, const QCMakePreset& rhs); +bool operator<(const QCMakePreset& lhs, const QCMakePreset& rhs); +bool operator<=(const QCMakePreset& lhs, const QCMakePreset& rhs); +bool operator>(const QCMakePreset& lhs, const QCMakePreset& rhs); +bool operator>=(const QCMakePreset& lhs, const QCMakePreset& rhs); + +Q_DECLARE_METATYPE(QCMakePreset) diff --git a/Source/QtDialog/QCMakePresetComboBox.cxx b/Source/QtDialog/QCMakePresetComboBox.cxx new file mode 100644 index 0000000..efadb73 --- /dev/null +++ b/Source/QtDialog/QCMakePresetComboBox.cxx @@ -0,0 +1,64 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "QCMakePresetComboBox.h" + +#include "QCMakePresetItemModel.h" + +QCMakePresetComboBox::QCMakePresetComboBox(QWidget* parent) + : QComboBox(parent) +{ + this->m_model = new QCMakePresetItemModel(this); + this->setModel(this->m_model); + + QObject::connect(this->m_model, &QCMakePresetItemModel::modelAboutToBeReset, + this, [this]() { this->m_resetting = true; }); + QObject::connect(this->m_model, &QCMakePresetItemModel::modelReset, this, + [this]() { + this->setPresetName(this->m_lastPreset); + this->m_resetting = false; + this->emitPresetChanged(); + }); + QObject::connect( + this, + static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + this, [this](int /*row*/) { + if (!this->m_resetting) { + this->emitPresetChanged(); + } + }); +} + +const QVector<QCMakePreset>& QCMakePresetComboBox::presets() const +{ + return this->m_model->presets(); +} + +QString QCMakePresetComboBox::presetName() const +{ + auto preset = this->currentData(); + if (preset.canConvert<QCMakePreset>()) { + return preset.value<QCMakePreset>().name; + } + return QString{}; +} + +void QCMakePresetComboBox::setPresets(const QVector<QCMakePreset>& presets) +{ + this->m_model->setPresets(presets); +} + +void QCMakePresetComboBox::setPresetName(const QString& name) +{ + this->setCurrentIndex(this->m_model->presetNameToRow(name)); + if (this->signalsBlocked()) { + this->m_lastPreset = this->presetName(); + } +} + +void QCMakePresetComboBox::emitPresetChanged() +{ + if (this->presetName() != this->m_lastPreset) { + emit this->presetChanged(this->presetName()); + this->m_lastPreset = this->presetName(); + } +} diff --git a/Source/QtDialog/QCMakePresetComboBox.h b/Source/QtDialog/QCMakePresetComboBox.h new file mode 100644 index 0000000..d1eeffe --- /dev/null +++ b/Source/QtDialog/QCMakePresetComboBox.h @@ -0,0 +1,35 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "QCMakePreset.h" +#include <QComboBox> +#include <QObject> +#include <QString> +#include <QVector> + +class QCMakePresetItemModel; + +class QCMakePresetComboBox : public QComboBox +{ + Q_OBJECT +public: + QCMakePresetComboBox(QWidget* parent = nullptr); + + const QVector<QCMakePreset>& presets() const; + QString presetName() const; + +public slots: + void setPresets(const QVector<QCMakePreset>& presets); + void setPresetName(const QString& name); + +signals: + void presetChanged(const QString& name); + +private: + QCMakePresetItemModel* m_model; + bool m_resetting = false; + QString m_lastPreset; + + void emitPresetChanged(); +}; diff --git a/Source/QtDialog/QCMakePresetItemModel.cxx b/Source/QtDialog/QCMakePresetItemModel.cxx new file mode 100644 index 0000000..00a4e18 --- /dev/null +++ b/Source/QtDialog/QCMakePresetItemModel.cxx @@ -0,0 +1,143 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "QCMakePresetItemModel.h" + +#include <QFont> + +QCMakePresetItemModel::QCMakePresetItemModel(QObject* parent) + : QAbstractItemModel(parent) +{ +} + +QVariant QCMakePresetItemModel::data(const QModelIndex& index, int role) const +{ + switch (role) { + case Qt::AccessibleDescriptionRole: + // Separators have to return "separator" for the + // AccessibleDescriptionRole. This was determined by looking at + // QComboBoxDelegate::isSeparator() (located in qcombobox_p.h.) + if (index.internalId() == SEPARATOR_INDEX) { + return QString::fromLocal8Bit("separator"); + } + return QString{}; + case Qt::DisplayRole: { + if (index.internalId() == CUSTOM_INDEX) { + return QString::fromLocal8Bit("<custom>"); + } + if (index.internalId() == SEPARATOR_INDEX) { + return QVariant{}; + } + auto const& preset = this->m_presets[index.internalId()]; + return preset.displayName.isEmpty() ? preset.name : preset.displayName; + } + case Qt::ToolTipRole: + if (index.internalId() == CUSTOM_INDEX) { + return QString::fromLocal8Bit("Specify all settings manually"); + } + if (index.internalId() == SEPARATOR_INDEX) { + return QVariant{}; + } + return this->m_presets[index.internalId()].description; + case Qt::UserRole: + if (index.internalId() == CUSTOM_INDEX) { + return QVariant{}; + } + if (index.internalId() == SEPARATOR_INDEX) { + return QVariant{}; + } + return QVariant::fromValue(this->m_presets[index.internalId()]); + case Qt::FontRole: + if (index.internalId() == CUSTOM_INDEX) { + QFont font; + font.setItalic(true); + return font; + } + return QFont{}; + default: + return QVariant{}; + } +} + +Qt::ItemFlags QCMakePresetItemModel::flags(const QModelIndex& index) const +{ + Qt::ItemFlags flags = + Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + if (index.internalId() != SEPARATOR_INDEX && + (index.internalId() == CUSTOM_INDEX || + this->m_presets[index.internalId()].enabled)) { + flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled; + } + return flags; +} + +int QCMakePresetItemModel::rowCount(const QModelIndex& parent) const +{ + if (parent.isValid()) { + return 0; + } + if (this->m_presets.empty()) { + return 1; + } + return this->m_presets.size() + 2; +} + +int QCMakePresetItemModel::columnCount(const QModelIndex& parent) const +{ + if (parent.isValid()) { + return 0; + } + return 1; +} + +QModelIndex QCMakePresetItemModel::index(int row, int column, + const QModelIndex& parent) const +{ + if (parent.isValid() || column != 0 || row < 0 || + row >= this->rowCount(QModelIndex{})) { + return QModelIndex{}; + } + + if (this->m_presets.empty() || row == this->m_presets.size() + 1) { + return this->createIndex(row, column, CUSTOM_INDEX); + } + + if (row == this->m_presets.size()) { + return this->createIndex(row, column, SEPARATOR_INDEX); + } + + return this->createIndex(row, column, static_cast<quintptr>(row)); +} + +QModelIndex QCMakePresetItemModel::parent(const QModelIndex& /*index*/) const +{ + return QModelIndex{}; +} + +QVector<QCMakePreset> const& QCMakePresetItemModel::presets() const +{ + return this->m_presets; +} + +void QCMakePresetItemModel::setPresets(QVector<QCMakePreset> const& presets) +{ + this->beginResetModel(); + this->m_presets = presets; + this->endResetModel(); +} + +int QCMakePresetItemModel::presetNameToRow(const QString& name) const +{ + if (this->m_presets.empty()) { + return 0; + } + + int index = 0; + for (auto const& preset : this->m_presets) { + if (preset.name == name) { + return index; + } + index++; + } + + return this->m_presets.size() + 1; +} diff --git a/Source/QtDialog/QCMakePresetItemModel.h b/Source/QtDialog/QCMakePresetItemModel.h new file mode 100644 index 0000000..79fba29 --- /dev/null +++ b/Source/QtDialog/QCMakePresetItemModel.h @@ -0,0 +1,45 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include <cm/optional> + +#include "QCMakePreset.h" +#include <QAbstractItemModel> +#include <QModelIndex> +#include <QString> +#include <QVariant> +#include <QVector> +#include <QtGlobal> + +class QObject; + +class QCMakePresetItemModel : public QAbstractItemModel +{ + Q_OBJECT +public: + QCMakePresetItemModel(QObject* parent = nullptr); + + QVariant data(const QModelIndex& index, int role) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; + + int rowCount(const QModelIndex& parent = QModelIndex{}) const override; + int columnCount(const QModelIndex& parent = QModelIndex{}) const override; + + QModelIndex index(int row, int column, + const QModelIndex& parent = QModelIndex{}) const override; + QModelIndex parent(const QModelIndex& index) const override; + + QVector<QCMakePreset> const& presets() const; + + int presetNameToRow(const QString& name) const; + +public slots: + void setPresets(QVector<QCMakePreset> const& presets); + +private: + QVector<QCMakePreset> m_presets; + + static constexpr quintptr SEPARATOR_INDEX = static_cast<quintptr>(-2); + static constexpr quintptr CUSTOM_INDEX = static_cast<quintptr>(-1); +}; diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsFile.cxx new file mode 100644 index 0000000..25997fd --- /dev/null +++ b/Source/cmCMakePresetsFile.cxx @@ -0,0 +1,763 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmCMakePresetsFile.h" + +#include <cstdlib> +#include <functional> +#include <utility> + +#include <cmext/string_view> + +#include <cm3p/json/reader.h> +#include <cm3p/json/value.h> + +#include "cmsys/FStream.hxx" + +#include "cmJSONHelpers.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmVersion.h" + +namespace { +enum class CycleStatus +{ + Unvisited, + InProgress, + Verified, +}; + +using ReadFileResult = cmCMakePresetsFile::ReadFileResult; +using CacheVariable = cmCMakePresetsFile::CacheVariable; +using UnexpandedPreset = cmCMakePresetsFile::UnexpandedPreset; +using CMakeGeneratorConfig = cmCMakePresetsFile::CMakeGeneratorConfig; + +constexpr int MIN_VERSION = 1; +constexpr int MAX_VERSION = 1; + +struct CMakeVersion +{ + unsigned int Major = 0; + unsigned int Minor = 0; + unsigned int Patch = 0; +}; + +struct RootPresets +{ + CMakeVersion CMakeMinimumRequired; + std::vector<cmCMakePresetsFile::UnexpandedPreset> Presets; +}; + +cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error) +{ + return [error](std::nullptr_t& /*out*/, + const Json::Value* value) -> ReadFileResult { + if (!value) { + return ReadFileResult::READ_OK; + } + + if (!value->isObject()) { + return error; + } + + return ReadFileResult::READ_OK; + }; +} + +auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>( + ReadFileResult::NO_VERSION, VersionIntHelper); + +auto const RootVersionHelper = + cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_ROOT) + .Bind("version"_s, VersionHelper, false); + +auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); + +auto const VariableObjectHelper = + cmJSONObjectHelper<CacheVariable, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) + .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) + .Bind("value"_s, &CacheVariable::Value, VariableStringHelper); + +ReadFileResult VariableHelper(cm::optional<CacheVariable>& out, + const Json::Value* value) +{ + if (value->isString()) { + out = CacheVariable{ + /*Type=*/"", + /*Value=*/value->asString(), + }; + return ReadFileResult::READ_OK; + } + if (value->isObject()) { + out.emplace(); + return VariableObjectHelper(*out, value); + } + if (value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_VARIABLE; +} + +auto const VariablesHelper = + cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); + +auto const PresetStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + +ReadFileResult EnvironmentHelper(cm::optional<std::string>& out, + const Json::Value* value) +{ + if (!value || value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + if (value->isString()) { + out = value->asString(); + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_PRESET; +} + +auto const EnvironmentMapHelper = + cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + EnvironmentHelper); + +auto const PresetVectorStringHelper = + cmJSONVectorHelper<std::string, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + PresetStringHelper); + +ReadFileResult PresetInheritsHelper(std::vector<std::string>& out, + const Json::Value* value) +{ + out.clear(); + if (!value) { + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.push_back(value->asString()); + return ReadFileResult::READ_OK; + } + + return PresetVectorStringHelper(out, value); +} + +auto const PresetBoolHelper = cmJSONBoolHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + +auto const PresetOptionalBoolHelper = + cmJSONOptionalHelper<bool, ReadFileResult>(ReadFileResult::READ_OK, + PresetBoolHelper); + +auto const PresetWarningsHelper = + cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &UnexpandedPreset::WarnDev, PresetOptionalBoolHelper, false) + .Bind("deprecated"_s, &UnexpandedPreset::WarnDeprecated, + PresetOptionalBoolHelper, false) + .Bind("uninitialized"_s, &UnexpandedPreset::WarnUninitialized, + PresetOptionalBoolHelper, false) + .Bind("unusedCli"_s, &UnexpandedPreset::WarnUnusedCli, + PresetOptionalBoolHelper, false) + .Bind("systemVars"_s, &UnexpandedPreset::WarnSystemVars, + PresetOptionalBoolHelper, false); + +auto const PresetErrorsHelper = + cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &UnexpandedPreset::ErrorDev, PresetOptionalBoolHelper, + false) + .Bind("deprecated"_s, &UnexpandedPreset::ErrorDeprecated, + PresetOptionalBoolHelper, false); + +auto const PresetDebugHelper = + cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("output"_s, &UnexpandedPreset::DebugOutput, PresetOptionalBoolHelper, + false) + .Bind("tryCompile"_s, &UnexpandedPreset::DebugTryCompile, + PresetOptionalBoolHelper, false) + .Bind("find"_s, &UnexpandedPreset::DebugFind, PresetOptionalBoolHelper, + false); + +ReadFileResult CMakeGeneratorConfigHelper( + cm::optional<CMakeGeneratorConfig>& out, const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "default") { + out = CMakeGeneratorConfig::Default; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "ignore") { + out = CMakeGeneratorConfig::Ignore; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const PresetHelper = + cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &UnexpandedPreset::Name, PresetStringHelper) + .Bind("inherits"_s, &UnexpandedPreset::Inherits, PresetInheritsHelper, + false) + .Bind("hidden"_s, &UnexpandedPreset::Hidden, PresetBoolHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + VendorHelper(ReadFileResult::INVALID_PRESET), false) + .Bind("displayName"_s, &UnexpandedPreset::DisplayName, PresetStringHelper, + false) + .Bind("description"_s, &UnexpandedPreset::Description, PresetStringHelper, + false) + .Bind("generator"_s, &UnexpandedPreset::Generator, PresetStringHelper, + false) + .Bind("architecture"_s, &UnexpandedPreset::Architecture, + PresetStringHelper, false) + .Bind("toolset"_s, &UnexpandedPreset::Toolset, PresetStringHelper, false) + .Bind("cmakeGeneratorConfig"_s, &UnexpandedPreset::GeneratorConfig, + CMakeGeneratorConfigHelper, false) + .Bind("binaryDir"_s, &UnexpandedPreset::BinaryDir, PresetStringHelper, + false) + .Bind<std::string>("cmakeExecutable"_s, nullptr, PresetStringHelper, false) + .Bind("cacheVariables"_s, &UnexpandedPreset::CacheVariables, + VariablesHelper, false) + .Bind("environment"_s, &UnexpandedPreset::Environment, + EnvironmentMapHelper, false) + .Bind("warnings"_s, PresetWarningsHelper, false) + .Bind("errors"_s, PresetErrorsHelper, false) + .Bind("debug"_s, PresetDebugHelper, false); + +auto const PresetsHelper = + cmJSONVectorHelper<UnexpandedPreset, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, PresetHelper); + +auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const CMakeVersionHelper = + cmJSONObjectHelper<CMakeVersion, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) + .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) + .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) + .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); + +auto const RootPresetsHelper = + cmJSONObjectHelper<RootPresets, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) + .Bind<int>("version"_s, nullptr, VersionHelper) + .Bind("configurePresets"_s, &RootPresets::Presets, PresetsHelper, false) + .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, + CMakeVersionHelper, false) + .Bind<std::nullptr_t>("vendor"_s, nullptr, + VendorHelper(ReadFileResult::INVALID_ROOT), false); + +void InheritString(std::string& child, const std::string& parent) +{ + if (child.empty()) { + child = parent; + } +} + +void InheritOptionalBool(cm::optional<bool>& child, + const cm::optional<bool>& parent) +{ + if (!child) { + child = parent; + } +} + +/** + * Check preset inheritance for cycles (using a DAG check algorithm) while + * also bubbling up fields through the inheritance hierarchy, then verify + * that each preset has the required fields, either directly or through + * inheritance. + */ +ReadFileResult VisitPreset(std::map<std::string, UnexpandedPreset>& presets, + UnexpandedPreset& preset, + std::map<std::string, CycleStatus> cycleStatus) +{ + switch (cycleStatus[preset.Name]) { + case CycleStatus::InProgress: + return ReadFileResult::CYCLIC_PRESET_INHERITANCE; + case CycleStatus::Verified: + return ReadFileResult::READ_OK; + default: + break; + } + + cycleStatus[preset.Name] = CycleStatus::InProgress; + + for (auto const& i : preset.Inherits) { + auto parent = presets.find(i); + if (parent == presets.end()) { + return ReadFileResult::INVALID_PRESET; + } + + if (!preset.User && parent->second.User) { + return ReadFileResult::USER_PRESET_INHERITANCE; + } + + auto result = VisitPreset(presets, parent->second, cycleStatus); + if (result != ReadFileResult::READ_OK) { + return result; + } + + InheritString(preset.Generator, parent->second.Generator); + InheritString(preset.Architecture, parent->second.Architecture); + InheritString(preset.Toolset, parent->second.Toolset); + if (!preset.GeneratorConfig) { + preset.GeneratorConfig = parent->second.GeneratorConfig; + } + InheritString(preset.BinaryDir, parent->second.BinaryDir); + InheritOptionalBool(preset.WarnDev, parent->second.WarnDev); + InheritOptionalBool(preset.ErrorDev, parent->second.ErrorDev); + InheritOptionalBool(preset.WarnDeprecated, parent->second.WarnDeprecated); + InheritOptionalBool(preset.ErrorDeprecated, + parent->second.ErrorDeprecated); + InheritOptionalBool(preset.WarnUninitialized, + parent->second.WarnUninitialized); + InheritOptionalBool(preset.WarnUnusedCli, parent->second.WarnUnusedCli); + InheritOptionalBool(preset.WarnSystemVars, parent->second.WarnSystemVars); + for (auto const& v : parent->second.CacheVariables) { + preset.CacheVariables.insert(v); + } + for (auto const& v : parent->second.Environment) { + preset.Environment.insert(v); + } + } + + if (!preset.Hidden) { + if (preset.Generator.empty()) { + return ReadFileResult::INVALID_PRESET; + } + if (preset.BinaryDir.empty()) { + return ReadFileResult::INVALID_PRESET; + } + if (preset.WarnDev == false && preset.ErrorDev == true) { + return ReadFileResult::INVALID_PRESET; + } + if (preset.WarnDeprecated == false && preset.ErrorDeprecated == true) { + return ReadFileResult::INVALID_PRESET; + } + } + + cycleStatus[preset.Name] = CycleStatus::Verified; + return ReadFileResult::READ_OK; +} + +ReadFileResult ComputePresetInheritance( + std::map<std::string, UnexpandedPreset>& presets) +{ + std::map<std::string, CycleStatus> cycleStatus; + for (auto const& it : presets) { + cycleStatus[it.first] = CycleStatus::Unvisited; + } + + for (auto& it : presets) { + auto result = VisitPreset(presets, it.second, cycleStatus); + if (result != ReadFileResult::READ_OK) { + return result; + } + } + + return ReadFileResult::READ_OK; +} + +constexpr const char* ValidPrefixes[] = { + "", + "env", + "penv", + "vendor", +}; + +bool PrefixesValidMacroNamespace(const std::string& str) +{ + for (auto const& prefix : ValidPrefixes) { + if (cmHasPrefix(prefix, str)) { + return true; + } + } + return false; +} + +bool IsValidMacroNamespace(const std::string& str) +{ + for (auto const& prefix : ValidPrefixes) { + if (str == prefix) { + return true; + } + } + return false; +} + +bool VisitEnv(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& value, CycleStatus& status); +bool ExpandMacros(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out); +bool ExpandMacro(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out, const std::string& macroNamespace, + const std::string& macroName); + +bool VisitEnv(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& value, CycleStatus& status) +{ + if (status == CycleStatus::Verified) { + return true; + } + if (status == CycleStatus::InProgress) { + return false; + } + + status = CycleStatus::InProgress; + if (!ExpandMacros(file, preset, envCycles, value)) { + return false; + } + status = CycleStatus::Verified; + return true; +} + +bool ExpandMacros(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out) +{ + std::string result; + std::string macroNamespace; + std::string macroName; + + enum class State + { + Default, + MacroNamespace, + MacroName, + } state = State::Default; + + for (auto c : out) { + switch (state) { + case State::Default: + if (c == '$') { + state = State::MacroNamespace; + } else { + result += c; + } + break; + + case State::MacroNamespace: + if (c == '{') { + if (IsValidMacroNamespace(macroNamespace)) { + state = State::MacroName; + } else { + result += '$'; + result += macroNamespace; + result += '{'; + macroNamespace.clear(); + state = State::Default; + } + } else { + macroNamespace += c; + if (!PrefixesValidMacroNamespace(macroNamespace)) { + result += '$'; + result += macroNamespace; + macroNamespace.clear(); + state = State::Default; + } + } + break; + + case State::MacroName: + if (c == '}') { + if (!ExpandMacro(file, preset, envCycles, result, macroNamespace, + macroName)) { + return false; + } + macroNamespace.clear(); + macroName.clear(); + state = State::Default; + } else { + macroName += c; + } + break; + } + } + + switch (state) { + case State::Default: + break; + case State::MacroNamespace: + result += '$'; + result += macroNamespace; + break; + case State::MacroName: + return false; + } + + out = std::move(result); + return true; +} + +bool ExpandMacro(const cmCMakePresetsFile& file, + cmCMakePresetsFile::ExpandedPreset& preset, + std::map<std::string, CycleStatus>& envCycles, + std::string& out, const std::string& macroNamespace, + const std::string& macroName) +{ + if (macroNamespace.empty()) { + if (macroName == "sourceDir") { + out += file.SourceDir; + return true; + } + if (macroName == "sourceParentDir") { + out += cmSystemTools::GetParentDirectory(file.SourceDir); + return true; + } + if (macroName == "presetName") { + out += preset.Name; + return true; + } + if (macroName == "generator") { + out += preset.Generator; + return true; + } + if (macroName == "dollar") { + out += '$'; + return true; + } + } + + if (macroNamespace == "env") { + auto v = preset.Environment.find(macroName); + if (v != preset.Environment.end() && v->second) { + if (!VisitEnv(file, preset, envCycles, *v->second, + envCycles[macroName])) { + return false; + } + out += *v->second; + return true; + } + } + + if (macroNamespace == "env" || macroNamespace == "penv") { + const char* value = std::getenv(macroName.c_str()); + if (value) { + out += value; + } + return true; + } + + // "vendor" falls through to here + return false; +} +} + +std::string cmCMakePresetsFile::GetFilename(const std::string& sourceDir) +{ + return cmStrCat(sourceDir, "/CMakePresets.json"); +} + +std::string cmCMakePresetsFile::GetUserFilename(const std::string& sourceDir) +{ + return cmStrCat(sourceDir, "/CMakeUserPresets.json"); +} + +cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadProjectPresets( + const std::string& sourceDir, bool allowNoFiles) +{ + bool haveOneFile = false; + this->SourceDir = sourceDir; + this->Presets.clear(); + this->PresetOrder.clear(); + + std::vector<std::string> presetOrder; + std::map<std::string, UnexpandedPreset> presetMap; + + std::string filename = GetUserFilename(this->SourceDir); + if (cmSystemTools::FileExists(filename)) { + auto result = this->ReadJSONFile(filename, presetOrder, presetMap, true); + if (result != ReadFileResult::READ_OK) { + return result; + } + haveOneFile = true; + } + + filename = GetFilename(this->SourceDir); + if (cmSystemTools::FileExists(filename)) { + auto result = this->ReadJSONFile(filename, presetOrder, presetMap, false); + if (result != ReadFileResult::READ_OK) { + return result; + } + haveOneFile = true; + } + + if (!haveOneFile) { + return allowNoFiles ? ReadFileResult::READ_OK + : ReadFileResult::FILE_NOT_FOUND; + } + + auto result = ComputePresetInheritance(presetMap); + if (result != ReadFileResult::READ_OK) { + return result; + } + + this->PresetOrder = std::move(presetOrder); + this->Presets = std::move(presetMap); + return ReadFileResult::READ_OK; +} + +const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) +{ + switch (result) { + case ReadFileResult::READ_OK: + return "OK"; + case ReadFileResult::FILE_NOT_FOUND: + return "File not found"; + case ReadFileResult::JSON_PARSE_ERROR: + return "JSON parse error"; + case ReadFileResult::INVALID_ROOT: + return "Invalid root object"; + case ReadFileResult::NO_VERSION: + return "No \"version\" field"; + case ReadFileResult::INVALID_VERSION: + return "Invalid \"version\" field"; + case ReadFileResult::UNRECOGNIZED_VERSION: + return "Unrecognized \"version\" field"; + case ReadFileResult::INVALID_CMAKE_VERSION: + return "Invalid \"cmakeMinimumRequired\" field"; + case ReadFileResult::UNRECOGNIZED_CMAKE_VERSION: + return "\"cmakeMinimumRequired\" version too new"; + case ReadFileResult::INVALID_PRESETS: + return "Invalid \"configurePresets\" field"; + case ReadFileResult::INVALID_PRESET: + return "Invalid preset"; + case ReadFileResult::INVALID_VARIABLE: + return "Invalid CMake variable definition"; + case ReadFileResult::DUPLICATE_PRESETS: + return "Duplicate presets"; + case ReadFileResult::CYCLIC_PRESET_INHERITANCE: + return "Cyclic preset inheritance"; + case ReadFileResult::USER_PRESET_INHERITANCE: + return "Project preset inherits from user preset"; + default: + return "Unknown error"; + } +} + +cm::optional<cmCMakePresetsFile::ExpandedPreset> +cmCMakePresetsFile::ExpandMacros(const UnexpandedPreset& preset) const +{ + ExpandedPreset retval{ preset }; + + std::map<std::string, CycleStatus> envCycles; + for (auto const& v : retval.Environment) { + envCycles[v.first] = CycleStatus::Unvisited; + } + + for (auto& v : retval.Environment) { + if (v.second && + !VisitEnv(*this, retval, envCycles, *v.second, envCycles[v.first])) { + return cm::nullopt; + } + } + + std::string binaryDir = preset.BinaryDir; + if (!::ExpandMacros(*this, retval, envCycles, binaryDir)) { + return cm::nullopt; + } + if (!cmSystemTools::FileIsFullPath(binaryDir)) { + binaryDir = cmStrCat(this->SourceDir, '/', binaryDir); + } + retval.BinaryDir = cmSystemTools::CollapseFullPath(binaryDir); + cmSystemTools::ConvertToUnixSlashes(retval.BinaryDir); + + for (auto& variable : retval.CacheVariables) { + if (variable.second && + !::ExpandMacros(*this, retval, envCycles, variable.second->Value)) { + return cm::nullopt; + } + } + + return cm::make_optional(retval); +} + +cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( + const std::string& filename, std::vector<std::string>& presetOrder, + std::map<std::string, UnexpandedPreset>& presetMap, bool user) +{ + cmsys::ifstream fin(filename.c_str()); + if (!fin) { + return ReadFileResult::FILE_NOT_FOUND; + } + // If there's a BOM, toss it. + cmsys::FStream::ReadBOM(fin); + + Json::Value root; + Json::CharReaderBuilder builder; + if (!Json::parseFromStream(builder, fin, &root, nullptr)) { + return ReadFileResult::JSON_PARSE_ERROR; + } + + int v = 0; + auto result = RootVersionHelper(v, &root); + if (result != ReadFileResult::READ_OK) { + return result; + } + if (v < MIN_VERSION || v > MAX_VERSION) { + return ReadFileResult::UNRECOGNIZED_VERSION; + } + + RootPresets presets; + if ((result = RootPresetsHelper(presets, &root)) != + ReadFileResult::READ_OK) { + return result; + } + + unsigned int currentMajor = cmVersion::GetMajorVersion(); + unsigned int currentMinor = cmVersion::GetMinorVersion(); + unsigned int currentPatch = cmVersion::GetPatchVersion(); + auto const& required = presets.CMakeMinimumRequired; + if (required.Major > currentMajor || + (required.Major == currentMajor && + (required.Minor > currentMinor || + (required.Minor == currentMinor && + (required.Patch > currentPatch))))) { + return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION; + } + + for (auto& preset : presets.Presets) { + preset.User = user; + if (preset.Name.empty()) { + return ReadFileResult::INVALID_PRESET; + } + if (!presetMap.insert({ preset.Name, preset }).second) { + return ReadFileResult::DUPLICATE_PRESETS; + } + presetOrder.push_back(preset.Name); + } + + return ReadFileResult::READ_OK; +} diff --git a/Source/cmCMakePresetsFile.h b/Source/cmCMakePresetsFile.h new file mode 100644 index 0000000..70ec4c5 --- /dev/null +++ b/Source/cmCMakePresetsFile.h @@ -0,0 +1,141 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include <map> +#include <string> +#include <utility> +#include <vector> + +#include <cm/optional> + +class cmCMakePresetsFile +{ +public: + enum class CMakeGeneratorConfig + { + Default, + Ignore, + }; + + class CacheVariable + { + public: + std::string Type; + std::string Value; + }; + + class Preset + { + public: +#if __cplusplus < 201703L && (!defined(_MSVC_LANG) || _MSVC_LANG < 201703L) + Preset() = default; + Preset(const Preset& /*other*/) = default; + Preset(Preset&& /*other*/) = default; + + Preset& operator=(const Preset& /*other*/) = default; + + // The move assignment operators for several STL classes did not become + // noexcept until C++17, which causes some tools to warn about this move + // assignment operator throwing an exception when it shouldn't. Disable the + // move assignment operator until C++17 is enabled. + Preset& operator=(Preset&& /*other*/) = delete; +#endif + + std::string Name; + std::vector<std::string> Inherits; + bool Hidden; + bool User; + std::string DisplayName; + std::string Description; + std::string Generator; + std::string Architecture; + std::string Toolset; + cm::optional<CMakeGeneratorConfig> GeneratorConfig; + std::string BinaryDir; + + std::map<std::string, cm::optional<CacheVariable>> CacheVariables; + std::map<std::string, cm::optional<std::string>> Environment; + + cm::optional<bool> WarnDev; + cm::optional<bool> ErrorDev; + cm::optional<bool> WarnDeprecated; + cm::optional<bool> ErrorDeprecated; + cm::optional<bool> WarnUninitialized; + cm::optional<bool> WarnUnusedCli; + cm::optional<bool> WarnSystemVars; + + cm::optional<bool> DebugOutput; + cm::optional<bool> DebugTryCompile; + cm::optional<bool> DebugFind; + }; + + class UnexpandedPreset : public Preset + { + public: + using Preset::Preset; + + UnexpandedPreset() = default; + UnexpandedPreset(const Preset& preset) + : Preset(preset) + { + } + UnexpandedPreset(Preset&& preset) + : Preset(std::move(preset)) + { + } + }; + + class ExpandedPreset : public Preset + { + public: + using Preset::Preset; + + ExpandedPreset() = default; + ExpandedPreset(const Preset& preset) + : Preset(preset) + { + } + ExpandedPreset(Preset&& preset) + : Preset(std::move(preset)) + { + } + }; + + std::string SourceDir; + std::map<std::string, UnexpandedPreset> Presets; + std::vector<std::string> PresetOrder; + + enum class ReadFileResult + { + READ_OK, + FILE_NOT_FOUND, + JSON_PARSE_ERROR, + INVALID_ROOT, + NO_VERSION, + INVALID_VERSION, + UNRECOGNIZED_VERSION, + INVALID_CMAKE_VERSION, + UNRECOGNIZED_CMAKE_VERSION, + INVALID_PRESETS, + INVALID_PRESET, + INVALID_VARIABLE, + DUPLICATE_PRESETS, + CYCLIC_PRESET_INHERITANCE, + USER_PRESET_INHERITANCE, + }; + + static std::string GetFilename(const std::string& sourceDir); + static std::string GetUserFilename(const std::string& sourceDir); + ReadFileResult ReadProjectPresets(const std::string& sourceDir, + bool allowNoFiles = false); + static const char* ResultToString(ReadFileResult result); + + cm::optional<ExpandedPreset> ExpandMacros( + const UnexpandedPreset& preset) const; + +private: + ReadFileResult ReadJSONFile( + const std::string& filename, std::vector<std::string>& presetOrder, + std::map<std::string, UnexpandedPreset>& presetMap, bool user); +}; diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h index 3a7f806..d6ababb 100644 --- a/Source/cmGlobalGeneratorFactory.h +++ b/Source/cmGlobalGeneratorFactory.h @@ -25,7 +25,7 @@ public: /** Create a GlobalGenerator */ virtual std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& n, cmake* cm) const = 0; + const std::string& n, bool allowArch, cmake* cm) const = 0; /** Get the documentation entry for this factory */ virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0; @@ -53,7 +53,7 @@ class cmGlobalGeneratorSimpleFactory : public cmGlobalGeneratorFactory public: /** Create a GlobalGenerator */ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool /*allowArch*/, cmake* cm) const override { if (name != T::GetActualName()) { return std::unique_ptr<cmGlobalGenerator>(); diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 3805546..7794df3 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -59,7 +59,7 @@ class cmGlobalVisualStudio10Generator::Factory { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool allowArch, cmake* cm) const override { std::string genName; const char* p = cmVS10GenName(name, genName); @@ -70,7 +70,7 @@ public: return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudio10Generator(cm, genName, "")); } - if (*p++ != ' ') { + if (!allowArch || *p++ != ' ') { return std::unique_ptr<cmGlobalGenerator>(); } if (strcmp(p, "Win64") == 0) { diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index a385375..a5ffcf0 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -31,7 +31,7 @@ class cmGlobalVisualStudio11Generator::Factory { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool allowArch, cmake* cm) const override { std::string genName; const char* p = cmVS11GenName(name, genName); @@ -42,7 +42,7 @@ public: return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudio11Generator(cm, genName, "")); } - if (*p++ != ' ') { + if (!allowArch || *p++ != ' ') { return std::unique_ptr<cmGlobalGenerator>(); } if (strcmp(p, "Win64") == 0) { diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index 5a27994..8bdf356 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -29,7 +29,7 @@ class cmGlobalVisualStudio12Generator::Factory { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool allowArch, cmake* cm) const override { std::string genName; const char* p = cmVS12GenName(name, genName); @@ -40,7 +40,7 @@ public: return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudio12Generator(cm, genName, "")); } - if (*p++ != ' ') { + if (!allowArch || *p++ != ' ') { return std::unique_ptr<cmGlobalGenerator>(); } if (strcmp(p, "Win64") == 0) { diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index a12b7e1..e17c6d7 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -30,7 +30,7 @@ class cmGlobalVisualStudio14Generator::Factory { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool allowArch, cmake* cm) const override { std::string genName; const char* p = cmVS14GenName(name, genName); @@ -41,7 +41,7 @@ public: return std::unique_ptr<cmGlobalGenerator>( new cmGlobalVisualStudio14Generator(cm, genName, "")); } - if (*p++ != ' ') { + if (!allowArch || *p++ != ' ') { return std::unique_ptr<cmGlobalGenerator>(); } if (strcmp(p, "Win64") == 0) { diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index 9f73c15..2339a80 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -16,7 +16,7 @@ class cmGlobalVisualStudio9Generator::Factory : public cmGlobalGeneratorFactory { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool allowArch, cmake* cm) const override { if (strncmp(name.c_str(), vs9generatorName, sizeof(vs9generatorName) - 1) != 0) { @@ -29,7 +29,7 @@ public: new cmGlobalVisualStudio9Generator(cm, name, "")); } - if (p[0] != ' ') { + if (!allowArch || p[0] != ' ') { return std::unique_ptr<cmGlobalGenerator>(); } diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index 4b877ce..95357e7 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -140,7 +140,7 @@ class cmGlobalVisualStudioVersionedGenerator::Factory15 { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool allowArch, cmake* cm) const override { std::string genName; const char* p = cmVS15GenName(name, genName); @@ -152,7 +152,7 @@ public: new cmGlobalVisualStudioVersionedGenerator( cmGlobalVisualStudioGenerator::VS15, cm, genName, "")); } - if (*p++ != ' ') { + if (!allowArch || *p++ != ' ') { return std::unique_ptr<cmGlobalGenerator>(); } if (strcmp(p, "Win64") == 0) { @@ -234,7 +234,7 @@ class cmGlobalVisualStudioVersionedGenerator::Factory16 { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override + const std::string& name, bool /*allowArch*/, cmake* cm) const override { std::string genName; const char* p = cmVS16GenName(name, genName); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index f1a1ce6..952a179 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -135,7 +135,7 @@ class cmGlobalXCodeGenerator::Factory : public cmGlobalGeneratorFactory { public: std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name, cmake* cm) const override; + const std::string& name, bool allowArch, cmake* cm) const override; void GetDocumentation(cmDocumentationEntry& entry) const override { @@ -197,6 +197,7 @@ std::unique_ptr<cmGlobalGeneratorFactory> cmGlobalXCodeGenerator::NewFactory() std::unique_ptr<cmGlobalGenerator> cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(const std::string& name, + bool /*allowArch*/, cmake* cm) const { if (name != GetActualName()) { diff --git a/Source/cmJSONHelpers.h b/Source/cmJSONHelpers.h index 2da2a03..a63347d 100644 --- a/Source/cmJSONHelpers.h +++ b/Source/cmJSONHelpers.h @@ -29,6 +29,9 @@ public: template <typename M, typename F> cmJSONObjectHelper& Bind(const cm::string_view& name, std::nullptr_t, F func, bool required = true); + template <typename F> + cmJSONObjectHelper& Bind(const cm::string_view& name, F func, + bool required = true); E operator()(T& out, const Json::Value* value) const; @@ -87,6 +90,14 @@ cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind( } template <typename T, typename E> +template <typename F> +cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind( + const cm::string_view& name, F func, bool required) +{ + return this->BindPrivate(name, MemberFunction(func), required); +} + +template <typename T, typename E> cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::BindPrivate( const cm::string_view& name, MemberFunction&& func, bool required) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index d9c6b7a..2a14b03 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -13,6 +13,7 @@ #include <utility> #include <cm/memory> +#include <cm/optional> #include <cm/string_view> #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW) # include <cm/iterator> @@ -27,6 +28,7 @@ #include "cm_sys_stat.h" +#include "cmCMakePresetsFile.h" #include "cmCommands.h" #include "cmDocumentation.h" #include "cmDocumentationEntry.h" @@ -286,6 +288,97 @@ void cmake::CleanupCommandsAndMacros() this->CurrentSnapshot.SetDefaultDefinitions(); } +#ifndef CMAKE_BOOTSTRAP +void cmake::SetWarningFromPreset(const std::string& name, + const cm::optional<bool>& warning, + const cm::optional<bool>& error) +{ + if (warning) { + if (*warning) { + this->DiagLevels[name] = std::max(this->DiagLevels[name], DIAG_WARN); + } else { + this->DiagLevels[name] = DIAG_IGNORE; + } + } + if (error) { + if (*error) { + this->DiagLevels[name] = DIAG_ERROR; + } else { + this->DiagLevels[name] = std::min(this->DiagLevels[name], DIAG_WARN); + } + } +} + +void cmake::ProcessPresetVariables() +{ + for (auto const& var : this->UnprocessedPresetVariables) { + if (!var.second) { + continue; + } + cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED; + if (!var.second->Type.empty()) { + type = cmState::StringToCacheEntryType(var.second->Type); + } + this->ProcessCacheArg(var.first, var.second->Value, type); + } +} + +void cmake::PrintPresetVariables() +{ + bool first = true; + for (auto const& var : this->UnprocessedPresetVariables) { + if (!var.second) { + continue; + } + cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED; + if (!var.second->Type.empty()) { + type = cmState::StringToCacheEntryType(var.second->Type); + } + if (first) { + std::cout << "Preset CMake variables:\n\n"; + first = false; + } + std::cout << " " << var.first; + if (type != cmStateEnums::UNINITIALIZED) { + std::cout << ':' << cmState::CacheEntryTypeToString(type); + } + std::cout << "=\"" << var.second->Value << "\"\n"; + } + if (!first) { + std::cout << '\n'; + } + this->UnprocessedPresetVariables.clear(); +} + +void cmake::ProcessPresetEnvironment() +{ + for (auto const& var : this->UnprocessedPresetEnvironment) { + if (var.second) { + cmSystemTools::PutEnv(cmStrCat(var.first, '=', *var.second)); + } + } +} + +void cmake::PrintPresetEnvironment() +{ + bool first = true; + for (auto const& var : this->UnprocessedPresetEnvironment) { + if (!var.second) { + continue; + } + if (first) { + std::cout << "Preset environment variables:\n\n"; + first = false; + } + std::cout << " " << var.first << "=\"" << *var.second << "\"\n"; + } + if (!first) { + std::cout << '\n'; + } + this->UnprocessedPresetEnvironment.clear(); +} +#endif + // Parse the args bool cmake::SetCacheArgs(const std::vector<std::string>& args) { @@ -308,28 +401,10 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) std::string value; cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED; if (cmState::ParseCacheEntry(entry, var, value, type)) { - // The value is transformed if it is a filepath for example, so - // we can't compare whether the value is already in the cache until - // after we call AddCacheEntry. - bool haveValue = false; - std::string cachedValue; - if (this->WarnUnusedCli) { - if (cmProp v = this->State->GetInitializedCacheValue(var)) { - haveValue = true; - cachedValue = *v; - } - } - - this->AddCacheEntry(var, value.c_str(), - "No help, variable specified on the command line.", - type); - - if (this->WarnUnusedCli) { - if (!haveValue || - cachedValue != *this->State->GetInitializedCacheValue(var)) { - this->WatchUnusedCli(var); - } - } +#ifndef CMAKE_BOOTSTRAP + this->UnprocessedPresetVariables.erase(var); +#endif + this->ProcessCacheArg(var, value, type); } else { cmSystemTools::Error("Parse error in command line argument: " + arg + "\n" + "Should be: VAR:type=value\n"); @@ -409,6 +484,9 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) // now remove them from the cache for (std::string const& currentEntry : entriesToDelete) { +#ifndef CMAKE_BOOTSTRAP + this->UnprocessedPresetVariables.erase(currentEntry); +#endif this->State->RemoveCacheEntry(currentEntry); } } else if (cmHasLiteralPrefix(arg, "-C")) { @@ -462,6 +540,33 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) return true; } +void cmake::ProcessCacheArg(const std::string& var, const std::string& value, + cmStateEnums::CacheEntryType type) +{ + // The value is transformed if it is a filepath for example, so + // we can't compare whether the value is already in the cache until + // after we call AddCacheEntry. + bool haveValue = false; + std::string cachedValue; + if (this->WarnUnusedCli) { + if (cmProp v = this->State->GetInitializedCacheValue(var)) { + haveValue = true; + cachedValue = *v; + } + } + + this->AddCacheEntry(var, value.c_str(), + "No help, variable specified on the command line.", + type); + + if (this->WarnUnusedCli) { + if (!haveValue || + cachedValue != *this->State->GetInitializedCacheValue(var)) { + this->WatchUnusedCli(var); + } + } +} + void cmake::ReadListFile(const std::vector<std::string>& args, const std::string& path) { @@ -625,6 +730,8 @@ void cmake::SetArgs(const std::vector<std::string>& args) #if !defined(CMAKE_BOOTSTRAP) std::string profilingFormat; std::string profilingOutput; + std::string presetName; + bool listPresets = false; #endif for (unsigned int i = 1; i < args.size(); ++i) { std::string const& arg = args[i]; @@ -830,19 +937,9 @@ void cmake::SetArgs(const std::vector<std::string>& args) } value = args[i]; } - auto gen = this->CreateGlobalGenerator(value); - if (!gen) { - std::string kdevError; - if (value.find("KDevelop3", 0) != std::string::npos) { - kdevError = "\nThe KDevelop3 generator is not supported anymore."; - } - - cmSystemTools::Error( - cmStrCat("Could not create named generator ", value, kdevError)); - this->PrintGeneratorList(); + if (!this->CreateAndSetGlobalGenerator(value, true)) { return; } - this->SetGlobalGenerator(std::move(gen)); #if !defined(CMAKE_BOOTSTRAP) } else if (cmHasLiteralPrefix(arg, "--profiling-format")) { profilingFormat = arg.substr(strlen("--profiling-format=")); @@ -856,6 +953,13 @@ void cmake::SetArgs(const std::vector<std::string>& args) if (profilingOutput.empty()) { cmSystemTools::Error("No path specified for --profiling-output"); } + } else if (cmHasLiteralPrefix(arg, "--preset")) { + presetName = arg.substr(strlen("--preset=")); + if (presetName.empty()) { + cmSystemTools::Error("No preset specified for --preset"); + } + } else if (cmHasLiteralPrefix(arg, "--list-presets")) { + listPresets = true; #endif } // no option assume it is the path to the source or an existing build @@ -915,6 +1019,91 @@ void cmake::SetArgs(const std::vector<std::string>& args) if (!haveBinaryDir) { this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory()); } + +#if !defined(CMAKE_BOOTSTRAP) + if (listPresets || !presetName.empty()) { + cmCMakePresetsFile settingsFile; + auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory()); + if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + cmSystemTools::Error( + cmStrCat("Could not read presets from ", this->GetHomeDirectory(), + ": ", cmCMakePresetsFile::ResultToString(result))); + return; + } + if (listPresets) { + this->PrintPresetList(settingsFile); + return; + } + auto preset = settingsFile.Presets.find(presetName); + if (preset == settingsFile.Presets.end()) { + cmSystemTools::Error(cmStrCat("No such preset in ", + this->GetHomeDirectory(), ": \"", + presetName, '"')); + this->PrintPresetList(settingsFile); + return; + } + if (preset->second.Hidden) { + cmSystemTools::Error(cmStrCat("Cannot use hidden preset in ", + this->GetHomeDirectory(), ": \"", + presetName, '"')); + this->PrintPresetList(settingsFile); + return; + } + auto expandedPreset = settingsFile.ExpandMacros(preset->second); + if (!expandedPreset) { + cmSystemTools::Error(cmStrCat("Could not evaluate preset \"", + preset->second.Name, + "\": Invalid macro expansion")); + return; + } + + if (!haveBinaryDir) { + this->SetHomeOutputDirectory(expandedPreset->BinaryDir); + } + if (!this->GlobalGenerator) { + if (!this->CreateAndSetGlobalGenerator(expandedPreset->Generator, + false)) { + return; + } + } + this->UnprocessedPresetVariables = expandedPreset->CacheVariables; + this->UnprocessedPresetEnvironment = expandedPreset->Environment; + + if (!expandedPreset->GeneratorConfig || + expandedPreset->GeneratorConfig == + cmCMakePresetsFile::CMakeGeneratorConfig::Default) { + if (!this->GeneratorPlatformSet) { + this->SetGeneratorPlatform(expandedPreset->Architecture); + } + if (!this->GeneratorToolsetSet) { + this->SetGeneratorToolset(expandedPreset->Toolset); + } + } + + this->SetWarningFromPreset("dev", expandedPreset->WarnDev, + expandedPreset->ErrorDev); + this->SetWarningFromPreset("deprecated", expandedPreset->WarnDeprecated, + expandedPreset->ErrorDeprecated); + if (expandedPreset->WarnUninitialized == true) { + this->SetWarnUninitialized(true); + } + if (expandedPreset->WarnUnusedCli == false) { + this->SetWarnUnusedCli(false); + } + if (expandedPreset->WarnSystemVars == true) { + this->SetCheckSystemVars(true); + } + if (expandedPreset->DebugOutput == true) { + this->SetDebugOutputOn(true); + } + if (expandedPreset->DebugTryCompile == true) { + this->DebugTryCompileOn(); + } + if (expandedPreset->DebugFind == true) { + this->SetDebugFindOutputOn(true); + } + } +#endif } cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr) @@ -1217,7 +1406,7 @@ createExtraGenerator( } std::unique_ptr<cmGlobalGenerator> cmake::CreateGlobalGenerator( - const std::string& gname) + const std::string& gname, bool allowArch) { std::pair<std::unique_ptr<cmExternalMakefileProjectGenerator>, std::string> extra = createExtraGenerator(this->ExtraGenerators, gname); @@ -1227,7 +1416,7 @@ std::unique_ptr<cmGlobalGenerator> cmake::CreateGlobalGenerator( std::unique_ptr<cmGlobalGenerator> generator; for (const auto& g : this->Generators) { - generator = g->CreateGlobalGenerator(name, this); + generator = g->CreateGlobalGenerator(name, allowArch, this); if (generator) { break; } @@ -1240,6 +1429,79 @@ std::unique_ptr<cmGlobalGenerator> cmake::CreateGlobalGenerator( return generator; } +bool cmake::CreateAndSetGlobalGenerator(const std::string& name, + bool allowArch) +{ + auto gen = this->CreateGlobalGenerator(name, allowArch); + if (!gen) { + std::string kdevError; + std::string vsError; + if (name.find("KDevelop3", 0) != std::string::npos) { + kdevError = "\nThe KDevelop3 generator is not supported anymore."; + } + if (!allowArch && cmHasLiteralPrefix(name, "Visual Studio ") && + name.length() >= cmStrLen("Visual Studio xx xxxx ")) { + vsError = "\nUsing platforms in Visual Studio generator names is not " + "supported in CMakePresets.json."; + } + + cmSystemTools::Error( + cmStrCat("Could not create named generator ", name, kdevError, vsError)); + this->PrintGeneratorList(); + return false; + } + + this->SetGlobalGenerator(std::move(gen)); + return true; +} + +#ifndef CMAKE_BOOTSTRAP +void cmake::PrintPresetList(const cmCMakePresetsFile& file) const +{ + std::vector<GeneratorInfo> generators; + this->GetRegisteredGenerators(generators, false); + + std::vector<cmCMakePresetsFile::UnexpandedPreset> presets; + for (auto const& p : file.PresetOrder) { + auto const& preset = file.Presets.at(p); + if (!preset.Hidden && + std::find_if(generators.begin(), generators.end(), + [&preset](const GeneratorInfo& info) { + return info.name == preset.Generator; + }) != generators.end() && + file.ExpandMacros(preset)) { + presets.push_back(preset); + } + } + + if (presets.empty()) { + return; + } + + std::cout << "Available presets:\n\n"; + + auto longestPresetName = + std::max_element(presets.begin(), presets.end(), + [](const cmCMakePresetsFile::UnexpandedPreset& a, + const cmCMakePresetsFile::UnexpandedPreset& b) { + return a.Name.length() < b.Name.length(); + }); + auto longestLength = longestPresetName->Name.length(); + + for (auto const& preset : presets) { + std::cout << " \"" << preset.Name << '"'; + auto const& description = preset.DisplayName; + if (!description.empty()) { + for (std::size_t i = 0; i < longestLength - preset.Name.length(); ++i) { + std::cout << ' '; + } + std::cout << " - " << description; + } + std::cout << '\n'; + } +} +#endif + void cmake::SetHomeDirectory(const std::string& dir) { this->State->SetSourceDirectory(dir); @@ -1803,6 +2065,9 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) if (cmSystemTools::GetErrorOccuredFlag()) { return -1; } + if (this->GetWorkingMode() == HELP_MODE) { + return 0; + } // Log the trace format version to the desired output if (this->GetTrace()) { @@ -1831,11 +2096,19 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) this->AddCMakePaths(); } +#ifndef CMAKE_BOOTSTRAP + this->ProcessPresetVariables(); + this->ProcessPresetEnvironment(); +#endif // Add any cache args if (!this->SetCacheArgs(args)) { cmSystemTools::Error("Problem processing arguments. Aborting.\n"); return -1; } +#ifndef CMAKE_BOOTSTRAP + this->PrintPresetVariables(); + this->PrintPresetEnvironment(); +#endif // In script mode we terminate after running the script. if (this->GetWorkingMode() != NORMAL_MODE) { diff --git a/Source/cmake.h b/Source/cmake.h index 63635cb..262d673 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -27,7 +27,11 @@ #include "cmStateTypes.h" #if !defined(CMAKE_BOOTSTRAP) +# include <cm/optional> + # include <cm3p/json/value.h> + +# include "cmCMakePresetsFile.h" #endif class cmExternalMakefileProjectGeneratorFactory; @@ -88,13 +92,22 @@ public: enum WorkingMode { NORMAL_MODE, ///< Cmake runs to create project files - /** \brief Script mode (started by using -P). - * - * In script mode there is no generator and no cache. Also, - * languages are not enabled, so add_executable and things do - * nothing. - */ + + /** \brief Script mode (started by using -P). + * + * In script mode there is no generator and no cache. Also, + * languages are not enabled, so add_executable and things do + * nothing. + */ SCRIPT_MODE, + + /** \brief Help mode + * + * Used to print help for things that can only be determined after finding + * the source directory, for example, the list of presets. + */ + HELP_MODE, + /** \brief A pkg-config like mode * * In this mode cmake just searches for a package and prints the results to @@ -219,7 +232,15 @@ public: //! Create a GlobalGenerator std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( - const std::string& name); + const std::string& name, bool allowArch = true); + + //! Create a GlobalGenerator and set it as our own + bool CreateAndSetGlobalGenerator(const std::string& name, bool allowArch); + +#ifndef CMAKE_BOOTSTRAP + //! Print list of presets + void PrintPresetList(const cmCMakePresetsFile& file) const; +#endif //! Return the global generator assigned to this instance of cmake cmGlobalGenerator* GetGlobalGenerator() @@ -329,9 +350,22 @@ public: bool GetIsInTryCompile() const; void SetIsInTryCompile(bool b); +#ifndef CMAKE_BOOTSTRAP + void SetWarningFromPreset(const std::string& name, + const cm::optional<bool>& warning, + const cm::optional<bool>& error); + void ProcessPresetVariables(); + void PrintPresetVariables(); + void ProcessPresetEnvironment(); + void PrintPresetEnvironment(); +#endif + //! Parse command line arguments that might set cache values bool SetCacheArgs(const std::vector<std::string>&); + void ProcessCacheArg(const std::string& var, const std::string& value, + cmStateEnums::CacheEntryType type); + using ProgressCallbackType = std::function<void(const std::string&, float)>; /** * Set the function used by GUIs to receive progress updates @@ -625,6 +659,12 @@ private: std::unique_ptr<cmFileTimeCache> FileTimeCache; std::string GraphVizFile; InstalledFilesMap InstalledFiles; +#ifndef CMAKE_BOOTSTRAP + std::map<std::string, cm::optional<cmCMakePresetsFile::CacheVariable>> + UnprocessedPresetVariables; + std::map<std::string, cm::optional<std::string>> + UnprocessedPresetEnvironment; +#endif #if !defined(CMAKE_BOOTSTRAP) std::unique_ptr<cmVariableWatch> VariableWatch; @@ -664,6 +704,8 @@ private: #define CMAKE_STANDARD_OPTIONS_TABLE \ { "-S <path-to-source>", "Explicitly specify a source directory." }, \ { "-B <path-to-build>", "Explicitly specify a build directory." }, \ + { "--preset=<preset-name>", "Explicitly specify a preset." }, \ + { "--list-presets", "List available presets." }, \ { "-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." }, \ diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 4600fc5..c769227 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -49,7 +49,8 @@ const char* cmDocumentationUsage[][2] = { { nullptr, " cmake [options] <path-to-source>\n" " cmake [options] <path-to-existing-build>\n" - " cmake [options] -S <path-to-source> -B <path-to-build>" }, + " cmake [options] -S <path-to-source> -B <path-to-build>\n" + " cmake [options] -S <path-to-source> --preset=<preset-name>" }, { nullptr, "Specify a source directory to (re-)generate a build system for " "it in the current working directory. Specify an existing build " @@ -253,6 +254,9 @@ int do_cmake(int ac, char const* const* av) } else if (cmHasLiteralPrefix(av[i], "--find-package")) { workingMode = cmake::FIND_PACKAGE_MODE; args.emplace_back(av[i]); + } else if (strcmp(av[i], "--list-presets") == 0) { + workingMode = cmake::HELP_MODE; + args.emplace_back(av[i]); } else { args.emplace_back(av[i]); } @@ -269,6 +273,7 @@ int do_cmake(int ac, char const* const* av) cmState::Mode mode = cmState::Unknown; switch (workingMode) { case cmake::NORMAL_MODE: + case cmake::HELP_MODE: mode = cmState::Project; break; case cmake::SCRIPT_MODE: diff --git a/Tests/CMakeGUI/CMakeGUITest.cmake b/Tests/CMakeGUI/CMakeGUITest.cmake index b60ec35..2c6baf3 100644 --- a/Tests/CMakeGUI/CMakeGUITest.cmake +++ b/Tests/CMakeGUI/CMakeGUITest.cmake @@ -27,6 +27,10 @@ function(run_cmake_gui_test name) if(EXISTS "${_cmakelists_in}") configure_file("${_cmakelists_in}" "${_workdir}/src/CMakeLists.txt" @ONLY) endif() + set(_cmakepresets_in "${_srcdir}/CMakePresets.json.in") + if(EXISTS "${_cmakepresets_in}") + configure_file("${_cmakepresets_in}" "${_workdir}/src/CMakePresets.json" @ONLY) + endif() if(_rcgt_DO_CONFIGURE) if(NOT _rcgt_GENERATOR) set(_rcgt_GENERATOR "${CMakeGUITest_GENERATOR}") @@ -118,3 +122,37 @@ set(ENV{KEPT_VARIABLE} "Kept variable") set(ENV{CHANGED_VARIABLE} "This variable will be changed") set(ENV{REMOVED_VARIABLE} "Removed variable") run_cmake_gui_test(environment) + +run_cmake_gui_test(presetArg:preset + ARGS + -S "${CMakeGUITest_BINARY_DIR}/presetArg-preset/src" + "--preset=ninja" + ) +run_cmake_gui_test(presetArg:presetBinary + ARGS + -S "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinary/src" + -B "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinary/build" + "--preset=ninja" + ) +run_cmake_gui_test(presetArg:presetBinaryChange + ARGS + -S "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinaryChange/src" + -B "${CMakeGUITest_BINARY_DIR}/presetArg-presetBinaryChange/build" + "--preset=ninja" + ) +run_cmake_gui_test(presetArg:noPresetBinaryChange + ARGS + -S "${CMakeGUITest_BINARY_DIR}/presetArg-noPresetBinaryChange/src" + -B "${CMakeGUITest_BINARY_DIR}/presetArg-noPresetBinaryChange/build" + ) +run_cmake_gui_test(presetArg:presetConfigExists + ARGS + -S "${CMakeGUITest_BINARY_DIR}/presetArg-presetConfigExists/src" + "--preset=ninja" + ) +run_cmake_gui_test(presetArg:noExist + ARGS + -S "${CMakeGUITest_BINARY_DIR}/presetArg-noExist/src" + "--preset=noExist" + ) +run_cmake_gui_test(changingPresets) diff --git a/Tests/CMakeGUI/CMakeGUITest.cxx b/Tests/CMakeGUI/CMakeGUITest.cxx index 80ea08d..5a6bec3 100644 --- a/Tests/CMakeGUI/CMakeGUITest.cxx +++ b/Tests/CMakeGUI/CMakeGUITest.cxx @@ -5,6 +5,10 @@ #include "QCMake.h" #include <QApplication> #include <QEventLoop> +#include <QFile> +#include <QJsonArray> +#include <QJsonDocument> +#include <QJsonObject> #include <QMessageBox> #include <QSettings> #include <QString> @@ -18,8 +22,11 @@ #include "CatchShow.h" #include "FirstConfigure.h" +using WindowSetupHelper = std::function<void(CMakeSetupDialog*)>; +Q_DECLARE_METATYPE(WindowSetupHelper) + namespace { -void loopSleep(int msecs = 100) +void loopSleep(int msecs = 500) { QEventLoop loop; QTimer::singleShot(msecs, &loop, &QEventLoop::quit); @@ -172,6 +179,264 @@ void CMakeGUITest::environment() QCOMPARE(penv.value("REMOVED_VARIABLE"), "Removed variable"); } +void CMakeGUITest::presetArg() +{ + QFETCH(WindowSetupHelper, setupFunction); + QFETCH(QString, presetName); + QFETCH(QString, sourceDir); + QFETCH(QString, binaryDir); + QFETCH(QCMakePropertyList, properties); + + if (setupFunction) { + setupFunction(this->m_window); + } + + // Wait a bit for everything to update + loopSleep(); + + QCOMPARE(this->m_window->Preset->presetName(), presetName); + QCOMPARE(this->m_window->SourceDirectory->text(), sourceDir); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), binaryDir); + + auto actualProperties = + this->m_window->CacheValues->cacheModel()->properties(); + QCOMPARE(actualProperties.size(), properties.size()); + for (int i = 0; i < actualProperties.size(); ++i) { + // operator==() only compares Key, we need to compare Value and Type too + QCOMPARE(actualProperties[i].Key, properties[i].Key); + QCOMPARE(actualProperties[i].Value, properties[i].Value); + QCOMPARE(actualProperties[i].Type, properties[i].Type); + } +} + +namespace { +QCMakePropertyList makePresetProperties(const QString& name) +{ + return QCMakePropertyList{ + QCMakeProperty{ + /*Key=*/"FALSE_VARIABLE", + /*Value=*/false, + /*Strings=*/{}, + /*Help=*/"", + /*Type=*/QCMakeProperty::BOOL, + /*Advanced=*/false, + }, + QCMakeProperty{ + /*Key=*/"FILEPATH_VARIABLE", + /*Value=*/ + QString::fromLocal8Bit(CMakeGUITest_BINARY_DIR "/%1/src/CMakeLists.txt") + .arg(name), + /*Strings=*/{}, + /*Help=*/"", + /*Type=*/QCMakeProperty::FILEPATH, + /*Advanced=*/false, + }, + QCMakeProperty{ + /*Key=*/"ON_VARIABLE", + /*Value=*/true, + /*Strings=*/{}, + /*Help=*/"", + /*Type=*/QCMakeProperty::BOOL, + /*Advanced=*/false, + }, + QCMakeProperty{ + /*Key=*/"PATH_VARIABLE", + /*Value=*/ + QString::fromLocal8Bit(CMakeGUITest_BINARY_DIR "/%1/src").arg(name), + /*Strings=*/{}, + /*Help=*/"", + /*Type=*/QCMakeProperty::PATH, + /*Advanced=*/false, + }, + QCMakeProperty{ + /*Key=*/"STRING_VARIABLE", + /*Value=*/"String value", + /*Strings=*/{}, + /*Help=*/"", + /*Type=*/QCMakeProperty::STRING, + /*Advanced=*/false, + }, + QCMakeProperty{ + /*Key=*/"UNINITIALIZED_VARIABLE", + /*Value=*/"Uninitialized value", + /*Strings=*/{}, + /*Help=*/"", + /*Type=*/QCMakeProperty::STRING, + /*Advanced=*/false, + }, + }; +} +} + +void CMakeGUITest::presetArg_data() +{ + QTest::addColumn<WindowSetupHelper>("setupFunction"); + QTest::addColumn<QString>("presetName"); + QTest::addColumn<QString>("sourceDir"); + QTest::addColumn<QString>("binaryDir"); + QTest::addColumn<QCMakePropertyList>("properties"); + + QTest::newRow("preset") << WindowSetupHelper{} << "ninja" + << CMakeGUITest_BINARY_DIR "/presetArg-preset/src" + << CMakeGUITest_BINARY_DIR + "/presetArg-preset/src/build" + << makePresetProperties("presetArg-preset"); + QTest::newRow("presetBinary") + << WindowSetupHelper{} << "ninja" + << CMakeGUITest_BINARY_DIR "/presetArg-presetBinary/src" + << CMakeGUITest_BINARY_DIR "/presetArg-presetBinary/build" + << makePresetProperties("presetArg-presetBinary"); + QTest::newRow("presetBinaryChange") + << WindowSetupHelper{ [](CMakeSetupDialog* window) { + loopSleep(); + window->Preset->setPresetName("ninja2"); + } } + << "ninja2" << CMakeGUITest_BINARY_DIR "/presetArg-presetBinaryChange/src" + << CMakeGUITest_BINARY_DIR "/presetArg-presetBinaryChange/src/build" + << makePresetProperties("presetArg-presetBinaryChange"); + QTest::newRow("noPresetBinaryChange") + << WindowSetupHelper{ [](CMakeSetupDialog* window) { + loopSleep(); + window->Preset->setPresetName("ninja"); + } } + << "ninja" << CMakeGUITest_BINARY_DIR "/presetArg-noPresetBinaryChange/src" + << CMakeGUITest_BINARY_DIR "/presetArg-noPresetBinaryChange/src/build" + << makePresetProperties("presetArg-noPresetBinaryChange"); + QTest::newRow("presetConfigExists") + << WindowSetupHelper{} << "ninja" + << CMakeGUITest_BINARY_DIR "/presetArg-presetConfigExists/src" + << CMakeGUITest_BINARY_DIR "/presetArg-presetConfigExists/src/build" + << makePresetProperties("presetArg-presetConfigExists"); + QTest::newRow("noExist") << WindowSetupHelper{} << QString{} + << CMakeGUITest_BINARY_DIR "/presetArg-noExist/src" + << "" << QCMakePropertyList{}; +} + +namespace { +void writePresets(const QString& buildDir, const QStringList& names) +{ + QJsonArray presets{ + QJsonObject{ + { "name", "base" }, + { "generator", "Ninja" }, + { "binaryDir", + QString::fromLocal8Bit("${sourceDir}/%1/${presetName}") + .arg(buildDir) }, + { "hidden", true }, + }, + }; + + for (auto const& name : names) { + presets.append(QJsonObject{ + { "name", name }, + { "inherits", QJsonArray{ "base" } }, + }); + } + + QJsonDocument doc{ QJsonObject{ + { "version", 1 }, + { "configurePresets", presets }, + } }; + + QFile presetsFile(CMakeGUITest_BINARY_DIR + "/changingPresets/src/CMakePresets.json"); + bool open = presetsFile.open(QIODevice::WriteOnly); + Q_ASSERT(open); + presetsFile.write(doc.toJson()); +} +} + +void CMakeGUITest::changingPresets() +{ + QDir::root().mkpath(CMakeGUITest_BINARY_DIR "/changingPresets/src"); + + this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR + "/changingPresets/src"); + loopSleep(); + QCOMPARE(this->m_window->Preset->presetName(), QString{}); + QCOMPARE(this->m_window->Preset->presets().size(), 0); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), ""); + QCOMPARE(this->m_window->Preset->isHidden(), true); + QCOMPARE(this->m_window->PresetLabel->isHidden(), true); + + writePresets("build1", { "preset" }); + loopSleep(1500); + QCOMPARE(this->m_window->Preset->presetName(), QString{}); + QCOMPARE(this->m_window->Preset->presets().size(), 1); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), ""); + QCOMPARE(this->m_window->Preset->isHidden(), false); + QCOMPARE(this->m_window->PresetLabel->isHidden(), false); + + this->m_window->Preset->setPresetName("preset"); + loopSleep(); + QCOMPARE(this->m_window->Preset->presetName(), "preset"); + QCOMPARE(this->m_window->Preset->presets().size(), 1); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), + CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset"); + QCOMPARE(this->m_window->Preset->isHidden(), false); + QCOMPARE(this->m_window->PresetLabel->isHidden(), false); + + writePresets("build2", { "preset2", "preset" }); + loopSleep(1500); + QCOMPARE(this->m_window->Preset->presetName(), "preset"); + QCOMPARE(this->m_window->Preset->presets().size(), 2); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), + CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset"); + QCOMPARE(this->m_window->Preset->isHidden(), false); + QCOMPARE(this->m_window->PresetLabel->isHidden(), false); + + writePresets("build3", { "preset2" }); + loopSleep(1500); + QCOMPARE(this->m_window->Preset->presetName(), QString{}); + QCOMPARE(this->m_window->Preset->presets().size(), 1); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), + CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset"); + QCOMPARE(this->m_window->Preset->isHidden(), false); + QCOMPARE(this->m_window->PresetLabel->isHidden(), false); + + this->m_window->Preset->setPresetName("preset2"); + loopSleep(); + QCOMPARE(this->m_window->Preset->presetName(), "preset2"); + QCOMPARE(this->m_window->Preset->presets().size(), 1); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), + CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2"); + QCOMPARE(this->m_window->Preset->isHidden(), false); + QCOMPARE(this->m_window->PresetLabel->isHidden(), false); + + QDir::root().mkpath(CMakeGUITest_BINARY_DIR "/changingPresets/src2"); + QFile::copy(CMakeGUITest_BINARY_DIR "/changingPresets/src/CMakePresets.json", + CMakeGUITest_BINARY_DIR + "/changingPresets/src2/CMakePresets.json"); + this->m_window->SourceDirectory->setText(CMakeGUITest_BINARY_DIR + "/changingPresets/src2"); + loopSleep(); + QCOMPARE(this->m_window->Preset->presetName(), QString{}); + QCOMPARE(this->m_window->Preset->presets().size(), 1); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), + CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2"); + QCOMPARE(this->m_window->Preset->isHidden(), false); + QCOMPARE(this->m_window->PresetLabel->isHidden(), false); + + this->m_window->Preset->setPresetName("preset2"); + loopSleep(); + QCOMPARE(this->m_window->Preset->presetName(), "preset2"); + QCOMPARE(this->m_window->Preset->presets().size(), 1); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), + CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2"); + QCOMPARE(this->m_window->Preset->isHidden(), false); + QCOMPARE(this->m_window->PresetLabel->isHidden(), false); + + QFile(CMakeGUITest_BINARY_DIR "/changingPresets/src2/CMakePresets.json") + .remove(); + loopSleep(1500); + QCOMPARE(this->m_window->Preset->presetName(), QString{}); + QCOMPARE(this->m_window->Preset->presets().size(), 0); + QCOMPARE(this->m_window->BinaryDirectory->currentText(), + CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2"); + QCOMPARE(this->m_window->Preset->isHidden(), true); + QCOMPARE(this->m_window->PresetLabel->isHidden(), true); +} + void SetupDefaultQSettings() { QSettings::setDefaultFormat(QSettings::IniFormat); diff --git a/Tests/CMakeGUI/CMakeGUITest.h b/Tests/CMakeGUI/CMakeGUITest.h index 891cf62..e6293a4 100644 --- a/Tests/CMakeGUI/CMakeGUITest.h +++ b/Tests/CMakeGUI/CMakeGUITest.h @@ -23,4 +23,7 @@ private slots: void simpleConfigure(); void simpleConfigure_data(); void environment(); + void presetArg(); + void presetArg_data(); + void changingPresets(); }; diff --git a/Tests/CMakeGUI/CMakeLists.txt b/Tests/CMakeGUI/CMakeLists.txt index c6bc88a..4e8609b 100644 --- a/Tests/CMakeGUI/CMakeLists.txt +++ b/Tests/CMakeGUI/CMakeLists.txt @@ -72,3 +72,24 @@ add_cmake_gui_lib_test(QCMakeCacheModel MOC_SOURCES QCMakeCacheModelTest.h ) +add_cmake_gui_lib_test(QCMakePreset + SOURCES + QCMakePresetTest.cxx + QCMakePresetTest.h + MOC_SOURCES + QCMakePresetTest.h + ) +add_cmake_gui_lib_test(QCMakePresetItemModel + SOURCES + QCMakePresetItemModelTest.cxx + QCMakePresetItemModelTest.h + MOC_SOURCES + QCMakePresetItemModelTest.h + ) +add_cmake_gui_lib_test(QCMakePresetComboBox + SOURCES + QCMakePresetComboBoxTest.cxx + QCMakePresetComboBoxTest.h + MOC_SOURCES + QCMakePresetComboBoxTest.h + ) diff --git a/Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx b/Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx new file mode 100644 index 0000000..6ee55c3 --- /dev/null +++ b/Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx @@ -0,0 +1,80 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "QCMakePresetComboBoxTest.h" + +#include <QtTest> + +void QCMakePresetComboBoxTest::changePresets() +{ + QCMakePresetComboBox box; + QSignalSpy presetChanged(&box, &QCMakePresetComboBox::presetChanged); + + QCOMPARE(presetChanged.size(), 0); + + box.setPresets({}); + QCOMPARE(presetChanged.size(), 0); + + box.setPresetName(QString{}); + QCOMPARE(presetChanged.size(), 0); + + box.setPresets({ + { + /*name=*/"preset", + /*description=*/"", + /*description=*/"", + /*generator=*/"Ninja", + /*architecture=*/"", + /*toolset=*/"", + /*setGenConfig=*/true, + /*enabled=*/true, + }, + }); + QCOMPARE(presetChanged.size(), 0); + + box.setPresetName(QString{}); + QCOMPARE(presetChanged.size(), 0); + + box.setPresetName("noexist"); + QCOMPARE(presetChanged.size(), 0); + + box.setPresetName("preset"); + QCOMPARE(presetChanged.size(), 1); + QCOMPARE(presetChanged.last(), QList<QVariant>{ "preset" }); + + box.setPresets({ + { + /*name=*/"preset", + /*description=*/"", + /*description=*/"", + /*generator=*/"Ninja Multi-Config", + /*architecture=*/"", + /*toolset=*/"", + /*setGenConfig=*/true, + /*enabled=*/true, + }, + }); + QCOMPARE(presetChanged.size(), 1); + + box.setPresetName("noexist"); + QCOMPARE(presetChanged.size(), 2); + QCOMPARE(presetChanged.last(), QList<QVariant>{ QString{} }); + + box.setPresetName("preset"); + QCOMPARE(presetChanged.size(), 3); + QCOMPARE(presetChanged.last(), QList<QVariant>{ "preset" }); + + box.blockSignals(true); + box.setPresetName(QString{}); + box.blockSignals(false); + QCOMPARE(presetChanged.size(), 3); + + box.setPresetName("preset"); + QCOMPARE(presetChanged.size(), 4); + QCOMPARE(presetChanged.last(), QList<QVariant>{ "preset" }); + + box.setPresets({}); + QCOMPARE(presetChanged.size(), 5); + QCOMPARE(presetChanged.last(), QList<QVariant>{ QString{} }); +} + +QTEST_MAIN(QCMakePresetComboBoxTest) diff --git a/Tests/CMakeGUI/QCMakePresetComboBoxTest.h b/Tests/CMakeGUI/QCMakePresetComboBoxTest.h new file mode 100644 index 0000000..433adbb --- /dev/null +++ b/Tests/CMakeGUI/QCMakePresetComboBoxTest.h @@ -0,0 +1,13 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "QCMakePresetComboBox.h" +#include <QObject> + +class QCMakePresetComboBoxTest : public QObject +{ + Q_OBJECT +private slots: + void changePresets(); +}; diff --git a/Tests/CMakeGUI/QCMakePresetItemModelTest.cxx b/Tests/CMakeGUI/QCMakePresetItemModelTest.cxx new file mode 100644 index 0000000..ee45d39 --- /dev/null +++ b/Tests/CMakeGUI/QCMakePresetItemModelTest.cxx @@ -0,0 +1,162 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "QCMakePresetItemModelTest.h" + +#include <utility> + +#include "QCMakePreset.h" +#include "QCMakePresetItemModel.h" +#include <QHash> +#include <QMetaType> +#include <QSignalSpy> +#include <QVariant> +#include <QVector> +#include <QtTest> + +using QItemDataHash = QHash<Qt::ItemDataRole, QVariant>; + +void QCMakePresetItemModelTest::initTestCase() +{ + QMetaType::registerComparators<QCMakePreset>(); +} + +void QCMakePresetItemModelTest::initTestCase_data() +{ + QTest::addColumn<QVector<QCMakePreset>>("presets"); + QTest::addColumn<QVector<QItemDataHash>>("data"); + + QVector<QCMakePreset> presets{ + QCMakePreset{ + /*name=*/"no-description", + /*description=*/"", + /*description=*/"", + /*generator=*/"", + /*architecture=*/"", + /*toolset=*/"", + /*setGenConfig=*/true, + /*enabled=*/true, + }, + QCMakePreset{ + /*name=*/"short-description", + /*description=*/"Short Description", + /*description=*/"", + /*generator=*/"", + /*architecture=*/"", + /*toolset=*/"", + /*setGenConfig=*/true, + /*enabled=*/true, + }, + QCMakePreset{ + /*name=*/"long-description", + /*description=*/"", + /*description=*/"Long Description", + /*generator=*/"", + /*architecture=*/"", + /*toolset=*/"", + /*setGenConfig=*/true, + /*enabled=*/true, + }, + QCMakePreset{ + /*name=*/"disabled", + /*description=*/"", + /*description=*/"", + /*generator=*/"", + /*architecture=*/"", + /*toolset=*/"", + /*setGenConfig=*/true, + /*enabled=*/false, + }, + }; + QVector<QItemDataHash> data{ + QItemDataHash{ + { Qt::AccessibleDescriptionRole, "" }, + { Qt::DisplayRole, "no-description" }, + { Qt::ToolTipRole, "" }, + { Qt::UserRole, QVariant::fromValue(presets[0]) }, + { Qt::FontRole, QFont{} }, + }, + QItemDataHash{ + { Qt::AccessibleDescriptionRole, "" }, + { Qt::DisplayRole, "Short Description" }, + { Qt::ToolTipRole, "" }, + { Qt::UserRole, QVariant::fromValue(presets[1]) }, + { Qt::FontRole, QFont{} }, + }, + QItemDataHash{ + { Qt::AccessibleDescriptionRole, "" }, + { Qt::DisplayRole, "long-description" }, + { Qt::ToolTipRole, "Long Description" }, + { Qt::UserRole, QVariant::fromValue(presets[2]) }, + { Qt::FontRole, QFont{} }, + }, + QItemDataHash{ + { Qt::AccessibleDescriptionRole, "" }, + { Qt::DisplayRole, "disabled" }, + { Qt::ToolTipRole, "" }, + { Qt::UserRole, QVariant::fromValue(presets[3]) }, + { Qt::FontRole, QFont{} }, + }, + QItemDataHash{ + { Qt::AccessibleDescriptionRole, "separator" }, + { Qt::DisplayRole, QVariant{} }, + { Qt::ToolTipRole, QVariant{} }, + { Qt::UserRole, QVariant{} }, + { Qt::FontRole, QFont{} }, + }, + QItemDataHash{ + { Qt::AccessibleDescriptionRole, "" }, + { Qt::DisplayRole, "<custom>" }, + { Qt::ToolTipRole, "Specify all settings manually" }, + { Qt::UserRole, QVariant{} }, + { Qt::FontRole, + []() { + QFont f; + f.setItalic(true); + return f; + }() }, + }, + }; + QTest::newRow("many") << presets << data; + QTest::newRow("none") << QVector<QCMakePreset>{} + << QVector<QItemDataHash>{ data.last() }; +} + +void QCMakePresetItemModelTest::data() +{ + QFETCH_GLOBAL(QVector<QCMakePreset>, presets); + QFETCH_GLOBAL(QVector<QItemDataHash>, data); + QFETCH(Qt::ItemDataRole, role); + + QCMakePresetItemModel model; + QSignalSpy spy1(&model, &QCMakePresetItemModel::modelAboutToBeReset); + QSignalSpy spy2(&model, &QCMakePresetItemModel::modelReset); + model.setPresets(presets); + QCOMPARE(spy1.size(), 1); + QCOMPARE(spy2.size(), 1); + + QVector<QVariant> expectedData(data.size()); + for (int i = 0; i < data.size(); ++i) { + expectedData[i] = data[i][role]; + } + + auto rows = model.rowCount(); + QVector<QVariant> actualData(rows); + for (int i = 0; i < rows; ++i) { + actualData[i] = model.data(model.index(i, 0), role); + } + + QCOMPARE(actualData, expectedData); +} + +void QCMakePresetItemModelTest::data_data() +{ + QTest::addColumn<Qt::ItemDataRole>("role"); + + QTest::newRow("accessible") << Qt::AccessibleDescriptionRole; + QTest::newRow("display") << Qt::DisplayRole; + QTest::newRow("tooltip") << Qt::ToolTipRole; + QTest::newRow("user") << Qt::UserRole; + QTest::newRow("font") << Qt::FontRole; +} + +QTEST_MAIN(QCMakePresetItemModelTest) diff --git a/Tests/CMakeGUI/QCMakePresetItemModelTest.h b/Tests/CMakeGUI/QCMakePresetItemModelTest.h new file mode 100644 index 0000000..ff6efae --- /dev/null +++ b/Tests/CMakeGUI/QCMakePresetItemModelTest.h @@ -0,0 +1,17 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "QCMakePresetItemModel.h" +#include <QObject> + +class QCMakePresetItemModelTest : public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void initTestCase_data(); + + void data(); + void data_data(); +}; diff --git a/Tests/CMakeGUI/QCMakePresetTest.cxx b/Tests/CMakeGUI/QCMakePresetTest.cxx new file mode 100644 index 0000000..8fd07e7 --- /dev/null +++ b/Tests/CMakeGUI/QCMakePresetTest.cxx @@ -0,0 +1,82 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "QCMakePresetTest.h" + +#include <utility> + +#include "QCMakePreset.h" +#include <QtTest> + +namespace { +QCMakePreset makePreset() +{ + return QCMakePreset{ + /*name=*/"name", + /*displayName=*/"displayName", + /*description=*/"description", + /*generator=*/"generator", + /*architecture=*/"architecture", + /*toolset=*/"toolset", + /*setGenConfig=*/true, + /*enabled=*/true, + }; +} + +template <typename T, typename U> +QCMakePreset makePreset(T QCMakePreset::*field, U&& value) +{ + auto preset = makePreset(); + preset.*field = std::forward<U>(value); + return preset; +} +} + +void QCMakePresetTest::equality() +{ + QFETCH(QCMakePreset, rhs); + QFETCH(bool, equal); + QFETCH(bool, lt); + QFETCH(bool, gt); + + auto lhs = makePreset(); + QVERIFY((lhs == rhs) == equal); + QVERIFY((lhs != rhs) == !equal); + QVERIFY((lhs < rhs) == lt); + QVERIFY((lhs >= rhs) == !lt); + QVERIFY((lhs > rhs) == gt); + QVERIFY((lhs <= rhs) == !gt); +} + +void QCMakePresetTest::equality_data() +{ + QTest::addColumn<QCMakePreset>("rhs"); + QTest::addColumn<bool>("equal"); + QTest::addColumn<bool>("lt"); + QTest::addColumn<bool>("gt"); + + QTest::newRow("equal") << makePreset() << true << false << false; + QTest::newRow("name") << makePreset(&QCMakePreset::name, "other-name") + << false << true << false; + QTest::newRow("displayName") + << makePreset(&QCMakePreset::displayName, "other-displayName") << false + << true << false; + QTest::newRow("description") + << makePreset(&QCMakePreset::description, "other-description") << false + << true << false; + QTest::newRow("generator") + << makePreset(&QCMakePreset::generator, "other-generator") << false << true + << false; + QTest::newRow("architecture") + << makePreset(&QCMakePreset::architecture, "other-architecture") << false + << true << false; + QTest::newRow("toolset") << makePreset(&QCMakePreset::toolset, + "other-toolset") + << false << false << true; + QTest::newRow("setGenConfig") + << makePreset(&QCMakePreset::setGenConfig, false) << false << false + << true; + QTest::newRow("enabled") << makePreset(&QCMakePreset::enabled, false) + << false << false << true; +} + +QTEST_MAIN(QCMakePresetTest) diff --git a/Tests/CMakeGUI/QCMakePresetTest.h b/Tests/CMakeGUI/QCMakePresetTest.h new file mode 100644 index 0000000..5eac88d --- /dev/null +++ b/Tests/CMakeGUI/QCMakePresetTest.h @@ -0,0 +1,14 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "QCMakePreset.h" +#include <QObject> + +class QCMakePresetTest : public QObject +{ + Q_OBJECT +private slots: + void equality(); + void equality_data(); +}; diff --git a/Tests/CMakeGUI/presetArg-noPresetBinaryChange/CMakePresets.json.in b/Tests/CMakeGUI/presetArg-noPresetBinaryChange/CMakePresets.json.in new file mode 100644 index 0000000..d78d69d --- /dev/null +++ b/Tests/CMakeGUI/presetArg-noPresetBinaryChange/CMakePresets.json.in @@ -0,0 +1,33 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ninja", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "STRING_VARIABLE": { + "type": "STRING", + "value": "String value" + }, + "PATH_VARIABLE": { + "type": "PATH", + "value": "${sourceDir}" + }, + "FILEPATH_VARIABLE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMakeLists.txt" + }, + "ON_VARIABLE": { + "type": "BOOL", + "value": "ON" + }, + "FALSE_VARIABLE": { + "type": "BOOL", + "value": "FALSE" + }, + "UNINITIALIZED_VARIABLE": "Uninitialized value" + } + } + ] +} diff --git a/Tests/CMakeGUI/presetArg-preset/CMakePresets.json.in b/Tests/CMakeGUI/presetArg-preset/CMakePresets.json.in new file mode 100644 index 0000000..d78d69d --- /dev/null +++ b/Tests/CMakeGUI/presetArg-preset/CMakePresets.json.in @@ -0,0 +1,33 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ninja", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "STRING_VARIABLE": { + "type": "STRING", + "value": "String value" + }, + "PATH_VARIABLE": { + "type": "PATH", + "value": "${sourceDir}" + }, + "FILEPATH_VARIABLE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMakeLists.txt" + }, + "ON_VARIABLE": { + "type": "BOOL", + "value": "ON" + }, + "FALSE_VARIABLE": { + "type": "BOOL", + "value": "FALSE" + }, + "UNINITIALIZED_VARIABLE": "Uninitialized value" + } + } + ] +} diff --git a/Tests/CMakeGUI/presetArg-presetBinary/CMakePresets.json.in b/Tests/CMakeGUI/presetArg-presetBinary/CMakePresets.json.in new file mode 100644 index 0000000..d78d69d --- /dev/null +++ b/Tests/CMakeGUI/presetArg-presetBinary/CMakePresets.json.in @@ -0,0 +1,33 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ninja", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "STRING_VARIABLE": { + "type": "STRING", + "value": "String value" + }, + "PATH_VARIABLE": { + "type": "PATH", + "value": "${sourceDir}" + }, + "FILEPATH_VARIABLE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMakeLists.txt" + }, + "ON_VARIABLE": { + "type": "BOOL", + "value": "ON" + }, + "FALSE_VARIABLE": { + "type": "BOOL", + "value": "FALSE" + }, + "UNINITIALIZED_VARIABLE": "Uninitialized value" + } + } + ] +} diff --git a/Tests/CMakeGUI/presetArg-presetBinaryChange/CMakePresets.json.in b/Tests/CMakeGUI/presetArg-presetBinaryChange/CMakePresets.json.in new file mode 100644 index 0000000..6fe20d6 --- /dev/null +++ b/Tests/CMakeGUI/presetArg-presetBinaryChange/CMakePresets.json.in @@ -0,0 +1,39 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ninja", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "STRING_VARIABLE": { + "type": "STRING", + "value": "String value" + }, + "PATH_VARIABLE": { + "type": "PATH", + "value": "${sourceDir}" + }, + "FILEPATH_VARIABLE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMakeLists.txt" + }, + "ON_VARIABLE": { + "type": "BOOL", + "value": "ON" + }, + "FALSE_VARIABLE": { + "type": "BOOL", + "value": "FALSE" + }, + "UNINITIALIZED_VARIABLE": "Uninitialized value" + } + }, + { + "name": "ninja2", + "inherits": [ + "ninja" + ] + } + ] +} diff --git a/Tests/CMakeGUI/presetArg-presetConfigExists/CMakeLists.txt.in b/Tests/CMakeGUI/presetArg-presetConfigExists/CMakeLists.txt.in new file mode 100644 index 0000000..2ae4a57 --- /dev/null +++ b/Tests/CMakeGUI/presetArg-presetConfigExists/CMakeLists.txt.in @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.18) +project(sourceBinaryArgs-sourceDir NONE) diff --git a/Tests/CMakeGUI/presetArg-presetConfigExists/CMakePresets.json.in b/Tests/CMakeGUI/presetArg-presetConfigExists/CMakePresets.json.in new file mode 100644 index 0000000..d78d69d --- /dev/null +++ b/Tests/CMakeGUI/presetArg-presetConfigExists/CMakePresets.json.in @@ -0,0 +1,33 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ninja", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "STRING_VARIABLE": { + "type": "STRING", + "value": "String value" + }, + "PATH_VARIABLE": { + "type": "PATH", + "value": "${sourceDir}" + }, + "FILEPATH_VARIABLE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMakeLists.txt" + }, + "ON_VARIABLE": { + "type": "BOOL", + "value": "ON" + }, + "FALSE_VARIABLE": { + "type": "BOOL", + "value": "FALSE" + }, + "UNINITIALIZED_VARIABLE": "Uninitialized value" + } + } + ] +} diff --git a/Tests/CMakeGUI/presetArg-presetConfigExists/CMakeSetup.ini.in b/Tests/CMakeGUI/presetArg-presetConfigExists/CMakeSetup.ini.in new file mode 100644 index 0000000..a5d0c71 --- /dev/null +++ b/Tests/CMakeGUI/presetArg-presetConfigExists/CMakeSetup.ini.in @@ -0,0 +1,2 @@ +[Settings] +StartPath\WhereBuild0=@CMake_BINARY_DIR@ diff --git a/Tests/CMakeLib/testJSONHelpers.cxx b/Tests/CMakeLib/testJSONHelpers.cxx index 78eed5b..a45d320 100644 --- a/Tests/CMakeLib/testJSONHelpers.cxx +++ b/Tests/CMakeLib/testJSONHelpers.cxx @@ -37,6 +37,7 @@ enum class ErrorCode InvalidInt, InvalidBool, InvalidString, + InvalidSubObject, InvalidObject, InvalidArray, MissingRequired, @@ -148,15 +149,20 @@ bool testString() bool testObject() { + auto const subhelper = + cmJSONObjectHelper<ObjectStruct, ErrorCode>(ErrorCode::Success, + ErrorCode::InvalidSubObject) + .Bind("subfield"_s, &ObjectStruct::Field2, IntHelper); auto const helper = cmJSONObjectHelper<ObjectStruct, ErrorCode>( ErrorCode::Success, ErrorCode::InvalidObject) .Bind("field1"_s, &ObjectStruct::Field1, StringHelper) - .Bind("field2"_s, &ObjectStruct::Field2, IntHelper) + .Bind("field2"_s, subhelper) .Bind<std::string>("field3"_s, nullptr, StringHelper); Json::Value v(Json::objectValue); v["field1"] = "Hello"; - v["field2"] = 2; + v["field2"] = Json::objectValue; + v["field2"]["subfield"] = 2; v["field3"] = "world!"; v["extra"] = "extra"; @@ -165,29 +171,34 @@ bool testObject() ASSERT_TRUE(s1.Field1 == "Hello"); ASSERT_TRUE(s1.Field2 == 2); - v["field2"] = "wrong"; + v["field2"]["subfield"] = "wrong"; ObjectStruct s2; ASSERT_TRUE(helper(s2, &v) == ErrorCode::InvalidInt); - v.removeMember("field2"); + v["field2"].removeMember("subfield"); ObjectStruct s3; - ASSERT_TRUE(helper(s3, &v) == ErrorCode::InvalidObject); + ASSERT_TRUE(helper(s3, &v) == ErrorCode::InvalidSubObject); - v["field2"] = 2; - v["field3"] = 3; + v.removeMember("field2"); ObjectStruct s4; - ASSERT_TRUE(helper(s4, &v) == ErrorCode::InvalidString); + ASSERT_TRUE(helper(s4, &v) == ErrorCode::InvalidObject); - v.removeMember("field3"); + v["field2"] = Json::objectValue; + v["field2"]["subfield"] = 2; + v["field3"] = 3; ObjectStruct s5; - ASSERT_TRUE(helper(s5, &v) == ErrorCode::InvalidObject); + ASSERT_TRUE(helper(s5, &v) == ErrorCode::InvalidString); - v = "Hello"; + v.removeMember("field3"); ObjectStruct s6; ASSERT_TRUE(helper(s6, &v) == ErrorCode::InvalidObject); + v = "Hello"; ObjectStruct s7; - ASSERT_TRUE(helper(s7, nullptr) == ErrorCode::InvalidObject); + ASSERT_TRUE(helper(s7, &v) == ErrorCode::InvalidObject); + + ObjectStruct s8; + ASSERT_TRUE(helper(s8, nullptr) == ErrorCode::InvalidObject); return true; } diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 9d5c8fb..cd8cbc1 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -758,6 +758,7 @@ add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}) add_RunCMake_test("UnityBuild") +add_RunCMake_test(CMakePresets) if(WIN32) add_RunCMake_test(Win32GenEx) diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-stderr.txt b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-stderr.txt new file mode 100644 index 0000000..a3b79b6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-stderr.txt @@ -0,0 +1,11 @@ +^CMake Error at CMakeLists\.txt:[0-9]+ \(project\): + Generator + + [^ +]* + + does not support platform specification, but platform + + a + + was specified\.$ diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigIgnore.cmake b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigIgnore.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigIgnore.cmake diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-stderr.txt b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-stderr.txt new file mode 100644 index 0000000..a3b79b6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-stderr.txt @@ -0,0 +1,11 @@ +^CMake Error at CMakeLists\.txt:[0-9]+ \(project\): + Generator + + [^ +]* + + does not support platform specification, but platform + + a + + was specified\.$ diff --git a/Tests/RunCMake/CMakePresets/CMakeLists.txt.in b/Tests/RunCMake/CMakePresets/CMakeLists.txt.in new file mode 100644 index 0000000..67c2d48 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.18) +project(${RunCMake_TEST} NONE) +set(RunCMake_SOURCE_DIR [==[@RunCMake_SOURCE_DIR@]==]) +include("${RunCMake_SOURCE_DIR}/${RunCMake_TEST}.cmake") diff --git a/Tests/RunCMake/CMakePresets/CMakePresets.json.in b/Tests/RunCMake/CMakePresets/CMakePresets.json.in new file mode 100644 index 0000000..78e31c6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CMakePresets.json.in @@ -0,0 +1,481 @@ +/* + * Block comment + */ +{ + // Inline comment + "version": 1, + "cmakeMinimumRequired": { + "major": 3, + "minor": 18, + "patch": 0 + }, + "vendor": { + "example.com/ExampleIDE/1.0": true + }, + "configurePresets": [ + { + "name": "Good", + "displayName": "Good Preset", + "description": "This preset is meant to test most of the fields when set correctly.", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cmakeExecutable": "/path/does/not/exist/cmake", + "vendor": { + "example.com/ExampleIDE/1.0": { + "transmogrify": true + } + }, + "cacheVariables": { + "TEST_SOURCE_DIR": { + "type": "PATH", + "value": "${sourceDir}" + }, + "TEST_SOURCE_PARENT_DIR": { + "type": "PATH", + "value": "${sourceParentDir}" + }, + "TEST_SOURCE_LIST": { + "type": "FILEPATH", + "value": "${sourceDir}/CMakeLists.txt" + }, + "TEST_TRUE": { + "type": "BOOL", + "value": "TRUE" + }, + "TEST_OFF": { + "type": "BOOL", + "value": "OFF" + }, + "TEST_PRESET_NAME": { + "type": "STRING", + "value": "x${presetName}x" + }, + "TEST_GENERATOR": { + "value": "x${generator}x" + }, + "TEST_DOLLAR": { + "value": "${dollar}" + }, + "TEST_ENV_REF": "$env{TEST_ENV_REF}", + "TEST_ENV": "$env{TEST_ENV}", + "TEST_D_ENV_REF": "$env{TEST_D_ENV_REF}", + "TEST_ENV_OVERRIDE": "$env{TEST_ENV_OVERRIDE}", + "TEST_PENV": "$env{TEST_PENV}", + "TEST_ENV_REF_PENV": "$env{TEST_ENV_REF_PENV}", + "TEST_ENV_REF_P": "$penv{TEST_ENV_REF}", + "TEST_ENV_P": "$penv{TEST_ENV}", + "TEST_D_ENV_REF_P": "$penv{TEST_D_ENV_REF}", + "TEST_ENV_OVERRIDE_P": "$penv{TEST_ENV_OVERRIDE}", + "TEST_PENV_P": "$penv{TEST_PENV}", + "TEST_ENV_REF_PENV_P": "$penv{TEST_ENV_REF_PENV}", + "TEST_MULTIPLE_MACROS": "${presetName} ${generator}", + "TEST_EXPANSION": "\\${presetName} ${dollar}{dollar} $unknown{namespace} $en{NOT_ENV} $enve{NOT_ENV} $ \\$ $a", + "TEST_TRAILING_DOLLAR": "a $", + "TEST_TRAILING_BACKSLASH": "a \\", + "TEST_TRAILING_UNKNOWN_NAMESPACE": "$unknown{namespace", + "TEST_OVERRIDE_1": { + "type": "STRING", + "value": "Default value" + }, + "TEST_OVERRIDE_2": "Default value", + "TEST_OVERRIDE_3": { + "type": "STRING", + "value": "Default value" + }, + "TEST_OVERRIDE_4": { + "type": "STRING", + "value": "Default value" + }, + "TEST_UNDEF": "undef" + }, + "environment": { + "TEST_ENV_REF": "$env{TEST_ENV}", + "TEST_ENV": "Environment variable", + "TEST_D_ENV_REF": "x$env{TEST_ENV_REF}x", + "TEST_ENV_OVERRIDE": "Overridden environment variable", + "TEST_ENV_REF_PENV": "prefix+$penv{TEST_ENV_REF_PENV}", + "TEST_PENV": null + } + }, + { + "name": "GoodNoArgs", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "GoodBinaryUp", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/../GoodBinaryUp-build" + }, + { + "name": "GoodBinaryRelative", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "build" + }, + { + "name": "Good Spaces", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "GoodWindowsBackslash", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}\\build" + }, + { + "name": "GoodBinaryCmdLine", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "GoodGeneratorCmdLine", + "generator": "Invalid Generator", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "InvalidGeneratorCmdLine", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "GoodNoS", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "GoodInheritanceParentBase", + "hidden": true, + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "TEST_VARIABLE": { + "type": "STRING", + "value": "Some string" + } + }, + "environment": { + "TEST_ENV": "Some environment variable" + } + }, + { + "name": "GoodInheritanceParent", + "inherits": "GoodInheritanceParentBase" + }, + { + "name": "GoodInheritanceChildBase", + "hidden": true + }, + { + "name": "GoodInheritanceChild", + "inherits": "GoodInheritanceChildBase", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "TEST_VARIABLE": { + "type": "STRING", + "value": "Some string" + } + }, + "environment": { + "TEST_ENV": "Some environment variable" + } + }, + { + "name": "GoodInheritanceOverrideBase", + "hidden": true, + "generator": "Invalid Generator", + "binaryDir": "${sourceDir}/../GoodInheritanceBase-build", + "cacheVariables": { + "PARENT_VARIABLE": { + "type": "STRING", + "value": "Parent variable" + }, + "OVERRIDDEN_VARIABLE": { + "type": "BOOL", + "value": "ON" + }, + "DELETED_VARIABLE": "This variable will be deleted" + }, + "environment": { + "PARENT_ENV": "Parent environment variable", + "OVERRIDDEN_ENV": "This environment variable will be overridden", + "DELETED_ENV": "This environment variable will be deleted" + } + }, + { + "name": "GoodInheritanceOverride", + "inherits": "GoodInheritanceOverrideBase", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "OVERRIDDEN_VARIABLE": { + "type": "STRING", + "value": "Overridden variable" + }, + "CHILD_VARIABLE": { + "type": "STRING", + "value": "Child variable" + }, + "DELETED_VARIABLE": null + }, + "environment": { + "OVERRIDDEN_ENV": "Overridden environment variable", + "CHILD_ENV": "Child environment variable", + "DELETED_ENV": null + } + }, + { + "name": "GoodInheritanceOverrideDummy", + "inherits": "GoodInheritanceOverride" + }, + { + "name": "GoodInheritanceMulti1", + "hidden": true, + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "FIRST_VARIABLE": { + "type": "STRING", + "value": "First variable" + }, + "OVERRIDDEN_VARIABLE": { + "type": "STRING", + "value": "Overridden variable" + } + }, + "environment": { + "FIRST_ENV": "First environment variable", + "OVERRIDDEN_ENV": "Overridden environment variable" + } + }, + { + "name": "GoodInheritanceMulti2", + "hidden": true, + "generator": "Invalid Generator", + "binaryDir": "${sourceDir}/../GoodInheritanceMulti2-build", + "cacheVariables": { + "SECOND_VARIABLE": { + "type": "STRING", + "value": "Second variable" + }, + "OVERRIDDEN_VARIABLE": { + "type": "BOOL", + "value": "ON" + } + }, + "environment": { + "SECOND_ENV": "Second environment variable", + "OVERRIDDEN_ENV": "This will be overridden" + } + }, + { + "name": "GoodInheritanceMulti", + "inherits": [ + "GoodInheritanceMulti1", + "GoodInheritanceMulti2" + ] + }, + { + "name": "GoodInheritanceMultiSecond1", + "hidden": true + }, + { + "name": "GoodInheritanceMultiSecond2", + "hidden": true, + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "GoodInheritanceMultiSecond", + "inherits": [ + "GoodInheritanceMultiSecond1", + "GoodInheritanceMultiSecond2" + ] + }, + { + "name": "GoodInheritanceMacroBase", + "hidden": true, + "cacheVariables": { + "PRESET_NAME": "${presetName}" + } + }, + { + "name": "GoodInheritanceMacro", + "inherits": "GoodInheritanceMacroBase", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "UnclosedMacro", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir" + }, + { + "name": "NoSuchMacro", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${noexist}" + }, + { + "name": "VendorMacro", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "$vendor{unknown.unknownMacro}" + }, + { + "name": "InvalidGenerator", + "generator": "Invalid Generator", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "EnvCycle", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "environment": { + "ENV_1": "$env{ENV_2}", + "ENV_2": "$env{ENV_1}" + } + }, + { + "name": "UseHiddenPreset", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "hidden": true + }, + { + "name": "VisualStudioGeneratorArch", + "generator": "@RunCMake_GENERATOR@ Win64", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "VisualStudioWin32", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "architecture": "Win32" + }, + { + "name": "VisualStudioWin64", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "architecture": "x64" + }, + { + "name": "VisualStudioWin32Override", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "architecture": "Win32" + }, + { + "name": "VisualStudioToolset", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "toolset": "Test Toolset" + }, + { + "name": "VisualStudioToolsetOverride", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "toolset": "Invalid Toolset" + }, + { + "name": "VisualStudioInheritanceParentBase", + "hidden": true, + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "architecture": "Test Platform", + "toolset": "Test Toolset" + }, + { + "name": "VisualStudioInheritanceParent", + "inherits": "VisualStudioInheritanceParentBase" + }, + { + "name": "VisualStudioInheritanceChildBase", + "hidden": true + }, + { + "name": "VisualStudioInheritanceChild", + "inherits": "VisualStudioInheritanceChildBase", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "architecture": "Test Platform", + "toolset": "Test Toolset" + }, + { + "name": "VisualStudioInheritanceOverrideBase", + "hidden": true, + "architecture": "Invalid Platform", + "toolset": "Invalid Toolset" + }, + { + "name": "VisualStudioInheritanceOverride", + "inherits": "VisualStudioInheritanceOverrideBase", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "architecture": "Test Platform", + "toolset": "Test Toolset" + }, + { + "name": "VisualStudioInheritanceMulti1", + "hidden": true, + "architecture": "Test Platform", + "toolset": "Test Toolset" + }, + { + "name": "VisualStudioInheritanceMulti2", + "hidden": true, + "architecture": "Invalid Platform", + "toolset": "Invalid Toolset" + }, + { + "name": "VisualStudioInheritanceMulti", + "inherits": [ + "VisualStudioInheritanceMulti1", + "VisualStudioInheritanceMulti2" + ], + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "VisualStudioInheritanceMultiSecond1", + "hidden": true + }, + { + "name": "VisualStudioInheritanceMultiSecond2", + "hidden": true, + "architecture": "Test Platform", + "toolset": "Test Toolset" + }, + { + "name": "VisualStudioInheritanceMultiSecond", + "inherits": [ + "VisualStudioInheritanceMultiSecond1", + "VisualStudioInheritanceMultiSecond2" + ], + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "CMakeGeneratorConfigNone", + "generator": "@RunCMake_GENERATOR@", + "architecture": "a", + "toolset": "a", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "CMakeGeneratorConfigBase", + "generator": "@RunCMake_GENERATOR@", + "architecture": "a", + "toolset": "a", + "cmakeGeneratorConfig": "ignore", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "CMakeGeneratorConfigDefault", + "inherits": "CMakeGeneratorConfigBase", + "cmakeGeneratorConfig": "default" + }, + { + "name": "CMakeGeneratorConfigIgnore", + "inherits": "CMakeGeneratorConfigBase" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/CacheOverride.cmake b/Tests/RunCMake/CMakePresets/CacheOverride.cmake new file mode 100644 index 0000000..d0ebe17 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CacheOverride.cmake @@ -0,0 +1,2 @@ +set(TEST_OVERRIDE_3 "Overridden value" CACHE STRING "") +set(TEST_OVERRIDE_4 "Overridden value" CACHE INTERNAL "") diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance0-result.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance0-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance0-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt new file mode 100644 index 0000000..895afcb --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance0-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/CyclicInheritance0: Cyclic preset inheritance$ diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance0.json.in b/Tests/RunCMake/CMakePresets/CyclicInheritance0.json.in new file mode 100644 index 0000000..3468936 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance0.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "CyclicInheritance0", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "CyclicInheritance0" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance1-result.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt new file mode 100644 index 0000000..1e59e92 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance1-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/CyclicInheritance1: Cyclic preset inheritance$ diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance1.json.in b/Tests/RunCMake/CMakePresets/CyclicInheritance1.json.in new file mode 100644 index 0000000..fabd4af --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance1.json.in @@ -0,0 +1,21 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "CyclicInheritance0", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "CyclicInheritance1" + ] + }, + { + "name": "CyclicInheritance1", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "CyclicInheritance0" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance2-result.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt b/Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt new file mode 100644 index 0000000..56e630b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance2-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/CyclicInheritance2: Cyclic preset inheritance$ diff --git a/Tests/RunCMake/CMakePresets/CyclicInheritance2.json.in b/Tests/RunCMake/CMakePresets/CyclicInheritance2.json.in new file mode 100644 index 0000000..0e1d7d4 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/CyclicInheritance2.json.in @@ -0,0 +1,29 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "CyclicInheritance0", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "CyclicInheritance1" + ] + }, + { + "name": "CyclicInheritance1", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "CyclicInheritance2" + ] + }, + { + "name": "CyclicInheritance2", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "CyclicInheritance0" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/Debug-stderr.txt b/Tests/RunCMake/CMakePresets/Debug-stderr.txt new file mode 100644 index 0000000..7fdb8b3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Debug-stderr.txt @@ -0,0 +1 @@ + find_package considered the following locations for the Config module: diff --git a/Tests/RunCMake/CMakePresets/Debug-stdout.txt b/Tests/RunCMake/CMakePresets/Debug-stdout.txt new file mode 100644 index 0000000..7d1f388 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Debug-stdout.txt @@ -0,0 +1,4 @@ +-- Generating [^ +]*/Tests/RunCMake/CMakePresets/Debug/build + Called from: \[1\][^ +]*/Tests/RunCMake/CMakePresets/Debug/CMakeLists\.txt diff --git a/Tests/RunCMake/CMakePresets/Debug.cmake b/Tests/RunCMake/CMakePresets/Debug.cmake new file mode 100644 index 0000000..19c7db2 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Debug.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/DebugBase.cmake) +if(NOT EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CMakeLists.txt") + message(SEND_ERROR "Debugging try_compile() did not work") +endif() diff --git a/Tests/RunCMake/CMakePresets/Debug.json.in b/Tests/RunCMake/CMakePresets/Debug.json.in new file mode 100644 index 0000000..500700e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Debug.json.in @@ -0,0 +1,19 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "NoDebug", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "Debug", + "inherits": "NoDebug", + "debug": { + "output": true, + "find": true, + "tryCompile": true + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/DebugBase.cmake b/Tests/RunCMake/CMakePresets/DebugBase.cmake new file mode 100644 index 0000000..870f31c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/DebugBase.cmake @@ -0,0 +1,3 @@ +enable_language(C) +try_compile(_result ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/main.c) +find_package(ThisPackageHopefullyDoesNotExist CONFIG) diff --git a/Tests/RunCMake/CMakePresets/DisableWarningFlags.cmake b/Tests/RunCMake/CMakePresets/DisableWarningFlags.cmake new file mode 100644 index 0000000..5de7687 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/DisableWarningFlags.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/WarningsBase.cmake) diff --git a/Tests/RunCMake/CMakePresets/DuplicatePresets-result.txt b/Tests/RunCMake/CMakePresets/DuplicatePresets-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/DuplicatePresets-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt b/Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt new file mode 100644 index 0000000..c9361ae --- /dev/null +++ b/Tests/RunCMake/CMakePresets/DuplicatePresets-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/DuplicatePresets: Duplicate presets$ diff --git a/Tests/RunCMake/CMakePresets/DuplicatePresets.json.in b/Tests/RunCMake/CMakePresets/DuplicatePresets.json.in new file mode 100644 index 0000000..cf388e7 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/DuplicatePresets.json.in @@ -0,0 +1,15 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "DuplicatePresets", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "DuplicatePresets", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/EmptyPresetName-result.txt b/Tests/RunCMake/CMakePresets/EmptyPresetName-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EmptyPresetName-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt new file mode 100644 index 0000000..6970674 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/EmptyPresetName: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/EmptyPresetName.json.in b/Tests/RunCMake/CMakePresets/EmptyPresetName.json.in new file mode 100644 index 0000000..fd4bedd --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EmptyPresetName.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/EnvCycle-result.txt b/Tests/RunCMake/CMakePresets/EnvCycle-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EnvCycle-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt b/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt new file mode 100644 index 0000000..c8568f1 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Could not evaluate preset "EnvCycle": Invalid macro expansion$ diff --git a/Tests/RunCMake/CMakePresets/ErrorDeprecated-result.txt b/Tests/RunCMake/CMakePresets/ErrorDeprecated-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorDeprecated-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ErrorDeprecated-stderr.txt b/Tests/RunCMake/CMakePresets/ErrorDeprecated-stderr.txt new file mode 100644 index 0000000..964a504 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorDeprecated-stderr.txt @@ -0,0 +1,7 @@ +^CMake Deprecation Error at [^ +]*/Tests/RunCMake/CMakePresets/WarningsBase\.cmake:[0-9]+ \(message\): + Deprecation warning +Call Stack \(most recent call first\): + [^ +]*/Tests/RunCMake/CMakePresets/ErrorDeprecated\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CMakePresets/ErrorDeprecated.cmake b/Tests/RunCMake/CMakePresets/ErrorDeprecated.cmake new file mode 100644 index 0000000..5de7687 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorDeprecated.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/WarningsBase.cmake) diff --git a/Tests/RunCMake/CMakePresets/ErrorDev-result.txt b/Tests/RunCMake/CMakePresets/ErrorDev-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorDev-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ErrorDev-stderr.txt b/Tests/RunCMake/CMakePresets/ErrorDev-stderr.txt new file mode 100644 index 0000000..f76478c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorDev-stderr.txt @@ -0,0 +1,8 @@ +^CMake Error \(dev\) at [^ +]*/Tests/RunCMake/CMakePresets/WarningsBase\.cmake:[0-9]+ \(message\): + Dev warning +Call Stack \(most recent call first\): + [^ +]*/Tests/RunCMake/CMakePresets/ErrorDev\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\) +This error is for project developers\. Use -Wno-error=dev to suppress it\.$ diff --git a/Tests/RunCMake/CMakePresets/ErrorDev.cmake b/Tests/RunCMake/CMakePresets/ErrorDev.cmake new file mode 100644 index 0000000..5de7687 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorDev.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/WarningsBase.cmake) diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-result.txt b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt new file mode 100644 index 0000000..3221345 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated.json.in b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated.json.in new file mode 100644 index 0000000..664b3ee --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDeprecated.json.in @@ -0,0 +1,16 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ErrorNoWarningDeprecated", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "warnings": { + "deprecated": false + }, + "errors": { + "deprecated": true + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-result.txt b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt new file mode 100644 index 0000000..d2ddb90 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/ErrorNoWarningDev: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/ErrorNoWarningDev.json.in b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev.json.in new file mode 100644 index 0000000..d681b2a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ErrorNoWarningDev.json.in @@ -0,0 +1,16 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ErrorNoWarningDev", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "warnings": { + "dev": false + }, + "errors": { + "dev": true + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/ExtraPresetField-result.txt b/Tests/RunCMake/CMakePresets/ExtraPresetField-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraPresetField-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt b/Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt new file mode 100644 index 0000000..559e3c2 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraPresetField-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/ExtraPresetField: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/ExtraPresetField.json.in b/Tests/RunCMake/CMakePresets/ExtraPresetField.json.in new file mode 100644 index 0000000..b529758 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraPresetField.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ExtraPresetField", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "invalid": true + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/ExtraRootField-result.txt b/Tests/RunCMake/CMakePresets/ExtraRootField-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraRootField-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt b/Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt new file mode 100644 index 0000000..bb281be --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraRootField-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/ExtraRootField: Invalid root object$ diff --git a/Tests/RunCMake/CMakePresets/ExtraRootField.json.in b/Tests/RunCMake/CMakePresets/ExtraRootField.json.in new file mode 100644 index 0000000..bcfa68b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraRootField.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ExtraRootField", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ], + "invalid": true +} diff --git a/Tests/RunCMake/CMakePresets/ExtraVariableField-result.txt b/Tests/RunCMake/CMakePresets/ExtraVariableField-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraVariableField-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt b/Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt new file mode 100644 index 0000000..9b346e7 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraVariableField-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/ExtraVariableField: Invalid CMake variable definition$ diff --git a/Tests/RunCMake/CMakePresets/ExtraVariableField.json.in b/Tests/RunCMake/CMakePresets/ExtraVariableField.json.in new file mode 100644 index 0000000..a810560 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ExtraVariableField.json.in @@ -0,0 +1,16 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "ExtraVariableField", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "EXTRA": { + "value": "", + "invalid": true + } + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/Good-stdout.txt b/Tests/RunCMake/CMakePresets/Good-stdout.txt new file mode 100644 index 0000000..ce6189e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Good-stdout.txt @@ -0,0 +1,46 @@ +Preset CMake variables: + + TEST_DOLLAR="\$" + TEST_D_ENV_REF="xEnvironment variablex" + TEST_D_ENV_REF_P="" + TEST_ENV="Environment variable" + TEST_ENV_OVERRIDE="Overridden environment variable" + TEST_ENV_OVERRIDE_P="This environment variable will be overridden" + TEST_ENV_P="" + TEST_ENV_REF="Environment variable" + TEST_ENV_REF_P="" + TEST_ENV_REF_PENV="prefix\+suffix" + TEST_ENV_REF_PENV_P="suffix" + TEST_EXPANSION="\\Good \${dollar} \$unknown{namespace} \$en{NOT_ENV} \$enve{NOT_ENV} \$ \\\$ \$a" + TEST_GENERATOR="x[^ +]*x" + TEST_MULTIPLE_MACROS="Good [^ +]*" + TEST_OFF:BOOL="OFF" + TEST_OVERRIDE_3:STRING="Default value" + TEST_OVERRIDE_4:STRING="Default value" + TEST_PENV="Process environment variable" + TEST_PENV_P="Process environment variable" + TEST_PRESET_NAME:STRING="xGoodx" + TEST_SOURCE_DIR:PATH="[^ +]*/Tests/RunCMake/CMakePresets/Good" + TEST_SOURCE_LIST:FILEPATH="[^ +]*/Tests/RunCMake/CMakePresets/Good/CMakeLists\.txt" + TEST_SOURCE_PARENT_DIR:PATH="[^ +]*/Tests/RunCMake/CMakePresets" + TEST_TRAILING_BACKSLASH="a \\" + TEST_TRAILING_DOLLAR="a \$" + TEST_TRAILING_UNKNOWN_NAMESPACE="\$unknown{namespace" + TEST_TRUE:BOOL="TRUE" + +Preset environment variables: + + TEST_D_ENV_REF="xEnvironment variablex" + TEST_ENV="Environment variable" + TEST_ENV_OVERRIDE="Overridden environment variable" + TEST_ENV_REF="Environment variable" + TEST_ENV_REF_PENV="prefix\+suffix" + +(-- Selecting Windows SDK version [^ +]* +)?-- Configuring done diff --git a/Tests/RunCMake/CMakePresets/Good.cmake b/Tests/RunCMake/CMakePresets/Good.cmake new file mode 100644 index 0000000..d8e3e2d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Good.cmake @@ -0,0 +1,45 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +get_filename_component(_parent_dir "${CMAKE_SOURCE_DIR}" DIRECTORY) +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") +test_variable(CMAKE_GENERATOR "" "${RunCMake_GENERATOR}") +test_variable(TEST_SOURCE_DIR "PATH" "${CMAKE_SOURCE_DIR}") +test_variable(TEST_SOURCE_PARENT_DIR "PATH" "${_parent_dir}") +test_variable(TEST_SOURCE_LIST "FILEPATH" "${CMAKE_SOURCE_DIR}/CMakeLists.txt") +test_variable(TEST_TRUE "BOOL" "TRUE") +test_variable(TEST_OFF "BOOL" "OFF") +test_variable(TEST_PRESET_NAME "STRING" "xGoodx") +test_variable(TEST_GENERATOR "UNINITIALIZED" "x${CMAKE_GENERATOR}x") +test_variable(TEST_DOLLAR "UNINITIALIZED" "$") +test_variable(TEST_ENV_REF "UNINITIALIZED" "Environment variable") +test_variable(TEST_ENV "UNINITIALIZED" "Environment variable") +test_variable(TEST_D_ENV_REF "UNINITIALIZED" "xEnvironment variablex") +test_variable(TEST_ENV_OVERRIDE "UNINITIALIZED" "Overridden environment variable") +test_variable(TEST_PENV "UNINITIALIZED" "Process environment variable") +test_variable(TEST_ENV_REF_PENV "UNINITIALIZED" "prefix+suffix") +test_variable(TEST_ENV_REF_P "UNINITIALIZED" "") +test_variable(TEST_ENV_P "UNINITIALIZED" "") +test_variable(TEST_D_ENV_REF_P "UNINITIALIZED" "") +test_variable(TEST_ENV_OVERRIDE_P "UNINITIALIZED" "This environment variable will be overridden") +test_variable(TEST_PENV_P "UNINITIALIZED" "Process environment variable") +test_variable(TEST_ENV_REF_PENV_P "UNINITIALIZED" "suffix") +test_variable(TEST_MULTIPLE_MACROS "UNINITIALIZED" "Good ${CMAKE_GENERATOR}") +test_variable(TEST_EXPANSION "UNINITIALIZED" "\\Good \${dollar} \$unknown{namespace} \$en{NOT_ENV} \$enve{NOT_ENV} $ \\$ $a") +test_variable(TEST_TRAILING_DOLLAR "UNINITIALIZED" "a $") +test_variable(TEST_TRAILING_BACKSLASH "UNINITIALIZED" "a \\") +test_variable(TEST_TRAILING_UNKNOWN_NAMESPACE "UNINITIALIZED" "\$unknown{namespace") +test_variable(TEST_OVERRIDE_1 "UNINITIALIZED" "Overridden value") +test_variable(TEST_OVERRIDE_2 "STRING" "Overridden value") +test_variable(TEST_OVERRIDE_3 "STRING" "Default value") +test_variable(TEST_OVERRIDE_4 "INTERNAL" "Overridden value") + +if(DEFINED TEST_UNDEF OR DEFINED CACHE{TEST_UNDEF}) + message(SEND_ERROR "TEST_UNDEF should not be defined") +endif() + +test_environment_variable(TEST_ENV_REF "Environment variable") +test_environment_variable(TEST_ENV "Environment variable") +test_environment_variable(TEST_D_ENV_REF "xEnvironment variablex") +test_environment_variable(TEST_ENV_OVERRIDE "Overridden environment variable") +test_environment_variable(TEST_PENV "Process environment variable") +test_environment_variable(TEST_ENV_REF_PENV "prefix+suffix") diff --git a/Tests/RunCMake/CMakePresets/GoodBOM.cmake b/Tests/RunCMake/CMakePresets/GoodBOM.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodBOM.cmake diff --git a/Tests/RunCMake/CMakePresets/GoodBOM.json.in b/Tests/RunCMake/CMakePresets/GoodBOM.json.in new file mode 100644 index 0000000..2152511 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodBOM.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "GoodBOM", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodBinaryCmdLine.cmake b/Tests/RunCMake/CMakePresets/GoodBinaryCmdLine.cmake new file mode 100644 index 0000000..9f928fe --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodBinaryCmdLine.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +get_filename_component(_parent "${CMAKE_SOURCE_DIR}" DIRECTORY) +test_variable(CMAKE_BINARY_DIR "" "${_parent}/GoodBinaryCmdLine-build") diff --git a/Tests/RunCMake/CMakePresets/GoodBinaryRelative.cmake b/Tests/RunCMake/CMakePresets/GoodBinaryRelative.cmake new file mode 100644 index 0000000..49e7a25 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodBinaryRelative.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") diff --git a/Tests/RunCMake/CMakePresets/GoodBinaryUp.cmake b/Tests/RunCMake/CMakePresets/GoodBinaryUp.cmake new file mode 100644 index 0000000..f7fb224 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodBinaryUp.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +get_filename_component(_parent "${CMAKE_SOURCE_DIR}" DIRECTORY) +test_variable(CMAKE_BINARY_DIR "" "${_parent}/GoodBinaryUp-build") diff --git a/Tests/RunCMake/CMakePresets/GoodGeneratorCmdLine.cmake b/Tests/RunCMake/CMakePresets/GoodGeneratorCmdLine.cmake new file mode 100644 index 0000000..4319e72 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodGeneratorCmdLine.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_GENERATOR "" "${RunCMake_GENERATOR}") diff --git a/Tests/RunCMake/CMakePresets/GoodInheritanceChild.cmake b/Tests/RunCMake/CMakePresets/GoodInheritanceChild.cmake new file mode 100644 index 0000000..cfc93be --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInheritanceChild.cmake @@ -0,0 +1,6 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") +test_variable(TEST_VARIABLE "STRING" "Some string") + +test_environment_variable(TEST_ENV "Some environment variable") diff --git a/Tests/RunCMake/CMakePresets/GoodInheritanceMacro.cmake b/Tests/RunCMake/CMakePresets/GoodInheritanceMacro.cmake new file mode 100644 index 0000000..96fede0 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInheritanceMacro.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(PRESET_NAME "UNINITIALIZED" "GoodInheritanceMacro") diff --git a/Tests/RunCMake/CMakePresets/GoodInheritanceMulti.cmake b/Tests/RunCMake/CMakePresets/GoodInheritanceMulti.cmake new file mode 100644 index 0000000..6430f4d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInheritanceMulti.cmake @@ -0,0 +1,10 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") +test_variable(FIRST_VARIABLE "STRING" "First variable") +test_variable(SECOND_VARIABLE "STRING" "Second variable") +test_variable(OVERRIDDEN_VARIABLE "STRING" "Overridden variable") + +test_environment_variable(FIRST_ENV "First environment variable") +test_environment_variable(SECOND_ENV "Second environment variable") +test_environment_variable(OVERRIDDEN_ENV "Overridden environment variable") diff --git a/Tests/RunCMake/CMakePresets/GoodInheritanceMultiSecond.cmake b/Tests/RunCMake/CMakePresets/GoodInheritanceMultiSecond.cmake new file mode 100644 index 0000000..49e7a25 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInheritanceMultiSecond.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") diff --git a/Tests/RunCMake/CMakePresets/GoodInheritanceOverride.cmake b/Tests/RunCMake/CMakePresets/GoodInheritanceOverride.cmake new file mode 100644 index 0000000..5231803 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInheritanceOverride.cmake @@ -0,0 +1,18 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") +test_variable(PARENT_VARIABLE "STRING" "Parent variable") +test_variable(OVERRIDDEN_VARIABLE "STRING" "Overridden variable") +test_variable(CHILD_VARIABLE "STRING" "Child variable") + +if(DEFINED DELETED_VARIABLE OR DEFINED CACHE{DELETED_VARIABLE}) + message(SEND_ERROR "DELETED_VARIABLE should not be defined") +endif() + +test_environment_variable(PARENT_ENV "Parent environment variable") +test_environment_variable(CHILD_ENV "Child environment variable") +test_environment_variable(OVERRIDDEN_ENV "Overridden environment variable") + +if(DEFINED ENV{DELETED_ENV}) + message(SEND_ERROR "DELETED_ENV should not be defined") +endif() diff --git a/Tests/RunCMake/CMakePresets/GoodInheritanceParent.cmake b/Tests/RunCMake/CMakePresets/GoodInheritanceParent.cmake new file mode 100644 index 0000000..cfc93be --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodInheritanceParent.cmake @@ -0,0 +1,6 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_BINARY_DIR "" "${CMAKE_SOURCE_DIR}/build") +test_variable(TEST_VARIABLE "STRING" "Some string") + +test_environment_variable(TEST_ENV "Some environment variable") diff --git a/Tests/RunCMake/CMakePresets/GoodNoArgs.cmake b/Tests/RunCMake/CMakePresets/GoodNoArgs.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodNoArgs.cmake diff --git a/Tests/RunCMake/CMakePresets/GoodNoS.cmake b/Tests/RunCMake/CMakePresets/GoodNoS.cmake new file mode 100644 index 0000000..1d3b2ff --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodNoS.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +get_filename_component(_parent "${CMAKE_SOURCE_DIR}" DIRECTORY) +test_variable(CMAKE_BINARY_DIR "" "${_parent}/GoodNoS-build") diff --git a/Tests/RunCMake/CMakePresets/GoodSpaces.cmake b/Tests/RunCMake/CMakePresets/GoodSpaces.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodSpaces.cmake diff --git a/Tests/RunCMake/CMakePresets/GoodUserFromMain.cmake b/Tests/RunCMake/CMakePresets/GoodUserFromMain.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserFromMain.cmake diff --git a/Tests/RunCMake/CMakePresets/GoodUserFromMain.json.in b/Tests/RunCMake/CMakePresets/GoodUserFromMain.json.in new file mode 100644 index 0000000..348443e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserFromMain.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "GoodUserFromMain", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodUserFromMainUser.json.in b/Tests/RunCMake/CMakePresets/GoodUserFromMainUser.json.in new file mode 100644 index 0000000..77b4ef6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserFromMainUser.json.in @@ -0,0 +1,4 @@ +{ + "version": 1, + "configurePresets": [] +} diff --git a/Tests/RunCMake/CMakePresets/GoodUserFromUser.cmake b/Tests/RunCMake/CMakePresets/GoodUserFromUser.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserFromUser.cmake diff --git a/Tests/RunCMake/CMakePresets/GoodUserFromUser.json.in b/Tests/RunCMake/CMakePresets/GoodUserFromUser.json.in new file mode 100644 index 0000000..77b4ef6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserFromUser.json.in @@ -0,0 +1,4 @@ +{ + "version": 1, + "configurePresets": [] +} diff --git a/Tests/RunCMake/CMakePresets/GoodUserFromUserUser.json.in b/Tests/RunCMake/CMakePresets/GoodUserFromUserUser.json.in new file mode 100644 index 0000000..83196be --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserFromUserUser.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "GoodUserFromUser", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodUserOnly.cmake b/Tests/RunCMake/CMakePresets/GoodUserOnly.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserOnly.cmake diff --git a/Tests/RunCMake/CMakePresets/GoodUserOnlyUser.json.in b/Tests/RunCMake/CMakePresets/GoodUserOnlyUser.json.in new file mode 100644 index 0000000..274f4c7 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodUserOnlyUser.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "GoodUserOnly", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodWindowsBackslash.cmake b/Tests/RunCMake/CMakePresets/GoodWindowsBackslash.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodWindowsBackslash.cmake diff --git a/Tests/RunCMake/CMakePresets/HighVersion-result.txt b/Tests/RunCMake/CMakePresets/HighVersion-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HighVersion-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/HighVersion-stderr.txt b/Tests/RunCMake/CMakePresets/HighVersion-stderr.txt new file mode 100644 index 0000000..d8622f2 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HighVersion-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/HighVersion: Unrecognized "version" field$ diff --git a/Tests/RunCMake/CMakePresets/HighVersion.json.in b/Tests/RunCMake/CMakePresets/HighVersion.json.in new file mode 100644 index 0000000..8107842 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/HighVersion.json.in @@ -0,0 +1,4 @@ +{ + "version": 1000, + "configurePresets": [] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-result.txt b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-stderr.txt new file mode 100644 index 0000000..72a20d5 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig.json.in b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig.json.in new file mode 100644 index 0000000..1479c66 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "InvalidCMakeGeneratorConfig", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cmakeGeneratorConfig": {} + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidGenerator-result.txt b/Tests/RunCMake/CMakePresets/InvalidGenerator-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidGenerator-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidGenerator-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidGenerator-stderr.txt new file mode 100644 index 0000000..c7dd19b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidGenerator-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: Could not create named generator Invalid Generator + +Generators diff --git a/Tests/RunCMake/CMakePresets/InvalidGeneratorCmdLine-result.txt b/Tests/RunCMake/CMakePresets/InvalidGeneratorCmdLine-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidGeneratorCmdLine-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidGeneratorCmdLine-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidGeneratorCmdLine-stderr.txt new file mode 100644 index 0000000..c7dd19b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidGeneratorCmdLine-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: Could not create named generator Invalid Generator + +Generators diff --git a/Tests/RunCMake/CMakePresets/InvalidInheritance-result.txt b/Tests/RunCMake/CMakePresets/InvalidInheritance-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidInheritance-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt new file mode 100644 index 0000000..97f3876 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidInheritance-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidInheritance: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/InvalidInheritance.json.in b/Tests/RunCMake/CMakePresets/InvalidInheritance.json.in new file mode 100644 index 0000000..77bd9a3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidInheritance.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "InvalidInheritance", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "NoExist" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-result.txt b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt new file mode 100644 index 0000000..2fe8c66 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir.json.in b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir.json.in new file mode 100644 index 0000000..2bb95d9 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetBinaryDir.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "InvalidPresetBinaryDir", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": [] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-result.txt b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt new file mode 100644 index 0000000..9572875 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidPresetGenerator: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetGenerator.json.in b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator.json.in new file mode 100644 index 0000000..95e6e65 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetGenerator.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "InvalidPresetGenerator", + "generator": [], + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetName-result.txt b/Tests/RunCMake/CMakePresets/InvalidPresetName-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetName-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt new file mode 100644 index 0000000..8f6ff7c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetName-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidPresetName: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetName.json.in b/Tests/RunCMake/CMakePresets/InvalidPresetName.json.in new file mode 100644 index 0000000..08361da --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetName.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": [], + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetVendor-result.txt b/Tests/RunCMake/CMakePresets/InvalidPresetVendor-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetVendor-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt new file mode 100644 index 0000000..89a424a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetVendor-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidPresetVendor: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/InvalidPresetVendor.json.in b/Tests/RunCMake/CMakePresets/InvalidPresetVendor.json.in new file mode 100644 index 0000000..2a5d9ba --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresetVendor.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "InvalidPresetVendor", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "vendor": true + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidPresets-result.txt b/Tests/RunCMake/CMakePresets/InvalidPresets-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresets-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt new file mode 100644 index 0000000..2b0f560 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresets-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidPresets: Invalid "configurePresets" field$ diff --git a/Tests/RunCMake/CMakePresets/InvalidPresets.json.in b/Tests/RunCMake/CMakePresets/InvalidPresets.json.in new file mode 100644 index 0000000..facfd57 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidPresets.json.in @@ -0,0 +1,4 @@ +{ + "version": 1, + "configurePresets": {} +} diff --git a/Tests/RunCMake/CMakePresets/InvalidRoot-result.txt b/Tests/RunCMake/CMakePresets/InvalidRoot-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidRoot-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt new file mode 100644 index 0000000..e5c434d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidRoot-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidRoot: Invalid root object$ diff --git a/Tests/RunCMake/CMakePresets/InvalidRoot.json.in b/Tests/RunCMake/CMakePresets/InvalidRoot.json.in new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidRoot.json.in @@ -0,0 +1 @@ +[] diff --git a/Tests/RunCMake/CMakePresets/InvalidVariableValue-result.txt b/Tests/RunCMake/CMakePresets/InvalidVariableValue-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVariableValue-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt new file mode 100644 index 0000000..0ab07c3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVariableValue-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidVariableValue: Invalid CMake variable definition$ diff --git a/Tests/RunCMake/CMakePresets/InvalidVariableValue.json.in b/Tests/RunCMake/CMakePresets/InvalidVariableValue.json.in new file mode 100644 index 0000000..55c7644 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVariableValue.json.in @@ -0,0 +1,15 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "InvalidVariableValue", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "VAR": { + "value": [] + } + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidVariables-result.txt b/Tests/RunCMake/CMakePresets/InvalidVariables-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVariables-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt new file mode 100644 index 0000000..6d9102a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVariables-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidVariables: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/InvalidVariables.json.in b/Tests/RunCMake/CMakePresets/InvalidVariables.json.in new file mode 100644 index 0000000..30dcaf0 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVariables.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "InvalidVariables", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": [] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidVendor-result.txt b/Tests/RunCMake/CMakePresets/InvalidVendor-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVendor-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt new file mode 100644 index 0000000..af923f0 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVendor-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidVendor: Invalid root object$ diff --git a/Tests/RunCMake/CMakePresets/InvalidVendor.json.in b/Tests/RunCMake/CMakePresets/InvalidVendor.json.in new file mode 100644 index 0000000..2315b72 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVendor.json.in @@ -0,0 +1,5 @@ +{ + "version": 1, + "vendor": true, + "configurePresets": [] +} diff --git a/Tests/RunCMake/CMakePresets/InvalidVersion-result.txt b/Tests/RunCMake/CMakePresets/InvalidVersion-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVersion-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt new file mode 100644 index 0000000..7e0fcfd --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVersion-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/InvalidVersion: Invalid "version" field$ diff --git a/Tests/RunCMake/CMakePresets/InvalidVersion.json.in b/Tests/RunCMake/CMakePresets/InvalidVersion.json.in new file mode 100644 index 0000000..e6e19bc --- /dev/null +++ b/Tests/RunCMake/CMakePresets/InvalidVersion.json.in @@ -0,0 +1,4 @@ +{ + "version": "1.0", + "configurePresets": [] +} diff --git a/Tests/RunCMake/CMakePresets/JSONParseError-result.txt b/Tests/RunCMake/CMakePresets/JSONParseError-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/JSONParseError-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt new file mode 100644 index 0000000..a43bf77 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/JSONParseError: JSON parse error$ diff --git a/Tests/RunCMake/CMakePresets/JSONParseError.json.in b/Tests/RunCMake/CMakePresets/JSONParseError.json.in new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/JSONParseError.json.in diff --git a/Tests/RunCMake/CMakePresets/ListPresets-stdout.txt b/Tests/RunCMake/CMakePresets/ListPresets-stdout.txt new file mode 100644 index 0000000..1758f33 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresets-stdout.txt @@ -0,0 +1,6 @@ +^Not searching for unused variables given on the command line\. +Available presets: + + "zzzzzz" - Sleepy + "aaaaaaaa" - Screaming + "mmmmmm"$ diff --git a/Tests/RunCMake/CMakePresets/ListPresets.json.in b/Tests/RunCMake/CMakePresets/ListPresets.json.in new file mode 100644 index 0000000..c7646c6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresets.json.in @@ -0,0 +1,36 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "zzzzzz", + "displayName": "Sleepy", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build/zzzzzz" + }, + { + "name": "aaaaaaaa", + "displayName": "Screaming", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build/aaaaaaaa" + }, + { + "name": "mmmmmm", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build/mmmmmm" + }, + { + "name": "invalid-generator", + "generator": "Invalid Generator", + "binaryDir": "${sourceDir}/build/invalid" + }, + { + "name": "invalid-macro", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${noexist}" + }, + { + "name": "ListPresetsHidden", + "hidden": true + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/ListPresetsHidden-result.txt b/Tests/RunCMake/CMakePresets/ListPresetsHidden-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresetsHidden-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ListPresetsHidden-stderr.txt b/Tests/RunCMake/CMakePresets/ListPresetsHidden-stderr.txt new file mode 100644 index 0000000..1403814 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresetsHidden-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Cannot use hidden preset in [^ +]*/Tests/RunCMake/CMakePresets/ListPresetsHidden: "ListPresetsHidden"$ diff --git a/Tests/RunCMake/CMakePresets/ListPresetsHidden-stdout.txt b/Tests/RunCMake/CMakePresets/ListPresetsHidden-stdout.txt new file mode 100644 index 0000000..1758f33 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresetsHidden-stdout.txt @@ -0,0 +1,6 @@ +^Not searching for unused variables given on the command line\. +Available presets: + + "zzzzzz" - Sleepy + "aaaaaaaa" - Screaming + "mmmmmm"$ diff --git a/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-result.txt b/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-stderr.txt b/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-stderr.txt new file mode 100644 index 0000000..eea1b99 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: No such preset in [^ +]*/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset: "ListPresetsNoSuchPreset"$ diff --git a/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-stdout.txt b/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-stdout.txt new file mode 100644 index 0000000..1758f33 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresetsNoSuchPreset-stdout.txt @@ -0,0 +1,6 @@ +^Not searching for unused variables given on the command line\. +Available presets: + + "zzzzzz" - Sleepy + "aaaaaaaa" - Screaming + "mmmmmm"$ diff --git a/Tests/RunCMake/CMakePresets/ListPresetsWorkingDir-stdout.txt b/Tests/RunCMake/CMakePresets/ListPresetsWorkingDir-stdout.txt new file mode 100644 index 0000000..1758f33 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/ListPresetsWorkingDir-stdout.txt @@ -0,0 +1,6 @@ +^Not searching for unused variables given on the command line\. +Available presets: + + "zzzzzz" - Sleepy + "aaaaaaaa" - Screaming + "mmmmmm"$ diff --git a/Tests/RunCMake/CMakePresets/LowVersion-result.txt b/Tests/RunCMake/CMakePresets/LowVersion-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/LowVersion-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/LowVersion-stderr.txt b/Tests/RunCMake/CMakePresets/LowVersion-stderr.txt new file mode 100644 index 0000000..92b3723 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/LowVersion-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/LowVersion: Unrecognized "version" field$ diff --git a/Tests/RunCMake/CMakePresets/LowVersion.json.in b/Tests/RunCMake/CMakePresets/LowVersion.json.in new file mode 100644 index 0000000..e03afa9 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/LowVersion.json.in @@ -0,0 +1,4 @@ +{ + "version": 0, + "configurePresets": [] +} diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredEmpty.cmake b/Tests/RunCMake/CMakePresets/MinimumRequiredEmpty.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredEmpty.cmake diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredEmpty.json.in b/Tests/RunCMake/CMakePresets/MinimumRequiredEmpty.json.in new file mode 100644 index 0000000..37740ef --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredEmpty.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "cmakeMinimumRequired": {}, + "configurePresets": [ + { + "name": "MinimumRequiredEmpty", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-result.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt new file mode 100644 index 0000000..6548caf --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid: Invalid "cmakeMinimumRequired" field$ diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid.json.in b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid.json.in new file mode 100644 index 0000000..da79603 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredInvalid.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "cmakeMinimumRequired": "3.18", + "configurePresets": [ + { + "name": "MinimumRequiredInvalid", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-result.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt new file mode 100644 index 0000000..6036fe3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/MinimumRequiredMajor: "cmakeMinimumRequired" version too new$ diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMajor.json.in b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor.json.in new file mode 100644 index 0000000..a17cdf6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMajor.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "cmakeMinimumRequired": { + "major": 1000 + }, + "configurePresets": [ + { + "name": "MinimumRequiredMajor", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-result.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt new file mode 100644 index 0000000..bdee4cd --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/MinimumRequiredMinor: "cmakeMinimumRequired" version too new$ diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredMinor.json.in b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor.json.in new file mode 100644 index 0000000..33a8816 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredMinor.json.in @@ -0,0 +1,14 @@ +{ + "version": 1, + "cmakeMinimumRequired": { + "major": @CMAKE_MAJOR_VERSION@, + "minor": 1000 + }, + "configurePresets": [ + { + "name": "MinimumRequiredMinor", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-result.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt new file mode 100644 index 0000000..b5d3a39 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/MinimumRequiredPatch: "cmakeMinimumRequired" version too new$ diff --git a/Tests/RunCMake/CMakePresets/MinimumRequiredPatch.json.in b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch.json.in new file mode 100644 index 0000000..4a53f8d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/MinimumRequiredPatch.json.in @@ -0,0 +1,15 @@ +{ + "version": 1, + "cmakeMinimumRequired": { + "major": @CMAKE_MAJOR_VERSION@, + "minor": @CMAKE_MINOR_VERSION@, + "patch": 50000000 + }, + "configurePresets": [ + { + "name": "MinimumRequiredPatch", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/NoCMakePresets-result.txt b/Tests/RunCMake/CMakePresets/NoCMakePresets-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoCMakePresets-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt b/Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt new file mode 100644 index 0000000..c807ffc --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoCMakePresets-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/NoCMakePresets: File not found$ diff --git a/Tests/RunCMake/CMakePresets/NoDebug-stdout.txt b/Tests/RunCMake/CMakePresets/NoDebug-stdout.txt new file mode 100644 index 0000000..c23ab89 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoDebug-stdout.txt @@ -0,0 +1,2 @@ +-- Configuring done +-- Generating done diff --git a/Tests/RunCMake/CMakePresets/NoDebug.cmake b/Tests/RunCMake/CMakePresets/NoDebug.cmake new file mode 100644 index 0000000..f2b3d4a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoDebug.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/DebugBase.cmake) +if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CMakeLists.txt") + message(SEND_ERROR "Not debugging try_compile() did not work") +endif() diff --git a/Tests/RunCMake/CMakePresets/NoPresetArgument-result.txt b/Tests/RunCMake/CMakePresets/NoPresetArgument-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetArgument-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoPresetArgument-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetArgument-stderr.txt new file mode 100644 index 0000000..aef30d2 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetArgument-stderr.txt @@ -0,0 +1 @@ +^CMake Error: No preset specified for --preset$ diff --git a/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-result.txt b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt new file mode 100644 index 0000000..b525fc3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/NoPresetBinaryDir: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/NoPresetBinaryDir.json.in b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir.json.in new file mode 100644 index 0000000..8989cfd --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetBinaryDir.json.in @@ -0,0 +1,9 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "NoPresetBinaryDir", + "generator": "@RunCMake_GENERATOR@" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/NoPresetGenerator-result.txt b/Tests/RunCMake/CMakePresets/NoPresetGenerator-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetGenerator-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt new file mode 100644 index 0000000..6c0c9f7 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetGenerator-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/NoPresetGenerator: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/NoPresetGenerator.json.in b/Tests/RunCMake/CMakePresets/NoPresetGenerator.json.in new file mode 100644 index 0000000..74f83b7 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetGenerator.json.in @@ -0,0 +1,9 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "NoPresetGenerator", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/NoPresetName-result.txt b/Tests/RunCMake/CMakePresets/NoPresetName-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetName-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt new file mode 100644 index 0000000..0ee338a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetName-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/NoPresetName: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/NoPresetName.json.in b/Tests/RunCMake/CMakePresets/NoPresetName.json.in new file mode 100644 index 0000000..373591d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresetName.json.in @@ -0,0 +1,9 @@ +{ + "version": 1, + "configurePresets": [ + { + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/NoPresets-result.txt b/Tests/RunCMake/CMakePresets/NoPresets-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresets-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoPresets-stderr.txt b/Tests/RunCMake/CMakePresets/NoPresets-stderr.txt new file mode 100644 index 0000000..5ff3d33 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresets-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: No such preset in [^ +]*/Tests/RunCMake/CMakePresets/NoPresets: "NoPresets"$ diff --git a/Tests/RunCMake/CMakePresets/NoPresets-stdout.txt b/Tests/RunCMake/CMakePresets/NoPresets-stdout.txt new file mode 100644 index 0000000..cb01a02 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresets-stdout.txt @@ -0,0 +1 @@ +^Not searching for unused variables given on the command line\.$ diff --git a/Tests/RunCMake/CMakePresets/NoPresets.json.in b/Tests/RunCMake/CMakePresets/NoPresets.json.in new file mode 100644 index 0000000..61a2092 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoPresets.json.in @@ -0,0 +1,3 @@ +{ + "version": 1 +} diff --git a/Tests/RunCMake/CMakePresets/NoSuchMacro-result.txt b/Tests/RunCMake/CMakePresets/NoSuchMacro-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoSuchMacro-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt b/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt new file mode 100644 index 0000000..08fa87b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Could not evaluate preset "NoSuchMacro": Invalid macro expansion$ diff --git a/Tests/RunCMake/CMakePresets/NoSuchPreset-result.txt b/Tests/RunCMake/CMakePresets/NoSuchPreset-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoSuchPreset-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoSuchPreset-stderr.txt b/Tests/RunCMake/CMakePresets/NoSuchPreset-stderr.txt new file mode 100644 index 0000000..9a2d0d5 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoSuchPreset-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: No such preset in [^ +]*/Tests/RunCMake/CMakePresets/NoSuchPreset: "NoSuchPreset"$ diff --git a/Tests/RunCMake/CMakePresets/NoVariableValue-result.txt b/Tests/RunCMake/CMakePresets/NoVariableValue-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoVariableValue-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt b/Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt new file mode 100644 index 0000000..cdab32f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoVariableValue-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/NoVariableValue: Invalid CMake variable definition$ diff --git a/Tests/RunCMake/CMakePresets/NoVariableValue.json.in b/Tests/RunCMake/CMakePresets/NoVariableValue.json.in new file mode 100644 index 0000000..482700d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoVariableValue.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "NoVariableValue", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "VAR": {} + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/NoVersion-result.txt b/Tests/RunCMake/CMakePresets/NoVersion-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoVersion-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/NoVersion-stderr.txt b/Tests/RunCMake/CMakePresets/NoVersion-stderr.txt new file mode 100644 index 0000000..d4f07e4 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoVersion-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/NoVersion: No "version" field$ diff --git a/Tests/RunCMake/CMakePresets/NoVersion.json.in b/Tests/RunCMake/CMakePresets/NoVersion.json.in new file mode 100644 index 0000000..3fe8332 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoVersion.json.in @@ -0,0 +1,3 @@ +{ + "configurePresets": [] +} diff --git a/Tests/RunCMake/CMakePresets/NoWarningFlags-stderr.txt b/Tests/RunCMake/CMakePresets/NoWarningFlags-stderr.txt new file mode 100644 index 0000000..a16d362 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoWarningFlags-stderr.txt @@ -0,0 +1,23 @@ +^CMake Warning \(dev\) at [^ +]*/Tests/RunCMake/CMakePresets/WarningsBase\.cmake:[0-9]+ \(message\): + Dev warning +Call Stack \(most recent call first\): + [^ +]*/Tests/RunCMake/CMakePresets/NoWarningFlags\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\. + +CMake Deprecation Warning at [^ +]*/Tests/RunCMake/CMakePresets/WarningsBase\.cmake:[0-9]+ \(message\): + Deprecation warning +Call Stack \(most recent call first\): + [^ +]*/Tests/RunCMake/CMakePresets/NoWarningFlags\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\) + + +CMake Warning: + Manually-specified variables were not used by the project: + + RunCMake_GENERATOR + UNUSED_VARIABLE$ diff --git a/Tests/RunCMake/CMakePresets/NoWarningFlags.cmake b/Tests/RunCMake/CMakePresets/NoWarningFlags.cmake new file mode 100644 index 0000000..5de7687 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/NoWarningFlags.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/WarningsBase.cmake) diff --git a/Tests/RunCMake/CMakePresets/PresetNotObject-result.txt b/Tests/RunCMake/CMakePresets/PresetNotObject-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/PresetNotObject-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt b/Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt new file mode 100644 index 0000000..6604a14 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/PresetNotObject-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/PresetNotObject: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/PresetNotObject.json.in b/Tests/RunCMake/CMakePresets/PresetNotObject.json.in new file mode 100644 index 0000000..d5892fc --- /dev/null +++ b/Tests/RunCMake/CMakePresets/PresetNotObject.json.in @@ -0,0 +1,6 @@ +{ + "version": 1, + "configurePresets": [ + [] + ] +} diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake new file mode 100644 index 0000000..f591964 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake @@ -0,0 +1,212 @@ +include(RunCMake) + +# Fix Visual Studio generator name +if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ") + set(RunCMake_GENERATOR "${CMAKE_MATCH_1}") +endif() + +function(run_cmake_presets name) + set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}") + set(_source_arg "${RunCMake_TEST_SOURCE_DIR}") + if(CMakePresets_RELATIVE_SOURCE) + set(_source_arg "../${name}") + endif() + file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") + configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY) + + if(NOT CMakePresets_FILE) + set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/${name}.json.in") + endif() + if(EXISTS "${CMakePresets_FILE}") + configure_file("${CMakePresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" @ONLY) + endif() + + if(NOT CMakeUserPresets_FILE) + set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/${name}User.json.in") + endif() + if(EXISTS "${CMakeUserPresets_FILE}") + configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY) + endif() + + set(_s_arg -S) + if(CMakePresets_NO_S_ARG) + set(_s_arg) + endif() + set(_source_args ${_s_arg} ${_source_arg}) + if(CMakePresets_NO_SOURCE_ARGS) + set(_source_args) + endif() + set(_unused_cli --no-warn-unused-cli) + if(CMakePresets_WARN_UNUSED_CLI) + set(_unused_cli) + endif() + + set(RunCMake_TEST_COMMAND ${CMAKE_COMMAND} + ${_source_args} + -DRunCMake_TEST=${name} + -DRunCMake_GENERATOR=${RunCMake_GENERATOR} + -DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM} + ${_unused_cli} + --preset=${name} + ${ARGN} + ) + run_cmake(${name}) +endfunction() + +# Test CMakePresets.json errors +run_cmake_presets(NoCMakePresets) +run_cmake_presets(JSONParseError) +run_cmake_presets(InvalidRoot) +run_cmake_presets(NoVersion) +run_cmake_presets(InvalidVersion) +run_cmake_presets(LowVersion) +run_cmake_presets(HighVersion) +run_cmake_presets(InvalidVendor) +run_cmake_presets(NoPresets) +run_cmake_presets(InvalidPresets) +run_cmake_presets(PresetNotObject) +run_cmake_presets(NoPresetName) +run_cmake_presets(InvalidPresetName) +run_cmake_presets(EmptyPresetName) +run_cmake_presets(NoPresetGenerator) +run_cmake_presets(InvalidPresetGenerator) +run_cmake_presets(NoPresetBinaryDir) +run_cmake_presets(InvalidPresetBinaryDir) +run_cmake_presets(InvalidVariables) +run_cmake_presets(VariableNotObject) +run_cmake_presets(NoVariableValue) +run_cmake_presets(InvalidVariableValue) +run_cmake_presets(ExtraRootField) +run_cmake_presets(ExtraPresetField) +run_cmake_presets(ExtraVariableField) +run_cmake_presets(InvalidPresetVendor) +run_cmake_presets(DuplicatePresets) +run_cmake_presets(CyclicInheritance0) +run_cmake_presets(CyclicInheritance1) +run_cmake_presets(CyclicInheritance2) +run_cmake_presets(InvalidInheritance) +run_cmake_presets(ErrorNoWarningDev) +run_cmake_presets(ErrorNoWarningDeprecated) +run_cmake_presets(InvalidCMakeGeneratorConfig) +run_cmake_presets(UnknownCMakeGeneratorConfig) + +# Test cmakeMinimumRequired field +run_cmake_presets(MinimumRequiredInvalid) +run_cmake_presets(MinimumRequiredEmpty) +run_cmake_presets(MinimumRequiredMajor) +run_cmake_presets(MinimumRequiredMinor) +run_cmake_presets(MinimumRequiredPatch) + +# Test properly working CMakePresets.json +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in") +unset(ENV{TEST_ENV}) +unset(ENV{TEST_ENV_REF}) +unset(ENV{TEST_D_ENV_REF}) +set(ENV{TEST_ENV_OVERRIDE} "This environment variable will be overridden") +set(ENV{TEST_PENV} "Process environment variable") +set(ENV{TEST_ENV_REF_PENV} "suffix") +run_cmake_presets(Good "-DTEST_OVERRIDE_1=Overridden value" "-DTEST_OVERRIDE_2:STRING=Overridden value" -C "${RunCMake_SOURCE_DIR}/CacheOverride.cmake" "-UTEST_UNDEF") +unset(ENV{TEST_ENV_OVERRIDE}) +unset(ENV{TEST_PENV}) +unset(ENV{TEST_ENV_REF_PENV}) +run_cmake_presets(GoodNoArgs) +file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryUp-build) +run_cmake_presets(GoodBinaryUp) +set(CMakePresets_RELATIVE_SOURCE TRUE) +run_cmake_presets(GoodBinaryRelative) +unset(CMakePresets_RELATIVE_SOURCE) +run_cmake_presets(GoodSpaces "--preset=Good Spaces") +if(WIN32) + run_cmake_presets(GoodWindowsBackslash) +endif() +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodBOM.json.in") +run_cmake_presets(GoodBOM) +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in") +file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build) +run_cmake_presets(GoodBinaryCmdLine -B ${RunCMake_BINARY_DIR}/GoodBinaryCmdLine-build) +run_cmake_presets(GoodGeneratorCmdLine -G ${RunCMake_GENERATOR}) +run_cmake_presets(InvalidGeneratorCmdLine -G "Invalid Generator") +set(CMakePresets_NO_S_ARG TRUE) +run_cmake_presets(GoodNoS) +unset(CMakePresets_NO_S_ARG) +run_cmake_presets(GoodInheritanceParent) +run_cmake_presets(GoodInheritanceChild) +run_cmake_presets(GoodInheritanceOverride) +run_cmake_presets(GoodInheritanceMulti) +run_cmake_presets(GoodInheritanceMultiSecond) +run_cmake_presets(GoodInheritanceMacro) + +# Test bad preset arguments +run_cmake_presets(UnclosedMacro) +run_cmake_presets(NoSuchMacro) +run_cmake_presets(VendorMacro) +run_cmake_presets(InvalidGenerator) +run_cmake_presets(EnvCycle) + +# Test Visual Studio-specific stuff +if(RunCMake_GENERATOR MATCHES "^Visual Studio ") + run_cmake_presets(VisualStudioGeneratorArch) + run_cmake_presets(VisualStudioWin32) + run_cmake_presets(VisualStudioWin64) + run_cmake_presets(VisualStudioWin32Override -A x64) + if(NOT RunCMake_GENERATOR STREQUAL "Visual Studio 9 2008") + run_cmake_presets(VisualStudioToolset) + run_cmake_presets(VisualStudioToolsetOverride -T "Test Toolset") + run_cmake_presets(VisualStudioInheritanceParent) + run_cmake_presets(VisualStudioInheritanceChild) + run_cmake_presets(VisualStudioInheritanceOverride) + run_cmake_presets(VisualStudioInheritanceMulti) + run_cmake_presets(VisualStudioInheritanceMultiSecond) + endif() +else() + run_cmake_presets(CMakeGeneratorConfigNone) + run_cmake_presets(CMakeGeneratorConfigDefault) + run_cmake_presets(CMakeGeneratorConfigIgnore) +endif() + +# Test bad command line arguments +run_cmake_presets(NoSuchPreset) +run_cmake_presets(NoPresetArgument --preset=) +run_cmake_presets(UseHiddenPreset) + +# Test CMakeUserPresets.json +unset(CMakePresets_FILE) +run_cmake_presets(GoodUserOnly) +run_cmake_presets(GoodUserFromMain) +run_cmake_presets(GoodUserFromUser) + +# Test CMakeUserPresets.json errors +run_cmake_presets(UserDuplicateInUser) +run_cmake_presets(UserDuplicateCross) +run_cmake_presets(UserInheritance) + +# Test listing presets +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/ListPresets.json.in") +run_cmake_presets(ListPresets --list-presets) + +set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ListPresetsWorkingDir") +set(RunCMake_TEST_NO_CLEAN 1) +set(CMakePresets_NO_SOURCE_ARGS 1) +run_cmake_presets(ListPresetsWorkingDir --list-presets) +unset(CMakePresets_NO_SOURCE_ARGS) +unset(RunCMake_TEST_NO_CLEAN) +unset(RunCMake_TEST_BINARY_DIR) + +run_cmake_presets(ListPresetsNoSuchPreset) +run_cmake_presets(ListPresetsHidden) + +# Test warning and error flags +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Warnings.json.in") +set(CMakePresets_WARN_UNUSED_CLI 1) +run_cmake_presets(NoWarningFlags) +run_cmake_presets(WarningFlags) +run_cmake_presets(DisableWarningFlags) +run_cmake_presets(ErrorDev) +run_cmake_presets(ErrorDeprecated) +unset(CMakePresets_WARN_UNUSED_CLI) + +# Test debug +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Debug.json.in") +run_cmake_presets(NoDebug) +run_cmake_presets(Debug) diff --git a/Tests/RunCMake/CMakePresets/TestVariable.cmake b/Tests/RunCMake/CMakePresets/TestVariable.cmake new file mode 100644 index 0000000..934af52 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/TestVariable.cmake @@ -0,0 +1,25 @@ +function(test_variable name expected_type expected_value) + if(NOT DEFINED "${name}") + message(SEND_ERROR "${name} is not defined") + elseif(NOT "${${name}}" STREQUAL expected_value) + message(SEND_ERROR "Expected value of ${name}: \"${expected_value}\"\nActual value: \"${${name}}\"") + endif() + if(expected_type) + if(NOT DEFINED "CACHE{${name}}") + message(SEND_ERROR "Cache entry ${name} does not exist") + else() + get_property(type CACHE ${name} PROPERTY TYPE) + if(NOT type STREQUAL expected_type) + message(SEND_ERROR "Expected type of ${name}: \"${expected_type}\"\nActual type: \"${type}\"") + endif() + endif() + endif() +endfunction() + +function(test_environment_variable name expected_value) + if(NOT DEFINED "ENV{${name}}") + message(SEND_ERROR "Environment variable ${name} is not defined") + elseif(NOT "$ENV{${name}}" STREQUAL expected_value) + message(SEND_ERROR "Expected value of environment variable ${name}: \"${expected_value}\"\nActual value: \"$ENV{${name}}\"") + endif() +endfunction() diff --git a/Tests/RunCMake/CMakePresets/UnclosedMacro-result.txt b/Tests/RunCMake/CMakePresets/UnclosedMacro-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UnclosedMacro-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt b/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt new file mode 100644 index 0000000..248510d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Could not evaluate preset "UnclosedMacro": Invalid macro expansion$ diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-result.txt b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-stderr.txt b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-stderr.txt new file mode 100644 index 0000000..b1759b0 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig: Invalid preset$ diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in new file mode 100644 index 0000000..900c6df --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "UnknownCMakeGeneratorConfig", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cmakeGeneratorConfig": "unknown" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/UseHiddenPreset-result.txt b/Tests/RunCMake/CMakePresets/UseHiddenPreset-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UseHiddenPreset-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/UseHiddenPreset-stderr.txt b/Tests/RunCMake/CMakePresets/UseHiddenPreset-stderr.txt new file mode 100644 index 0000000..45b4cd4 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UseHiddenPreset-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Cannot use hidden preset in [^ +]*/Tests/RunCMake/CMakePresets/UseHiddenPreset: "UseHiddenPreset"$ diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateCross-result.txt b/Tests/RunCMake/CMakePresets/UserDuplicateCross-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserDuplicateCross-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt b/Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt new file mode 100644 index 0000000..125265f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserDuplicateCross-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/UserDuplicateCross: Duplicate presets$ diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateCross.json.in b/Tests/RunCMake/CMakePresets/UserDuplicateCross.json.in new file mode 100644 index 0000000..172cfba --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserDuplicateCross.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "UserDuplicateCross", + "generator": "@RunCMake_GENERATOR", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateCrossUser.json.in b/Tests/RunCMake/CMakePresets/UserDuplicateCrossUser.json.in new file mode 100644 index 0000000..172cfba --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserDuplicateCrossUser.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "UserDuplicateCross", + "generator": "@RunCMake_GENERATOR", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateInUser-result.txt b/Tests/RunCMake/CMakePresets/UserDuplicateInUser-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserDuplicateInUser-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt b/Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt new file mode 100644 index 0000000..1071b17 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserDuplicateInUser-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/UserDuplicateInUser: Duplicate presets$ diff --git a/Tests/RunCMake/CMakePresets/UserDuplicateInUserUser.json.in b/Tests/RunCMake/CMakePresets/UserDuplicateInUserUser.json.in new file mode 100644 index 0000000..365fafe --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserDuplicateInUserUser.json.in @@ -0,0 +1,15 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "UserDuplicateInUser", + "generator": "@RunCMake_GENERATOR", + "binaryDir": "${sourceDir}/build" + }, + { + "name": "UserDuplicateInUser", + "generator": "@RunCMake_GENERATOR", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/UserInheritance-result.txt b/Tests/RunCMake/CMakePresets/UserInheritance-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserInheritance-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt b/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt new file mode 100644 index 0000000..213215a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/UserInheritance: Project preset inherits from user preset$ diff --git a/Tests/RunCMake/CMakePresets/UserInheritance.json.in b/Tests/RunCMake/CMakePresets/UserInheritance.json.in new file mode 100644 index 0000000..d9973d7 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserInheritance.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "UserInheritance", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "inherits": [ + "UserInheritanceUser" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/UserInheritanceUser.json.in b/Tests/RunCMake/CMakePresets/UserInheritanceUser.json.in new file mode 100644 index 0000000..1321a73 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/UserInheritanceUser.json.in @@ -0,0 +1,10 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "UserInheritanceUser", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/VariableNotObject-result.txt b/Tests/RunCMake/CMakePresets/VariableNotObject-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VariableNotObject-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt b/Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt new file mode 100644 index 0000000..8cacb0a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VariableNotObject-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/VariableNotObject: Invalid CMake variable definition$ diff --git a/Tests/RunCMake/CMakePresets/VariableNotObject.json.in b/Tests/RunCMake/CMakePresets/VariableNotObject.json.in new file mode 100644 index 0000000..51298f5 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VariableNotObject.json.in @@ -0,0 +1,13 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "VariableNotObject", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "VAR": [] + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/VendorMacro-result.txt b/Tests/RunCMake/CMakePresets/VendorMacro-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VendorMacro-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/VendorMacro-stderr.txt b/Tests/RunCMake/CMakePresets/VendorMacro-stderr.txt new file mode 100644 index 0000000..2e98019 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VendorMacro-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Could not evaluate preset "VendorMacro": Invalid macro expansion$ diff --git a/Tests/RunCMake/CMakePresets/VisualStudioGeneratorArch-result.txt b/Tests/RunCMake/CMakePresets/VisualStudioGeneratorArch-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioGeneratorArch-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/VisualStudioGeneratorArch-stderr.txt b/Tests/RunCMake/CMakePresets/VisualStudioGeneratorArch-stderr.txt new file mode 100644 index 0000000..a311321 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioGeneratorArch-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error: Could not create named generator Visual Studio [^ +]* Win64 +Using platforms in Visual Studio generator names is not supported in CMakePresets\.json\. + +Generators diff --git a/Tests/RunCMake/CMakePresets/VisualStudioInheritanceChild.cmake b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceChild.cmake new file mode 100644 index 0000000..d485ab3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceChild.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "Test Platform") +test_variable(CMAKE_VS_PLATFORM_TOOLSET "" "Test Toolset") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioInheritanceMulti.cmake b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceMulti.cmake new file mode 100644 index 0000000..d485ab3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceMulti.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "Test Platform") +test_variable(CMAKE_VS_PLATFORM_TOOLSET "" "Test Toolset") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioInheritanceMultiSecond.cmake b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceMultiSecond.cmake new file mode 100644 index 0000000..d485ab3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceMultiSecond.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "Test Platform") +test_variable(CMAKE_VS_PLATFORM_TOOLSET "" "Test Toolset") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioInheritanceOverride.cmake b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceOverride.cmake new file mode 100644 index 0000000..d485ab3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceOverride.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "Test Platform") +test_variable(CMAKE_VS_PLATFORM_TOOLSET "" "Test Toolset") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioInheritanceParent.cmake b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceParent.cmake new file mode 100644 index 0000000..d485ab3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioInheritanceParent.cmake @@ -0,0 +1,4 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "Test Platform") +test_variable(CMAKE_VS_PLATFORM_TOOLSET "" "Test Toolset") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioToolset.cmake b/Tests/RunCMake/CMakePresets/VisualStudioToolset.cmake new file mode 100644 index 0000000..722e976 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioToolset.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_TOOLSET "" "Test Toolset") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioToolsetOverride.cmake b/Tests/RunCMake/CMakePresets/VisualStudioToolsetOverride.cmake new file mode 100644 index 0000000..722e976 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioToolsetOverride.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_TOOLSET "" "Test Toolset") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioWin32.cmake b/Tests/RunCMake/CMakePresets/VisualStudioWin32.cmake new file mode 100644 index 0000000..a1c61b4 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioWin32.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "Win32") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioWin32Override.cmake b/Tests/RunCMake/CMakePresets/VisualStudioWin32Override.cmake new file mode 100644 index 0000000..b3464d6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioWin32Override.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "x64") diff --git a/Tests/RunCMake/CMakePresets/VisualStudioWin64.cmake b/Tests/RunCMake/CMakePresets/VisualStudioWin64.cmake new file mode 100644 index 0000000..b3464d6 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/VisualStudioWin64.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake) + +test_variable(CMAKE_VS_PLATFORM_NAME "" "x64") diff --git a/Tests/RunCMake/CMakePresets/WarningFlags-stderr.txt b/Tests/RunCMake/CMakePresets/WarningFlags-stderr.txt new file mode 100644 index 0000000..6e488a9 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/WarningFlags-stderr.txt @@ -0,0 +1,34 @@ +^CMake Warning \(dev\) at [^ +]*/Modules/[^/ +]*:[0-9]+ \([a-zA-Z_][a-zA-Z0-9_]*\): + uninitialized variable '[^ +]*' +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(project\) +This warning is for project developers\. Use -Wno-dev to suppress it\..* +CMake Warning \(dev\) at [^ +]*/Tests/RunCMake/CMakePresets/WarningsBase\.cmake:[0-9]+ \(message\): + Dev warning +Call Stack \(most recent call first\): + [^ +]*/Tests/RunCMake/CMakePresets/WarningFlags\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\. + +CMake Deprecation Warning at [^ +]*/Tests/RunCMake/CMakePresets/WarningsBase\.cmake:[0-9]+ \(message\): + Deprecation warning +Call Stack \(most recent call first\): + [^ +]*/Tests/RunCMake/CMakePresets/WarningFlags\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\) + + +CMake Warning \(dev\) at [^ +]*/Tests/RunCMake/CMakePresets/WarningsBase\.cmake:[0-9]+ \(set\): + uninitialized variable 'UNINITIALIZED_VARIABLE' +Call Stack \(most recent call first\): + [^ +]*/Tests/RunCMake/CMakePresets/WarningFlags\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\.$ diff --git a/Tests/RunCMake/CMakePresets/WarningFlags.cmake b/Tests/RunCMake/CMakePresets/WarningFlags.cmake new file mode 100644 index 0000000..5de7687 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/WarningFlags.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/WarningsBase.cmake) diff --git a/Tests/RunCMake/CMakePresets/Warnings.json.in b/Tests/RunCMake/CMakePresets/Warnings.json.in new file mode 100644 index 0000000..40ec6ce --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Warnings.json.in @@ -0,0 +1,50 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "NoWarningFlags", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "UNUSED_VARIABLE": "Unused" + } + }, + { + "name": "WarningFlags", + "inherits": "NoWarningFlags", + "warnings": { + "dev": true, + "deprecated": true, + "uninitialized": true, + "unusedCli": false, + "systemVars": true + } + }, + { + "name": "DisableWarningFlags", + "inherits": "NoWarningFlags", + "warnings": { + "dev": false, + "deprecated": false, + "unusedCli": false + } + }, + { + "name": "ErrorDev", + "inherits": "NoWarningFlags", + "errors": { + "dev": true + } + }, + { + "name": "ErrorDeprecated", + "inherits": "NoWarningFlags", + "warnings": { + "dev": false + }, + "errors": { + "deprecated": true + } + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/WarningsBase.cmake b/Tests/RunCMake/CMakePresets/WarningsBase.cmake new file mode 100644 index 0000000..1a434dc --- /dev/null +++ b/Tests/RunCMake/CMakePresets/WarningsBase.cmake @@ -0,0 +1,3 @@ +message(AUTHOR_WARNING "Dev warning") +message(DEPRECATION "Deprecation warning") +set(_uninitialized "${UNINITIALIZED_VARIABLE}") diff --git a/Tests/RunCMake/CMakePresets/main.c b/Tests/RunCMake/CMakePresets/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/CommandLine/NoArgs-stdout.txt b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt index f1dafc8..50f7d9d 100644 --- a/Tests/RunCMake/CommandLine/NoArgs-stdout.txt +++ b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt @@ -3,6 +3,7 @@ cmake \[options\] <path-to-source> cmake \[options\] <path-to-existing-build> cmake \[options\] -S <path-to-source> -B <path-to-build> + cmake \[options\] -S <path-to-source> --preset=<preset-name> Specify a source directory to \(re-\)generate a build system for it in the current working directory. Specify an existing build directory to |