Ninja Multi-Config: Shuffle variables around

Remove redundant variable CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE.
Rename other variables. Document and improve handling of error
conditions.
This commit is contained in:
Kyle Edwards
2020-01-29 17:43:28 -05:00
committed by Brad King
parent feea34e7eb
commit b966f86d86
32 changed files with 456 additions and 173 deletions

View File

@@ -12,35 +12,67 @@ multiple configurations at once with :variable:`CMAKE_CONFIGURATION_TYPES`
instead of only one configuration with :variable:`CMAKE_BUILD_TYPE`. One
``build-<Config>.ninja`` file will be generated for each of these
configurations (with ``<Config>`` being the configuration name.) No
``build.ninja`` file is generated, unless
:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE` is specified. You must specify
the desired ``build-<Config>.ninja`` file with ``ninja -f``. Running
``cmake --build . --config <Config> --target <target>`` will run Ninja with
``build-<Config>.ninja`` as the ``-f`` file and ``<target>`` as the build
target.
``build.ninja`` file is generated by default (see below for how to generate
it.)
If :variable:`CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE` is turned on, executables
and libraries of any configuration can be built regardless of which
``build-<Config>.ninja`` file is used, simply by specifying
``<target>:<OtherConfig>`` as the Ninja target. You can also specify
``<target>:all`` to build a target in all configurations. Each
``build-<Config>.ninja`` file will additionally have ``<target>`` targets which
are aliases for ``<target>:<Config>``. However, custom commands and custom
targets will always use the configuration specified in
``build-<Config>.ninja``. This is due to the fact that it is impossible in
Ninja for the same file to be output with different commands in the same build
graph.
Each ``build-<Config>.ninja`` file contains ``<target>`` targets as well as
``<target>:<Config>`` targets, where ``<Config>`` is the same as the
configuration specified in ``build-<Config>.ninja`` Additionally, if
cross-config mode is enabled, ``build-<Config>.ninja`` may contain
``<target>:<OtherConfig>`` targets, where ``<OtherConfig>`` is a cross-config,
as well as ``<target>:all``, which builds the target in all cross-configs. See
below for how to enable cross-config mode.
You can additionally use :variable:`CMAKE_NINJA_MULTI_CROSS_CONFIGS` to limit
the configurations that get cross-generated. If this variable is set, each
``build-<Config>.ninja`` file will only contain rules for the configurations
listed in the variable, plus their own configuration. This also affects which
configurations are built by the ``<target>:all`` target.
The ``Ninja Multi-Config`` generator recognizes the following variables:
If :variable:`CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE` is not enabled, you can
still build any target in ``build-<Config>.ninja`` by specifying
``<target>:<Config>`` or ``<target>``, but not ``<target>:<OtherConfig>`` or
``<target>:all``.
:variable:`CMAKE_CONFIGURATION_TYPES`
Specifies the total set of configurations to build. See the variable's
documentation for more information.
:variable:`CMAKE_NMC_CROSS_CONFIGS`
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
configurations available from all ``build-<Config>.ninja`` files.
This variable activates cross-config mode.
Targets from each config specified in this variable can be built from any
``build-<Config>.ninja`` file. Custom commands will use the configuration
native to ``build-<Config>.ninja``. If it is set to ``all``, all
configurations from :variable:`CMAKE_CONFIGURATION_TYPES` are cross-configs.
If it is not specified, or empty, each ``build-<Config>.ninja`` file will
only contain build rules for its own configuration.
The value of this variable must be a subset of
:variable:`CMAKE_CONFIGURATION_TYPES`.
:variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`
Specifies the configuration to use by default in a ``build.ninja`` file. If
this variable is specified, a ``build.ninja`` file is generated which uses
build rules from ``build-<Config>.ninja`` by default. All custom commands are
executed with this configuration. If the variable is not specified, no
``build.ninja`` file is generated.
The value of this variable must be one of the items from
:variable:`CMAKE_CONFIGURATION_TYPES`.
:variable:`CMAKE_NMC_DEFAULT_CONFIGS`
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
configurations to build for a target in ``build.ninja``
if no ``:<Config>`` suffix is specified. If it is set to ``all``, all
configurations from :variable:`CMAKE_NMC_CROSS_CONFIGS` are used. If
it is not specified, it defaults to
:variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`.
For example, if you set
:variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG` to ``Release``, but
set :variable:`CMAKE_NMC_DEFAULT_CONFIGS` to ``Debug`` or ``all``,
all ``<target>`` aliases in ``build.ninja`` will resolve to
``<target>:Debug`` or ``<target>:all``, but custom commands will still use
the ``Release`` configuration.
The value of this variable must be a subset of
:variable:`CMAKE_NMC_CROSS_CONFIGS` or be the same as
:variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`. It must not be
specified if :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG` or
:variable:`CMAKE_NMC_CROSS_CONFIGS` is not used.
Consider the following example:
@@ -66,7 +98,7 @@ This would build the ``Debug`` configuration of ``generator``, which would be
used to generate ``generated.c``, which would be used to build the ``Debug``
configuration of ``generated``.
But if :variable:`CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE` is enabled, and you
But if :variable:`CMAKE_NMC_CROSS_CONFIGS` is set to ``all``, and you
run the following instead:
.. code-block:: shell
@@ -80,17 +112,3 @@ used to generate ``generated.c``, which would be used to build the ``Debug``
configuration of ``generated``. This is useful for running a release-optimized
version of a generator utility while still building the debug version of the
targets built with the generated code.
As a convenience, ``Ninja Multi-Config`` offers a
:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE` setting. If this variable is
specified, a ``build.ninja`` file will be generated which points to the
specified ``build-<Config>.ninja`` file. In addition, if
:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE` is used in conjunction with
:variable:`CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE`, you can also specify
:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS`, which changes the config
of the ``<target>`` targets in ``build.ninja``. For example, if you set
:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE` to ``Release``, but set
:variable:`CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS` to ``Debug`` or ``all``,
all ``<target>`` aliases in ``build.ninja`` will resolve to ``<target>:Debug``
or ``<target>:all``, but custom commands will still use the ``Release``
configuration.

View File

@@ -426,10 +426,9 @@ Variables that Control the Build
/variable/CMAKE_MODULE_LINKER_FLAGS_INIT
/variable/CMAKE_MSVCIDE_RUN_PATH
/variable/CMAKE_MSVC_RUNTIME_LIBRARY
/variable/CMAKE_NINJA_MULTI_CROSS_CONFIGS
/variable/CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE
/variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS
/variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE
/variable/CMAKE_NMC_CROSS_CONFIGS
/variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG
/variable/CMAKE_NMC_DEFAULT_CONFIGS
/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX
/variable/CMAKE_NO_BUILTIN_CHRPATH
/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED

View File

@@ -1,7 +0,0 @@
CMAKE_NINJA_MULTI_CROSS_CONFIGS
-------------------------------
Set which configurations get cross-built if
:variable:`CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE` is set. See the
documentation for the :generator:`Ninja Multi-Config` generator for more
information.

View File

@@ -1,10 +0,0 @@
CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE
-------------------------------------
If this variable is enabled, cross-configuration building is enabled in the
:generator:`Ninja Multi-Config` generator. See the generator's description for
more details. This variable is ``OFF`` by default.
This variable is meant to be set from the command line (via
``-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE:BOOL=ON``) and should not be set from
project code.

View File

@@ -1,6 +0,0 @@
CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS
-------------------------------------
Controls the config of ``<target>`` aliases in ``build.ninja`` for the
:generator:`Ninja Multi-Config` generator. See the generator's documentation
for more details.

View File

@@ -1,7 +0,0 @@
CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE
------------------------------------
Specifies a configuration type to use as the default in ``build.ninja`` for the
:generator:`Ninja Multi-Config` generator.
If this variable is not specified, no ``build.ninja`` file is generated.

View File

@@ -0,0 +1,7 @@
CMAKE_NMC_CROSS_CONFIGS
-------------------------------
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
configurations available from all ``build-<Config>.ninja`` files in the
:generator:`Ninja Multi-Config` generator. See the generator's
documentation for more details.

View File

@@ -0,0 +1,6 @@
CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG
-------------------------------------------
Specifies the configuration to use by default in a ``build.ninja`` file in the
:generator:`Ninja Multi-Config` generator. See the generator's documentation
for more details.

View File

@@ -0,0 +1,7 @@
CMAKE_NMC_DEFAULT_CONFIGS
---------------------------------
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations
to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified in
the :generator:`Ninja Multi-Config` generator.
See the generator's documentation for more details.

View File

@@ -485,6 +485,9 @@ void cmGlobalNinjaGenerator::Generate()
msg.str());
return;
}
if (!this->InspectConfigTypeVariables()) {
return;
}
if (!this->OpenBuildFileStreams()) {
return;
}
@@ -885,6 +888,28 @@ bool cmGlobalNinjaGenerator::OpenFileStream(
return true;
}
cm::optional<std::set<std::string>> cmGlobalNinjaGenerator::ListSubsetWithAll(
const std::set<std::string>& defaults, const std::vector<std::string>& items)
{
std::set<std::string> result;
for (auto const& item : items) {
if (item == "all") {
if (items.size() == 1) {
result = defaults;
} else {
return cm::nullopt;
}
} else if (defaults.count(item)) {
result.insert(item);
} else {
return cm::nullopt;
}
}
return cm::make_optional(result);
}
void cmGlobalNinjaGenerator::CloseBuildFileStreams()
{
if (this->BuildFileStream) {
@@ -1188,6 +1213,7 @@ void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
// uses the output as an alias.
for (std::string const& output : outputs) {
this->TargetAliases[output].GeneratorTarget = nullptr;
this->DefaultTargetAliases[output].GeneratorTarget = nullptr;
for (const std::string& config2 :
this->Makefiles.front()->GetGeneratorConfigs()) {
this->Configs[config2].TargetAliases[output].GeneratorTarget = nullptr;
@@ -1199,18 +1225,28 @@ void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
TargetAlias ta;
ta.GeneratorTarget = target;
ta.Config = config;
std::pair<TargetAliasMap::iterator, bool> newAliasGlobal =
auto newAliasGlobal =
this->TargetAliases.insert(std::make_pair(buildAlias, ta));
if (newAliasGlobal.second &&
newAliasGlobal.first->second.GeneratorTarget != target) {
newAliasGlobal.first->second.GeneratorTarget = nullptr;
}
std::pair<TargetAliasMap::iterator, bool> newAliasConfig =
auto newAliasConfig =
this->Configs[config].TargetAliases.insert(std::make_pair(outputPath, ta));
if (newAliasConfig.second &&
newAliasConfig.first->second.GeneratorTarget != target) {
newAliasConfig.first->second.GeneratorTarget = nullptr;
}
if (this->DefaultConfigs.count(config)) {
auto newAliasDefaultGlobal =
this->DefaultTargetAliases.insert(std::make_pair(outputPath, ta));
if (newAliasDefaultGlobal.second &&
newAliasDefaultGlobal.first->second.GeneratorTarget != target) {
newAliasDefaultGlobal.first->second.GeneratorTarget = nullptr;
}
}
}
void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
@@ -1235,7 +1271,7 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
build.Outputs.front() = ta.first;
build.ExplicitDeps.clear();
if (ta.second.Config == "all") {
for (auto const& config : this->GetCrossConfigs("")) {
for (auto const& config : this->CrossConfigs) {
this->AppendTargetOutputs(ta.second.GeneratorTarget,
build.ExplicitDeps, config);
}
@@ -1245,7 +1281,7 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
}
this->WriteBuild(this->EnableCrossConfigBuild() &&
(ta.second.Config == "all" ||
this->GetCrossConfigs("").count(ta.second.Config))
this->CrossConfigs.count(ta.second.Config))
? os
: *this->GetImplFileStream(ta.second.Config),
build);
@@ -1273,10 +1309,8 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
}
}
auto const* defaultConfig = this->GetDefaultBuildAlias();
if (defaultConfig) {
std::string config = defaultConfig;
for (auto const& ta : this->Configs[config].TargetAliases) {
if (!this->DefaultConfigs.empty()) {
for (auto const& ta : this->DefaultTargetAliases) {
// Don't write ambiguous aliases.
if (!ta.second.GeneratorTarget) {
continue;
@@ -1290,13 +1324,7 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
build.Outputs.front() = ta.first;
build.ExplicitDeps.clear();
if (config == "all") {
for (auto const& config2 :
this->Makefiles.front()->GetGeneratorConfigs()) {
this->AppendTargetOutputs(ta.second.GeneratorTarget,
build.ExplicitDeps, config2);
}
} else {
for (auto const& config : this->DefaultConfigs) {
this->AppendTargetOutputs(ta.second.GeneratorTarget,
build.ExplicitDeps, config);
}
@@ -1347,7 +1375,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
}
// Write target
this->WriteBuild(this->EnableCrossConfigBuild() &&
this->GetCrossConfigs("").count(config)
this->CrossConfigs.count(config)
? os
: *this->GetImplFileStream(config),
build);
@@ -1363,11 +1391,12 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
this->WriteBuild(*this->GetConfigFileStream(config), build);
}
auto const* defaultConfig = this->GetDefaultBuildAlias();
if (defaultConfig) {
std::string config = defaultConfig;
build.ExplicitDeps = { this->BuildAlias(
this->ConvertToNinjaPath(currentBinaryDir + "/all"), config) };
if (!this->DefaultFileConfig.empty()) {
build.ExplicitDeps.clear();
for (auto const& config : this->DefaultConfigs) {
build.ExplicitDeps.push_back(this->BuildAlias(
this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
}
build.Outputs.front() =
this->ConvertToNinjaPath(currentBinaryDir + "/all");
this->WriteBuild(*this->GetDefaultFileStream(), build);
@@ -1377,7 +1406,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
// Add target for all configs
if (this->EnableCrossConfigBuild()) {
build.ExplicitDeps.clear();
for (auto const& config : this->GetCrossConfigs("")) {
for (auto const& config : this->CrossConfigs) {
build.ExplicitDeps.push_back(this->BuildAlias(
this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
}
@@ -1524,7 +1553,7 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
this->WriteTargetDefault(*this->GetConfigFileStream(config));
}
if (this->GetDefaultBuildType()) {
if (!this->DefaultFileConfig.empty()) {
this->WriteTargetDefault(*this->GetDefaultFileStream());
}
}
@@ -1832,7 +1861,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
build.ExplicitDeps.clear();
if (additionalFiles) {
for (auto const& config : this->GetCrossConfigs("")) {
for (auto const& config : this->CrossConfigs) {
build.ExplicitDeps.push_back(this->BuildAlias(
this->NinjaOutputPath(this->GetAdditionalCleanTargetName()),
config));
@@ -1840,7 +1869,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
}
std::vector<std::string> byproducts;
for (auto const& config : this->GetCrossConfigs("")) {
for (auto const& config : this->CrossConfigs) {
byproducts.push_back(
this->BuildAlias(GetByproductsForCleanTargetName(), config));
}
@@ -1867,11 +1896,12 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
this->WriteBuild(*this->GetConfigFileStream(config), build);
}
auto const* defaultConfig = this->GetDefaultBuildAlias();
if (defaultConfig) {
std::string config = defaultConfig;
build.ExplicitDeps.front() = this->BuildAlias(
this->NinjaOutputPath(this->GetCleanTargetName()), config);
if (!this->DefaultConfigs.empty()) {
build.ExplicitDeps.clear();
for (auto const& config : this->DefaultConfigs) {
build.ExplicitDeps.push_back(this->BuildAlias(
this->NinjaOutputPath(this->GetCleanTargetName()), config));
}
this->WriteBuild(*this->GetDefaultFileStream(), build);
}
}
@@ -2319,8 +2349,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const
{
return this->IsMultiConfig() &&
this->Makefiles.front()->IsOn("CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE");
return !this->CrossConfigs.empty();
}
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
@@ -2415,11 +2444,10 @@ void cmGlobalNinjaGenerator::AppendDirectoryForConfig(
}
std::set<std::string> cmGlobalNinjaGenerator::GetCrossConfigs(
const std::string& /*fileConfig*/) const
const std::string& fileConfig) const
{
std::set<std::string> result;
result.insert(
this->Makefiles.front()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
auto result = this->CrossConfigs;
result.insert(fileConfig);
return result;
}
@@ -2455,15 +2483,14 @@ bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams()
return false;
}
auto const* defaultConfig = this->GetDefaultBuildType();
if (defaultConfig) {
if (!this->DefaultFileConfig.empty()) {
if (!this->OpenFileStream(this->DefaultFileStream, NINJA_BUILD_FILE)) {
return false;
}
*this->DefaultFileStream
<< "# This file is a convenience file generated by\n"
<< "# CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE.\n\n"
<< "include " << GetNinjaImplFilename(defaultConfig) << "\n\n";
<< "# CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.\n\n"
<< "include " << GetNinjaImplFilename(this->DefaultFileConfig) << "\n\n";
}
// Write a comment about this file.
@@ -2555,8 +2582,7 @@ void cmGlobalNinjaMultiGenerator::AddRebuildManifestOutputs(
outputs.push_back(this->NinjaOutputPath(GetNinjaImplFilename(config)));
outputs.push_back(this->NinjaOutputPath(GetNinjaConfigFilename(config)));
}
if (this->Makefiles.front()->GetDefinition(
"CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE")) {
if (!this->DefaultFileConfig.empty()) {
outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
}
}
@@ -2571,43 +2597,70 @@ void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
}
}
const char* cmGlobalNinjaMultiGenerator::GetDefaultBuildType() const
bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
{
return this->Makefiles.front()->GetDefinition(
"CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE");
}
auto configsVec = this->Makefiles.front()->GetGeneratorConfigs();
std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
const char* cmGlobalNinjaMultiGenerator::GetDefaultBuildAlias() const
{
if (this->EnableCrossConfigBuild()) {
auto const* alias = this->Makefiles.front()->GetDefinition(
"CMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS");
if (alias) {
return alias;
this->DefaultFileConfig = this->Makefiles.front()->GetSafeDefinition(
"CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG");
if (!this->DefaultFileConfig.empty() &&
!configs.count(this->DefaultFileConfig)) {
std::ostringstream msg;
msg << "The configuration specified by "
<< "CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG (" << this->DefaultFileConfig
<< ") is not present in CMAKE_CONFIGURATION_TYPES";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
return false;
}
std::vector<std::string> crossConfigsVec;
cmExpandList(
this->Makefiles.front()->GetSafeDefinition("CMAKE_NMC_CROSS_CONFIGS"),
crossConfigsVec);
auto crossConfigs = ListSubsetWithAll(configs, crossConfigsVec);
if (!crossConfigs) {
std::ostringstream msg;
msg << "CMAKE_NMC_CROSS_CONFIGS is not a subset of "
<< "CMAKE_CONFIGURATION_TYPES";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
return false;
}
this->CrossConfigs = *crossConfigs;
auto defaultConfigsString =
this->Makefiles.front()->GetSafeDefinition("CMAKE_NMC_DEFAULT_CONFIGS");
if (defaultConfigsString.empty()) {
defaultConfigsString = this->DefaultFileConfig;
}
if (!defaultConfigsString.empty() &&
(this->DefaultFileConfig.empty() || this->CrossConfigs.empty())) {
std::ostringstream msg;
msg << "CMAKE_NMC_DEFAULT_CONFIGS cannot be used without "
<< "CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or "
<< "CMAKE_NMC_CROSS_CONFIGS";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
return false;
}
std::vector<std::string> defaultConfigsVec;
cmExpandList(defaultConfigsString, defaultConfigsVec);
if (!this->DefaultFileConfig.empty()) {
auto defaultConfigs = ListSubsetWithAll(
this->GetCrossConfigs(this->DefaultFileConfig), defaultConfigsVec);
if (!defaultConfigs) {
std::ostringstream msg;
msg << "CMAKE_NMC_DEFAULT_CONFIGS is not a subset of "
<< "CMAKE_NMC_CROSS_CONFIGS";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
return false;
}
this->DefaultConfigs = *defaultConfigs;
}
return this->GetDefaultBuildType();
}
std::set<std::string> cmGlobalNinjaMultiGenerator::GetCrossConfigs(
const std::string& fileConfig) const
{
std::vector<std::string> configs;
if (this->EnableCrossConfigBuild()) {
auto configsValue = this->Makefiles.front()->GetSafeDefinition(
"CMAKE_NINJA_MULTI_CROSS_CONFIGS");
if (!configsValue.empty()) {
cmExpandList(configsValue, configs);
} else {
configs = this->Makefiles.front()->GetGeneratorConfigs();
}
}
std::set<std::string> result(configs.cbegin(), configs.cend());
if (!fileConfig.empty()) {
result.insert(fileConfig);
}
return result;
return true;
}

View File

@@ -15,6 +15,8 @@
#include <utility>
#include <vector>
#include <cm/optional>
#include "cm_codecvt.hxx"
#include "cmGeneratedFileStream.h"
@@ -408,12 +410,7 @@ public:
bool EnableCrossConfigBuild() const;
virtual const char* GetDefaultBuildType() const { return nullptr; }
virtual const char* GetDefaultBuildAlias() const { return nullptr; }
virtual std::set<std::string> GetCrossConfigs(
const std::string& fileConfig) const;
std::set<std::string> GetCrossConfigs(const std::string& config) const;
protected:
void Generate() override;
@@ -426,6 +423,16 @@ protected:
bool OpenFileStream(std::unique_ptr<cmGeneratedFileStream>& stream,
const std::string& name);
static cm::optional<std::set<std::string>> ListSubsetWithAll(
const std::set<std::string>& defaults,
const std::vector<std::string>& items);
virtual bool InspectConfigTypeVariables() { return true; }
std::set<std::string> CrossConfigs;
std::set<std::string> DefaultConfigs;
std::string DefaultFileConfig;
private:
std::string GetEditCacheCommand() const override;
bool FindMakeProgram(cmMakefile* mf) override;
@@ -504,6 +511,7 @@ private:
};
using TargetAliasMap = std::map<std::string, TargetAlias>;
TargetAliasMap TargetAliases;
TargetAliasMap DefaultTargetAliases;
/// the local cache for calls to ConvertToNinjaPath
mutable std::unordered_map<std::string, std::string> ConvertToNinjaPathCache;
@@ -623,12 +631,7 @@ public:
void GetQtAutoGenConfigs(std::vector<std::string>& configs) const override;
const char* GetDefaultBuildType() const override;
const char* GetDefaultBuildAlias() const override;
std::set<std::string> GetCrossConfigs(
const std::string& fileConfig) const override;
bool InspectConfigTypeVariables() override;
protected:
bool OpenBuildFileStreams() override;

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,5 @@
^CMake Error:
CMAKE_NMC_CROSS_CONFIGS is not a subset of CMAKE_CONFIGURATION_TYPES
CMake Generate step failed\. Build files cannot be regenerated correctly\.$

View File

@@ -0,0 +1,6 @@
^CMake Error:
The configuration specified by CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG
\(RelWithDebInfo\) is not present in CMAKE_CONFIGURATION_TYPES
CMake Generate step failed\. Build files cannot be regenerated correctly\.$

View File

@@ -0,0 +1,5 @@
^CMake Error:
CMAKE_NMC_DEFAULT_CONFIGS is not a subset of CMAKE_NMC_CROSS_CONFIGS
CMake Generate step failed\. Build files cannot be regenerated correctly\.$

View File

@@ -0,0 +1,6 @@
^CMake Error:
CMAKE_NMC_DEFAULT_CONFIGS cannot be used without
CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or CMAKE_NMC_CROSS_CONFIGS
CMake Generate step failed\. Build files cannot be regenerated correctly\.$

View File

@@ -0,0 +1,6 @@
^CMake Error:
CMAKE_NMC_DEFAULT_CONFIGS cannot be used without
CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or CMAKE_NMC_CROSS_CONFIGS
CMake Generate step failed\. Build files cannot be regenerated correctly\.$

View File

@@ -76,7 +76,7 @@ endfunction()
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Simple-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE=RelWithDebInfo;-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo;-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(Simple)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -108,7 +108,7 @@ run_ninja(Simple default-build-file-clean-minsizerel build.ninja clean:MinSizeRe
run_ninja(Simple default-build-file-all build.ninja all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAlias-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE=Release;-DCMAKE_NINJA_MULTI_DEFAULT_BUILD_ALIAS=all;-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all;-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(SimpleDefaultBuildAlias)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -116,6 +116,38 @@ run_ninja(SimpleDefaultBuildAlias target build.ninja simpleexe)
run_ninja(SimpleDefaultBuildAlias all build.ninja all)
run_ninja(SimpleDefaultBuildAlias clean build.ninja clean)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasList-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(SimpleDefaultBuildAliasList)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
run_ninja(SimpleDefaultBuildAliasList target-configs build.ninja simpleexe)
run_ninja(SimpleDefaultBuildAliasList all-configs build.ninja all)
run_ninja(SimpleDefaultBuildAliasList all-relwithdebinfo build.ninja all:RelWithDebInfo)
run_ninja(SimpleDefaultBuildAliasList clean-configs build.ninja clean)
unset(RunCMake_TEST_BINARY_DIR)
set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
run_cmake(InvalidCrossConfigs)
unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo")
run_cmake(InvalidDefaultBuildFileConfig)
unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
run_cmake(InvalidDefaultConfigsCross)
unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all")
run_cmake(InvalidDefaultConfigsNoDefaultFile)
unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all")
run_cmake(InvalidDefaultConfigsNoCross)
unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleNoCross-build)
run_cmake_configure(SimpleNoCross)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -129,7 +161,7 @@ run_ninja(SimpleNoCross all-all build-Debug.ninja all:all)
run_cmake_build(SimpleNoCross all-clean Debug clean:all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleCrossConfigs-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON;-DCMAKE_NINJA_MULTI_CROSS_CONFIGS=Debug\\;Release")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release")
run_cmake_configure(SimpleCrossConfigs)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
run_ninja(SimpleCrossConfigs release-in-release-graph build-Release.ninja simpleexe)
@@ -143,14 +175,14 @@ run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all)
run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(Framework)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
run_cmake_build(Framework framework Debug all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandGenerator-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(CustomCommandGenerator)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -167,7 +199,7 @@ run_ninja(CustomCommandGenerator release-in-debug-graph build-Debug.ninja genera
run_cmake_command(CustomCommandGenerator-release-in-debug-graph-generated "${TARGET_FILE_generated_Release}")
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandsAndTargets-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(CustomCommandsAndTargets)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -183,7 +215,7 @@ run_cmake_build(CustomCommandsAndTargets debug-targetpostbuild Debug TopTargetPo
run_ninja(CustomCommandsAndTargets release-targetpostbuild build-Release.ninja SubdirTargetPostBuild)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostfixAndLocation-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(PostfixAndLocation)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -198,14 +230,14 @@ run_ninja(Clean release-notall build-Release.ninja exenotall)
run_cmake_build(Clean release-clean Release clean)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdditionalCleanFiles-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(AdditionalCleanFiles)
unset(RunCMake_TEST_OPTIONS)
run_cmake_build(AdditionalCleanFiles release-clean Release clean)
run_ninja(AdditionalCleanFiles all-clean build-Debug.ninja clean:all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Install-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(Install)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -227,7 +259,7 @@ endif()
if(CMake_TEST_Qt5)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build)
set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE=ON")
set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
run_cmake_configure(Qt5)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)

View File

@@ -0,0 +1,39 @@
check_files("${RunCMake_TEST_BINARY_DIR}"
INCLUDE
${GENERATED_FILES}
${TARGET_FILE_simpleexe_Debug}
${TARGET_OBJECT_FILES_simpleexe_Debug}
${TARGET_FILE_simpleshared_Debug}
${TARGET_LINKER_FILE_simpleshared_Debug}
${TARGET_OBJECT_FILES_simpleshared_Debug}
${TARGET_FILE_simplestatic_Debug}
${TARGET_OBJECT_FILES_simplestatic_Debug}
${TARGET_OBJECT_FILES_simpleobj_Debug}
${TARGET_FILE_simpleexe_Release}
${TARGET_OBJECT_FILES_simpleexe_Release}
${TARGET_FILE_simpleshared_Release}
${TARGET_LINKER_FILE_simpleshared_Release}
${TARGET_OBJECT_FILES_simpleshared_Release}
${TARGET_FILE_simplestatic_Release}
${TARGET_OBJECT_FILES_simplestatic_Release}
${TARGET_OBJECT_FILES_simpleobj_Release}
EXCLUDE
${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
)

View File

@@ -0,0 +1,46 @@
check_files("${RunCMake_TEST_BINARY_DIR}"
INCLUDE
${GENERATED_FILES}
${TARGET_FILE_simpleexe_Debug}
${TARGET_OBJECT_FILES_simpleexe_Debug}
${TARGET_FILE_simpleshared_Debug}
${TARGET_LINKER_FILE_simpleshared_Debug}
${TARGET_OBJECT_FILES_simpleshared_Debug}
${TARGET_FILE_simplestatic_Debug}
${TARGET_OBJECT_FILES_simplestatic_Debug}
${TARGET_OBJECT_FILES_simpleobj_Debug}
${TARGET_FILE_simpleexe_Release}
${TARGET_OBJECT_FILES_simpleexe_Release}
${TARGET_FILE_simpleshared_Release}
${TARGET_LINKER_FILE_simpleshared_Release}
${TARGET_OBJECT_FILES_simpleshared_Release}
${TARGET_FILE_simplestatic_Release}
${TARGET_OBJECT_FILES_simplestatic_Release}
${TARGET_OBJECT_FILES_simpleobj_Release}
${TARGET_FILE_simpleexe_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
${TARGET_FILE_simpleshared_RelWithDebInfo}
${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
${TARGET_FILE_simplestatic_RelWithDebInfo}
${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
EXCLUDE
${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
)

View File

@@ -0,0 +1,32 @@
check_files("${RunCMake_TEST_BINARY_DIR}"
INCLUDE
${GENERATED_FILES}
${TARGET_FILE_simpleexe_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
${TARGET_FILE_simpleshared_RelWithDebInfo}
${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
${TARGET_FILE_simplestatic_RelWithDebInfo}
${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
EXCLUDE
${TARGET_OBJECT_FILES_simpleexe_Debug}
${TARGET_OBJECT_FILES_simpleshared_Debug}
${TARGET_OBJECT_FILES_simplestatic_Debug}
${TARGET_OBJECT_FILES_simpleobj_Debug}
${TARGET_OBJECT_FILES_simpleexe_Release}
${TARGET_OBJECT_FILES_simpleshared_Release}
${TARGET_OBJECT_FILES_simplestatic_Release}
${TARGET_OBJECT_FILES_simpleobj_Release}
${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
)

View File

@@ -0,0 +1,37 @@
check_files("${RunCMake_TEST_BINARY_DIR}"
INCLUDE
${GENERATED_FILES}
${TARGET_FILE_simpleexe_Debug}
${TARGET_OBJECT_FILES_simpleexe_Debug}
${TARGET_FILE_simpleshared_Debug}
${TARGET_LINKER_FILE_simpleshared_Debug}
${TARGET_OBJECT_FILES_simpleshared_Debug}
${TARGET_OBJECT_FILES_simpleobj_Debug}
${TARGET_FILE_simpleexe_Release}
${TARGET_OBJECT_FILES_simpleexe_Release}
${TARGET_FILE_simpleshared_Release}
${TARGET_LINKER_FILE_simpleshared_Release}
${TARGET_OBJECT_FILES_simpleshared_Release}
${TARGET_OBJECT_FILES_simpleobj_Release}
EXCLUDE
${TARGET_OBJECT_FILES_simplestatic_Debug}
${TARGET_OBJECT_FILES_simplestatic_Release}
${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
)

View File

@@ -0,0 +1 @@
include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake")