mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-30 11:10:06 -05:00
Merge topic 'ninja-multi'
8c062f9d99Help: Add documentation and release notes for multi-config Ninjae0478cc646Tests: Add test for Multi-Configuration Ninja generator5a8a9f7229Ninja: Add multi-config variant3bc63e99e4Refactor: Prepare Ninja generator for multi-config Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !4086
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
Ninja Multi-Config
|
||||
------------------
|
||||
|
||||
Generates multiple ``build-<Config>.ninja`` files.
|
||||
|
||||
This generator is very much like the :generator:`Ninja` generator, but with
|
||||
some key differences. Only these differences will be discussed in this
|
||||
document.
|
||||
|
||||
Unlike the :generator:`Ninja` generator, ``Ninja Multi-Config`` generates
|
||||
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.
|
||||
|
||||
Executables and libraries of any configuration can be built regardless of which
|
||||
``build-<Config>.ninja`` file is used, simply by specifying
|
||||
``<target>:<Config>`` 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.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(MultiConfigNinja C)
|
||||
|
||||
add_executable(generator generator.c)
|
||||
add_custom_command(OUTPUT generated.c COMMAND generator generated.c)
|
||||
add_library(generated ${CMAKE_BINARY_DIR}/generated.c)
|
||||
|
||||
Now assume you configure the project with ``Ninja Multi-Config`` and run one of
|
||||
the following commands:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ninja -f build-Debug.ninja generated
|
||||
# OR
|
||||
cmake --build . --config Debug --target generated
|
||||
|
||||
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 you run the following instead:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
ninja -f build-Release.ninja generated:Debug
|
||||
# OR
|
||||
cmake --build . --config Release --target generated:Debug
|
||||
|
||||
This would build the ``Release`` configuration of ``generator``, which would be
|
||||
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.
|
||||
@@ -1,7 +1,7 @@
|
||||
Ninja
|
||||
-----
|
||||
|
||||
Generates build.ninja files.
|
||||
Generates ``build.ninja`` files.
|
||||
|
||||
A ``build.ninja`` file is generated into the build tree. Use the ninja
|
||||
program to build the project through the ``all`` target and install the
|
||||
@@ -38,3 +38,9 @@ features have not been integrated into upstream Ninja. Kitware maintains
|
||||
a branch of Ninja with the required features on `github.com/Kitware/ninja`_.
|
||||
|
||||
.. _`github.com/Kitware/ninja`: https://github.com/Kitware/ninja/tree/features-for-fortran#readme
|
||||
|
||||
See Also
|
||||
^^^^^^^^
|
||||
|
||||
The :generator:`Ninja Multi-Config` generator is similar to the ``Ninja``
|
||||
generator, but generates multiple configurations at once.
|
||||
|
||||
@@ -52,13 +52,14 @@ Makefile Generators
|
||||
/generator/Unix Makefiles
|
||||
/generator/Watcom WMake
|
||||
|
||||
Ninja Generator
|
||||
^^^^^^^^^^^^^^^
|
||||
Ninja Generators
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
/generator/Ninja
|
||||
/generator/Ninja Multi-Config
|
||||
|
||||
.. _`IDE Build Tool Generators`:
|
||||
|
||||
|
||||
@@ -214,6 +214,7 @@ Variables that Change Behavior
|
||||
/variable/CMAKE_MESSAGE_INDENT
|
||||
/variable/CMAKE_MESSAGE_LOG_LEVEL
|
||||
/variable/CMAKE_MODULE_PATH
|
||||
/variable/CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE
|
||||
/variable/CMAKE_POLICY_DEFAULT_CMPNNNN
|
||||
/variable/CMAKE_POLICY_WARNING_CMPNNNN
|
||||
/variable/CMAKE_PREFIX_PATH
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
multi-configuration-ninja
|
||||
-------------------------
|
||||
|
||||
* :manual:`cmake(1)` gained a :generator:`Ninja Multi-Config` generator,
|
||||
which is similar to the :generator:`Ninja` generator but can be used to build
|
||||
multiple configurations at once.
|
||||
@@ -0,0 +1,7 @@
|
||||
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.
|
||||
@@ -25,27 +25,29 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
|
||||
static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
|
||||
, GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>(
|
||||
gt->LocalGenerator->GetGlobalGenerator()))
|
||||
, ConfigName(LocalCommonGenerator->GetConfigName())
|
||||
, ConfigNames(LocalCommonGenerator->GetConfigNames())
|
||||
{
|
||||
}
|
||||
|
||||
cmCommonTargetGenerator::~cmCommonTargetGenerator() = default;
|
||||
|
||||
std::string const& cmCommonTargetGenerator::GetConfigName() const
|
||||
std::vector<std::string> const& cmCommonTargetGenerator::GetConfigNames() const
|
||||
{
|
||||
return this->ConfigName;
|
||||
return this->ConfigNames;
|
||||
}
|
||||
|
||||
const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
|
||||
const char* cmCommonTargetGenerator::GetFeature(const std::string& feature,
|
||||
const std::string& config)
|
||||
{
|
||||
return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
|
||||
return this->GeneratorTarget->GetFeature(feature, config);
|
||||
}
|
||||
|
||||
void cmCommonTargetGenerator::AddModuleDefinitionFlag(
|
||||
cmLinkLineComputer* linkLineComputer, std::string& flags)
|
||||
cmLinkLineComputer* linkLineComputer, std::string& flags,
|
||||
const std::string& config)
|
||||
{
|
||||
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
|
||||
this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
|
||||
this->GeneratorTarget->GetModuleDefinitionInfo(config);
|
||||
if (!mdi || mdi->DefFile.empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -94,57 +96,60 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmCommonTargetGenerator::GetFlags(const std::string& l)
|
||||
std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
|
||||
const std::string& config)
|
||||
{
|
||||
auto i = this->FlagsByLanguage.find(l);
|
||||
if (i == this->FlagsByLanguage.end()) {
|
||||
auto i = this->Configs[config].FlagsByLanguage.find(l);
|
||||
if (i == this->Configs[config].FlagsByLanguage.end()) {
|
||||
std::string flags;
|
||||
|
||||
this->LocalCommonGenerator->GetTargetCompileFlags(
|
||||
this->GeneratorTarget, this->ConfigName, l, flags);
|
||||
this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
|
||||
config, l, flags);
|
||||
|
||||
ByLanguageMap::value_type entry(l, flags);
|
||||
i = this->FlagsByLanguage.insert(entry).first;
|
||||
i = this->Configs[config].FlagsByLanguage.insert(entry).first;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
std::string cmCommonTargetGenerator::GetDefines(const std::string& l)
|
||||
std::string cmCommonTargetGenerator::GetDefines(const std::string& l,
|
||||
const std::string& config)
|
||||
{
|
||||
auto i = this->DefinesByLanguage.find(l);
|
||||
if (i == this->DefinesByLanguage.end()) {
|
||||
auto i = this->Configs[config].DefinesByLanguage.find(l);
|
||||
if (i == this->Configs[config].DefinesByLanguage.end()) {
|
||||
std::set<std::string> defines;
|
||||
this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget,
|
||||
this->ConfigName, l, defines);
|
||||
this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget, config,
|
||||
l, defines);
|
||||
|
||||
std::string definesString;
|
||||
this->LocalCommonGenerator->JoinDefines(defines, definesString, l);
|
||||
|
||||
ByLanguageMap::value_type entry(l, definesString);
|
||||
i = this->DefinesByLanguage.insert(entry).first;
|
||||
i = this->Configs[config].DefinesByLanguage.insert(entry).first;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
|
||||
std::string cmCommonTargetGenerator::GetIncludes(std::string const& l,
|
||||
const std::string& config)
|
||||
{
|
||||
auto i = this->IncludesByLanguage.find(l);
|
||||
if (i == this->IncludesByLanguage.end()) {
|
||||
auto i = this->Configs[config].IncludesByLanguage.find(l);
|
||||
if (i == this->Configs[config].IncludesByLanguage.end()) {
|
||||
std::string includes;
|
||||
this->AddIncludeFlags(includes, l);
|
||||
this->AddIncludeFlags(includes, l, config);
|
||||
ByLanguageMap::value_type entry(l, includes);
|
||||
i = this->IncludesByLanguage.insert(entry).first;
|
||||
i = this->Configs[config].IncludesByLanguage.insert(entry).first;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
|
||||
const
|
||||
std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
|
||||
const std::string& config) const
|
||||
{
|
||||
std::vector<std::string> dirs;
|
||||
std::set<cmGeneratorTarget const*> emitted;
|
||||
if (cmComputeLinkInformation* cli =
|
||||
this->GeneratorTarget->GetLinkInformation(this->ConfigName)) {
|
||||
this->GeneratorTarget->GetLinkInformation(config)) {
|
||||
cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
|
||||
for (auto const& item : items) {
|
||||
cmGeneratorTarget const* linkee = item.Target;
|
||||
@@ -165,19 +170,24 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
|
||||
return dirs;
|
||||
}
|
||||
|
||||
std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
|
||||
std::string cmCommonTargetGenerator::ComputeTargetCompilePDB(
|
||||
const std::string& config) const
|
||||
{
|
||||
std::string compilePdbPath;
|
||||
if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) {
|
||||
return compilePdbPath;
|
||||
}
|
||||
|
||||
compilePdbPath =
|
||||
this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
|
||||
compilePdbPath = this->GeneratorTarget->GetCompilePDBPath(config);
|
||||
if (compilePdbPath.empty()) {
|
||||
// Match VS default: `$(IntDir)vc$(PlatformToolsetVersion).pdb`.
|
||||
// A trailing slash tells the toolchain to add its default file name.
|
||||
compilePdbPath = this->GeneratorTarget->GetSupportDirectory() + "/";
|
||||
compilePdbPath = this->GeneratorTarget->GetSupportDirectory();
|
||||
if (this->GlobalCommonGenerator->IsMultiConfig()) {
|
||||
compilePdbPath += "/";
|
||||
compilePdbPath += config;
|
||||
}
|
||||
compilePdbPath += "/";
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
||||
// Match VS default for static libs: `$(IntDir)$(ProjectName).pdb`.
|
||||
compilePdbPath += this->GeneratorTarget->GetName();
|
||||
@@ -188,10 +198,10 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
|
||||
return compilePdbPath;
|
||||
}
|
||||
|
||||
std::string cmCommonTargetGenerator::GetManifests()
|
||||
std::string cmCommonTargetGenerator::GetManifests(const std::string& config)
|
||||
{
|
||||
std::vector<cmSourceFile const*> manifest_srcs;
|
||||
this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
|
||||
this->GeneratorTarget->GetManifests(manifest_srcs, config);
|
||||
|
||||
std::vector<std::string> manifests;
|
||||
manifests.reserve(manifest_srcs.size());
|
||||
|
||||
@@ -25,42 +25,50 @@ public:
|
||||
cmCommonTargetGenerator(cmGeneratorTarget* gt);
|
||||
virtual ~cmCommonTargetGenerator();
|
||||
|
||||
std::string const& GetConfigName() const;
|
||||
std::vector<std::string> const& GetConfigNames() const;
|
||||
|
||||
protected:
|
||||
// Feature query methods.
|
||||
const char* GetFeature(const std::string& feature);
|
||||
const char* GetFeature(const std::string& feature,
|
||||
const std::string& config);
|
||||
|
||||
// Helper to add flag for windows .def file.
|
||||
void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer,
|
||||
std::string& flags);
|
||||
std::string& flags, const std::string& config);
|
||||
|
||||
cmGeneratorTarget* GeneratorTarget;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalCommonGenerator* LocalCommonGenerator;
|
||||
cmGlobalCommonGenerator* GlobalCommonGenerator;
|
||||
std::string ConfigName;
|
||||
std::vector<std::string> ConfigNames;
|
||||
|
||||
void AppendFortranFormatFlags(std::string& flags,
|
||||
cmSourceFile const& source);
|
||||
|
||||
virtual void AddIncludeFlags(std::string& flags,
|
||||
std::string const& lang) = 0;
|
||||
virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
|
||||
const std::string& config) = 0;
|
||||
|
||||
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
|
||||
const char* name, bool so);
|
||||
|
||||
using ByLanguageMap = std::map<std::string, std::string>;
|
||||
std::string GetFlags(const std::string& l);
|
||||
ByLanguageMap FlagsByLanguage;
|
||||
std::string GetDefines(const std::string& l);
|
||||
ByLanguageMap DefinesByLanguage;
|
||||
std::string GetIncludes(std::string const& l);
|
||||
ByLanguageMap IncludesByLanguage;
|
||||
std::string GetManifests();
|
||||
std::string GetFlags(const std::string& l, const std::string& config);
|
||||
std::string GetDefines(const std::string& l, const std::string& config);
|
||||
std::string GetIncludes(std::string const& l, const std::string& config);
|
||||
std::string GetManifests(const std::string& config);
|
||||
|
||||
std::vector<std::string> GetLinkedTargetDirectories() const;
|
||||
std::string ComputeTargetCompilePDB() const;
|
||||
std::vector<std::string> GetLinkedTargetDirectories(
|
||||
const std::string& config) const;
|
||||
std::string ComputeTargetCompilePDB(const std::string& config) const;
|
||||
|
||||
private:
|
||||
using ByLanguageMap = std::map<std::string, std::string>;
|
||||
struct ByConfig
|
||||
{
|
||||
ByLanguageMap FlagsByLanguage;
|
||||
ByLanguageMap DefinesByLanguage;
|
||||
ByLanguageMap IncludesByLanguage;
|
||||
};
|
||||
std::map<std::string, ByConfig> Configs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -201,7 +201,9 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
|
||||
if (this->OldStyle) {
|
||||
cmd += escapeForShellOldStyle(emulator[j]);
|
||||
} else {
|
||||
cmd += this->LG->EscapeForShell(emulator[j], this->MakeVars);
|
||||
cmd +=
|
||||
this->LG->EscapeForShell(emulator[j], this->MakeVars, false, false,
|
||||
this->MakeVars && this->LG->IsNinjaMulti());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +224,9 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
|
||||
if (this->OldStyle) {
|
||||
cmd += escapeForShellOldStyle(arg);
|
||||
} else {
|
||||
cmd += this->LG->EscapeForShell(arg, this->MakeVars);
|
||||
cmd +=
|
||||
this->LG->EscapeForShell(arg, this->MakeVars, false, false,
|
||||
this->MakeVars && this->LG->IsNinjaMulti());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
|
||||
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
|
||||
|
||||
cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
|
||||
cmTarget::VisibilityNormal, tgt->Target->GetMakefile());
|
||||
cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
|
||||
true);
|
||||
|
||||
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
|
||||
|
||||
|
||||
@@ -649,6 +649,7 @@ void cmGeneratorTarget::ClearSourcesCache()
|
||||
this->KindedSourcesMap.clear();
|
||||
this->LinkImplementationLanguageIsContextDependent = true;
|
||||
this->Objects.clear();
|
||||
this->VisitedConfigsForObjects.clear();
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before)
|
||||
@@ -738,7 +739,7 @@ void cmGeneratorTarget::GetObjectSources(
|
||||
{
|
||||
IMPLEMENT_VISIT(SourceKindObjectSource);
|
||||
|
||||
if (!this->Objects.empty()) {
|
||||
if (this->VisitedConfigsForObjects.count(config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -747,16 +748,17 @@ void cmGeneratorTarget::GetObjectSources(
|
||||
}
|
||||
|
||||
this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
|
||||
this->VisitedConfigsForObjects.insert(config);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::ComputeObjectMapping()
|
||||
{
|
||||
if (!this->Objects.empty()) {
|
||||
auto const& configs = this->Makefile->GetGeneratorConfigs();
|
||||
std::set<std::string> configSet(configs.begin(), configs.end());
|
||||
if (configSet == this->VisitedConfigsForObjects) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> const& configs =
|
||||
this->Makefile->GetGeneratorConfigs();
|
||||
for (std::string const& c : configs) {
|
||||
std::vector<cmSourceFile const*> sourceFiles;
|
||||
this->GetObjectSources(sourceFiles, c);
|
||||
|
||||
@@ -767,6 +767,7 @@ private:
|
||||
};
|
||||
using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>;
|
||||
SourceEntriesType SourceDepends;
|
||||
mutable std::set<std::string> VisitedConfigsForObjects;
|
||||
mutable std::map<cmSourceFile const*, std::string> Objects;
|
||||
std::set<cmSourceFile const*> ExplicitObjectName;
|
||||
mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache;
|
||||
|
||||
@@ -2476,6 +2476,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
|
||||
}
|
||||
GlobalTargetInfo gti;
|
||||
gti.Name = editCacheTargetName;
|
||||
gti.PerConfig = false;
|
||||
cmCustomCommandLine singleLine;
|
||||
|
||||
// Use generator preference for the edit_cache rule if it is defined.
|
||||
@@ -2510,6 +2511,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
|
||||
gti.Name = rebuildCacheTargetName;
|
||||
gti.Message = "Running CMake to regenerate build system...";
|
||||
gti.UsesTerminal = true;
|
||||
gti.PerConfig = false;
|
||||
cmCustomCommandLine singleLine;
|
||||
singleLine.push_back(cmSystemTools::GetCMakeCommand());
|
||||
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
|
||||
@@ -2654,7 +2656,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
|
||||
{
|
||||
// Package
|
||||
cmTarget target(gti.Name, cmStateEnums::GLOBAL_TARGET,
|
||||
cmTarget::VisibilityNormal, mf);
|
||||
cmTarget::VisibilityNormal, mf, gti.PerConfig);
|
||||
target.SetProperty("EXCLUDE_FROM_ALL", "TRUE");
|
||||
|
||||
std::vector<std::string> no_outputs;
|
||||
|
||||
@@ -479,6 +479,11 @@ public:
|
||||
|
||||
int RecursionDepth;
|
||||
|
||||
virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const
|
||||
{
|
||||
configs.emplace_back("$<CONFIG>");
|
||||
}
|
||||
|
||||
protected:
|
||||
// for a project collect all its targets by following depend
|
||||
// information, and also collect all the targets
|
||||
@@ -527,6 +532,7 @@ protected:
|
||||
std::vector<std::string> Depends;
|
||||
std::string WorkingDir;
|
||||
bool UsesTerminal = false;
|
||||
bool PerConfig = true;
|
||||
};
|
||||
|
||||
void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
|
||||
|
||||
+489
-125
@@ -115,6 +115,11 @@ std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit)
|
||||
std::string result = lit;
|
||||
cmSystemTools::ReplaceString(result, "$", "$$");
|
||||
cmSystemTools::ReplaceString(result, "\n", "$\n");
|
||||
if (this->IsMultiConfig()) {
|
||||
cmSystemTools::ReplaceString(result,
|
||||
cmStrCat('$', this->GetCMakeCFGIntDir()),
|
||||
this->GetCMakeCFGIntDir());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -249,8 +254,8 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
|
||||
const std::string& command, const std::string& description,
|
||||
const std::string& comment, const std::string& depfile,
|
||||
const std::string& job_pool, bool uses_terminal, bool restat,
|
||||
const cmNinjaDeps& outputs, const cmNinjaDeps& explicitDeps,
|
||||
const cmNinjaDeps& orderOnlyDeps)
|
||||
const cmNinjaDeps& outputs, const std::string& config,
|
||||
const cmNinjaDeps& explicitDeps, const cmNinjaDeps& orderOnlyDeps)
|
||||
{
|
||||
this->AddCustomCommandRule();
|
||||
|
||||
@@ -283,7 +288,11 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
|
||||
if (!depfile.empty()) {
|
||||
vars["depfile"] = depfile;
|
||||
}
|
||||
this->WriteBuild(*this->BuildFileStream, build);
|
||||
if (config.empty()) {
|
||||
this->WriteBuild(*this->GetCommonFileStream(), build);
|
||||
} else {
|
||||
this->WriteBuild(*this->GetConfigFileStream(config), build);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->ComputingUnknownDependencies) {
|
||||
@@ -305,14 +314,15 @@ void cmGlobalNinjaGenerator::AddMacOSXContentRule()
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(std::string input,
|
||||
std::string output)
|
||||
std::string output,
|
||||
const std::string& config)
|
||||
{
|
||||
this->AddMacOSXContentRule();
|
||||
{
|
||||
cmNinjaBuild build("COPY_OSX_CONTENT");
|
||||
build.Outputs.push_back(std::move(output));
|
||||
build.ExplicitDeps.push_back(std::move(input));
|
||||
this->WriteBuild(*this->BuildFileStream, build);
|
||||
this->WriteBuild(*this->GetConfigFileStream(config), build);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,14 +483,16 @@ void cmGlobalNinjaGenerator::Generate()
|
||||
msg.str());
|
||||
return;
|
||||
}
|
||||
if (!this->OpenBuildFileStream()) {
|
||||
if (!this->OpenBuildFileStreams()) {
|
||||
return;
|
||||
}
|
||||
if (!this->OpenRulesFileStream()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->TargetDependsClosures.clear();
|
||||
for (auto& it : this->Configs) {
|
||||
it.second.TargetDependsClosures.clear();
|
||||
}
|
||||
|
||||
this->InitOutputPathPrefix();
|
||||
this->TargetAll = this->NinjaOutputPath("all");
|
||||
@@ -496,19 +508,26 @@ void cmGlobalNinjaGenerator::Generate()
|
||||
this->cmGlobalGenerator::Generate();
|
||||
|
||||
this->WriteAssumedSourceDependencies();
|
||||
this->WriteTargetAliases(*this->BuildFileStream);
|
||||
this->WriteFolderTargets(*this->BuildFileStream);
|
||||
this->WriteUnknownExplicitDependencies(*this->BuildFileStream);
|
||||
this->WriteBuiltinTargets(*this->BuildFileStream);
|
||||
this->WriteTargetAliases(*this->GetCommonFileStream());
|
||||
this->WriteFolderTargets(*this->GetCommonFileStream());
|
||||
this->WriteUnknownExplicitDependencies(*this->GetCommonFileStream());
|
||||
this->WriteBuiltinTargets(*this->GetCommonFileStream());
|
||||
|
||||
if (cmSystemTools::GetErrorOccuredFlag()) {
|
||||
this->RulesFileStream->setstate(std::ios::failbit);
|
||||
this->BuildFileStream->setstate(std::ios::failbit);
|
||||
for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
|
||||
this->GetConfigFileStream(config)->setstate(std::ios::failbit);
|
||||
}
|
||||
this->GetCommonFileStream()->setstate(std::ios::failbit);
|
||||
}
|
||||
|
||||
this->CloseCompileCommandsStream();
|
||||
this->CloseRulesFileStream();
|
||||
this->CloseBuildFileStream();
|
||||
this->CloseBuildFileStreams();
|
||||
|
||||
if (!this->WriteDefaultBuildFile()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
|
||||
@@ -612,6 +631,17 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
|
||||
void cmGlobalNinjaGenerator::EnableLanguage(
|
||||
std::vector<std::string> const& langs, cmMakefile* mf, bool optional)
|
||||
{
|
||||
if (this->IsMultiConfig()) {
|
||||
if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
|
||||
mf->AddCacheDefinition(
|
||||
"CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo",
|
||||
"Semicolon separated list of supported configuration types, only "
|
||||
"supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything "
|
||||
"else will be ignored",
|
||||
cmStateEnums::STRING);
|
||||
}
|
||||
}
|
||||
|
||||
this->cmGlobalGenerator::EnableLanguage(langs, mf, optional);
|
||||
for (std::string const& l : langs) {
|
||||
if (l == "NONE") {
|
||||
@@ -653,7 +683,7 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
|
||||
cmGlobalNinjaGenerator::GenerateBuildCommand(
|
||||
const std::string& makeProgram, const std::string& /*projectName*/,
|
||||
const std::string& /*projectDir*/,
|
||||
std::vector<std::string> const& targetNames, const std::string& /*config*/,
|
||||
std::vector<std::string> const& targetNames, const std::string& config,
|
||||
bool /*fast*/, int jobs, bool verbose,
|
||||
std::vector<std::string> const& makeOptions)
|
||||
{
|
||||
@@ -669,6 +699,9 @@ cmGlobalNinjaGenerator::GenerateBuildCommand(
|
||||
makeCommand.Add("-j", std::to_string(jobs));
|
||||
}
|
||||
|
||||
this->AppendNinjaFileArgument(makeCommand,
|
||||
config.empty() ? "Debug" : config);
|
||||
|
||||
makeCommand.Add(makeOptions.begin(), makeOptions.end());
|
||||
for (const auto& tname : targetNames) {
|
||||
if (!tname.empty()) {
|
||||
@@ -710,35 +743,21 @@ void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory(
|
||||
cmGeneratorTarget* gt) const
|
||||
{
|
||||
// Compute full path to object file directory for this target.
|
||||
std::string dir =
|
||||
cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
|
||||
gt->LocalGenerator->GetTargetDirectory(gt), '/');
|
||||
std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
|
||||
'/', gt->LocalGenerator->GetTargetDirectory(gt),
|
||||
'/', this->GetCMakeCFGIntDir(), '/');
|
||||
gt->ObjectDirectory = dir;
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
||||
bool cmGlobalNinjaGenerator::OpenBuildFileStream()
|
||||
bool cmGlobalNinjaGenerator::OpenBuildFileStreams()
|
||||
{
|
||||
// Compute Ninja's build file path.
|
||||
std::string buildFilePath =
|
||||
cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
|
||||
cmGlobalNinjaGenerator::NINJA_BUILD_FILE);
|
||||
|
||||
// Get a stream where to generate things.
|
||||
if (!this->BuildFileStream) {
|
||||
this->BuildFileStream = cm::make_unique<cmGeneratedFileStream>(
|
||||
buildFilePath, false, this->GetMakefileEncoding());
|
||||
if (!(*this->BuildFileStream)) {
|
||||
// An error message is generated by the constructor if it cannot
|
||||
// open the file.
|
||||
return false;
|
||||
}
|
||||
if (!this->OpenFileStream(this->BuildFileStream,
|
||||
cmGlobalNinjaGenerator::NINJA_BUILD_FILE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the do not edit header.
|
||||
this->WriteDisclaimer(*this->BuildFileStream);
|
||||
|
||||
// Write a comment about this file.
|
||||
*this->BuildFileStream
|
||||
<< "# This file contains all the build statements describing the\n"
|
||||
@@ -747,7 +766,30 @@ bool cmGlobalNinjaGenerator::OpenBuildFileStream()
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::CloseBuildFileStream()
|
||||
bool cmGlobalNinjaGenerator::OpenFileStream(
|
||||
std::unique_ptr<cmGeneratedFileStream>& stream, const std::string& name)
|
||||
{
|
||||
// Get a stream where to generate things.
|
||||
if (!stream) {
|
||||
// Compute Ninja's build file path.
|
||||
std::string path =
|
||||
cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/', name);
|
||||
stream = cm::make_unique<cmGeneratedFileStream>(
|
||||
path, false, this->GetMakefileEncoding());
|
||||
if (!(*stream)) {
|
||||
// An error message is generated by the constructor if it cannot
|
||||
// open the file.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the do not edit header.
|
||||
this->WriteDisclaimer(*stream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::CloseBuildFileStreams()
|
||||
{
|
||||
if (this->BuildFileStream) {
|
||||
this->BuildFileStream.reset();
|
||||
@@ -758,25 +800,11 @@ void cmGlobalNinjaGenerator::CloseBuildFileStream()
|
||||
|
||||
bool cmGlobalNinjaGenerator::OpenRulesFileStream()
|
||||
{
|
||||
// Compute Ninja's build file path.
|
||||
std::string rulesFilePath =
|
||||
cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
|
||||
cmGlobalNinjaGenerator::NINJA_RULES_FILE);
|
||||
|
||||
// Get a stream where to generate things.
|
||||
if (!this->RulesFileStream) {
|
||||
this->RulesFileStream = cm::make_unique<cmGeneratedFileStream>(
|
||||
rulesFilePath, false, this->GetMakefileEncoding());
|
||||
if (!(*this->RulesFileStream)) {
|
||||
// An error message is generated by the constructor if it cannot
|
||||
// open the file.
|
||||
return false;
|
||||
}
|
||||
if (!this->OpenFileStream(this->RulesFileStream,
|
||||
cmGlobalNinjaGenerator::NINJA_RULES_FILE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the do not edit header.
|
||||
this->WriteDisclaimer(*this->RulesFileStream);
|
||||
|
||||
// Write comment about this file.
|
||||
/* clang-format off */
|
||||
*this->RulesFileStream
|
||||
@@ -834,9 +862,10 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
|
||||
.first->second;
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName)
|
||||
void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName,
|
||||
const std::string& config)
|
||||
{
|
||||
this->AdditionalCleanFiles.emplace(std::move(fileName));
|
||||
this->Configs[config].AdditionalCleanFiles.emplace(std::move(fileName));
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
|
||||
@@ -904,23 +933,22 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
|
||||
"Assume dependencies for generated source file.",
|
||||
/*depfile*/ "", /*job_pool*/ "",
|
||||
/*uses_terminal*/ false,
|
||||
/*restat*/ true, cmNinjaDeps(1, asd.first),
|
||||
/*restat*/ true, cmNinjaDeps(1, asd.first), "",
|
||||
cmNinjaDeps(), orderOnlyDeps);
|
||||
}
|
||||
}
|
||||
|
||||
std::string OrderDependsTargetForTarget(cmGeneratorTarget const* target)
|
||||
std::string cmGlobalNinjaGenerator::OrderDependsTargetForTarget(
|
||||
cmGeneratorTarget const* target, const std::string& config)
|
||||
{
|
||||
return "cmake_object_order_depends_target_" + target->GetName();
|
||||
return "cmake_object_order_depends_target_" + target->GetName() + "_" +
|
||||
config;
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AppendTargetOutputs(
|
||||
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
|
||||
cmNinjaTargetDepends depends)
|
||||
const std::string& config, cmNinjaTargetDepends depends)
|
||||
{
|
||||
std::string configName =
|
||||
target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
|
||||
|
||||
// for frameworks, we want the real name, not smple name
|
||||
// frameworks always appear versioned, and the build.ninja
|
||||
// will always attempt to manage symbolic links instead
|
||||
@@ -932,19 +960,19 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
|
||||
case cmStateEnums::STATIC_LIBRARY:
|
||||
case cmStateEnums::MODULE_LIBRARY: {
|
||||
if (depends == DependOnTargetOrdering) {
|
||||
outputs.push_back(OrderDependsTargetForTarget(target));
|
||||
outputs.push_back(OrderDependsTargetForTarget(target, config));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case cmStateEnums::EXECUTABLE: {
|
||||
outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
|
||||
configName, cmStateEnums::RuntimeBinaryArtifact, realname)));
|
||||
config, cmStateEnums::RuntimeBinaryArtifact, realname)));
|
||||
break;
|
||||
}
|
||||
case cmStateEnums::OBJECT_LIBRARY: {
|
||||
if (depends == DependOnTargetOrdering) {
|
||||
outputs.push_back(OrderDependsTargetForTarget(target));
|
||||
outputs.push_back(OrderDependsTargetForTarget(target, config));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -954,7 +982,11 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
|
||||
std::string path =
|
||||
target->GetLocalGenerator()->GetCurrentBinaryDirectory() +
|
||||
std::string("/") + target->GetName();
|
||||
outputs.push_back(this->ConvertToNinjaPath(path));
|
||||
std::string output = this->ConvertToNinjaPath(path);
|
||||
if (target->Target->IsPerConfig()) {
|
||||
output = this->BuildAlias(output, config);
|
||||
}
|
||||
outputs.push_back(output);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -965,6 +997,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
|
||||
|
||||
void cmGlobalNinjaGenerator::AppendTargetDepends(
|
||||
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
|
||||
const std::string& config, const std::string& fileConfig,
|
||||
cmNinjaTargetDepends depends)
|
||||
{
|
||||
if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
|
||||
@@ -973,7 +1006,7 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
|
||||
std::string d =
|
||||
target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" +
|
||||
util.Value;
|
||||
outputs.push_back(this->ConvertToNinjaPath(d));
|
||||
outputs.push_back(this->BuildAlias(this->ConvertToNinjaPath(d), config));
|
||||
}
|
||||
} else {
|
||||
cmNinjaDeps outs;
|
||||
@@ -982,7 +1015,14 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
|
||||
if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
|
||||
continue;
|
||||
}
|
||||
this->AppendTargetOutputs(targetDep, outs, depends);
|
||||
// For some reason, object libraries show up as "utility" dependencies
|
||||
// even though they're used for linking. Treat them as link dependencies.
|
||||
if (targetDep.IsUtil() &&
|
||||
targetDep->GetType() != cmStateEnums::OBJECT_LIBRARY) {
|
||||
this->AppendTargetOutputs(targetDep, outs, fileConfig, depends);
|
||||
} else {
|
||||
this->AppendTargetOutputs(targetDep, outs, config, depends);
|
||||
}
|
||||
}
|
||||
std::sort(outs.begin(), outs.end());
|
||||
cmAppend(outputs, outs);
|
||||
@@ -990,21 +1030,24 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
|
||||
cmGeneratorTarget const* target, cmNinjaDeps& outputs)
|
||||
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
|
||||
const std::string& config)
|
||||
{
|
||||
cmNinjaOuts outs;
|
||||
this->AppendTargetDependsClosure(target, outs, true);
|
||||
this->AppendTargetDependsClosure(target, outs, config, true);
|
||||
cmAppend(outputs, outs);
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
|
||||
cmGeneratorTarget const* target, cmNinjaOuts& outputs, bool omit_self)
|
||||
cmGeneratorTarget const* target, cmNinjaOuts& outputs,
|
||||
const std::string& config, bool omit_self)
|
||||
{
|
||||
|
||||
// try to locate the target in the cache
|
||||
auto find = this->TargetDependsClosures.lower_bound(target);
|
||||
auto find = this->Configs[config].TargetDependsClosures.lower_bound(target);
|
||||
|
||||
if (find == this->TargetDependsClosures.end() || find->first != target) {
|
||||
if (find == this->Configs[config].TargetDependsClosures.end() ||
|
||||
find->first != target) {
|
||||
// We now calculate the closure outputs by inspecting the dependent
|
||||
// targets recursively.
|
||||
// For that we have to distinguish between a local result set that is only
|
||||
@@ -1019,10 +1062,10 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
|
||||
}
|
||||
|
||||
// Collect the dependent targets for _this_ target
|
||||
this->AppendTargetDependsClosure(dep_target, this_outs, false);
|
||||
this->AppendTargetDependsClosure(dep_target, this_outs, config, false);
|
||||
}
|
||||
find = this->TargetDependsClosures.emplace_hint(find, target,
|
||||
std::move(this_outs));
|
||||
find = this->Configs[config].TargetDependsClosures.emplace_hint(
|
||||
find, target, std::move(this_outs));
|
||||
}
|
||||
|
||||
// now fill the outputs of the final result from the newly generated cache
|
||||
@@ -1032,29 +1075,48 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
|
||||
// finally generate the outputs of the target itself, if applicable
|
||||
cmNinjaDeps outs;
|
||||
if (!omit_self) {
|
||||
this->AppendTargetOutputs(target, outs);
|
||||
this->AppendTargetOutputs(target, outs, config);
|
||||
}
|
||||
outputs.insert(outs.begin(), outs.end());
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
|
||||
cmGeneratorTarget* target)
|
||||
cmGeneratorTarget* target,
|
||||
const std::string& config)
|
||||
{
|
||||
std::string buildAlias = this->NinjaOutputPath(alias);
|
||||
std::string outputPath = this->NinjaOutputPath(alias);
|
||||
std::string buildAlias = this->BuildAlias(outputPath, config);
|
||||
cmNinjaDeps outputs;
|
||||
this->AppendTargetOutputs(target, outputs);
|
||||
// Mark the target's outputs as ambiguous to ensure that no other target uses
|
||||
// the output as an alias.
|
||||
this->AppendTargetOutputs(target, outputs, config);
|
||||
// Mark the target's outputs as ambiguous to ensure that no other target
|
||||
// uses the output as an alias.
|
||||
for (std::string const& output : outputs) {
|
||||
TargetAliases[output] = nullptr;
|
||||
this->TargetAliases[output].GeneratorTarget = nullptr;
|
||||
for (const std::string& config2 :
|
||||
this->Makefiles.front()->GetGeneratorConfigs()) {
|
||||
this->Configs[config2].TargetAliases[output].GeneratorTarget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the alias into the map. If the alias was already present in the
|
||||
// map and referred to another target, mark it as ambiguous.
|
||||
std::pair<TargetAliasMap::iterator, bool> newAlias =
|
||||
TargetAliases.insert(std::make_pair(buildAlias, target));
|
||||
if (newAlias.second && newAlias.first->second != target) {
|
||||
newAlias.first->second = nullptr;
|
||||
TargetAlias ta;
|
||||
ta.GeneratorTarget = target;
|
||||
ta.Config = config;
|
||||
std::pair<TargetAliasMap::iterator, bool> newAliasGlobal =
|
||||
this->TargetAliases.insert(std::make_pair(buildAlias, ta));
|
||||
if (newAliasGlobal.second &&
|
||||
newAliasGlobal.first->second.GeneratorTarget != target) {
|
||||
newAliasGlobal.first->second.GeneratorTarget = nullptr;
|
||||
}
|
||||
if (config != "all") {
|
||||
std::pair<TargetAliasMap::iterator, bool> newAliasConfig =
|
||||
this->Configs[config].TargetAliases.insert(
|
||||
std::make_pair(outputPath, ta));
|
||||
if (newAliasConfig.second &&
|
||||
newAliasConfig.first->second.GeneratorTarget != target) {
|
||||
newAliasConfig.first->second.GeneratorTarget = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1064,10 +1126,10 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
|
||||
os << "# Target aliases.\n\n";
|
||||
|
||||
cmNinjaBuild build("phony");
|
||||
build.Outputs.emplace_back("");
|
||||
for (auto const& ta : TargetAliases) {
|
||||
build.Outputs.emplace_back();
|
||||
for (auto const& ta : this->TargetAliases) {
|
||||
// Don't write ambiguous aliases.
|
||||
if (!ta.second) {
|
||||
if (!ta.second.GeneratorTarget) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1077,14 +1139,43 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Outputs
|
||||
build.Outputs[0] = ta.first;
|
||||
// Explicit depdendencies
|
||||
build.Outputs.front() = ta.first;
|
||||
build.ExplicitDeps.clear();
|
||||
this->AppendTargetOutputs(ta.second, build.ExplicitDeps);
|
||||
// Write
|
||||
if (ta.second.Config == "all") {
|
||||
for (auto const& config :
|
||||
ta.second.GeneratorTarget->Makefile->GetGeneratorConfigs()) {
|
||||
this->AppendTargetOutputs(ta.second.GeneratorTarget,
|
||||
build.ExplicitDeps, config);
|
||||
}
|
||||
} else {
|
||||
this->AppendTargetOutputs(ta.second.GeneratorTarget, build.ExplicitDeps,
|
||||
ta.second.Config);
|
||||
}
|
||||
this->WriteBuild(os, build);
|
||||
}
|
||||
|
||||
if (this->IsMultiConfig()) {
|
||||
for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
|
||||
for (auto const& ta : this->Configs[config].TargetAliases) {
|
||||
// Don't write ambiguous aliases.
|
||||
if (!ta.second.GeneratorTarget) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't write alias if there is a already a custom command with
|
||||
// matching output
|
||||
if (this->HasCustomCommandOutput(ta.first)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
build.Outputs.front() = ta.first;
|
||||
build.ExplicitDeps.clear();
|
||||
this->AppendTargetOutputs(ta.second.GeneratorTarget,
|
||||
build.ExplicitDeps, config);
|
||||
this->WriteBuild(*this->GetConfigFileStream(config), build);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
|
||||
@@ -1100,24 +1191,58 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
|
||||
cmGlobalNinjaGenerator::WriteDivider(os);
|
||||
std::string const& currentBinaryDir = it.first;
|
||||
DirectoryTarget const& dt = it.second;
|
||||
std::vector<std::string> configs;
|
||||
dt.LG->GetMakefile()->GetConfigurations(configs, true);
|
||||
if (configs.empty()) {
|
||||
configs.emplace_back();
|
||||
}
|
||||
|
||||
// Setup target
|
||||
cmNinjaDeps configDeps;
|
||||
build.Comment = "Folder: " + currentBinaryDir;
|
||||
build.Outputs.emplace_back(
|
||||
this->ConvertToNinjaPath(currentBinaryDir + "/all"));
|
||||
for (DirectoryTarget::Target const& t : dt.Targets) {
|
||||
if (!t.ExcludeFromAll) {
|
||||
this->AppendTargetOutputs(t.GT, build.ExplicitDeps);
|
||||
build.Outputs.emplace_back();
|
||||
for (auto const& config : configs) {
|
||||
build.ExplicitDeps.clear();
|
||||
build.Outputs.front() = this->BuildAlias(
|
||||
this->ConvertToNinjaPath(currentBinaryDir + "/all"), config);
|
||||
configDeps.emplace_back(build.Outputs.front());
|
||||
for (DirectoryTarget::Target const& t : dt.Targets) {
|
||||
if (!t.ExcludeFromAll) {
|
||||
this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config);
|
||||
}
|
||||
}
|
||||
for (DirectoryTarget::Dir const& d : dt.Children) {
|
||||
if (!d.ExcludeFromAll) {
|
||||
build.ExplicitDeps.emplace_back(this->BuildAlias(
|
||||
this->ConvertToNinjaPath(d.Path + "/all"), config));
|
||||
}
|
||||
}
|
||||
// Write target
|
||||
this->WriteBuild(os, build);
|
||||
}
|
||||
|
||||
// Add shortcut target
|
||||
if (this->IsMultiConfig()) {
|
||||
for (auto const& config : configs) {
|
||||
build.ExplicitDeps = { this->BuildAlias(
|
||||
this->ConvertToNinjaPath(currentBinaryDir + "/all"), config) };
|
||||
build.Outputs.front() =
|
||||
this->ConvertToNinjaPath(currentBinaryDir + "/all");
|
||||
this->WriteBuild(*this->GetConfigFileStream(config), build);
|
||||
}
|
||||
}
|
||||
for (DirectoryTarget::Dir const& d : dt.Children) {
|
||||
if (!d.ExcludeFromAll) {
|
||||
build.ExplicitDeps.emplace_back(
|
||||
this->ConvertToNinjaPath(d.Path + "/all"));
|
||||
|
||||
// Add target for all configs
|
||||
if (this->IsMultiConfig()) {
|
||||
build.ExplicitDeps.clear();
|
||||
for (auto const& config : configs) {
|
||||
build.ExplicitDeps.push_back(this->BuildAlias(
|
||||
this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
|
||||
}
|
||||
build.Outputs.front() = this->BuildAlias(
|
||||
this->ConvertToNinjaPath(currentBinaryDir + "/all"), "all");
|
||||
this->WriteBuild(*this->GetCommonFileStream(), build);
|
||||
}
|
||||
// Write target
|
||||
this->WriteBuild(os, build);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1250,10 +1375,13 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
|
||||
cmGlobalNinjaGenerator::WriteDivider(os);
|
||||
os << "# Built-in targets\n\n";
|
||||
|
||||
this->WriteTargetDefault(os);
|
||||
this->WriteTargetRebuildManifest(os);
|
||||
this->WriteTargetClean(os);
|
||||
this->WriteTargetHelp(os);
|
||||
|
||||
for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
|
||||
this->WriteTargetDefault(*this->GetConfigFileStream(config));
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::WriteTargetDefault(std::ostream& os)
|
||||
@@ -1290,7 +1418,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
|
||||
|
||||
cmNinjaBuild reBuild("RERUN_CMAKE");
|
||||
reBuild.Comment = "Re-run CMake if any of its inputs changed.";
|
||||
reBuild.Outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
|
||||
this->AddRebuildManifestOutputs(reBuild.Outputs);
|
||||
|
||||
for (const auto& localGen : this->LocalGenerators) {
|
||||
for (std::string const& fi : localGen->GetMakefile()->GetListFiles()) {
|
||||
@@ -1420,9 +1548,23 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
|
||||
std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
|
||||
std::string cleanScriptAbs =
|
||||
cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
|
||||
std::vector<std::string> configs;
|
||||
this->Makefiles[0]->GetConfigurations(configs, true);
|
||||
if (configs.empty()) {
|
||||
configs.emplace_back();
|
||||
}
|
||||
|
||||
// Check if there are additional files to clean
|
||||
if (this->AdditionalCleanFiles.empty()) {
|
||||
bool empty = true;
|
||||
for (auto const& config : configs) {
|
||||
auto const it = this->Configs.find(config);
|
||||
if (it != this->Configs.end() &&
|
||||
!it->second.AdditionalCleanFiles.empty()) {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (empty) {
|
||||
// Remove cmake clean script file if it exists
|
||||
cmSystemTools::RemoveFile(cleanScriptAbs);
|
||||
return false;
|
||||
@@ -1434,14 +1576,23 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
|
||||
if (!fout) {
|
||||
return false;
|
||||
}
|
||||
fout << "# Additional clean files\n\n";
|
||||
fout << "file(REMOVE_RECURSE\n";
|
||||
for (std::string const& acf : this->AdditionalCleanFiles) {
|
||||
fout << " "
|
||||
<< cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf))
|
||||
<< '\n';
|
||||
fout << "# Additional clean files\ncmake_minimum_required(VERSION 3.16)\n";
|
||||
for (auto const& config : configs) {
|
||||
auto const it = this->Configs.find(config);
|
||||
if (it != this->Configs.end() &&
|
||||
!it->second.AdditionalCleanFiles.empty()) {
|
||||
fout << "\nif(\"${CONFIG}\" STREQUAL \"\" OR \"${CONFIG}\" STREQUAL \""
|
||||
<< config << "\")\n";
|
||||
fout << " file(REMOVE_RECURSE\n";
|
||||
for (std::string const& acf : it->second.AdditionalCleanFiles) {
|
||||
fout << " "
|
||||
<< cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf))
|
||||
<< '\n';
|
||||
}
|
||||
fout << " )\n";
|
||||
fout << "endif()\n";
|
||||
}
|
||||
}
|
||||
fout << ")\n";
|
||||
}
|
||||
// Register clean script file
|
||||
lgr->GetMakefile()->AddCMakeOutputFile(cleanScriptAbs);
|
||||
@@ -1450,7 +1601,7 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
|
||||
{
|
||||
cmNinjaRule rule("CLEAN_ADDITIONAL");
|
||||
rule.Command = cmStrCat(
|
||||
CMakeCmd(), " -P ",
|
||||
CMakeCmd(), " -DCONFIG=$CONFIG -P ",
|
||||
lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel),
|
||||
cmOutputConverter::SHELL));
|
||||
rule.Description = "Cleaning additional files...";
|
||||
@@ -1462,9 +1613,19 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
|
||||
{
|
||||
cmNinjaBuild build("CLEAN_ADDITIONAL");
|
||||
build.Comment = "Clean additional files.";
|
||||
build.Outputs.push_back(
|
||||
this->NinjaOutputPath(this->GetAdditionalCleanTargetName()));
|
||||
WriteBuild(os, build);
|
||||
build.Outputs.emplace_back();
|
||||
for (auto const& config : configs) {
|
||||
build.Outputs.front() = this->BuildAlias(
|
||||
this->NinjaOutputPath(this->GetAdditionalCleanTargetName()), config);
|
||||
build.Variables["CONFIG"] = config;
|
||||
WriteBuild(os, build);
|
||||
}
|
||||
if (this->IsMultiConfig()) {
|
||||
build.Outputs.front() =
|
||||
this->NinjaOutputPath(this->GetAdditionalCleanTargetName());
|
||||
build.Variables["CONFIG"] = "";
|
||||
WriteBuild(os, build);
|
||||
}
|
||||
}
|
||||
// Return success
|
||||
return true;
|
||||
@@ -1479,22 +1640,91 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
|
||||
// Write rule
|
||||
{
|
||||
cmNinjaRule rule("CLEAN");
|
||||
rule.Command = NinjaCmd() + " -t clean";
|
||||
rule.Command = NinjaCmd() + " $FILE_ARG -t clean $TARGETS";
|
||||
rule.Description = "Cleaning all built files...";
|
||||
rule.Comment = "Rule for cleaning all built files.";
|
||||
WriteRule(*this->RulesFileStream, rule);
|
||||
}
|
||||
|
||||
auto const configs = this->Makefiles.front()->GetGeneratorConfigs();
|
||||
|
||||
// Write build
|
||||
{
|
||||
cmNinjaBuild build("CLEAN");
|
||||
build.Comment = "Clean all the built files.";
|
||||
build.Outputs.push_back(this->NinjaOutputPath(this->GetCleanTargetName()));
|
||||
if (additionalFiles) {
|
||||
build.ExplicitDeps.push_back(
|
||||
this->NinjaOutputPath(this->GetAdditionalCleanTargetName()));
|
||||
build.Outputs.emplace_back();
|
||||
|
||||
for (auto const& config : configs) {
|
||||
build.Outputs.front() = this->BuildAlias(
|
||||
this->NinjaOutputPath(this->GetCleanTargetName()), config);
|
||||
if (this->IsMultiConfig()) {
|
||||
build.Variables["TARGETS"] =
|
||||
cmStrCat(this->BuildAlias(GetByproductsForCleanTargetName(), config),
|
||||
" ", GetByproductsForCleanTargetName());
|
||||
}
|
||||
build.ExplicitDeps.clear();
|
||||
if (additionalFiles) {
|
||||
build.ExplicitDeps.push_back(this->BuildAlias(
|
||||
this->NinjaOutputPath(this->GetAdditionalCleanTargetName()),
|
||||
config));
|
||||
}
|
||||
for (auto const& fileConfig : configs) {
|
||||
if (this->IsMultiConfig()) {
|
||||
build.Variables["FILE_ARG"] = cmStrCat(
|
||||
"-f ", cmGlobalNinjaMultiGenerator::GetNinjaFilename(fileConfig));
|
||||
}
|
||||
this->WriteBuild(*this->GetConfigFileStream(fileConfig), build);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->IsMultiConfig()) {
|
||||
build.Outputs.front() = this->BuildAlias(
|
||||
this->NinjaOutputPath(this->GetCleanTargetName()), "all");
|
||||
build.ExplicitDeps.clear();
|
||||
|
||||
if (additionalFiles) {
|
||||
build.ExplicitDeps.push_back(
|
||||
this->NinjaOutputPath(this->GetAdditionalCleanTargetName()));
|
||||
}
|
||||
|
||||
build.Variables["TARGETS"] = "";
|
||||
|
||||
for (auto const& fileConfig : configs) {
|
||||
build.Variables["FILE_ARG"] = cmStrCat(
|
||||
"-f ", cmGlobalNinjaMultiGenerator::GetNinjaFilename(fileConfig));
|
||||
this->WriteBuild(*this->GetConfigFileStream(fileConfig), build);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->IsMultiConfig()) {
|
||||
cmNinjaBuild build("phony");
|
||||
build.Outputs.emplace_back(
|
||||
this->NinjaOutputPath(this->GetCleanTargetName()));
|
||||
build.ExplicitDeps.emplace_back();
|
||||
|
||||
for (auto const& config : configs) {
|
||||
build.ExplicitDeps.front() = this->BuildAlias(
|
||||
this->NinjaOutputPath(this->GetCleanTargetName()), config);
|
||||
this->WriteBuild(*this->GetConfigFileStream(config), build);
|
||||
}
|
||||
}
|
||||
|
||||
// Write byproducts
|
||||
if (this->IsMultiConfig()) {
|
||||
cmNinjaBuild build("phony");
|
||||
build.Comment = "Clean byproducts.";
|
||||
build.Outputs.emplace_back(
|
||||
this->ConvertToNinjaPath(GetByproductsForCleanTargetName()));
|
||||
build.ExplicitDeps = this->ByproductsForCleanTarget;
|
||||
WriteBuild(os, build);
|
||||
|
||||
for (auto const& config : configs) {
|
||||
build.Outputs.front() = this->BuildAlias(
|
||||
this->ConvertToNinjaPath(GetByproductsForCleanTargetName()), config);
|
||||
build.ExplicitDeps = this->Configs[config].ByproductsForCleanTarget;
|
||||
WriteBuild(os, build);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2001,3 +2231,137 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::AppendDirectoryForConfig(
|
||||
const std::string& prefix, const std::string& config,
|
||||
const std::string& suffix, std::string& dir)
|
||||
{
|
||||
if (!config.empty() && this->IsMultiConfig()) {
|
||||
dir += prefix;
|
||||
dir += config;
|
||||
dir += suffix;
|
||||
}
|
||||
}
|
||||
|
||||
const char* cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE = "common.ninja";
|
||||
const char* cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION = ".ninja";
|
||||
|
||||
cmGlobalNinjaMultiGenerator::cmGlobalNinjaMultiGenerator(cmake* cm)
|
||||
: cmGlobalNinjaGenerator(cm)
|
||||
{
|
||||
cm->GetState()->SetIsGeneratorMultiConfig(true);
|
||||
cm->GetState()->SetNinjaMulti(true);
|
||||
}
|
||||
|
||||
void cmGlobalNinjaMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
|
||||
{
|
||||
entry.Name = cmGlobalNinjaMultiGenerator::GetActualName();
|
||||
entry.Brief = "Generates build-<Config>.ninja files.";
|
||||
}
|
||||
|
||||
std::string cmGlobalNinjaMultiGenerator::ExpandCFGIntDir(
|
||||
const std::string& str, const std::string& config) const
|
||||
{
|
||||
std::string result = str;
|
||||
cmSystemTools::ReplaceString(result, this->GetCMakeCFGIntDir(), config);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams()
|
||||
{
|
||||
if (!this->OpenFileStream(this->CommonFileStream,
|
||||
cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write a comment about this file.
|
||||
*this->CommonFileStream
|
||||
<< "# This file contains build statements common to all "
|
||||
"configurations.\n\n";
|
||||
|
||||
for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
|
||||
if (!this->OpenFileStream(this->ConfigFileStreams[config],
|
||||
GetNinjaFilename(config))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write a comment about this file.
|
||||
*this->ConfigFileStreams[config]
|
||||
<< "# This file contains build statements specific to the \"" << config
|
||||
<< "\"\n# configuration.\n\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGlobalNinjaMultiGenerator::CloseBuildFileStreams()
|
||||
{
|
||||
if (this->CommonFileStream) {
|
||||
this->CommonFileStream.reset();
|
||||
} else {
|
||||
cmSystemTools::Error("Common file stream was not open.");
|
||||
}
|
||||
|
||||
for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
|
||||
if (this->ConfigFileStreams[config]) {
|
||||
this->ConfigFileStreams[config].reset();
|
||||
} else {
|
||||
cmSystemTools::Error(
|
||||
cmStrCat("Config file stream for \"", config, "\" was not open."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalNinjaMultiGenerator::AppendNinjaFileArgument(
|
||||
GeneratedMakeCommand& command, const std::string& config) const
|
||||
{
|
||||
command.Add("-f");
|
||||
command.Add(GetNinjaFilename(config));
|
||||
}
|
||||
|
||||
std::string cmGlobalNinjaMultiGenerator::GetNinjaFilename(
|
||||
const std::string& config)
|
||||
{
|
||||
return cmStrCat("build-", config,
|
||||
cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
void cmGlobalNinjaMultiGenerator::AddRebuildManifestOutputs(
|
||||
cmNinjaDeps& outputs) const
|
||||
{
|
||||
for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
|
||||
outputs.push_back(this->NinjaOutputPath(GetNinjaFilename(config)));
|
||||
}
|
||||
if (this->Makefiles.front()->GetDefinition(
|
||||
"CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE")) {
|
||||
outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
|
||||
std::vector<std::string>& configs) const
|
||||
{
|
||||
auto const oldSize = configs.size();
|
||||
this->Makefiles.front()->GetConfigurations(configs);
|
||||
if (configs.size() == oldSize) {
|
||||
configs.emplace_back();
|
||||
}
|
||||
}
|
||||
|
||||
bool cmGlobalNinjaMultiGenerator::WriteDefaultBuildFile()
|
||||
{
|
||||
auto const* defaultConfig = this->Makefiles.front()->GetDefinition(
|
||||
"CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE");
|
||||
if (defaultConfig) {
|
||||
std::unique_ptr<cmGeneratedFileStream> defaultStream;
|
||||
if (!this->OpenFileStream(defaultStream, NINJA_BUILD_FILE)) {
|
||||
return false;
|
||||
}
|
||||
*defaultStream << "# This file is a convenience file generated by\n"
|
||||
<< "# CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE.\n\n"
|
||||
<< "include " << this->GetNinjaFilename(defaultConfig)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+175
-20
@@ -22,6 +22,7 @@
|
||||
#include "cmGlobalGeneratorFactory.h"
|
||||
#include "cmNinjaTypes.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
|
||||
class cmCustomCommand;
|
||||
class cmGeneratorTarget;
|
||||
@@ -73,7 +74,7 @@ public:
|
||||
static void WriteDivider(std::ostream& os);
|
||||
|
||||
static std::string EncodeRuleName(std::string const& name);
|
||||
static std::string EncodeLiteral(const std::string& lit);
|
||||
std::string EncodeLiteral(const std::string& lit);
|
||||
std::string EncodePath(const std::string& path);
|
||||
|
||||
cmLinkLineComputer* CreateLinkLineComputer(
|
||||
@@ -111,11 +112,12 @@ public:
|
||||
const std::string& command, const std::string& description,
|
||||
const std::string& comment, const std::string& depfile,
|
||||
const std::string& pool, bool uses_terminal, bool restat,
|
||||
const cmNinjaDeps& outputs,
|
||||
const cmNinjaDeps& outputs, const std::string& config,
|
||||
const cmNinjaDeps& explicitDeps = cmNinjaDeps(),
|
||||
const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
|
||||
|
||||
void WriteMacOSXContentBuild(std::string input, std::string output);
|
||||
void WriteMacOSXContentBuild(std::string input, std::string output,
|
||||
const std::string& config);
|
||||
|
||||
/**
|
||||
* Write a rule statement to @a os.
|
||||
@@ -205,7 +207,13 @@ public:
|
||||
}
|
||||
const char* GetCleanTargetName() const override { return "clean"; }
|
||||
|
||||
cmGeneratedFileStream* GetBuildFileStream() const
|
||||
virtual cmGeneratedFileStream* GetConfigFileStream(
|
||||
const std::string& /*config*/) const
|
||||
{
|
||||
return this->BuildFileStream.get();
|
||||
}
|
||||
|
||||
virtual cmGeneratedFileStream* GetCommonFileStream() const
|
||||
{
|
||||
return this->BuildFileStream.get();
|
||||
}
|
||||
@@ -232,12 +240,17 @@ public:
|
||||
MapToNinjaPathImpl MapToNinjaPath() { return { this }; }
|
||||
|
||||
// -- Additional clean files
|
||||
void AddAdditionalCleanFile(std::string fileName);
|
||||
void AddAdditionalCleanFile(std::string fileName, const std::string& config);
|
||||
const char* GetAdditionalCleanTargetName() const
|
||||
{
|
||||
return "CMakeFiles/clean.additional";
|
||||
}
|
||||
|
||||
static const char* GetByproductsForCleanTargetName()
|
||||
{
|
||||
return "CMakeFiles/cmake_byproducts_for_clean_target";
|
||||
}
|
||||
|
||||
void AddCXXCompileCommand(const std::string& commandLine,
|
||||
const std::string& sourceFile);
|
||||
|
||||
@@ -261,9 +274,9 @@ public:
|
||||
|
||||
/// Called when we have seen the given custom command. Returns true
|
||||
/// if we has seen it before.
|
||||
bool SeenCustomCommand(cmCustomCommand const* cc)
|
||||
bool SeenCustomCommand(cmCustomCommand const* cc, const std::string& config)
|
||||
{
|
||||
return !this->CustomCommands.insert(cc).second;
|
||||
return !this->Configs[config].CustomCommands.insert(cc).second;
|
||||
}
|
||||
|
||||
/// Called when we have seen the given custom command output.
|
||||
@@ -285,20 +298,43 @@ public:
|
||||
ASD.insert(deps.begin(), deps.end());
|
||||
}
|
||||
|
||||
static std::string OrderDependsTargetForTarget(
|
||||
cmGeneratorTarget const* target, const std::string& config);
|
||||
|
||||
void AppendTargetOutputs(
|
||||
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
|
||||
const std::string& config,
|
||||
cmNinjaTargetDepends depends = DependOnTargetArtifact);
|
||||
void AppendTargetDepends(
|
||||
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
|
||||
const std::string& config, const std::string& fileConfig,
|
||||
cmNinjaTargetDepends depends = DependOnTargetArtifact);
|
||||
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
|
||||
cmNinjaDeps& outputs);
|
||||
cmNinjaDeps& outputs,
|
||||
const std::string& config);
|
||||
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
|
||||
cmNinjaOuts& outputs, bool omit_self);
|
||||
cmNinjaOuts& outputs,
|
||||
const std::string& config, bool omit_self);
|
||||
|
||||
void AppendDirectoryForConfig(const std::string& prefix,
|
||||
const std::string& config,
|
||||
const std::string& suffix,
|
||||
std::string& dir) override;
|
||||
|
||||
virtual void AppendNinjaFileArgument(GeneratedMakeCommand& /*command*/,
|
||||
const std::string& /*config*/) const
|
||||
{
|
||||
}
|
||||
|
||||
virtual void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const
|
||||
{
|
||||
outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
|
||||
}
|
||||
|
||||
int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
|
||||
|
||||
void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
|
||||
void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target,
|
||||
const std::string& config);
|
||||
|
||||
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
|
||||
|
||||
@@ -331,11 +367,39 @@ public:
|
||||
std::vector<std::string> const& linked_target_dirs,
|
||||
std::string const& arg_lang);
|
||||
|
||||
virtual std::string BuildAlias(const std::string& alias,
|
||||
const std::string& /*config*/) const
|
||||
{
|
||||
return alias;
|
||||
}
|
||||
|
||||
virtual std::string ConfigDirectory(const std::string& /*config*/) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
cmNinjaDeps& GetByproductsForCleanTarget()
|
||||
{
|
||||
return this->ByproductsForCleanTarget;
|
||||
}
|
||||
|
||||
cmNinjaDeps& GetByproductsForCleanTarget(const std::string& config)
|
||||
{
|
||||
return this->Configs[config].ByproductsForCleanTarget;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Generate() override;
|
||||
|
||||
bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
|
||||
|
||||
virtual bool OpenBuildFileStreams();
|
||||
virtual void CloseBuildFileStreams();
|
||||
virtual bool WriteDefaultBuildFile() { return true; }
|
||||
|
||||
bool OpenFileStream(std::unique_ptr<cmGeneratedFileStream>& stream,
|
||||
const std::string& name);
|
||||
|
||||
private:
|
||||
std::string GetEditCacheCommand() const override;
|
||||
bool FindMakeProgram(cmMakefile* mf) override;
|
||||
@@ -344,9 +408,6 @@ private:
|
||||
cmMakefile* mf) const override;
|
||||
bool CheckFortran(cmMakefile* mf) const;
|
||||
|
||||
bool OpenBuildFileStream();
|
||||
void CloseBuildFileStream();
|
||||
|
||||
void CloseCompileCommandsStream();
|
||||
|
||||
bool OpenRulesFileStream();
|
||||
@@ -391,9 +452,6 @@ private:
|
||||
|
||||
bool UsingGCCOnWindows = false;
|
||||
|
||||
/// The set of custom commands we have seen.
|
||||
std::set<cmCustomCommand const*> CustomCommands;
|
||||
|
||||
/// The set of custom command outputs we have seen.
|
||||
std::set<std::string> CustomCommandOutputs;
|
||||
|
||||
@@ -412,11 +470,14 @@ private:
|
||||
/// The mapping from source file to assumed dependencies.
|
||||
std::map<std::string, std::set<std::string>> AssumedSourceDependencies;
|
||||
|
||||
using TargetAliasMap = std::map<std::string, cmGeneratorTarget*>;
|
||||
struct TargetAlias
|
||||
{
|
||||
cmGeneratorTarget* GeneratorTarget;
|
||||
std::string Config;
|
||||
};
|
||||
using TargetAliasMap = std::map<std::string, TargetAlias>;
|
||||
TargetAliasMap TargetAliases;
|
||||
|
||||
std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
|
||||
|
||||
/// the local cache for calls to ConvertToNinjaPath
|
||||
mutable std::unordered_map<std::string, std::string> ConvertToNinjaPathCache;
|
||||
|
||||
@@ -434,7 +495,101 @@ private:
|
||||
std::string OutputPathPrefix;
|
||||
std::string TargetAll;
|
||||
std::string CMakeCacheFile;
|
||||
std::set<std::string> AdditionalCleanFiles;
|
||||
|
||||
struct ByConfig
|
||||
{
|
||||
std::set<std::string> AdditionalCleanFiles;
|
||||
|
||||
/// The set of custom commands we have seen.
|
||||
std::set<cmCustomCommand const*> CustomCommands;
|
||||
|
||||
std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
|
||||
|
||||
TargetAliasMap TargetAliases;
|
||||
|
||||
cmNinjaDeps ByproductsForCleanTarget;
|
||||
};
|
||||
std::map<std::string, ByConfig> Configs;
|
||||
|
||||
cmNinjaDeps ByproductsForCleanTarget;
|
||||
};
|
||||
|
||||
class cmGlobalNinjaMultiGenerator : public cmGlobalNinjaGenerator
|
||||
{
|
||||
public:
|
||||
/// The default name of Ninja's common file. Typically: common.ninja.
|
||||
static const char* NINJA_COMMON_FILE;
|
||||
/// The default file extension to use for per-config Ninja files.
|
||||
static const char* NINJA_FILE_EXTENSION;
|
||||
|
||||
cmGlobalNinjaMultiGenerator(cmake* cm);
|
||||
bool IsMultiConfig() const override { return true; }
|
||||
static cmGlobalGeneratorFactory* NewFactory()
|
||||
{
|
||||
return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaMultiGenerator>();
|
||||
}
|
||||
|
||||
static void GetDocumentation(cmDocumentationEntry& entry);
|
||||
|
||||
std::string GetName() const override
|
||||
{
|
||||
return cmGlobalNinjaMultiGenerator::GetActualName();
|
||||
}
|
||||
|
||||
static std::string GetActualName() { return "Ninja Multi-Config"; }
|
||||
|
||||
std::string BuildAlias(const std::string& alias,
|
||||
const std::string& config) const override
|
||||
{
|
||||
if (config.empty()) {
|
||||
return alias;
|
||||
}
|
||||
return cmStrCat(alias, ":", config);
|
||||
}
|
||||
|
||||
std::string ConfigDirectory(const std::string& config) const override
|
||||
{
|
||||
if (!config.empty()) {
|
||||
return cmStrCat('/', config);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
const char* GetCMakeCFGIntDir() const override { return "${CONFIGURATION}"; }
|
||||
|
||||
std::string ExpandCFGIntDir(const std::string& str,
|
||||
const std::string& config) const override;
|
||||
|
||||
cmGeneratedFileStream* GetConfigFileStream(
|
||||
const std::string& config) const override
|
||||
{
|
||||
return this->ConfigFileStreams.at(config).get();
|
||||
}
|
||||
|
||||
cmGeneratedFileStream* GetCommonFileStream() const override
|
||||
{
|
||||
return this->CommonFileStream.get();
|
||||
}
|
||||
|
||||
void AppendNinjaFileArgument(GeneratedMakeCommand& command,
|
||||
const std::string& config) const override;
|
||||
|
||||
static std::string GetNinjaFilename(const std::string& config);
|
||||
|
||||
void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const override;
|
||||
|
||||
void GetQtAutoGenConfigs(std::vector<std::string>& configs) const override;
|
||||
|
||||
bool WriteDefaultBuildFile() override;
|
||||
|
||||
protected:
|
||||
bool OpenBuildFileStreams() override;
|
||||
void CloseBuildFileStreams() override;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
|
||||
ConfigFileStreams;
|
||||
std::unique_ptr<cmGeneratedFileStream> CommonFileStream;
|
||||
};
|
||||
|
||||
#endif // ! cmGlobalNinjaGenerator_h
|
||||
|
||||
@@ -23,6 +23,7 @@ cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
|
||||
, OutputConverter(outputConverter)
|
||||
, ForResponse(false)
|
||||
, UseWatcomQuote(false)
|
||||
, UseNinjaMulti(false)
|
||||
, Relink(false)
|
||||
{
|
||||
}
|
||||
@@ -34,6 +35,11 @@ void cmLinkLineComputer::SetUseWatcomQuote(bool useWatcomQuote)
|
||||
this->UseWatcomQuote = useWatcomQuote;
|
||||
}
|
||||
|
||||
void cmLinkLineComputer::SetUseNinjaMulti(bool useNinjaMulti)
|
||||
{
|
||||
this->UseNinjaMulti = useNinjaMulti;
|
||||
}
|
||||
|
||||
void cmLinkLineComputer::SetForResponse(bool forResponse)
|
||||
{
|
||||
this->ForResponse = forResponse;
|
||||
@@ -106,10 +112,14 @@ void cmLinkLineComputer::ComputeLinkLibs(
|
||||
|
||||
std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
|
||||
{
|
||||
cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
|
||||
? cmOutputConverter::RESPONSE
|
||||
: ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
|
||||
: cmOutputConverter::SHELL);
|
||||
cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
|
||||
if (this->ForResponse) {
|
||||
shellFormat = cmOutputConverter::RESPONSE;
|
||||
} else if (this->UseWatcomQuote) {
|
||||
shellFormat = cmOutputConverter::WATCOMQUOTE;
|
||||
} else if (this->UseNinjaMulti) {
|
||||
shellFormat = cmOutputConverter::NINJAMULTI;
|
||||
}
|
||||
|
||||
return this->OutputConverter->ConvertToOutputFormat(input, shellFormat);
|
||||
}
|
||||
@@ -117,10 +127,14 @@ std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
|
||||
std::string cmLinkLineComputer::ConvertToOutputForExisting(
|
||||
std::string const& input)
|
||||
{
|
||||
cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
|
||||
? cmOutputConverter::RESPONSE
|
||||
: ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
|
||||
: cmOutputConverter::SHELL);
|
||||
cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
|
||||
if (this->ForResponse) {
|
||||
shellFormat = cmOutputConverter::RESPONSE;
|
||||
} else if (this->UseWatcomQuote) {
|
||||
shellFormat = cmOutputConverter::WATCOMQUOTE;
|
||||
} else if (this->UseNinjaMulti) {
|
||||
shellFormat = cmOutputConverter::NINJAMULTI;
|
||||
}
|
||||
|
||||
return this->OutputConverter->ConvertToOutputForExisting(input, shellFormat);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
cmLinkLineComputer& operator=(cmLinkLineComputer const&) = delete;
|
||||
|
||||
void SetUseWatcomQuote(bool useWatcomQuote);
|
||||
void SetUseNinjaMulti(bool useNinjaMulti);
|
||||
void SetForResponse(bool forResponse);
|
||||
void SetRelink(bool relink);
|
||||
|
||||
@@ -69,6 +70,7 @@ protected:
|
||||
|
||||
bool ForResponse;
|
||||
bool UseWatcomQuote;
|
||||
bool UseNinjaMulti;
|
||||
bool Relink;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,13 +17,9 @@ cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
|
||||
: cmLocalGenerator(gg, mf)
|
||||
, WorkingDirectory(std::move(wd))
|
||||
{
|
||||
// Store the configuration name that will be generated.
|
||||
if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
|
||||
// Use the build type given by the user.
|
||||
this->ConfigName = config;
|
||||
} else {
|
||||
// No configuration type given.
|
||||
this->ConfigName.clear();
|
||||
this->Makefile->GetConfigurations(this->ConfigNames);
|
||||
if (this->ConfigNames.empty()) {
|
||||
this->ConfigNames.emplace_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmLocalGenerator.h"
|
||||
|
||||
@@ -25,7 +26,10 @@ public:
|
||||
std::string wd);
|
||||
~cmLocalCommonGenerator() override;
|
||||
|
||||
std::string const& GetConfigName() const { return this->ConfigName; }
|
||||
std::vector<std::string> const& GetConfigNames() const
|
||||
{
|
||||
return this->ConfigNames;
|
||||
}
|
||||
|
||||
std::string GetWorkingDirectory() const { return this->WorkingDirectory; }
|
||||
|
||||
@@ -39,7 +43,7 @@ public:
|
||||
protected:
|
||||
std::string WorkingDirectory;
|
||||
|
||||
std::string ConfigName;
|
||||
std::vector<std::string> ConfigNames;
|
||||
|
||||
friend class cmCommonTargetGenerator;
|
||||
};
|
||||
|
||||
@@ -2392,7 +2392,9 @@ void cmLocalGenerator::AppendFlags(
|
||||
void cmLocalGenerator::AppendFlagEscape(std::string& flags,
|
||||
const std::string& rawFlag) const
|
||||
{
|
||||
this->AppendFlags(flags, this->EscapeForShell(rawFlag));
|
||||
this->AppendFlags(
|
||||
flags,
|
||||
this->EscapeForShell(rawFlag, false, false, false, this->IsNinjaMulti()));
|
||||
}
|
||||
|
||||
void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
|
||||
@@ -3207,6 +3209,11 @@ bool cmLocalGenerator::IsNMake() const
|
||||
return this->GetState()->UseNMake();
|
||||
}
|
||||
|
||||
bool cmLocalGenerator::IsNinjaMulti() const
|
||||
{
|
||||
return this->GetState()->UseNinjaMulti();
|
||||
}
|
||||
|
||||
std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
|
||||
const cmSourceFile& source, std::string const& dir_max,
|
||||
bool* hasSourceExtension, char const* customOutputExtension)
|
||||
|
||||
@@ -466,6 +466,7 @@ public:
|
||||
bool IsWatcomWMake() const;
|
||||
bool IsMinGWMake() const;
|
||||
bool IsNMake() const;
|
||||
bool IsNinjaMulti() const;
|
||||
|
||||
void IssueMessage(MessageType t, std::string const& text) const;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmake.h"
|
||||
|
||||
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
|
||||
@@ -61,7 +62,12 @@ void cmLocalNinjaGenerator::Generate()
|
||||
this->HomeRelativeOutputPath.clear();
|
||||
}
|
||||
|
||||
this->WriteProcessedMakefile(this->GetBuildFileStream());
|
||||
if (this->GetGlobalGenerator()->IsMultiConfig()) {
|
||||
for (auto const& config : this->GetConfigNames()) {
|
||||
this->WriteProcessedMakefile(this->GetConfigFileStream(config));
|
||||
}
|
||||
}
|
||||
this->WriteProcessedMakefile(this->GetCommonFileStream());
|
||||
#ifdef NINJA_GEN_VERBOSE_FILES
|
||||
this->WriteProcessedMakefile(this->GetRulesFileStream());
|
||||
#endif
|
||||
@@ -88,12 +94,20 @@ void cmLocalNinjaGenerator::Generate()
|
||||
}
|
||||
auto tg = cmNinjaTargetGenerator::New(target.get());
|
||||
if (tg) {
|
||||
tg->Generate();
|
||||
if (target->Target->IsPerConfig()) {
|
||||
for (auto const& config : this->GetConfigNames()) {
|
||||
tg->Generate(config);
|
||||
}
|
||||
} else {
|
||||
tg->Generate("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->WriteCustomCommandBuildStatements();
|
||||
this->AdditionalCleanFiles();
|
||||
for (auto const& config : this->GetConfigNames()) {
|
||||
this->WriteCustomCommandBuildStatements(config);
|
||||
this->AdditionalCleanFiles(config);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it.
|
||||
@@ -140,9 +154,15 @@ std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
|
||||
|
||||
// Private methods.
|
||||
|
||||
cmGeneratedFileStream& cmLocalNinjaGenerator::GetBuildFileStream() const
|
||||
cmGeneratedFileStream& cmLocalNinjaGenerator::GetConfigFileStream(
|
||||
const std::string& config) const
|
||||
{
|
||||
return *this->GetGlobalNinjaGenerator()->GetBuildFileStream();
|
||||
return *this->GetGlobalNinjaGenerator()->GetConfigFileStream(config);
|
||||
}
|
||||
|
||||
cmGeneratedFileStream& cmLocalNinjaGenerator::GetCommonFileStream() const
|
||||
{
|
||||
return *this->GetGlobalNinjaGenerator()->GetCommonFileStream();
|
||||
}
|
||||
|
||||
cmGeneratedFileStream& cmLocalNinjaGenerator::GetRulesFileStream() const
|
||||
@@ -162,10 +182,22 @@ cmake* cmLocalNinjaGenerator::GetCMakeInstance()
|
||||
|
||||
void cmLocalNinjaGenerator::WriteBuildFileTop()
|
||||
{
|
||||
// For the build file.
|
||||
this->WriteProjectHeader(this->GetBuildFileStream());
|
||||
this->WriteNinjaRequiredVersion(this->GetBuildFileStream());
|
||||
this->WriteNinjaFilesInclusion(this->GetBuildFileStream());
|
||||
this->WriteProjectHeader(this->GetCommonFileStream());
|
||||
|
||||
if (this->GetGlobalGenerator()->IsMultiConfig()) {
|
||||
for (auto const& config : this->GetConfigNames()) {
|
||||
auto& stream = this->GetConfigFileStream(config);
|
||||
this->WriteProjectHeader(stream);
|
||||
this->WriteNinjaRequiredVersion(stream);
|
||||
this->WriteNinjaConfigurationVariable(stream, config);
|
||||
this->WriteNinjaFilesInclusionConfig(stream);
|
||||
}
|
||||
} else {
|
||||
this->WriteNinjaRequiredVersion(this->GetCommonFileStream());
|
||||
this->WriteNinjaConfigurationVariable(this->GetCommonFileStream(),
|
||||
this->GetConfigNames().front());
|
||||
}
|
||||
this->WriteNinjaFilesInclusionCommon(this->GetCommonFileStream());
|
||||
|
||||
// For the rule file.
|
||||
this->WriteProjectHeader(this->GetRulesFileStream());
|
||||
@@ -175,7 +207,8 @@ void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
|
||||
{
|
||||
cmGlobalNinjaGenerator::WriteDivider(os);
|
||||
os << "# Project: " << this->GetProjectName() << std::endl
|
||||
<< "# Configuration: " << this->ConfigName << std::endl;
|
||||
<< "# Configurations: " << cmJoin(this->GetConfigNames(), ", ")
|
||||
<< std::endl;
|
||||
cmGlobalNinjaGenerator::WriteDivider(os);
|
||||
}
|
||||
|
||||
@@ -206,6 +239,14 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::WriteNinjaConfigurationVariable(
|
||||
std::ostream& os, const std::string& config)
|
||||
{
|
||||
cmGlobalNinjaGenerator::WriteVariable(
|
||||
os, "CONFIGURATION", config,
|
||||
"Set configuration variable for custom commands.");
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::WritePools(std::ostream& os)
|
||||
{
|
||||
cmGlobalNinjaGenerator::WriteDivider(os);
|
||||
@@ -235,7 +276,21 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
|
||||
void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os)
|
||||
{
|
||||
cmGlobalNinjaGenerator::WriteDivider(os);
|
||||
os << "# Include auxiliary files.\n"
|
||||
<< "\n";
|
||||
cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
|
||||
std::string const ninjaCommonFile =
|
||||
ng->NinjaOutputPath(cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE);
|
||||
std::string const commonFilePath = ng->EncodePath(ninjaCommonFile);
|
||||
cmGlobalNinjaGenerator::WriteInclude(os, commonFilePath,
|
||||
"Include common file.");
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os)
|
||||
{
|
||||
cmGlobalNinjaGenerator::WriteDivider(os);
|
||||
os << "# Include auxiliary files.\n"
|
||||
@@ -263,25 +318,30 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target,
|
||||
cmNinjaDeps& outputs)
|
||||
cmNinjaDeps& outputs,
|
||||
const std::string& config)
|
||||
{
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs);
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs,
|
||||
config);
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
|
||||
cmNinjaDeps& outputs,
|
||||
const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
cmNinjaTargetDepends depends)
|
||||
{
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs,
|
||||
depends);
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs, config,
|
||||
fileConfig, depends);
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::AppendCustomCommandDeps(
|
||||
cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps)
|
||||
cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps,
|
||||
const std::string& config)
|
||||
{
|
||||
for (std::string const& i : ccg.GetDepends()) {
|
||||
std::string dep;
|
||||
if (this->GetRealDependency(i, this->GetConfigName(), dep)) {
|
||||
if (this->GetRealDependency(i, config, dep)) {
|
||||
ninjaDeps.push_back(
|
||||
this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(dep));
|
||||
}
|
||||
@@ -416,6 +476,8 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
|
||||
void cmLocalNinjaGenerator::AppendCustomCommandLines(
|
||||
cmCustomCommandGenerator const& ccg, std::vector<std::string>& cmdLines)
|
||||
{
|
||||
auto* gg = this->GetGlobalNinjaGenerator();
|
||||
|
||||
if (ccg.GetNumberOfCommands() > 0) {
|
||||
std::string wd = ccg.GetWorkingDirectory();
|
||||
if (wd.empty()) {
|
||||
@@ -437,8 +499,10 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
|
||||
|
||||
for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
|
||||
cmdLines.push_back(launcher +
|
||||
this->ConvertToOutputFormat(ccg.GetCommand(i),
|
||||
cmOutputConverter::SHELL));
|
||||
this->ConvertToOutputFormat(
|
||||
ccg.GetCommand(i),
|
||||
gg->IsMultiConfig() ? cmOutputConverter::NINJAMULTI
|
||||
: cmOutputConverter::SHELL));
|
||||
|
||||
std::string& cmd = cmdLines.back();
|
||||
ccg.AppendArguments(i, cmd);
|
||||
@@ -446,14 +510,15 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
||||
cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps)
|
||||
cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps,
|
||||
const std::string& config)
|
||||
{
|
||||
cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
|
||||
if (gg->SeenCustomCommand(cc)) {
|
||||
if (gg->SeenCustomCommand(cc, config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this);
|
||||
cmCustomCommandGenerator ccg(*cc, config, this);
|
||||
|
||||
const std::vector<std::string>& outputs = ccg.GetOutputs();
|
||||
const std::vector<std::string>& byproducts = ccg.GetByproducts();
|
||||
@@ -484,7 +549,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
||||
}
|
||||
|
||||
cmNinjaDeps ninjaDeps;
|
||||
this->AppendCustomCommandDeps(ccg, ninjaDeps);
|
||||
this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
|
||||
|
||||
std::vector<std::string> cmdLines;
|
||||
this->AppendCustomCommandLines(ccg, cmdLines);
|
||||
@@ -495,7 +560,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
||||
build.Outputs = std::move(ninjaOutputs);
|
||||
build.ExplicitDeps = std::move(ninjaDeps);
|
||||
build.OrderOnlyDeps = orderOnlyDeps;
|
||||
gg->WriteBuild(this->GetBuildFileStream(), build);
|
||||
gg->WriteBuild(this->GetConfigFileStream(config), build);
|
||||
} else {
|
||||
std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
|
||||
// Hash full path to make unique.
|
||||
@@ -507,8 +572,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
||||
this->BuildCommandLine(cmdLines, customStep),
|
||||
this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
|
||||
cc->GetDepfile(), cc->GetJobPool(), cc->GetUsesTerminal(),
|
||||
/*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, ninjaDeps,
|
||||
orderOnlyDeps);
|
||||
/*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
|
||||
ninjaDeps, orderOnlyDeps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +589,8 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
|
||||
ins.first->second.insert(target);
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
|
||||
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements(
|
||||
const std::string& config)
|
||||
{
|
||||
for (cmCustomCommand const* customCommand : this->CustomCommands) {
|
||||
auto i = this->CustomCommandTargets.find(customCommand);
|
||||
@@ -542,15 +608,16 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
|
||||
auto j = i->second.begin();
|
||||
assert(j != i->second.end());
|
||||
std::vector<std::string> ccTargetDeps;
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j,
|
||||
ccTargetDeps);
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(
|
||||
*j, ccTargetDeps, config);
|
||||
std::sort(ccTargetDeps.begin(), ccTargetDeps.end());
|
||||
++j;
|
||||
|
||||
for (; j != i->second.end(); ++j) {
|
||||
std::vector<std::string> jDeps;
|
||||
std::vector<std::string> depsIntersection;
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps);
|
||||
this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps,
|
||||
config);
|
||||
std::sort(jDeps.begin(), jDeps.end());
|
||||
std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(),
|
||||
jDeps.begin(), jDeps.end(),
|
||||
@@ -558,7 +625,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
|
||||
ccTargetDeps = depsIntersection;
|
||||
}
|
||||
|
||||
this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps);
|
||||
this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps, config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,15 +666,13 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
|
||||
return launcher;
|
||||
}
|
||||
|
||||
void cmLocalNinjaGenerator::AdditionalCleanFiles()
|
||||
void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
|
||||
{
|
||||
if (const char* prop_value =
|
||||
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
|
||||
std::vector<std::string> cleanFiles;
|
||||
{
|
||||
cmExpandList(cmGeneratorExpression::Evaluate(
|
||||
prop_value, this,
|
||||
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
|
||||
cmExpandList(cmGeneratorExpression::Evaluate(prop_value, this, config),
|
||||
cleanFiles);
|
||||
}
|
||||
std::string const& binaryDir = this->GetCurrentBinaryDirectory();
|
||||
@@ -615,7 +680,7 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles()
|
||||
for (std::string const& cleanFile : cleanFiles) {
|
||||
// Support relative paths
|
||||
gg->AddAdditionalCleanFile(
|
||||
cmSystemTools::CollapseFullPath(cleanFile, binaryDir));
|
||||
cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,9 +64,11 @@ public:
|
||||
std::string const& customStep = std::string(),
|
||||
cmGeneratorTarget const* target = nullptr) const;
|
||||
|
||||
void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs);
|
||||
void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs,
|
||||
const std::string& config);
|
||||
void AppendTargetDepends(
|
||||
cmGeneratorTarget* target, cmNinjaDeps& outputs,
|
||||
cmGeneratorTarget* target, cmNinjaDeps& outputs, const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
cmNinjaTargetDepends depends = DependOnTargetArtifact);
|
||||
|
||||
void AddCustomCommandTarget(cmCustomCommand const* cc,
|
||||
@@ -74,7 +76,8 @@ public:
|
||||
void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
|
||||
std::vector<std::string>& cmdLines);
|
||||
void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
|
||||
cmNinjaDeps& ninjaDeps);
|
||||
cmNinjaDeps& ninjaDeps,
|
||||
const std::string& config);
|
||||
|
||||
protected:
|
||||
std::string ConvertToIncludeReference(
|
||||
@@ -83,20 +86,25 @@ protected:
|
||||
bool forceFullPaths = false) override;
|
||||
|
||||
private:
|
||||
cmGeneratedFileStream& GetBuildFileStream() const;
|
||||
cmGeneratedFileStream& GetConfigFileStream(const std::string& config) const;
|
||||
cmGeneratedFileStream& GetCommonFileStream() const;
|
||||
cmGeneratedFileStream& GetRulesFileStream() const;
|
||||
|
||||
void WriteBuildFileTop();
|
||||
void WriteProjectHeader(std::ostream& os);
|
||||
void WriteNinjaRequiredVersion(std::ostream& os);
|
||||
void WriteNinjaFilesInclusion(std::ostream& os);
|
||||
void WriteNinjaConfigurationVariable(std::ostream& os,
|
||||
const std::string& config);
|
||||
void WriteNinjaFilesInclusionConfig(std::ostream& os);
|
||||
void WriteNinjaFilesInclusionCommon(std::ostream& os);
|
||||
void WriteProcessedMakefile(std::ostream& os);
|
||||
void WritePools(std::ostream& os);
|
||||
|
||||
void WriteCustomCommandBuildStatement(cmCustomCommand const* cc,
|
||||
const cmNinjaDeps& orderOnlyDeps);
|
||||
const cmNinjaDeps& orderOnlyDeps,
|
||||
const std::string& config);
|
||||
|
||||
void WriteCustomCommandBuildStatements();
|
||||
void WriteCustomCommandBuildStatements(const std::string& config);
|
||||
|
||||
std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
|
||||
|
||||
@@ -104,7 +112,7 @@ private:
|
||||
std::string const& customStep,
|
||||
cmGeneratorTarget const* target) const;
|
||||
|
||||
void AdditionalCleanFiles();
|
||||
void AdditionalCleanFiles(const std::string& config);
|
||||
|
||||
std::string HomeRelativeOutputPath;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "cmLocalUnixMakefileGenerator3.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
@@ -106,6 +107,13 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
|
||||
|
||||
cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() = default;
|
||||
|
||||
std::string cmLocalUnixMakefileGenerator3::GetConfigName() const
|
||||
{
|
||||
auto const& configNames = this->GetConfigNames();
|
||||
assert(configNames.size() == 1);
|
||||
return configNames.front();
|
||||
}
|
||||
|
||||
void cmLocalUnixMakefileGenerator3::Generate()
|
||||
{
|
||||
// Record whether some options are enabled to avoid checking many
|
||||
@@ -162,7 +170,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
|
||||
continue;
|
||||
}
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
gt->GetObjectSources(objectSources, this->ConfigName);
|
||||
gt->GetObjectSources(objectSources, this->GetConfigName());
|
||||
// Compute full path to object file directory for this target.
|
||||
std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
|
||||
'/', this->GetTargetDirectory(gt.get()), '/');
|
||||
@@ -401,7 +409,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
|
||||
|
||||
// Add a local name for the rule to relink the target before
|
||||
// installation.
|
||||
if (target->NeedRelinkBeforeInstall(this->ConfigName)) {
|
||||
if (target->NeedRelinkBeforeInstall(this->GetConfigName())) {
|
||||
makeTargetName = cmStrCat(
|
||||
this->GetRelativeTargetDirectory(target.get()), "/preinstall");
|
||||
localName = cmStrCat(target->GetName(), "/preinstall");
|
||||
@@ -858,7 +866,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepends(
|
||||
std::vector<std::string>& depends, const std::vector<cmCustomCommand>& ccs)
|
||||
{
|
||||
for (cmCustomCommand const& cc : ccs) {
|
||||
cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
|
||||
cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
|
||||
this->AppendCustomDepend(depends, ccg);
|
||||
}
|
||||
}
|
||||
@@ -869,7 +877,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepend(
|
||||
for (std::string const& d : ccg.GetDepends()) {
|
||||
// Lookup the real name of the dependency in case it is a CMake target.
|
||||
std::string dep;
|
||||
if (this->GetRealDependency(d, this->ConfigName, dep)) {
|
||||
if (this->GetRealDependency(d, this->GetConfigName(), dep)) {
|
||||
depends.push_back(std::move(dep));
|
||||
}
|
||||
}
|
||||
@@ -880,7 +888,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommands(
|
||||
cmGeneratorTarget* target, std::string const& relative)
|
||||
{
|
||||
for (cmCustomCommand const& cc : ccs) {
|
||||
cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
|
||||
cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
|
||||
this->AppendCustomCommand(commands, ccg, target, relative, true);
|
||||
}
|
||||
}
|
||||
@@ -1839,7 +1847,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
|
||||
|
||||
// Build a list of preprocessor definitions for the target.
|
||||
std::set<std::string> defines;
|
||||
this->GetTargetDefines(target, this->ConfigName, implicitLang.first,
|
||||
this->GetTargetDefines(target, this->GetConfigName(), implicitLang.first,
|
||||
defines);
|
||||
if (!defines.empty()) {
|
||||
/* clang-format off */
|
||||
@@ -1863,7 +1871,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
|
||||
std::vector<std::string> includes;
|
||||
|
||||
this->GetIncludeDirectories(includes, target, implicitLang.first,
|
||||
this->ConfigName);
|
||||
this->GetConfigName());
|
||||
std::string binaryDir = this->GetState()->GetBinaryDirectory();
|
||||
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
|
||||
std::string const& sourceDir = this->GetState()->GetSourceDirectory();
|
||||
|
||||
@@ -33,6 +33,8 @@ public:
|
||||
cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
|
||||
~cmLocalUnixMakefileGenerator3() override;
|
||||
|
||||
std::string GetConfigName() const;
|
||||
|
||||
void ComputeHomeRelativeOutputPath() override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1992,7 +1992,8 @@ cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
|
||||
{
|
||||
auto it =
|
||||
this->Targets
|
||||
.emplace(name, cmTarget(name, type, cmTarget::VisibilityNormal, this))
|
||||
.emplace(name,
|
||||
cmTarget(name, type, cmTarget::VisibilityNormal, this, true))
|
||||
.first;
|
||||
this->OrderedTargets.push_back(&it->second);
|
||||
this->GetGlobalGenerator()->IndexTarget(&it->second);
|
||||
@@ -4162,7 +4163,7 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
|
||||
new cmTarget(name, type,
|
||||
global ? cmTarget::VisibilityImportedGlobally
|
||||
: cmTarget::VisibilityImported,
|
||||
this));
|
||||
this, true));
|
||||
|
||||
// Add to the set of available imported targets.
|
||||
this->ImportedTargets[name] = target.get();
|
||||
|
||||
@@ -35,10 +35,9 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
|
||||
{
|
||||
this->CustomCommandDriver = OnDepends;
|
||||
this->TargetNames =
|
||||
this->GeneratorTarget->GetExecutableNames(this->ConfigName);
|
||||
this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
|
||||
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
|
||||
this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
}
|
||||
|
||||
@@ -64,7 +63,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
|
||||
|
||||
// write the link rules
|
||||
this->WriteExecutableRule(false);
|
||||
if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
|
||||
if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->GetConfigName())) {
|
||||
// Write rules to link an installable version of the target.
|
||||
this->WriteExecutableRule(true);
|
||||
}
|
||||
@@ -85,7 +84,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
|
||||
{
|
||||
#ifndef CMAKE_BOOTSTRAP
|
||||
const bool requiresDeviceLinking = requireDeviceLinking(
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
|
||||
if (!requiresDeviceLinking) {
|
||||
return;
|
||||
}
|
||||
@@ -141,10 +140,10 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
|
||||
|
||||
// Add language feature flags.
|
||||
this->LocalGenerator->AddLanguageFlagsForLinking(
|
||||
flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
|
||||
flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
|
||||
|
||||
this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
|
||||
linkLanguage, this->ConfigName);
|
||||
this->LocalGenerator->AddArchitectureFlags(
|
||||
flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
|
||||
|
||||
// Add target-specific linker flags.
|
||||
this->GetTargetLinkFlags(linkFlags, linkLanguage);
|
||||
@@ -213,7 +212,8 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
|
||||
output);
|
||||
|
||||
std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
|
||||
std::string targetFullPathCompilePDB =
|
||||
this->ComputeTargetCompilePDB(this->GetConfigName());
|
||||
std::string targetOutPathCompilePDB =
|
||||
this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
|
||||
cmOutputConverter::SHELL);
|
||||
@@ -287,12 +287,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
|
||||
// Get the name of the executable to generate.
|
||||
cmGeneratorTarget::Names targetNames =
|
||||
this->GeneratorTarget->GetExecutableNames(this->ConfigName);
|
||||
this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
|
||||
|
||||
// Construct the full path version of the names.
|
||||
std::string outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
|
||||
std::string outpath =
|
||||
this->GeneratorTarget->GetDirectory(this->GetConfigName());
|
||||
if (this->GeneratorTarget->IsAppBundleOnApple()) {
|
||||
this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath);
|
||||
this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath,
|
||||
this->GetConfigName());
|
||||
}
|
||||
outpath += '/';
|
||||
std::string outpathImp;
|
||||
@@ -308,18 +310,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
cmSystemTools::MakeDirectory(outpath);
|
||||
if (!targetNames.ImportLibrary.empty()) {
|
||||
outpathImp = this->GeneratorTarget->GetDirectory(
|
||||
this->ConfigName, cmStateEnums::ImportLibraryArtifact);
|
||||
this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
|
||||
cmSystemTools::MakeDirectory(outpathImp);
|
||||
outpathImp += '/';
|
||||
}
|
||||
}
|
||||
|
||||
std::string compilePdbOutputPath =
|
||||
this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
|
||||
this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
|
||||
cmSystemTools::MakeDirectory(compilePdbOutputPath);
|
||||
|
||||
std::string pdbOutputPath =
|
||||
this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
|
||||
this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
|
||||
cmSystemTools::MakeDirectory(pdbOutputPath);
|
||||
pdbOutputPath += '/';
|
||||
|
||||
@@ -347,7 +349,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
|
||||
// Get the language to use for linking this executable.
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
|
||||
|
||||
// Make sure we have a link language.
|
||||
if (linkLanguage.empty()) {
|
||||
@@ -380,7 +382,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
|
||||
// Add flags to create an executable.
|
||||
this->LocalGenerator->AddConfigVariableFlags(
|
||||
linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->ConfigName);
|
||||
linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->GetConfigName());
|
||||
|
||||
if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) {
|
||||
this->LocalGenerator->AppendFlags(
|
||||
@@ -409,10 +411,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
|
||||
// Add language feature flags.
|
||||
this->LocalGenerator->AddLanguageFlagsForLinking(
|
||||
flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
|
||||
flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
|
||||
|
||||
this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
|
||||
linkLanguage, this->ConfigName);
|
||||
this->LocalGenerator->AddArchitectureFlags(
|
||||
flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
|
||||
|
||||
// Add target-specific linker flags.
|
||||
this->GetTargetLinkFlags(linkFlags, linkLanguage);
|
||||
@@ -423,11 +425,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
this->LocalGenerator,
|
||||
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
|
||||
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags,
|
||||
this->GetConfigName());
|
||||
}
|
||||
|
||||
this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
|
||||
this->ConfigName, linkLanguage);
|
||||
this->LocalGenerator->AppendIPOLinkerFlags(
|
||||
linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
|
||||
|
||||
// Construct a list of files associated with this executable that
|
||||
// may need to be cleaned.
|
||||
@@ -451,7 +454,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
targetFullPathImport));
|
||||
std::string implib;
|
||||
if (this->GeneratorTarget->GetImplibGNUtoMS(
|
||||
this->ConfigName, targetFullPathImport, implib)) {
|
||||
this->GetConfigName(), targetFullPathImport, implib)) {
|
||||
exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
|
||||
}
|
||||
@@ -479,7 +482,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
// Construct the main link rule.
|
||||
std::vector<std::string> real_link_commands;
|
||||
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
|
||||
linkLanguage, this->ConfigName);
|
||||
linkLanguage, this->GetConfigName());
|
||||
std::string linkRule = this->GetLinkRule(linkRuleVar);
|
||||
std::vector<std::string> commands1;
|
||||
cmExpandList(linkRule, real_link_commands);
|
||||
@@ -536,7 +539,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
// maybe create .def file from list of objects
|
||||
this->GenDefFile(real_link_commands);
|
||||
|
||||
std::string manifests = this->GetManifests();
|
||||
std::string manifests = this->GetManifests(this->GetConfigName());
|
||||
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
|
||||
|
||||
@@ -36,11 +36,10 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
|
||||
this->CustomCommandDriver = OnDepends;
|
||||
if (this->GeneratorTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
|
||||
this->TargetNames =
|
||||
this->GeneratorTarget->GetLibraryNames(this->ConfigName);
|
||||
this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
|
||||
}
|
||||
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
|
||||
this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
}
|
||||
|
||||
@@ -69,14 +68,16 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
|
||||
break;
|
||||
case cmStateEnums::SHARED_LIBRARY:
|
||||
this->WriteSharedLibraryRules(false);
|
||||
if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
|
||||
if (this->GeneratorTarget->NeedRelinkBeforeInstall(
|
||||
this->GetConfigName())) {
|
||||
// Write rules to link an installable version of the target.
|
||||
this->WriteSharedLibraryRules(true);
|
||||
}
|
||||
break;
|
||||
case cmStateEnums::MODULE_LIBRARY:
|
||||
this->WriteModuleLibraryRules(false);
|
||||
if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
|
||||
if (this->GeneratorTarget->NeedRelinkBeforeInstall(
|
||||
this->GetConfigName())) {
|
||||
// Write rules to link an installable version of the target.
|
||||
this->WriteModuleLibraryRules(true);
|
||||
}
|
||||
@@ -126,21 +127,21 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
|
||||
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
|
||||
{
|
||||
const bool requiresDeviceLinking = requireDeviceLinking(
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
|
||||
if (requiresDeviceLinking) {
|
||||
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
|
||||
this->WriteDeviceLibraryRules(linkRuleVar, false);
|
||||
}
|
||||
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
|
||||
|
||||
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
|
||||
linkLanguage, this->ConfigName);
|
||||
linkLanguage, this->GetConfigName());
|
||||
|
||||
std::string extraFlags;
|
||||
this->LocalGenerator->GetStaticLibraryFlags(
|
||||
extraFlags, cmSystemTools::UpperCase(this->ConfigName), linkLanguage,
|
||||
extraFlags, cmSystemTools::UpperCase(this->GetConfigName()), linkLanguage,
|
||||
this->GeneratorTarget);
|
||||
this->WriteLibraryRules(linkRuleVar, extraFlags, false);
|
||||
}
|
||||
@@ -154,7 +155,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||
|
||||
if (!relink) {
|
||||
const bool requiresDeviceLinking = requireDeviceLinking(
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
|
||||
if (requiresDeviceLinking) {
|
||||
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
|
||||
this->WriteDeviceLibraryRules(linkRuleVar, relink);
|
||||
@@ -162,21 +163,22 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||
}
|
||||
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
|
||||
std::string linkRuleVar =
|
||||
cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY");
|
||||
|
||||
std::string extraFlags;
|
||||
this->GetTargetLinkFlags(extraFlags, linkLanguage);
|
||||
this->LocalGenerator->AddConfigVariableFlags(
|
||||
extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
|
||||
extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->GetConfigName());
|
||||
|
||||
std::unique_ptr<cmLinkLineComputer> linkLineComputer(
|
||||
this->CreateLinkLineComputer(
|
||||
this->LocalGenerator,
|
||||
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
|
||||
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
|
||||
this->GetConfigName());
|
||||
|
||||
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
|
||||
this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
|
||||
@@ -188,7 +190,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
|
||||
{
|
||||
if (!relink) {
|
||||
const bool requiresDeviceLinking = requireDeviceLinking(
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
|
||||
*this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
|
||||
if (requiresDeviceLinking) {
|
||||
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
|
||||
this->WriteDeviceLibraryRules(linkRuleVar, relink);
|
||||
@@ -196,21 +198,22 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
|
||||
}
|
||||
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
|
||||
std::string linkRuleVar =
|
||||
cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_MODULE");
|
||||
|
||||
std::string extraFlags;
|
||||
this->GetTargetLinkFlags(extraFlags, linkLanguage);
|
||||
this->LocalGenerator->AddConfigVariableFlags(
|
||||
extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
|
||||
extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->GetConfigName());
|
||||
|
||||
std::unique_ptr<cmLinkLineComputer> linkLineComputer(
|
||||
this->CreateLinkLineComputer(
|
||||
this->LocalGenerator,
|
||||
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
|
||||
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
|
||||
this->GetConfigName());
|
||||
|
||||
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
|
||||
}
|
||||
@@ -218,14 +221,14 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
|
||||
void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
|
||||
{
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
|
||||
std::string linkRuleVar =
|
||||
cmStrCat("CMAKE_", linkLanguage, "_CREATE_MACOSX_FRAMEWORK");
|
||||
|
||||
std::string extraFlags;
|
||||
this->GetTargetLinkFlags(extraFlags, linkLanguage);
|
||||
this->LocalGenerator->AddConfigVariableFlags(
|
||||
extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
|
||||
extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->GetConfigName());
|
||||
|
||||
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
|
||||
}
|
||||
@@ -331,7 +334,8 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
|
||||
output);
|
||||
|
||||
std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
|
||||
std::string targetFullPathCompilePDB =
|
||||
this->ComputeTargetCompilePDB(this->GetConfigName());
|
||||
std::string targetOutPathCompilePDB =
|
||||
this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
|
||||
cmOutputConverter::SHELL);
|
||||
@@ -347,7 +351,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
|
||||
// Add language-specific flags.
|
||||
std::string langFlags;
|
||||
this->LocalGenerator->AddLanguageFlagsForLinking(
|
||||
langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
|
||||
langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
|
||||
|
||||
vars.LanguageCompileFlags = langFlags.c_str();
|
||||
|
||||
@@ -420,7 +424,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
|
||||
// Get the language to use for linking this library.
|
||||
std::string linkLanguage =
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
|
||||
|
||||
// Make sure we have a link language.
|
||||
if (linkLanguage.empty()) {
|
||||
@@ -439,8 +443,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
// Create set of linking flags.
|
||||
std::string linkFlags;
|
||||
this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
|
||||
this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
|
||||
this->ConfigName, linkLanguage);
|
||||
this->LocalGenerator->AppendIPOLinkerFlags(
|
||||
linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
|
||||
|
||||
// Add OSX version flags, if any.
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
@@ -450,20 +454,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
}
|
||||
|
||||
// Construct the name of the library.
|
||||
this->GeneratorTarget->GetLibraryNames(this->ConfigName);
|
||||
this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
|
||||
|
||||
// Construct the full path version of the names.
|
||||
std::string outpath;
|
||||
std::string outpathImp;
|
||||
if (this->GeneratorTarget->IsFrameworkOnApple()) {
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
|
||||
this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
|
||||
outpath);
|
||||
outpath, this->GetConfigName());
|
||||
outpath += '/';
|
||||
} else if (this->GeneratorTarget->IsCFBundleOnApple()) {
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
|
||||
this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
|
||||
outpath);
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
|
||||
this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath,
|
||||
this->GetConfigName());
|
||||
outpath += '/';
|
||||
} else if (relink) {
|
||||
outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(),
|
||||
@@ -474,23 +478,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
outpathImp = outpath;
|
||||
}
|
||||
} else {
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
|
||||
cmSystemTools::MakeDirectory(outpath);
|
||||
outpath += '/';
|
||||
if (!this->TargetNames.ImportLibrary.empty()) {
|
||||
outpathImp = this->GeneratorTarget->GetDirectory(
|
||||
this->ConfigName, cmStateEnums::ImportLibraryArtifact);
|
||||
this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
|
||||
cmSystemTools::MakeDirectory(outpathImp);
|
||||
outpathImp += '/';
|
||||
}
|
||||
}
|
||||
|
||||
std::string compilePdbOutputPath =
|
||||
this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
|
||||
this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
|
||||
cmSystemTools::MakeDirectory(compilePdbOutputPath);
|
||||
|
||||
std::string pdbOutputPath =
|
||||
this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
|
||||
this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
|
||||
cmSystemTools::MakeDirectory(pdbOutputPath);
|
||||
pdbOutputPath += "/";
|
||||
|
||||
@@ -586,7 +590,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
targetFullPathImport));
|
||||
std::string implib;
|
||||
if (this->GeneratorTarget->GetImplibGNUtoMS(
|
||||
this->ConfigName, targetFullPathImport, implib)) {
|
||||
this->GetConfigName(), targetFullPathImport, implib)) {
|
||||
libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
|
||||
}
|
||||
@@ -638,7 +642,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE");
|
||||
|
||||
arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
|
||||
arCreateVar, linkLanguage, this->ConfigName);
|
||||
arCreateVar, linkLanguage, this->GetConfigName());
|
||||
|
||||
if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
|
||||
cmExpandList(rule, archiveCreateCommands);
|
||||
@@ -647,7 +651,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
|
||||
|
||||
arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
|
||||
arAppendVar, linkLanguage, this->ConfigName);
|
||||
arAppendVar, linkLanguage, this->GetConfigName());
|
||||
|
||||
if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
|
||||
cmExpandList(rule, archiveAppendCommands);
|
||||
@@ -656,7 +660,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
|
||||
|
||||
arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
|
||||
arFinishVar, linkLanguage, this->ConfigName);
|
||||
arFinishVar, linkLanguage, this->GetConfigName());
|
||||
|
||||
if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
|
||||
cmExpandList(rule, archiveFinishCommands);
|
||||
@@ -726,7 +730,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
// maybe create .def file from list of objects
|
||||
this->GenDefFile(real_link_commands);
|
||||
|
||||
std::string manifests = this->GetManifests();
|
||||
std::string manifests = this->GetManifests(this->GetConfigName());
|
||||
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.TargetPDB = targetOutPathPDB.c_str();
|
||||
@@ -771,7 +775,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
vars.Target = target.c_str();
|
||||
vars.LinkLibraries = linkLibs.c_str();
|
||||
vars.ObjectsQuoted = buildObjs.c_str();
|
||||
if (this->GeneratorTarget->HasSOName(this->ConfigName)) {
|
||||
if (this->GeneratorTarget->HasSOName(this->GetConfigName())) {
|
||||
vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
|
||||
vars.TargetSOName = this->TargetNames.SharedObject.c_str();
|
||||
}
|
||||
@@ -783,8 +787,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
std::string install_name_dir;
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY) {
|
||||
// Get the install_name directory for the build tree.
|
||||
install_name_dir =
|
||||
this->GeneratorTarget->GetInstallNameDirForBuildTree(this->ConfigName);
|
||||
install_name_dir = this->GeneratorTarget->GetInstallNameDirForBuildTree(
|
||||
this->GetConfigName());
|
||||
|
||||
// Set the rule variable replacement value.
|
||||
if (install_name_dir.empty()) {
|
||||
@@ -800,10 +804,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
||||
// Add language-specific flags.
|
||||
std::string langFlags;
|
||||
this->LocalGenerator->AddLanguageFlagsForLinking(
|
||||
langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
|
||||
langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
|
||||
|
||||
this->LocalGenerator->AddArchitectureFlags(
|
||||
langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
|
||||
langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
|
||||
|
||||
vars.LanguageCompileFlags = langFlags.c_str();
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmMakefileTargetGenerator.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
@@ -85,6 +86,13 @@ cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string cmMakefileTargetGenerator::GetConfigName()
|
||||
{
|
||||
auto const& configNames = this->LocalGenerator->GetConfigNames();
|
||||
assert(configNames.size() == 1);
|
||||
return configNames.front();
|
||||
}
|
||||
|
||||
void cmMakefileTargetGenerator::GetTargetLinkFlags(
|
||||
std::string& flags, const std::string& linkLanguage)
|
||||
{
|
||||
@@ -92,17 +100,18 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
|
||||
flags, this->GeneratorTarget->GetSafeProperty("LINK_FLAGS"));
|
||||
|
||||
std::string linkFlagsConfig =
|
||||
cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->ConfigName));
|
||||
cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->GetConfigName()));
|
||||
this->LocalGenerator->AppendFlags(
|
||||
flags, this->GeneratorTarget->GetSafeProperty(linkFlagsConfig));
|
||||
|
||||
std::vector<std::string> opts;
|
||||
this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage);
|
||||
this->GeneratorTarget->GetLinkOptions(opts, this->GetConfigName(),
|
||||
linkLanguage);
|
||||
// LINK_OPTIONS are escaped.
|
||||
this->LocalGenerator->AppendCompileOptions(flags, opts);
|
||||
|
||||
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
|
||||
flags, this->GeneratorTarget, this->ConfigName, linkLanguage);
|
||||
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
|
||||
}
|
||||
|
||||
void cmMakefileTargetGenerator::CreateRuleFile()
|
||||
@@ -154,10 +163,10 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
auto evaluatedFiles =
|
||||
[this](const char* prop_value) -> std::vector<std::string> {
|
||||
std::vector<std::string> files;
|
||||
cmExpandList(
|
||||
cmGeneratorExpression::Evaluate(prop_value, this->LocalGenerator,
|
||||
this->ConfigName, this->GeneratorTarget),
|
||||
files);
|
||||
cmExpandList(cmGeneratorExpression::Evaluate(
|
||||
prop_value, this->LocalGenerator, this->GetConfigName(),
|
||||
this->GeneratorTarget),
|
||||
files);
|
||||
return files;
|
||||
};
|
||||
|
||||
@@ -187,12 +196,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
// First generate the object rule files. Save a list of all object
|
||||
// files for this target.
|
||||
std::vector<cmSourceFile const*> customCommands;
|
||||
this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
|
||||
this->GeneratorTarget->GetCustomCommands(customCommands,
|
||||
this->GetConfigName());
|
||||
std::string currentBinDir =
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory();
|
||||
for (cmSourceFile const* sf : customCommands) {
|
||||
cmCustomCommandGenerator ccg(*sf->GetCustomCommand(), this->ConfigName,
|
||||
this->LocalGenerator);
|
||||
cmCustomCommandGenerator ccg(*sf->GetCustomCommand(),
|
||||
this->GetConfigName(), this->LocalGenerator);
|
||||
this->GenerateCustomRuleFile(ccg);
|
||||
if (clean) {
|
||||
const std::vector<std::string>& outputs = ccg.GetOutputs();
|
||||
@@ -220,7 +230,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
this->GeneratorTarget->GetPostBuildCommands());
|
||||
|
||||
for (const auto& be : buildEventCommands) {
|
||||
cmCustomCommandGenerator beg(be, this->ConfigName, this->LocalGenerator);
|
||||
cmCustomCommandGenerator beg(be, this->GetConfigName(),
|
||||
this->LocalGenerator);
|
||||
const std::vector<std::string>& byproducts = beg.GetByproducts();
|
||||
for (std::string const& byproduct : byproducts) {
|
||||
this->CleanFiles.insert(
|
||||
@@ -230,17 +241,19 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
}
|
||||
}
|
||||
std::vector<cmSourceFile const*> headerSources;
|
||||
this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
|
||||
this->GeneratorTarget->GetHeaderSources(headerSources,
|
||||
this->GetConfigName());
|
||||
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
|
||||
headerSources, this->MacOSXContentGenerator);
|
||||
headerSources, this->MacOSXContentGenerator, this->GetConfigName());
|
||||
std::vector<cmSourceFile const*> extraSources;
|
||||
this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
|
||||
this->GeneratorTarget->GetExtraSources(extraSources, this->GetConfigName());
|
||||
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
|
||||
extraSources, this->MacOSXContentGenerator);
|
||||
extraSources, this->MacOSXContentGenerator, this->GetConfigName());
|
||||
const char* pchExtension =
|
||||
this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
std::vector<cmSourceFile const*> externalObjects;
|
||||
this->GeneratorTarget->GetExternalObjects(externalObjects, this->ConfigName);
|
||||
this->GeneratorTarget->GetExternalObjects(externalObjects,
|
||||
this->GetConfigName());
|
||||
for (cmSourceFile const* sf : externalObjects) {
|
||||
auto const& objectFileName = sf->GetFullPath();
|
||||
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
|
||||
@@ -248,7 +261,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
}
|
||||
}
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
|
||||
this->GeneratorTarget->GetObjectSources(objectSources,
|
||||
this->GetConfigName());
|
||||
for (cmSourceFile const* sf : objectSources) {
|
||||
// Generate this object file's rule file.
|
||||
this->WriteObjectRuleFiles(*sf);
|
||||
@@ -334,9 +348,9 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
|
||||
}
|
||||
|
||||
for (std::string const& language : languages) {
|
||||
std::string flags = this->GetFlags(language);
|
||||
std::string defines = this->GetDefines(language);
|
||||
std::string includes = this->GetIncludes(language);
|
||||
std::string flags = this->GetFlags(language, this->GetConfigName());
|
||||
std::string defines = this->GetDefines(language, this->GetConfigName());
|
||||
std::string includes = this->GetIncludes(language, this->GetConfigName());
|
||||
// Escape comment characters so they do not terminate assignment.
|
||||
cmSystemTools::ReplaceString(flags, "#", "\\#");
|
||||
cmSystemTools::ReplaceString(defines, "#", "\\#");
|
||||
@@ -348,7 +362,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
|
||||
}
|
||||
|
||||
void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
|
||||
cmSourceFile const& source, const char* pkgloc)
|
||||
cmSourceFile const& source, const char* pkgloc, const std::string& config)
|
||||
{
|
||||
// Skip OS X content when not building a Framework or Bundle.
|
||||
if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
|
||||
@@ -356,7 +370,8 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
|
||||
}
|
||||
|
||||
std::string macdir =
|
||||
this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
|
||||
this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
|
||||
config);
|
||||
|
||||
// Get the input file location.
|
||||
std::string const& input = source.GetFullPath();
|
||||
@@ -451,7 +466,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
// generate the depend scanning rule
|
||||
this->WriteObjectDependRules(source, depends);
|
||||
|
||||
std::string config = this->LocalGenerator->GetConfigName();
|
||||
std::string config = this->GetConfigName();
|
||||
std::string configUpper = cmSystemTools::UpperCase(config);
|
||||
|
||||
// Add precompile headers dependencies
|
||||
@@ -593,16 +608,17 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
{
|
||||
std::string targetFullPathReal;
|
||||
std::string targetFullPathPDB;
|
||||
std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
|
||||
std::string targetFullPathCompilePDB =
|
||||
this->ComputeTargetCompilePDB(this->GetConfigName());
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
|
||||
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
|
||||
this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
|
||||
targetFullPathReal = this->GeneratorTarget->GetFullPath(
|
||||
this->ConfigName, cmStateEnums::RuntimeBinaryArtifact, true);
|
||||
targetFullPathPDB =
|
||||
cmStrCat(this->GeneratorTarget->GetPDBDirectory(this->ConfigName), '/',
|
||||
this->GeneratorTarget->GetPDBName(this->ConfigName));
|
||||
this->GetConfigName(), cmStateEnums::RuntimeBinaryArtifact, true);
|
||||
targetFullPathPDB = cmStrCat(
|
||||
this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
|
||||
this->GeneratorTarget->GetPDBName(this->GetConfigName()));
|
||||
}
|
||||
|
||||
targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
|
||||
@@ -708,13 +724,15 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
std::string workingDirectory = cmSystemTools::CollapseFullPath(
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory());
|
||||
compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
|
||||
this->GetFlags(lang));
|
||||
this->GetFlags(lang, this->GetConfigName()));
|
||||
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
|
||||
compileCommand.replace(compileCommand.find(langDefines),
|
||||
langDefines.size(), this->GetDefines(lang));
|
||||
langDefines.size(),
|
||||
this->GetDefines(lang, this->GetConfigName()));
|
||||
std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
|
||||
compileCommand.replace(compileCommand.find(langIncludes),
|
||||
langIncludes.size(), this->GetIncludes(lang));
|
||||
langIncludes.size(),
|
||||
this->GetIncludes(lang, this->GetConfigName()));
|
||||
|
||||
const char* eliminate[] = {
|
||||
this->Makefile->GetDefinition("CMAKE_START_TEMP_FILE"),
|
||||
@@ -1068,7 +1086,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
|
||||
<< "# Targets to which this target links.\n"
|
||||
<< "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
|
||||
/* clang-format on */
|
||||
std::vector<std::string> dirs = this->GetLinkedTargetDirectories();
|
||||
std::vector<std::string> dirs =
|
||||
this->GetLinkedTargetDirectories(this->GetConfigName());
|
||||
for (std::string const& d : dirs) {
|
||||
*this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n";
|
||||
}
|
||||
@@ -1171,7 +1190,7 @@ void cmMakefileTargetGenerator::DriveCustomCommands(
|
||||
sources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
|
||||
for (cmSourceFile* source : sources) {
|
||||
if (cmCustomCommand* cc = source->GetCustomCommand()) {
|
||||
cmCustomCommandGenerator ccg(*cc, this->ConfigName,
|
||||
cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
|
||||
this->LocalGenerator);
|
||||
cmAppend(depends, ccg.GetOutputs());
|
||||
}
|
||||
@@ -1429,7 +1448,7 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
|
||||
}
|
||||
|
||||
// Loop over all library dependencies.
|
||||
const std::string& cfg = this->LocalGenerator->GetConfigName();
|
||||
const std::string& cfg = this->GetConfigName();
|
||||
if (cmComputeLinkInformation* cli =
|
||||
this->GeneratorTarget->GetLinkInformation(cfg)) {
|
||||
cmAppend(depends, cli->GetDepends());
|
||||
@@ -1474,13 +1493,13 @@ void cmMakefileTargetGenerator::AppendLinkDepends(
|
||||
|
||||
// Add a dependency on user-specified manifest files, if any.
|
||||
std::vector<cmSourceFile const*> manifest_srcs;
|
||||
this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
|
||||
this->GeneratorTarget->GetManifests(manifest_srcs, this->GetConfigName());
|
||||
for (cmSourceFile const* manifest_src : manifest_srcs) {
|
||||
depends.push_back(manifest_src->GetFullPath());
|
||||
}
|
||||
|
||||
// Add user-specified dependencies.
|
||||
this->GeneratorTarget->GetLinkDepends(depends, this->ConfigName,
|
||||
this->GeneratorTarget->GetLinkDepends(depends, this->GetConfigName(),
|
||||
linkLanguage);
|
||||
}
|
||||
|
||||
@@ -1488,10 +1507,11 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
|
||||
const std::string& linkRuleVar)
|
||||
{
|
||||
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
|
||||
if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) {
|
||||
std::string ruleVar = cmStrCat(
|
||||
"CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
|
||||
"_GNUtoMS_RULE");
|
||||
if (this->GeneratorTarget->HasImplibGNUtoMS(this->GetConfigName())) {
|
||||
std::string ruleVar =
|
||||
cmStrCat("CMAKE_",
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
|
||||
"_GNUtoMS_RULE");
|
||||
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
|
||||
linkRule += rule;
|
||||
}
|
||||
@@ -1630,7 +1650,7 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
|
||||
std::string frameworkPath;
|
||||
std::string linkPath;
|
||||
cmComputeLinkInformation* pcli =
|
||||
this->GeneratorTarget->GetLinkInformation(this->ConfigName);
|
||||
this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
|
||||
this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
|
||||
frameworkPath, linkPath);
|
||||
linkLibs = frameworkPath + linkPath + linkLibs;
|
||||
@@ -1638,9 +1658,10 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
|
||||
if (useResponseFile &&
|
||||
linkLibs.find_first_not_of(' ') != std::string::npos) {
|
||||
// Lookup the response file reference flag.
|
||||
std::string responseFlagVar = cmStrCat(
|
||||
"CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
|
||||
"_RESPONSE_FILE_LINK_FLAG");
|
||||
std::string responseFlagVar =
|
||||
cmStrCat("CMAKE_",
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
|
||||
"_RESPONSE_FILE_LINK_FLAG");
|
||||
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
|
||||
if (!responseFlag) {
|
||||
responseFlag = "@";
|
||||
@@ -1675,9 +1696,10 @@ void cmMakefileTargetGenerator::CreateObjectLists(
|
||||
this->WriteObjectsStrings(object_strings, responseFileLimit);
|
||||
|
||||
// Lookup the response file reference flag.
|
||||
std::string responseFlagVar = cmStrCat(
|
||||
"CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
|
||||
"_RESPONSE_FILE_LINK_FLAG");
|
||||
std::string responseFlagVar =
|
||||
cmStrCat("CMAKE_",
|
||||
this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
|
||||
"_RESPONSE_FILE_LINK_FLAG");
|
||||
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
|
||||
if (!responseFlag) {
|
||||
responseFlag = "@";
|
||||
@@ -1716,7 +1738,8 @@ void cmMakefileTargetGenerator::CreateObjectLists(
|
||||
}
|
||||
|
||||
void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
|
||||
const std::string& lang)
|
||||
const std::string& lang,
|
||||
const std::string& /*config*/)
|
||||
{
|
||||
std::string responseVar =
|
||||
cmStrCat("CMAKE_", lang, "_USE_RESPONSE_FILE_FOR_INCLUDES");
|
||||
@@ -1724,11 +1747,11 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
|
||||
|
||||
std::vector<std::string> includes;
|
||||
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
|
||||
lang, this->ConfigName);
|
||||
lang, this->GetConfigName());
|
||||
|
||||
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
|
||||
includes, this->GeneratorTarget, lang, false, useResponseFile,
|
||||
this->ConfigName);
|
||||
this->GetConfigName());
|
||||
if (includeFlags.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
|
||||
cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
|
||||
|
||||
std::string GetConfigName();
|
||||
|
||||
protected:
|
||||
void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage);
|
||||
|
||||
@@ -81,7 +83,8 @@ protected:
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(cmSourceFile const& source, const char* pkgloc) override;
|
||||
void operator()(cmSourceFile const& source, const char* pkgloc,
|
||||
const std::string& config) override;
|
||||
|
||||
private:
|
||||
cmMakefileTargetGenerator* Generator;
|
||||
@@ -163,7 +166,8 @@ protected:
|
||||
/** Add commands for generate def files */
|
||||
void GenDefFile(std::vector<std::string>& real_link_commands);
|
||||
|
||||
void AddIncludeFlags(std::string& flags, const std::string& lang) override;
|
||||
void AddIncludeFlags(std::string& flags, const std::string& lang,
|
||||
const std::string& config) override;
|
||||
|
||||
virtual void CloseFileStreams();
|
||||
cmLocalUnixMakefileGenerator3* LocalGenerator;
|
||||
|
||||
@@ -22,8 +22,7 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
|
||||
: cmMakefileTargetGenerator(target)
|
||||
{
|
||||
this->CustomCommandDriver = OnUtility;
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
|
||||
this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,33 +41,25 @@
|
||||
cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
|
||||
cmGeneratorTarget* target)
|
||||
: cmNinjaTargetGenerator(target)
|
||||
, TargetLinkLanguage("")
|
||||
{
|
||||
this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
|
||||
if (target->GetType() == cmStateEnums::EXECUTABLE) {
|
||||
this->TargetNames = this->GetGeneratorTarget()->GetExecutableNames(
|
||||
GetLocalGenerator()->GetConfigName());
|
||||
} else {
|
||||
this->TargetNames = this->GetGeneratorTarget()->GetLibraryNames(
|
||||
GetLocalGenerator()->GetConfigName());
|
||||
}
|
||||
|
||||
if (target->GetType() != cmStateEnums::OBJECT_LIBRARY) {
|
||||
// on Windows the output dir is already needed at compile time
|
||||
// ensure the directory exists (OutDir test)
|
||||
EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
|
||||
for (auto const& config : this->GetConfigNames()) {
|
||||
EnsureDirectoryExists(target->GetDirectory(config));
|
||||
}
|
||||
}
|
||||
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName());
|
||||
this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
}
|
||||
|
||||
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default;
|
||||
|
||||
void cmNinjaNormalTargetGenerator::Generate()
|
||||
void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
|
||||
{
|
||||
if (this->TargetLinkLanguage.empty()) {
|
||||
std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
|
||||
if (this->TargetLinkLanguage(config).empty()) {
|
||||
cmSystemTools::Error("CMake can not determine linker language for "
|
||||
"target: " +
|
||||
this->GetGeneratorTarget()->GetName());
|
||||
@@ -75,25 +67,36 @@ void cmNinjaNormalTargetGenerator::Generate()
|
||||
}
|
||||
|
||||
// Write the rules for each language.
|
||||
this->WriteLanguagesRules();
|
||||
this->WriteLanguagesRules(config);
|
||||
|
||||
// Write the build statements
|
||||
this->WriteObjectBuildStatements();
|
||||
bool firstForConfig = true;
|
||||
for (auto const& fileConfig : this->GetConfigNames()) {
|
||||
this->WriteObjectBuildStatements(config, fileConfig, firstForConfig);
|
||||
firstForConfig = false;
|
||||
}
|
||||
|
||||
if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
||||
this->WriteObjectLibStatement();
|
||||
this->WriteObjectLibStatement(config);
|
||||
} else {
|
||||
// If this target has cuda language link inputs, and we need to do
|
||||
// device linking
|
||||
this->WriteDeviceLinkStatement();
|
||||
this->WriteLinkStatement();
|
||||
this->WriteDeviceLinkStatement(config);
|
||||
firstForConfig = true;
|
||||
for (auto const& fileConfig : this->GetConfigNames()) {
|
||||
this->WriteLinkStatement(config, fileConfig, firstForConfig);
|
||||
firstForConfig = false;
|
||||
}
|
||||
}
|
||||
this->GetGlobalGenerator()->AddTargetAlias(
|
||||
this->GetTargetName(), this->GetGeneratorTarget(), "all");
|
||||
|
||||
// Find ADDITIONAL_CLEAN_FILES
|
||||
this->AdditionalCleanFiles();
|
||||
this->AdditionalCleanFiles(config);
|
||||
}
|
||||
|
||||
void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
|
||||
void cmNinjaNormalTargetGenerator::WriteLanguagesRules(
|
||||
const std::string& config)
|
||||
{
|
||||
#ifdef NINJA_GEN_VERBOSE_FILES
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
|
||||
@@ -106,8 +109,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
|
||||
// Write rules for languages compiled in this target.
|
||||
std::set<std::string> languages;
|
||||
std::vector<cmSourceFile const*> sourceFiles;
|
||||
this->GetGeneratorTarget()->GetObjectSources(
|
||||
sourceFiles, this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
|
||||
this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config);
|
||||
for (cmSourceFile const* sf : sourceFiles) {
|
||||
std::string const lang = sf->GetLanguage();
|
||||
if (!lang.empty()) {
|
||||
@@ -115,7 +117,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
|
||||
}
|
||||
}
|
||||
for (std::string const& language : languages) {
|
||||
this->WriteLanguageRules(language);
|
||||
this->WriteLanguageRules(language, config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,22 +141,26 @@ const char* cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule() const
|
||||
std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule(
|
||||
const std::string& config) const
|
||||
{
|
||||
return this->TargetLinkLanguage + "_" +
|
||||
return this->TargetLinkLanguage(config) + "_" +
|
||||
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
|
||||
"_LINKER__" +
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(
|
||||
this->GetGeneratorTarget()->GetName());
|
||||
this->GetGeneratorTarget()->GetName()) +
|
||||
"_" + config;
|
||||
}
|
||||
|
||||
std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule() const
|
||||
std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule(
|
||||
const std::string& config) const
|
||||
{
|
||||
return this->TargetLinkLanguage + "_" +
|
||||
return this->TargetLinkLanguage(config) + "_" +
|
||||
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
|
||||
"_DEVICE_LINKER__" +
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(
|
||||
this->GetGeneratorTarget()->GetName());
|
||||
this->GetGeneratorTarget()->GetName()) +
|
||||
"_" + config;
|
||||
}
|
||||
|
||||
struct cmNinjaRemoveNoOpCommands
|
||||
@@ -165,9 +171,10 @@ struct cmNinjaRemoveNoOpCommands
|
||||
}
|
||||
};
|
||||
|
||||
void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
|
||||
void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(
|
||||
bool useResponseFile, const std::string& config)
|
||||
{
|
||||
cmNinjaRule rule(this->LanguageLinkerDeviceRule());
|
||||
cmNinjaRule rule(this->LanguageLinkerDeviceRule(config));
|
||||
if (!this->GetGlobalGenerator()->HasRule(rule.Name)) {
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
||||
@@ -241,30 +248,34 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
|
||||
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
|
||||
|
||||
// Write the linker rule with response file if needed.
|
||||
rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
|
||||
this->GetVisibleTypeName(), '.');
|
||||
rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
|
||||
this->GetVisibleTypeName(), " $TARGET_FILE");
|
||||
rule.Comment =
|
||||
cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
|
||||
this->GetVisibleTypeName(), '.');
|
||||
rule.Description =
|
||||
cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
|
||||
this->GetVisibleTypeName(), " $TARGET_FILE");
|
||||
rule.Restat = "$RESTAT";
|
||||
|
||||
this->GetGlobalGenerator()->AddRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
|
||||
void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
|
||||
const std::string& config)
|
||||
{
|
||||
cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType();
|
||||
|
||||
std::string linkRuleName = this->LanguageLinkerRule();
|
||||
std::string linkRuleName = this->LanguageLinkerRule(config);
|
||||
if (!this->GetGlobalGenerator()->HasRule(linkRuleName)) {
|
||||
cmNinjaRule rule(std::move(linkRuleName));
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
||||
vars.CMTargetType = cmState::GetTargetTypeName(targetType);
|
||||
|
||||
vars.Language = this->TargetLinkLanguage.c_str();
|
||||
std::string lang = this->TargetLinkLanguage(config);
|
||||
vars.Language = config.c_str();
|
||||
|
||||
if (this->TargetLinkLanguage == "Swift") {
|
||||
if (this->TargetLinkLanguage(config) == "Swift") {
|
||||
vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
|
||||
vars.SwiftModule = "$SWIFT_MODULE";
|
||||
vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
|
||||
@@ -278,7 +289,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
|
||||
|
||||
std::string responseFlag;
|
||||
|
||||
std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
|
||||
std::string cmakeVarLang =
|
||||
cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
|
||||
|
||||
// build response file name
|
||||
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
|
||||
@@ -286,7 +298,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
|
||||
|
||||
if (flag) {
|
||||
responseFlag = flag;
|
||||
} else if (this->TargetLinkLanguage != "CUDA") {
|
||||
} else if (this->TargetLinkLanguage(config) != "CUDA") {
|
||||
responseFlag = "@";
|
||||
}
|
||||
|
||||
@@ -304,7 +316,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
|
||||
rule.RspContent = "$in_newline";
|
||||
}
|
||||
rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
|
||||
if (this->TargetLinkLanguage == "Swift") {
|
||||
if (this->TargetLinkLanguage(config) == "Swift") {
|
||||
vars.SwiftSources = responseFlag.c_str();
|
||||
} else {
|
||||
vars.Objects = responseFlag.c_str();
|
||||
@@ -359,7 +371,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
|
||||
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
|
||||
|
||||
// Rule for linking library/executable.
|
||||
std::vector<std::string> linkCmds = this->ComputeLinkCmd();
|
||||
std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
|
||||
for (std::string& linkCmd : linkCmds) {
|
||||
linkCmd = cmStrCat(launcher, linkCmd);
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
|
||||
@@ -374,15 +386,18 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
|
||||
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
|
||||
|
||||
// Write the linker rule with response file if needed.
|
||||
rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
|
||||
this->GetVisibleTypeName(), '.');
|
||||
rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
|
||||
this->GetVisibleTypeName(), " $TARGET_FILE");
|
||||
rule.Comment =
|
||||
cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
|
||||
this->GetVisibleTypeName(), '.');
|
||||
rule.Description =
|
||||
cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
|
||||
this->GetVisibleTypeName(), " $TARGET_FILE");
|
||||
rule.Restat = "$RESTAT";
|
||||
this->GetGlobalGenerator()->AddRule(rule);
|
||||
}
|
||||
|
||||
if (this->TargetNames.Output != this->TargetNames.Real &&
|
||||
auto const tgtNames = this->TargetNames(config);
|
||||
if (tgtNames.Output != tgtNames.Real &&
|
||||
!this->GetGeneratorTarget()->IsFrameworkOnApple()) {
|
||||
std::string cmakeCommand =
|
||||
this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
@@ -441,7 +456,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
|
||||
return linkCmds;
|
||||
}
|
||||
|
||||
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
|
||||
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
|
||||
const std::string& config)
|
||||
{
|
||||
std::vector<std::string> linkCmds;
|
||||
cmMakefile* mf = this->GetMakefile();
|
||||
@@ -450,14 +466,14 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
|
||||
// this occurs when things like IPO is enabled, and we need to use the
|
||||
// CMAKE_<lang>_CREATE_STATIC_LIBRARY_IPO define instead.
|
||||
std::string linkCmdVar = this->GetGeneratorTarget()->GetCreateRuleVariable(
|
||||
this->TargetLinkLanguage, this->GetConfigName());
|
||||
this->TargetLinkLanguage(config), config);
|
||||
const char* linkCmd = mf->GetDefinition(linkCmdVar);
|
||||
if (linkCmd) {
|
||||
std::string linkCmdStr = linkCmd;
|
||||
if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) {
|
||||
std::string ruleVar = cmStrCat(
|
||||
"CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
|
||||
"_GNUtoMS_RULE");
|
||||
if (this->GetGeneratorTarget()->HasImplibGNUtoMS(config)) {
|
||||
std::string ruleVar =
|
||||
cmStrCat("CMAKE_", this->GeneratorTarget->GetLinkerLanguage(config),
|
||||
"_GNUtoMS_RULE");
|
||||
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
|
||||
linkCmdStr += rule;
|
||||
}
|
||||
@@ -469,9 +485,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
|
||||
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
|
||||
" -E __run_co_compile --lwyu=");
|
||||
cmGeneratorTarget& gt = *this->GetGeneratorTarget();
|
||||
const std::string cfgName = this->GetConfigName();
|
||||
std::string targetOutputReal = this->ConvertToNinjaPath(
|
||||
gt.GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
|
||||
gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
|
||||
/*realname=*/true));
|
||||
cmakeCommand += targetOutputReal;
|
||||
linkCmds.push_back(std::move(cmakeCommand));
|
||||
@@ -490,21 +505,21 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
|
||||
}
|
||||
// TODO: Use ARCHIVE_APPEND for archives over a certain size.
|
||||
{
|
||||
std::string linkCmdVar =
|
||||
cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_CREATE");
|
||||
std::string linkCmdVar = cmStrCat(
|
||||
"CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_CREATE");
|
||||
|
||||
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
|
||||
linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
|
||||
linkCmdVar, this->TargetLinkLanguage(config), config);
|
||||
|
||||
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
|
||||
cmExpandList(linkCmd, linkCmds);
|
||||
}
|
||||
{
|
||||
std::string linkCmdVar =
|
||||
cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_FINISH");
|
||||
std::string linkCmdVar = cmStrCat(
|
||||
"CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_FINISH");
|
||||
|
||||
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
|
||||
linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
|
||||
linkCmdVar, this->TargetLinkLanguage(config), config);
|
||||
|
||||
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
|
||||
cmExpandList(linkCmd, linkCmds);
|
||||
@@ -535,7 +550,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
|
||||
const std::string& config)
|
||||
{
|
||||
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
|
||||
if (!globalGen->GetLanguageEnabled("CUDA")) {
|
||||
@@ -545,7 +561,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
|
||||
|
||||
bool requiresDeviceLinking = requireDeviceLinking(
|
||||
*this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName);
|
||||
*this->GeneratorTarget, *this->GetLocalGenerator(), config);
|
||||
if (!requiresDeviceLinking) {
|
||||
return;
|
||||
}
|
||||
@@ -558,24 +574,23 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
std::string const& objExt =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
|
||||
|
||||
std::string const cfgName = this->GetConfigName();
|
||||
std::string const targetOutputReal = ConvertToNinjaPath(
|
||||
genTarget->ObjectDirectory + "cmake_device_link" + objExt);
|
||||
|
||||
std::string const targetOutputImplib = ConvertToNinjaPath(
|
||||
genTarget->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
|
||||
genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
|
||||
|
||||
this->DeviceLinkObject = targetOutputReal;
|
||||
|
||||
// Write comments.
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetCommonFileStream());
|
||||
const cmStateEnums::TargetType targetType = genTarget->GetType();
|
||||
this->GetBuildFileStream() << "# Device Link build statements for "
|
||||
<< cmState::GetTargetTypeName(targetType)
|
||||
<< " target " << this->GetTargetName() << "\n\n";
|
||||
this->GetCommonFileStream() << "# Device Link build statements for "
|
||||
<< cmState::GetTargetTypeName(targetType)
|
||||
<< " target " << this->GetTargetName() << "\n\n";
|
||||
|
||||
// Compute the comment.
|
||||
cmNinjaBuild build(this->LanguageLinkerDeviceRule());
|
||||
cmNinjaBuild build(this->LanguageLinkerDeviceRule(config));
|
||||
build.Comment =
|
||||
cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
|
||||
|
||||
@@ -584,14 +599,15 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
// Compute outputs.
|
||||
build.Outputs.push_back(targetOutputReal);
|
||||
// Compute specific libraries to link with.
|
||||
build.ExplicitDeps = this->GetObjects();
|
||||
build.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
|
||||
build.ExplicitDeps = this->GetObjects(config);
|
||||
build.ImplicitDeps =
|
||||
this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
|
||||
|
||||
std::string frameworkPath;
|
||||
std::string linkPath;
|
||||
|
||||
std::string createRule = genTarget->GetCreateRuleVariable(
|
||||
this->TargetLinkLanguage, this->GetConfigName());
|
||||
std::string createRule =
|
||||
genTarget->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
|
||||
const bool useWatcomQuote =
|
||||
this->GetMakefile()->IsOn(createRule + "_USE_WATCOM_QUOTE");
|
||||
cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
|
||||
@@ -605,17 +621,17 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
this->GetLocalGenerator()->GetStateSnapshot().GetDirectory(),
|
||||
globalGen));
|
||||
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
|
||||
linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
|
||||
|
||||
localGen.GetTargetFlags(
|
||||
linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
|
||||
vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
|
||||
linkLineComputer.get(), config, vars["LINK_LIBRARIES"], vars["FLAGS"],
|
||||
vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
|
||||
|
||||
this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
|
||||
|
||||
vars["LINK_FLAGS"] =
|
||||
cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
|
||||
vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
|
||||
|
||||
vars["MANIFESTS"] = this->GetManifests();
|
||||
vars["MANIFESTS"] = this->GetManifests(config);
|
||||
|
||||
vars["LINK_PATH"] = frameworkPath + linkPath;
|
||||
|
||||
@@ -624,24 +640,25 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
// code between the Makefile executable and library generators.
|
||||
if (targetType == cmStateEnums::EXECUTABLE) {
|
||||
std::string t = vars["FLAGS"];
|
||||
localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
|
||||
localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
|
||||
vars["FLAGS"] = t;
|
||||
} else {
|
||||
std::string t = vars["ARCH_FLAGS"];
|
||||
localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
|
||||
localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
|
||||
vars["ARCH_FLAGS"] = t;
|
||||
t.clear();
|
||||
localGen.AddLanguageFlagsForLinking(t, genTarget, cudaLinkLanguage,
|
||||
cfgName);
|
||||
config);
|
||||
vars["LANGUAGE_COMPILE_FLAGS"] = t;
|
||||
}
|
||||
if (genTarget->HasSOName(cfgName)) {
|
||||
auto const tgtNames = this->TargetNames(config);
|
||||
if (genTarget->HasSOName(config)) {
|
||||
vars["SONAME_FLAG"] =
|
||||
this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage);
|
||||
vars["SONAME"] = this->TargetNames.SharedObject;
|
||||
this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage(config));
|
||||
vars["SONAME"] = tgtNames.SharedObject;
|
||||
if (targetType == cmStateEnums::SHARED_LIBRARY) {
|
||||
std::string install_dir =
|
||||
this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName);
|
||||
this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(config);
|
||||
if (!install_dir.empty()) {
|
||||
vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
|
||||
install_dir, cmOutputConverter::SHELL);
|
||||
@@ -649,25 +666,28 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->TargetNames.ImportLibrary.empty()) {
|
||||
if (!tgtNames.ImportLibrary.empty()) {
|
||||
const std::string impLibPath = localGen.ConvertToOutputFormat(
|
||||
targetOutputImplib, cmOutputConverter::SHELL);
|
||||
vars["TARGET_IMPLIB"] = impLibPath;
|
||||
EnsureParentDirectoryExists(impLibPath);
|
||||
}
|
||||
|
||||
const std::string objPath = GetGeneratorTarget()->GetSupportDirectory();
|
||||
const std::string objPath =
|
||||
cmStrCat(GetGeneratorTarget()->GetSupportDirectory(),
|
||||
globalGen->ConfigDirectory(config));
|
||||
|
||||
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
|
||||
EnsureDirectoryExists(objPath);
|
||||
|
||||
this->SetMsvcTargetPdbVariable(vars);
|
||||
this->SetMsvcTargetPdbVariable(vars, config);
|
||||
|
||||
std::string& linkLibraries = vars["LINK_LIBRARIES"];
|
||||
std::string& link_path = vars["LINK_PATH"];
|
||||
if (globalGen->IsGCCOnWindows()) {
|
||||
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
|
||||
std::string& linkLibraries = vars["LINK_LIBRARIES"];
|
||||
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
|
||||
std::string& link_path = vars["LINK_PATH"];
|
||||
std::replace(link_path.begin(), link_path.end(), '\\', '/');
|
||||
}
|
||||
|
||||
@@ -675,65 +695,88 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
|
||||
// do not check if the user has explicitly forced a response file.
|
||||
int const commandLineLengthLimit =
|
||||
static_cast<int>(cmSystemTools::CalculateCommandLineLengthLimit()) -
|
||||
globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule());
|
||||
globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule(config));
|
||||
|
||||
build.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
|
||||
genTarget->GetName() + ".rsp");
|
||||
|
||||
// Gather order-only dependencies.
|
||||
this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(),
|
||||
build.OrderOnlyDeps);
|
||||
this->GetLocalGenerator()->AppendTargetDepends(
|
||||
this->GetGeneratorTarget(), build.OrderOnlyDeps, config, config);
|
||||
|
||||
// Write the build statement for this target.
|
||||
bool usedResponseFile = false;
|
||||
globalGen->WriteBuild(this->GetBuildFileStream(), build,
|
||||
globalGen->WriteBuild(this->GetCommonFileStream(), build,
|
||||
commandLineLengthLimit, &usedResponseFile);
|
||||
this->WriteDeviceLinkRule(usedResponseFile);
|
||||
this->WriteDeviceLinkRule(usedResponseFile, config);
|
||||
}
|
||||
|
||||
void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||
const std::string& config, const std::string& fileConfig,
|
||||
bool firstForConfig)
|
||||
{
|
||||
cmMakefile* mf = this->GetMakefile();
|
||||
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
|
||||
cmGeneratorTarget* gt = this->GetGeneratorTarget();
|
||||
|
||||
const std::string cfgName = this->GetConfigName();
|
||||
std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(cfgName));
|
||||
std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(config));
|
||||
std::string targetOutputReal = ConvertToNinjaPath(
|
||||
gt->GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
|
||||
gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
|
||||
/*realname=*/true));
|
||||
std::string targetOutputImplib = ConvertToNinjaPath(
|
||||
gt->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
|
||||
gt->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
|
||||
|
||||
if (config != fileConfig) {
|
||||
if (targetOutput == ConvertToNinjaPath(gt->GetFullPath(fileConfig))) {
|
||||
return;
|
||||
}
|
||||
if (targetOutputReal ==
|
||||
ConvertToNinjaPath(gt->GetFullPath(fileConfig,
|
||||
cmStateEnums::RuntimeBinaryArtifact,
|
||||
/*realname=*/true))) {
|
||||
return;
|
||||
}
|
||||
if (!gt->GetFullName(config, cmStateEnums::ImportLibraryArtifact)
|
||||
.empty() &&
|
||||
!gt->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
|
||||
.empty() &&
|
||||
targetOutputImplib ==
|
||||
ConvertToNinjaPath(gt->GetFullPath(
|
||||
fileConfig, cmStateEnums::ImportLibraryArtifact))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto const tgtNames = this->TargetNames(config);
|
||||
if (gt->IsAppBundleOnApple()) {
|
||||
// Create the app bundle
|
||||
std::string outpath = gt->GetDirectory(cfgName);
|
||||
this->OSXBundleGenerator->CreateAppBundle(this->TargetNames.Output,
|
||||
outpath);
|
||||
std::string outpath = gt->GetDirectory(config);
|
||||
this->OSXBundleGenerator->CreateAppBundle(tgtNames.Output, outpath,
|
||||
config);
|
||||
|
||||
// Calculate the output path
|
||||
targetOutput = cmStrCat(outpath, '/', this->TargetNames.Output);
|
||||
targetOutput = cmStrCat(outpath, '/', tgtNames.Output);
|
||||
targetOutput = this->ConvertToNinjaPath(targetOutput);
|
||||
targetOutputReal = cmStrCat(outpath, '/', this->TargetNames.Real);
|
||||
targetOutputReal = cmStrCat(outpath, '/', tgtNames.Real);
|
||||
targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
|
||||
} else if (gt->IsFrameworkOnApple()) {
|
||||
// Create the library framework.
|
||||
this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
|
||||
gt->GetDirectory(cfgName));
|
||||
this->OSXBundleGenerator->CreateFramework(
|
||||
tgtNames.Output, gt->GetDirectory(config), config);
|
||||
} else if (gt->IsCFBundleOnApple()) {
|
||||
// Create the core foundation bundle.
|
||||
this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
|
||||
gt->GetDirectory(cfgName));
|
||||
this->OSXBundleGenerator->CreateCFBundle(tgtNames.Output,
|
||||
gt->GetDirectory(config), config);
|
||||
}
|
||||
|
||||
// Write comments.
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetConfigFileStream(fileConfig));
|
||||
const cmStateEnums::TargetType targetType = gt->GetType();
|
||||
this->GetBuildFileStream()
|
||||
this->GetConfigFileStream(fileConfig)
|
||||
<< "# Link build statements for " << cmState::GetTargetTypeName(targetType)
|
||||
<< " target " << this->GetTargetName() << "\n\n";
|
||||
|
||||
cmNinjaBuild linkBuild(this->LanguageLinkerRule());
|
||||
cmNinjaBuild linkBuild(this->LanguageLinkerRule(config));
|
||||
cmNinjaVars& vars = linkBuild.Variables;
|
||||
|
||||
// Compute the comment.
|
||||
@@ -742,11 +785,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
|
||||
// Compute outputs.
|
||||
linkBuild.Outputs.push_back(targetOutputReal);
|
||||
if (firstForConfig) {
|
||||
globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal);
|
||||
}
|
||||
|
||||
if (this->TargetLinkLanguage == "Swift") {
|
||||
vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string {
|
||||
if (this->TargetLinkLanguage(config) == "Swift") {
|
||||
vars["SWIFT_LIBRARY_NAME"] = [this, config]() -> std::string {
|
||||
cmGeneratorTarget::Names targetNames =
|
||||
this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
|
||||
this->GetGeneratorTarget()->GetLibraryNames(config);
|
||||
return targetNames.Base;
|
||||
}();
|
||||
|
||||
@@ -782,12 +828,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
"/output-file-map.json"),
|
||||
cmOutputConverter::SHELL);
|
||||
|
||||
vars["SWIFT_SOURCES"] = [this]() -> std::string {
|
||||
vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
|
||||
std::vector<cmSourceFile const*> sources;
|
||||
std::stringstream oss;
|
||||
|
||||
this->GetGeneratorTarget()->GetObjectSources(sources,
|
||||
this->GetConfigName());
|
||||
this->GetGeneratorTarget()->GetObjectSources(sources, config);
|
||||
cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
|
||||
for (const auto& source : sources) {
|
||||
oss << " "
|
||||
@@ -801,27 +846,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
// Since we do not perform object builds, compute the
|
||||
// defines/flags/includes here so that they can be passed along
|
||||
// appropriately.
|
||||
vars["DEFINES"] = this->GetDefines("Swift");
|
||||
vars["FLAGS"] = this->GetFlags("Swift");
|
||||
vars["INCLUDES"] = this->GetIncludes("Swift");
|
||||
vars["DEFINES"] = this->GetDefines("Swift", config);
|
||||
vars["FLAGS"] = this->GetFlags("Swift", config);
|
||||
vars["INCLUDES"] = this->GetIncludes("Swift", config);
|
||||
}
|
||||
|
||||
// Compute specific libraries to link with.
|
||||
if (this->TargetLinkLanguage == "Swift") {
|
||||
if (this->TargetLinkLanguage(config) == "Swift") {
|
||||
std::vector<cmSourceFile const*> sources;
|
||||
gt->GetObjectSources(sources, this->GetConfigName());
|
||||
gt->GetObjectSources(sources, config);
|
||||
for (const auto& source : sources) {
|
||||
linkBuild.Outputs.push_back(
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source)));
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source, config)));
|
||||
linkBuild.ExplicitDeps.push_back(
|
||||
this->ConvertToNinjaPath(this->GetSourceFilePath(source)));
|
||||
}
|
||||
|
||||
linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]);
|
||||
} else {
|
||||
linkBuild.ExplicitDeps = this->GetObjects();
|
||||
linkBuild.ExplicitDeps = this->GetObjects(config);
|
||||
}
|
||||
linkBuild.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
|
||||
linkBuild.ImplicitDeps =
|
||||
this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
|
||||
|
||||
if (!this->DeviceLinkObject.empty()) {
|
||||
linkBuild.ExplicitDeps.push_back(this->DeviceLinkObject);
|
||||
@@ -831,7 +877,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
std::string linkPath;
|
||||
|
||||
std::string createRule =
|
||||
gt->GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName());
|
||||
gt->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
|
||||
bool useWatcomQuote = mf->IsOn(createRule + "_USE_WATCOM_QUOTE");
|
||||
cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
|
||||
|
||||
@@ -843,27 +889,29 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
this->GetLocalGenerator(),
|
||||
this->GetLocalGenerator()->GetStateSnapshot().GetDirectory()));
|
||||
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
|
||||
linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
|
||||
|
||||
localGen.GetTargetFlags(linkLineComputer.get(), this->GetConfigName(),
|
||||
localGen.GetTargetFlags(linkLineComputer.get(), config,
|
||||
vars["LINK_LIBRARIES"], vars["FLAGS"],
|
||||
vars["LINK_FLAGS"], frameworkPath, linkPath, gt);
|
||||
|
||||
// Add OS X version flags, if any.
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
|
||||
this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
|
||||
"COMPATIBILITY", true);
|
||||
this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
|
||||
"CURRENT", false);
|
||||
this->AppendOSXVerFlag(vars["LINK_FLAGS"],
|
||||
this->TargetLinkLanguage(config), "COMPATIBILITY",
|
||||
true);
|
||||
this->AppendOSXVerFlag(vars["LINK_FLAGS"],
|
||||
this->TargetLinkLanguage(config), "CURRENT", false);
|
||||
}
|
||||
|
||||
this->addPoolNinjaVariable("JOB_POOL_LINK", gt, vars);
|
||||
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
|
||||
vars["LINK_FLAGS"] =
|
||||
cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
|
||||
this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"],
|
||||
config);
|
||||
vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
|
||||
|
||||
vars["MANIFESTS"] = this->GetManifests();
|
||||
vars["MANIFESTS"] = this->GetManifests(config);
|
||||
|
||||
vars["LINK_PATH"] = frameworkPath + linkPath;
|
||||
std::string lwyuFlags;
|
||||
@@ -876,23 +924,26 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
// code between the Makefile executable and library generators.
|
||||
if (targetType == cmStateEnums::EXECUTABLE) {
|
||||
std::string t = vars["FLAGS"];
|
||||
localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
|
||||
localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
|
||||
config);
|
||||
t += lwyuFlags;
|
||||
vars["FLAGS"] = t;
|
||||
} else {
|
||||
std::string t = vars["ARCH_FLAGS"];
|
||||
localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
|
||||
localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
|
||||
config);
|
||||
vars["ARCH_FLAGS"] = t;
|
||||
t.clear();
|
||||
t += lwyuFlags;
|
||||
localGen.AddLanguageFlagsForLinking(t, gt, TargetLinkLanguage, cfgName);
|
||||
localGen.AddLanguageFlagsForLinking(
|
||||
t, gt, this->TargetLinkLanguage(config), config);
|
||||
vars["LANGUAGE_COMPILE_FLAGS"] = t;
|
||||
}
|
||||
if (gt->HasSOName(cfgName)) {
|
||||
vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
|
||||
vars["SONAME"] = this->TargetNames.SharedObject;
|
||||
if (gt->HasSOName(config)) {
|
||||
vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage(config));
|
||||
vars["SONAME"] = tgtNames.SharedObject;
|
||||
if (targetType == cmStateEnums::SHARED_LIBRARY) {
|
||||
std::string install_dir = gt->GetInstallNameDirForBuildTree(cfgName);
|
||||
std::string install_dir = gt->GetInstallNameDirForBuildTree(config);
|
||||
if (!install_dir.empty()) {
|
||||
vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
|
||||
install_dir, cmOutputConverter::SHELL);
|
||||
@@ -902,17 +953,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
|
||||
cmNinjaDeps byproducts;
|
||||
|
||||
if (!this->TargetNames.ImportLibrary.empty()) {
|
||||
if (!tgtNames.ImportLibrary.empty()) {
|
||||
const std::string impLibPath = localGen.ConvertToOutputFormat(
|
||||
targetOutputImplib, cmOutputConverter::SHELL);
|
||||
vars["TARGET_IMPLIB"] = impLibPath;
|
||||
EnsureParentDirectoryExists(impLibPath);
|
||||
if (gt->HasImportLibrary(cfgName)) {
|
||||
if (gt->HasImportLibrary(config)) {
|
||||
byproducts.push_back(targetOutputImplib);
|
||||
if (firstForConfig) {
|
||||
globalGen->GetByproductsForCleanTarget(config).push_back(
|
||||
targetOutputImplib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->SetMsvcTargetPdbVariable(vars)) {
|
||||
if (!this->SetMsvcTargetPdbVariable(vars, config)) {
|
||||
// It is common to place debug symbols at a specific place,
|
||||
// so we need a plain target name in the rule available.
|
||||
std::string prefix;
|
||||
@@ -927,16 +982,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
vars["TARGET_PDB"] = base + suffix + dbg_suffix;
|
||||
}
|
||||
|
||||
const std::string objPath = gt->GetSupportDirectory();
|
||||
const std::string objPath =
|
||||
cmStrCat(gt->GetSupportDirectory(), globalGen->ConfigDirectory(config));
|
||||
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
|
||||
EnsureDirectoryExists(objPath);
|
||||
|
||||
std::string& linkLibraries = vars["LINK_LIBRARIES"];
|
||||
std::string& link_path = vars["LINK_PATH"];
|
||||
if (globalGen->IsGCCOnWindows()) {
|
||||
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
|
||||
std::string& linkLibraries = vars["LINK_LIBRARIES"];
|
||||
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
|
||||
std::string& link_path = vars["LINK_PATH"];
|
||||
std::replace(link_path.begin(), link_path.end(), '\\', '/');
|
||||
}
|
||||
|
||||
@@ -947,23 +1003,30 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
|
||||
std::vector<std::string> preLinkCmdLines;
|
||||
std::vector<std::string> postBuildCmdLines;
|
||||
std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
|
||||
&preLinkCmdLines,
|
||||
&postBuildCmdLines };
|
||||
|
||||
for (unsigned i = 0; i != 3; ++i) {
|
||||
for (cmCustomCommand const& cc : *cmdLists[i]) {
|
||||
cmCustomCommandGenerator ccg(cc, cfgName, this->GetLocalGenerator());
|
||||
localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
|
||||
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
|
||||
std::transform(ccByproducts.begin(), ccByproducts.end(),
|
||||
std::back_inserter(byproducts), MapToNinjaPath());
|
||||
if (config == fileConfig) {
|
||||
std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
|
||||
&preLinkCmdLines,
|
||||
&postBuildCmdLines };
|
||||
|
||||
for (unsigned i = 0; i != 3; ++i) {
|
||||
for (cmCustomCommand const& cc : *cmdLists[i]) {
|
||||
cmCustomCommandGenerator ccg(cc, config, this->GetLocalGenerator());
|
||||
localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
|
||||
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
|
||||
std::transform(ccByproducts.begin(), ccByproducts.end(),
|
||||
std::back_inserter(byproducts), MapToNinjaPath());
|
||||
std::transform(
|
||||
ccByproducts.begin(), ccByproducts.end(),
|
||||
std::back_inserter(globalGen->GetByproductsForCleanTarget()),
|
||||
MapToNinjaPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybe create .def file from list of objects
|
||||
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
|
||||
gt->GetModuleDefinitionInfo(this->GetConfigName());
|
||||
gt->GetModuleDefinitionInfo(config);
|
||||
if (mdi && mdi->DefFileGenerated) {
|
||||
std::string cmakeCommand =
|
||||
this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
@@ -989,7 +1052,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
cmGeneratedFileStream fout(obj_list_file);
|
||||
|
||||
if (mdi->WindowsExportAllSymbols) {
|
||||
cmNinjaDeps objs = this->GetObjects();
|
||||
cmNinjaDeps objs = this->GetObjects(config);
|
||||
for (std::string const& obj : objs) {
|
||||
if (cmHasLiteralSuffix(obj, ".obj")) {
|
||||
fout << obj << "\n";
|
||||
@@ -1024,7 +1087,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
symlinkVars["POST_BUILD"] = postBuildCmdLine;
|
||||
}
|
||||
|
||||
std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
|
||||
std::string cmakeVarLang =
|
||||
cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
|
||||
|
||||
// build response file name
|
||||
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
|
||||
@@ -1032,8 +1096,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
const char* flag = GetMakefile()->GetDefinition(cmakeLinkVar);
|
||||
|
||||
bool const lang_supports_response =
|
||||
!(this->TargetLinkLanguage == "RC" ||
|
||||
(this->TargetLinkLanguage == "CUDA" && !flag));
|
||||
!(this->TargetLinkLanguage(config) == "RC" ||
|
||||
(this->TargetLinkLanguage(config) == "CUDA" && !flag));
|
||||
int commandLineLengthLimit = -1;
|
||||
if (!lang_supports_response || !this->ForceResponseFile()) {
|
||||
commandLineLengthLimit =
|
||||
@@ -1045,18 +1109,19 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
gt->GetName() + ".rsp");
|
||||
|
||||
// Gather order-only dependencies.
|
||||
this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps);
|
||||
this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
|
||||
config, fileConfig);
|
||||
|
||||
// Add order-only dependencies on versioning symlinks of shared libs we link.
|
||||
if (!this->GeneratorTarget->IsDLLPlatform()) {
|
||||
if (cmComputeLinkInformation* cli =
|
||||
this->GeneratorTarget->GetLinkInformation(this->GetConfigName())) {
|
||||
this->GeneratorTarget->GetLinkInformation(config)) {
|
||||
for (auto const& item : cli->GetItems()) {
|
||||
if (item.Target &&
|
||||
item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&
|
||||
!item.Target->IsFrameworkOnApple()) {
|
||||
std::string const& lib = this->ConvertToNinjaPath(
|
||||
item.Target->GetFullPath(this->GetConfigName()));
|
||||
std::string const& lib =
|
||||
this->ConvertToNinjaPath(item.Target->GetFullPath(config));
|
||||
if (std::find(linkBuild.ImplicitDeps.begin(),
|
||||
linkBuild.ImplicitDeps.end(),
|
||||
lib) == linkBuild.ImplicitDeps.end()) {
|
||||
@@ -1077,24 +1142,27 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
|
||||
// Write the build statement for this target.
|
||||
bool usedResponseFile = false;
|
||||
globalGen->WriteBuild(this->GetBuildFileStream(), linkBuild,
|
||||
globalGen->WriteBuild(this->GetConfigFileStream(fileConfig), linkBuild,
|
||||
commandLineLengthLimit, &usedResponseFile);
|
||||
this->WriteLinkRule(usedResponseFile);
|
||||
this->WriteLinkRule(usedResponseFile, config);
|
||||
|
||||
if (symlinkNeeded) {
|
||||
if (targetType == cmStateEnums::EXECUTABLE) {
|
||||
cmNinjaBuild build("CMAKE_SYMLINK_EXECUTABLE");
|
||||
build.Comment = "Create executable symlink " + targetOutput;
|
||||
build.Outputs.push_back(targetOutput);
|
||||
if (firstForConfig) {
|
||||
globalGen->GetByproductsForCleanTarget(config).push_back(targetOutput);
|
||||
}
|
||||
build.ExplicitDeps.push_back(targetOutputReal);
|
||||
build.Variables = std::move(symlinkVars);
|
||||
globalGen->WriteBuild(this->GetBuildFileStream(), build);
|
||||
globalGen->WriteBuild(this->GetConfigFileStream(fileConfig), build);
|
||||
} else {
|
||||
cmNinjaBuild build("CMAKE_SYMLINK_LIBRARY");
|
||||
build.Comment = "Create library symlink " + targetOutput;
|
||||
|
||||
std::string const soName = this->ConvertToNinjaPath(
|
||||
this->GetTargetFilePath(this->TargetNames.SharedObject));
|
||||
this->GetTargetFilePath(tgtNames.SharedObject, config));
|
||||
// If one link has to be created.
|
||||
if (targetOutputReal == soName || targetOutput == soName) {
|
||||
symlinkVars["SONAME"] =
|
||||
@@ -1103,33 +1171,58 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
||||
} else {
|
||||
symlinkVars["SONAME"].clear();
|
||||
build.Outputs.push_back(soName);
|
||||
if (firstForConfig) {
|
||||
globalGen->GetByproductsForCleanTarget(config).push_back(soName);
|
||||
}
|
||||
}
|
||||
build.Outputs.push_back(targetOutput);
|
||||
if (firstForConfig) {
|
||||
globalGen->GetByproductsForCleanTarget(config).push_back(targetOutput);
|
||||
}
|
||||
build.ExplicitDeps.push_back(targetOutputReal);
|
||||
build.Variables = std::move(symlinkVars);
|
||||
|
||||
globalGen->WriteBuild(this->GetBuildFileStream(), build);
|
||||
globalGen->WriteBuild(this->GetConfigFileStream(fileConfig), build);
|
||||
}
|
||||
}
|
||||
|
||||
// Add aliases for the file name and the target name.
|
||||
globalGen->AddTargetAlias(this->TargetNames.Output, gt);
|
||||
globalGen->AddTargetAlias(this->GetTargetName(), gt);
|
||||
globalGen->AddTargetAlias(tgtNames.Output, gt, config);
|
||||
globalGen->AddTargetAlias(this->GetTargetName(), gt, config);
|
||||
}
|
||||
|
||||
void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
|
||||
void cmNinjaNormalTargetGenerator::WriteObjectLibStatement(
|
||||
const std::string& config)
|
||||
{
|
||||
// Write a phony output that depends on all object files.
|
||||
{
|
||||
cmNinjaBuild build("phony");
|
||||
build.Comment = "Object library " + this->GetTargetName();
|
||||
this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
|
||||
build.Outputs);
|
||||
build.ExplicitDeps = this->GetObjects();
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
|
||||
build.Outputs, config);
|
||||
this->GetLocalGenerator()->AppendTargetOutputs(
|
||||
this->GetGeneratorTarget(),
|
||||
this->GetGlobalGenerator()->GetByproductsForCleanTarget(config), config);
|
||||
build.ExplicitDeps = this->GetObjects(config);
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), build);
|
||||
}
|
||||
|
||||
// Add aliases for the target name.
|
||||
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
|
||||
this->GetGeneratorTarget());
|
||||
this->GetGlobalGenerator()->AddTargetAlias(
|
||||
this->GetTargetName(), this->GetGeneratorTarget(), config);
|
||||
}
|
||||
|
||||
cmGeneratorTarget::Names cmNinjaNormalTargetGenerator::TargetNames(
|
||||
const std::string& config) const
|
||||
{
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
|
||||
return this->GeneratorTarget->GetExecutableNames(config);
|
||||
}
|
||||
return this->GeneratorTarget->GetLibraryNames(config);
|
||||
}
|
||||
|
||||
std::string cmNinjaNormalTargetGenerator::TargetLinkLanguage(
|
||||
const std::string& config) const
|
||||
{
|
||||
return this->GeneratorTarget->GetLinkerLanguage(config);
|
||||
}
|
||||
|
||||
@@ -17,30 +17,31 @@ public:
|
||||
cmNinjaNormalTargetGenerator(cmGeneratorTarget* target);
|
||||
~cmNinjaNormalTargetGenerator() override;
|
||||
|
||||
void Generate() override;
|
||||
void Generate(const std::string& config) override;
|
||||
|
||||
private:
|
||||
std::string LanguageLinkerRule() const;
|
||||
std::string LanguageLinkerDeviceRule() const;
|
||||
std::string LanguageLinkerRule(const std::string& config) const;
|
||||
std::string LanguageLinkerDeviceRule(const std::string& config) const;
|
||||
|
||||
const char* GetVisibleTypeName() const;
|
||||
void WriteLanguagesRules();
|
||||
void WriteLanguagesRules(const std::string& config);
|
||||
|
||||
void WriteLinkRule(bool useResponseFile);
|
||||
void WriteDeviceLinkRule(bool useResponseFile);
|
||||
void WriteLinkRule(bool useResponseFile, const std::string& config);
|
||||
void WriteDeviceLinkRule(bool useResponseFile, const std::string& config);
|
||||
|
||||
void WriteLinkStatement();
|
||||
void WriteDeviceLinkStatement();
|
||||
void WriteLinkStatement(const std::string& config,
|
||||
const std::string& fileConfig, bool firstForConfig);
|
||||
void WriteDeviceLinkStatement(const std::string& config);
|
||||
|
||||
void WriteObjectLibStatement();
|
||||
void WriteObjectLibStatement(const std::string& config);
|
||||
|
||||
std::vector<std::string> ComputeLinkCmd();
|
||||
std::vector<std::string> ComputeLinkCmd(const std::string& config);
|
||||
std::vector<std::string> ComputeDeviceLinkCmd();
|
||||
|
||||
private:
|
||||
// Target name info.
|
||||
cmGeneratorTarget::Names TargetNames;
|
||||
std::string TargetLinkLanguage;
|
||||
cmGeneratorTarget::Names TargetNames(const std::string& config) const;
|
||||
std::string TargetLinkLanguage(const std::string& config) const;
|
||||
std::string DeviceLinkObject;
|
||||
};
|
||||
|
||||
|
||||
+183
-141
@@ -68,9 +68,15 @@ cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target)
|
||||
|
||||
cmNinjaTargetGenerator::~cmNinjaTargetGenerator() = default;
|
||||
|
||||
cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const
|
||||
cmGeneratedFileStream& cmNinjaTargetGenerator::GetConfigFileStream(
|
||||
const std::string& config) const
|
||||
{
|
||||
return *this->GetGlobalGenerator()->GetBuildFileStream();
|
||||
return *this->GetGlobalGenerator()->GetConfigFileStream(config);
|
||||
}
|
||||
|
||||
cmGeneratedFileStream& cmNinjaTargetGenerator::GetCommonFileStream() const
|
||||
{
|
||||
return *this->GetGlobalGenerator()->GetCommonFileStream();
|
||||
}
|
||||
|
||||
cmGeneratedFileStream& cmNinjaTargetGenerator::GetRulesFileStream() const
|
||||
@@ -84,17 +90,19 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
|
||||
const std::string& lang) const
|
||||
const std::string& lang, const std::string& config) const
|
||||
{
|
||||
return lang + "_COMPILER__" +
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
|
||||
"_" + config;
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
|
||||
std::string const& lang) const
|
||||
std::string const& lang, const std::string& config) const
|
||||
{
|
||||
return lang + "_PREPROCESS__" +
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
|
||||
"_" + config;
|
||||
}
|
||||
|
||||
bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
|
||||
@@ -117,10 +125,11 @@ bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines(
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::LanguageDyndepRule(
|
||||
const std::string& lang) const
|
||||
const std::string& lang, const std::string& config) const
|
||||
{
|
||||
return lang + "_DYNDEP__" +
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
|
||||
"_" + config;
|
||||
}
|
||||
|
||||
bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
|
||||
@@ -128,9 +137,11 @@ bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
|
||||
return lang == "Fortran";
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget()
|
||||
std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
|
||||
const std::string& config)
|
||||
{
|
||||
return "cmake_object_order_depends_target_" + this->GetTargetName();
|
||||
return cmGlobalNinjaGenerator::OrderDependsTargetForTarget(
|
||||
this->GeneratorTarget, config);
|
||||
}
|
||||
|
||||
// TODO: Most of the code is picked up from
|
||||
@@ -138,10 +149,10 @@ std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget()
|
||||
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
|
||||
// Refactor it.
|
||||
std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
cmSourceFile const* source, const std::string& language)
|
||||
cmSourceFile const* source, const std::string& language,
|
||||
const std::string& config)
|
||||
{
|
||||
std::string flags = this->GetFlags(language);
|
||||
const std::string configName = this->LocalGenerator->GetConfigName();
|
||||
std::string flags = this->GetFlags(language, config);
|
||||
|
||||
// Add Fortran format flags.
|
||||
if (language == "Fortran") {
|
||||
@@ -150,7 +161,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
|
||||
// Add source file specific flags.
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
this->LocalGenerator, configName, this->GeneratorTarget, language);
|
||||
this->LocalGenerator, config, this->GeneratorTarget, language);
|
||||
|
||||
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
|
||||
if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
|
||||
@@ -166,16 +177,16 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
|
||||
// Add precompile headers compile options.
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(configName, language);
|
||||
this->GeneratorTarget->GetPchSource(config, language);
|
||||
|
||||
if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
std::string pchOptions;
|
||||
if (source->GetFullPath() == pchSource) {
|
||||
pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
|
||||
configName, language);
|
||||
pchOptions =
|
||||
this->GeneratorTarget->GetPchCreateCompileOptions(config, language);
|
||||
} else {
|
||||
pchOptions =
|
||||
this->GeneratorTarget->GetPchUseCompileOptions(configName, language);
|
||||
this->GeneratorTarget->GetPchUseCompileOptions(config, language);
|
||||
}
|
||||
|
||||
this->LocalGenerator->AppendCompileOptions(
|
||||
@@ -186,16 +197,17 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
|
||||
std::string const& language)
|
||||
std::string const& language,
|
||||
const std::string& config)
|
||||
{
|
||||
std::vector<std::string> includes;
|
||||
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
|
||||
language, this->GetConfigName());
|
||||
language, config);
|
||||
// Add include directory flags.
|
||||
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
|
||||
includes, this->GeneratorTarget, language,
|
||||
language == "RC", // full include paths for RC needed by cmcldeps
|
||||
false, this->GetConfigName());
|
||||
false, config);
|
||||
if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
|
||||
std::replace(includeFlags.begin(), includeFlags.end(), '\\', '/');
|
||||
}
|
||||
@@ -232,13 +244,18 @@ bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
|
||||
// TODO: Refactor with
|
||||
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
|
||||
std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
|
||||
const std::string& language)
|
||||
const std::string& language,
|
||||
const std::string& config)
|
||||
{
|
||||
std::set<std::string> defines;
|
||||
const std::string config = this->LocalGenerator->GetConfigName();
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
this->LocalGenerator, config, this->GeneratorTarget, language);
|
||||
|
||||
// Seriously??
|
||||
if (this->GetGlobalGenerator()->IsMultiConfig()) {
|
||||
defines.insert(cmStrCat("CMAKE_INTDIR=\"", config, '"'));
|
||||
}
|
||||
|
||||
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
|
||||
if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
|
||||
this->LocalGenerator->AppendDefines(
|
||||
@@ -253,17 +270,17 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
|
||||
genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
|
||||
}
|
||||
|
||||
std::string definesString = this->GetDefines(language);
|
||||
std::string definesString = this->GetDefines(language, config);
|
||||
this->LocalGenerator->JoinDefines(defines, definesString, language);
|
||||
|
||||
return definesString;
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::ComputeIncludes(
|
||||
cmSourceFile const* source, const std::string& language)
|
||||
cmSourceFile const* source, const std::string& language,
|
||||
const std::string& config)
|
||||
{
|
||||
std::vector<std::string> includes;
|
||||
const std::string config = this->LocalGenerator->GetConfigName();
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
this->LocalGenerator, config, this->GeneratorTarget, language);
|
||||
|
||||
@@ -277,13 +294,13 @@ std::string cmNinjaTargetGenerator::ComputeIncludes(
|
||||
std::string includesString = this->LocalGenerator->GetIncludeFlags(
|
||||
includes, this->GeneratorTarget, language, true, false, config);
|
||||
this->LocalGenerator->AppendFlags(includesString,
|
||||
this->GetIncludes(language));
|
||||
this->GetIncludes(language, config));
|
||||
|
||||
return includesString;
|
||||
}
|
||||
|
||||
cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
|
||||
const std::string& linkLanguage) const
|
||||
const std::string& linkLanguage, const std::string& config) const
|
||||
{
|
||||
// Static libraries never depend on other targets for linking.
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
|
||||
@@ -292,7 +309,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
|
||||
}
|
||||
|
||||
cmComputeLinkInformation* cli =
|
||||
this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
|
||||
this->GeneratorTarget->GetLinkInformation(config);
|
||||
if (!cli) {
|
||||
return cmNinjaDeps();
|
||||
}
|
||||
@@ -303,8 +320,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
|
||||
|
||||
// Add a dependency on the link definitions file, if any.
|
||||
if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
|
||||
this->GeneratorTarget->GetModuleDefinitionInfo(
|
||||
this->GetConfigName())) {
|
||||
this->GeneratorTarget->GetModuleDefinitionInfo(config)) {
|
||||
for (cmSourceFile const* src : mdi->Sources) {
|
||||
result.push_back(this->ConvertToNinjaPath(src->GetFullPath()));
|
||||
}
|
||||
@@ -312,15 +328,14 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
|
||||
|
||||
// Add a dependency on user-specified manifest files, if any.
|
||||
std::vector<cmSourceFile const*> manifest_srcs;
|
||||
this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
|
||||
this->GeneratorTarget->GetManifests(manifest_srcs, config);
|
||||
for (cmSourceFile const* manifest_src : manifest_srcs) {
|
||||
result.push_back(this->ConvertToNinjaPath(manifest_src->GetFullPath()));
|
||||
}
|
||||
|
||||
// Add user-specified dependencies.
|
||||
std::vector<std::string> linkDeps;
|
||||
this->GeneratorTarget->GetLinkDepends(linkDeps, this->ConfigName,
|
||||
linkLanguage);
|
||||
this->GeneratorTarget->GetLinkDepends(linkDeps, config, linkLanguage);
|
||||
std::transform(linkDeps.begin(), linkDeps.end(), std::back_inserter(result),
|
||||
MapToNinjaPath());
|
||||
|
||||
@@ -334,7 +349,7 @@ std::string cmNinjaTargetGenerator::GetSourceFilePath(
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetObjectFilePath(
|
||||
cmSourceFile const* source) const
|
||||
cmSourceFile const* source, const std::string& config) const
|
||||
{
|
||||
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
|
||||
if (!path.empty()) {
|
||||
@@ -342,13 +357,14 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
|
||||
}
|
||||
std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
|
||||
path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
|
||||
path += this->GetGlobalGenerator()->ConfigDirectory(config);
|
||||
path += "/";
|
||||
path += objectName;
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
|
||||
cmSourceFile const* source) const
|
||||
cmSourceFile const* source, const std::string& config) const
|
||||
{
|
||||
// Choose an extension to compile already-preprocessed source.
|
||||
std::string ppExt = source->GetExtension();
|
||||
@@ -378,19 +394,21 @@ std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
|
||||
path += "/";
|
||||
}
|
||||
path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
|
||||
path += this->GetGlobalGenerator()->ConfigDirectory(config);
|
||||
path += "/";
|
||||
path += ppName;
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetDyndepFilePath(
|
||||
std::string const& lang) const
|
||||
std::string const& lang, const std::string& config) const
|
||||
{
|
||||
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
|
||||
if (!path.empty()) {
|
||||
path += "/";
|
||||
}
|
||||
path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
|
||||
path += this->GetGlobalGenerator()->ConfigDirectory(config);
|
||||
path += "/";
|
||||
path += lang;
|
||||
path += ".dd";
|
||||
@@ -398,25 +416,27 @@ std::string cmNinjaTargetGenerator::GetDyndepFilePath(
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetTargetDependInfoPath(
|
||||
std::string const& lang) const
|
||||
std::string const& lang, const std::string& config) const
|
||||
{
|
||||
std::string path =
|
||||
cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/',
|
||||
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
|
||||
'/', lang, "DependInfo.json");
|
||||
this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang,
|
||||
"DependInfo.json");
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
|
||||
std::string cmNinjaTargetGenerator::GetTargetOutputDir(
|
||||
const std::string& config) const
|
||||
{
|
||||
std::string dir = this->GeneratorTarget->GetDirectory(this->GetConfigName());
|
||||
std::string dir = this->GeneratorTarget->GetDirectory(config);
|
||||
return ConvertToNinjaPath(dir);
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetTargetFilePath(
|
||||
const std::string& name) const
|
||||
const std::string& name, const std::string& config) const
|
||||
{
|
||||
std::string path = this->GetTargetOutputDir();
|
||||
std::string path = this->GetTargetOutputDir(config);
|
||||
if (path.empty() || path == ".") {
|
||||
return name;
|
||||
}
|
||||
@@ -430,21 +450,21 @@ std::string cmNinjaTargetGenerator::GetTargetName() const
|
||||
return this->GeneratorTarget->GetName();
|
||||
}
|
||||
|
||||
bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
|
||||
bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(
|
||||
cmNinjaVars& vars, const std::string& config) const
|
||||
{
|
||||
cmMakefile* mf = this->GetMakefile();
|
||||
if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
|
||||
mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID") ||
|
||||
mf->GetDefinition("MSVC_CUDA_ARCHITECTURE_ID")) {
|
||||
std::string pdbPath;
|
||||
std::string compilePdbPath = this->ComputeTargetCompilePDB();
|
||||
std::string compilePdbPath = this->ComputeTargetCompilePDB(config);
|
||||
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
|
||||
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
|
||||
this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
|
||||
pdbPath = cmStrCat(
|
||||
this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
|
||||
this->GeneratorTarget->GetPDBName(this->GetConfigName()));
|
||||
pdbPath = cmStrCat(this->GeneratorTarget->GetPDBDirectory(config), '/',
|
||||
this->GeneratorTarget->GetPDBName(config));
|
||||
}
|
||||
|
||||
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
@@ -460,15 +480,17 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language)
|
||||
void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language,
|
||||
const std::string& config)
|
||||
{
|
||||
#ifdef NINJA_GEN_VERBOSE_FILES
|
||||
this->GetRulesFileStream() << "# Rules for language " << language << "\n\n";
|
||||
#endif
|
||||
this->WriteCompileRule(language);
|
||||
this->WriteCompileRule(language, config);
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
const std::string& config)
|
||||
{
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
|
||||
@@ -509,7 +531,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
|
||||
|
||||
std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
ConvertToNinjaPath(this->GetTargetDependInfoPath(lang)),
|
||||
ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)),
|
||||
cmLocalGenerator::SHELL);
|
||||
|
||||
std::string launcher;
|
||||
@@ -524,7 +546,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
|
||||
|
||||
if (explicitPP) {
|
||||
cmNinjaRule rule(this->LanguagePreprocessRule(lang));
|
||||
cmNinjaRule rule(this->LanguagePreprocessRule(lang, config));
|
||||
// Explicit preprocessing always uses a depfile.
|
||||
rule.DepType = ""; // no deps= for multiple outputs
|
||||
rule.DepFile = "$DEP_FILE";
|
||||
@@ -604,7 +626,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
|
||||
if (needDyndep) {
|
||||
// Write the rule for ninja dyndep file generation.
|
||||
cmNinjaRule rule(this->LanguageDyndepRule(lang));
|
||||
cmNinjaRule rule(this->LanguageDyndepRule(lang, config));
|
||||
// Command line length is almost always limited -> use response file for
|
||||
// dyndep rules
|
||||
rule.RspFile = "$out.rsp";
|
||||
@@ -628,7 +650,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
this->GetGlobalGenerator()->AddRule(rule);
|
||||
}
|
||||
|
||||
cmNinjaRule rule(this->LanguageCompilerRule(lang));
|
||||
cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
|
||||
// If using a response file, move defines, includes, and flags into it.
|
||||
if (!responseFlag.empty()) {
|
||||
rule.RspFile = "$RSP_FILE";
|
||||
@@ -787,50 +809,52 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
this->GetGlobalGenerator()->AddRule(rule);
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteObjectBuildStatements()
|
||||
void cmNinjaTargetGenerator::WriteObjectBuildStatements(
|
||||
const std::string& config, const std::string& fileConfig,
|
||||
bool firstForConfig)
|
||||
{
|
||||
// Write comments.
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
|
||||
this->GetBuildFileStream()
|
||||
cmGlobalNinjaGenerator::WriteDivider(this->GetConfigFileStream(fileConfig));
|
||||
this->GetConfigFileStream(fileConfig)
|
||||
<< "# Object build statements for "
|
||||
<< cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
|
||||
<< " target " << this->GetTargetName() << "\n\n";
|
||||
|
||||
{
|
||||
std::vector<cmSourceFile const*> customCommands;
|
||||
this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
|
||||
this->GeneratorTarget->GetCustomCommands(customCommands, config);
|
||||
for (cmSourceFile const* sf : customCommands) {
|
||||
cmCustomCommand const* cc = sf->GetCustomCommand();
|
||||
this->GetLocalGenerator()->AddCustomCommandTarget(
|
||||
cc, this->GetGeneratorTarget());
|
||||
// Record the custom commands for this target. The container is used
|
||||
// in WriteObjectBuildStatement when called in a loop below.
|
||||
this->CustomCommands.push_back(cc);
|
||||
this->Configs[config].CustomCommands.push_back(cc);
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<cmSourceFile const*> headerSources;
|
||||
this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
|
||||
this->GeneratorTarget->GetHeaderSources(headerSources, config);
|
||||
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
|
||||
headerSources, this->MacOSXContentGenerator.get());
|
||||
headerSources, this->MacOSXContentGenerator.get(), config);
|
||||
}
|
||||
{
|
||||
std::vector<cmSourceFile const*> extraSources;
|
||||
this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
|
||||
this->GeneratorTarget->GetExtraSources(extraSources, config);
|
||||
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
|
||||
extraSources, this->MacOSXContentGenerator.get());
|
||||
extraSources, this->MacOSXContentGenerator.get(), config);
|
||||
}
|
||||
{
|
||||
if (firstForConfig) {
|
||||
const char* pchExtension =
|
||||
GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
std::vector<cmSourceFile const*> externalObjects;
|
||||
this->GeneratorTarget->GetExternalObjects(externalObjects,
|
||||
this->ConfigName);
|
||||
this->GeneratorTarget->GetExternalObjects(externalObjects, config);
|
||||
for (cmSourceFile const* sf : externalObjects) {
|
||||
const auto objectFileName = this->GetSourceFilePath(sf);
|
||||
auto objectFileName = this->GetGlobalGenerator()->ExpandCFGIntDir(
|
||||
this->GetSourceFilePath(sf), config);
|
||||
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
|
||||
this->Objects.push_back(objectFileName);
|
||||
this->Configs[config].Objects.push_back(objectFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -838,19 +862,19 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
|
||||
{
|
||||
cmNinjaBuild build("phony");
|
||||
build.Comment = "Order-only phony target for " + this->GetTargetName();
|
||||
build.Outputs.push_back(this->OrderDependsTargetForTarget());
|
||||
build.Outputs.push_back(this->OrderDependsTargetForTarget(config));
|
||||
|
||||
cmNinjaDeps& orderOnlyDeps = build.OrderOnlyDeps;
|
||||
this->GetLocalGenerator()->AppendTargetDepends(
|
||||
this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering);
|
||||
this->GeneratorTarget, orderOnlyDeps, config, fileConfig,
|
||||
DependOnTargetOrdering);
|
||||
|
||||
// Add order-only dependencies on other files associated with the target.
|
||||
cmAppend(orderOnlyDeps, this->ExtraFiles);
|
||||
cmAppend(orderOnlyDeps, this->Configs[config].ExtraFiles);
|
||||
|
||||
// Add order-only dependencies on custom command outputs.
|
||||
for (cmCustomCommand const* cc : this->CustomCommands) {
|
||||
cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
|
||||
this->GetLocalGenerator());
|
||||
for (cmCustomCommand const* cc : this->Configs[config].CustomCommands) {
|
||||
cmCustomCommandGenerator ccg(*cc, config, this->GetLocalGenerator());
|
||||
const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
|
||||
const std::vector<std::string>& ccbyproducts = ccg.GetByproducts();
|
||||
std::transform(ccoutputs.begin(), ccoutputs.end(),
|
||||
@@ -876,26 +900,27 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
|
||||
orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir));
|
||||
}
|
||||
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
|
||||
this->GetGlobalGenerator()->WriteBuild(
|
||||
this->GetConfigFileStream(fileConfig), build);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
|
||||
this->GeneratorTarget->GetObjectSources(objectSources, config);
|
||||
for (cmSourceFile const* sf : objectSources) {
|
||||
this->WriteObjectBuildStatement(sf);
|
||||
this->WriteObjectBuildStatement(sf, config, fileConfig, firstForConfig);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& langDDIFiles : this->DDIFiles) {
|
||||
for (auto const& langDDIFiles : this->Configs[config].DDIFiles) {
|
||||
std::string const& language = langDDIFiles.first;
|
||||
cmNinjaDeps const& ddiFiles = langDDIFiles.second;
|
||||
|
||||
cmNinjaBuild build(this->LanguageDyndepRule(language));
|
||||
build.Outputs.push_back(this->GetDyndepFilePath(language));
|
||||
cmNinjaBuild build(this->LanguageDyndepRule(language, config));
|
||||
build.Outputs.push_back(this->GetDyndepFilePath(language, config));
|
||||
build.ExplicitDeps = ddiFiles;
|
||||
|
||||
this->WriteTargetDependInfo(language);
|
||||
this->WriteTargetDependInfo(language, config);
|
||||
|
||||
// Make sure dyndep files for all our dependencies have already
|
||||
// been generated so that the '<LANG>Modules.json' files they
|
||||
@@ -906,46 +931,51 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
|
||||
// refactoring the Ninja generator to generate targets in
|
||||
// dependency order so that we can collect the needed information.
|
||||
this->GetLocalGenerator()->AppendTargetDepends(
|
||||
this->GeneratorTarget, build.OrderOnlyDeps, DependOnTargetArtifact);
|
||||
this->GeneratorTarget, build.OrderOnlyDeps, config, fileConfig,
|
||||
DependOnTargetArtifact);
|
||||
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
|
||||
this->GetGlobalGenerator()->WriteBuild(
|
||||
this->GetConfigFileStream(fileConfig), build);
|
||||
}
|
||||
|
||||
this->GetBuildFileStream() << "\n";
|
||||
this->GetConfigFileStream(fileConfig) << "\n";
|
||||
|
||||
if (!this->SwiftOutputMap.empty()) {
|
||||
if (!this->Configs[config].SwiftOutputMap.empty()) {
|
||||
std::string const mapFilePath =
|
||||
this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json";
|
||||
std::string const targetSwiftDepsPath = [this]() -> std::string {
|
||||
std::string const targetSwiftDepsPath = [this, config]() -> std::string {
|
||||
cmGeneratorTarget const* target = this->GeneratorTarget;
|
||||
if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
|
||||
return name;
|
||||
}
|
||||
return this->ConvertToNinjaPath(target->GetSupportDirectory() + "/" +
|
||||
target->GetName() + ".swiftdeps");
|
||||
config + "/" + target->GetName() +
|
||||
".swiftdeps");
|
||||
}();
|
||||
|
||||
// build the global target dependencies
|
||||
// https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
|
||||
Json::Value deps(Json::objectValue);
|
||||
deps["swift-dependencies"] = targetSwiftDepsPath;
|
||||
this->SwiftOutputMap[""] = deps;
|
||||
this->Configs[config].SwiftOutputMap[""] = deps;
|
||||
|
||||
cmGeneratedFileStream output(mapFilePath);
|
||||
output << this->SwiftOutputMap;
|
||||
output << this->Configs[config].SwiftOutputMap;
|
||||
}
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
cmSourceFile const* source)
|
||||
cmSourceFile const* source, const std::string& config,
|
||||
const std::string& fileConfig, bool firstForConfig)
|
||||
{
|
||||
std::string const language = source->GetLanguage();
|
||||
std::string const sourceFileName =
|
||||
language == "RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
|
||||
std::string const objectDir =
|
||||
this->ConvertToNinjaPath(this->GeneratorTarget->GetSupportDirectory());
|
||||
std::string const objectDir = this->ConvertToNinjaPath(
|
||||
cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
|
||||
this->GetGlobalGenerator()->ConfigDirectory(config)));
|
||||
std::string const objectFileName =
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source));
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
|
||||
std::string const objectFileDir =
|
||||
cmSystemTools::GetFilenamePath(objectFileName);
|
||||
|
||||
@@ -961,11 +991,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
int const commandLineLengthLimit =
|
||||
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
|
||||
|
||||
cmNinjaBuild objBuild(this->LanguageCompilerRule(language));
|
||||
cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
|
||||
cmNinjaVars& vars = objBuild.Variables;
|
||||
vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
|
||||
vars["DEFINES"] = this->ComputeDefines(source, language);
|
||||
vars["INCLUDES"] = this->ComputeIncludes(source, language);
|
||||
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
|
||||
vars["DEFINES"] = this->ComputeDefines(source, language, config);
|
||||
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
|
||||
|
||||
if (!this->NeedDepTypeMSVC(language)) {
|
||||
bool replaceExt(false);
|
||||
@@ -993,11 +1023,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]);
|
||||
|
||||
objBuild.Outputs.push_back(objectFileName);
|
||||
const char* pchExtension =
|
||||
this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
|
||||
// Add this object to the list of object files.
|
||||
this->Objects.push_back(objectFileName);
|
||||
if (firstForConfig) {
|
||||
const char* pchExtension =
|
||||
this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
|
||||
// Add this object to the list of object files.
|
||||
this->Configs[config].Objects.push_back(objectFileName);
|
||||
}
|
||||
}
|
||||
|
||||
objBuild.ExplicitDeps.push_back(sourceFileName);
|
||||
@@ -1006,13 +1038,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
std::vector<std::string> depList;
|
||||
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(this->GetConfigName(), language);
|
||||
this->GeneratorTarget->GetPchSource(config, language);
|
||||
if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
depList.push_back(
|
||||
this->GeneratorTarget->GetPchHeader(this->GetConfigName(), language));
|
||||
depList.push_back(this->GeneratorTarget->GetPchHeader(config, language));
|
||||
if (source->GetFullPath() != pchSource) {
|
||||
depList.push_back(
|
||||
this->GeneratorTarget->GetPchFile(this->GetConfigName(), language));
|
||||
depList.push_back(this->GeneratorTarget->GetPchFile(config, language));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,7 +1063,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
MapToNinjaPath());
|
||||
}
|
||||
|
||||
objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
|
||||
objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config));
|
||||
|
||||
// If the source file is GENERATED and does not have a custom command
|
||||
// (either attached to this source file or another one), assume that one of
|
||||
@@ -1053,10 +1083,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
// For some cases we do an explicit preprocessor invocation.
|
||||
bool const explicitPP = this->NeedExplicitPreprocessing(language);
|
||||
if (explicitPP) {
|
||||
cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language));
|
||||
cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language, config));
|
||||
|
||||
std::string const ppFileName =
|
||||
this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source));
|
||||
this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
|
||||
ppBuild.Outputs.push_back(ppFileName);
|
||||
|
||||
ppBuild.RspFile = ppFileName + ".rsp";
|
||||
@@ -1114,7 +1144,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
|
||||
std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags(
|
||||
sourceDirectory, this->GeneratorTarget, language, false, false,
|
||||
this->GetConfigName());
|
||||
config);
|
||||
|
||||
vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
|
||||
}
|
||||
@@ -1138,17 +1168,19 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
std::string const ddiFile = objectFileName + ".ddi";
|
||||
ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
|
||||
ppBuild.ImplicitOuts.push_back(ddiFile);
|
||||
this->DDIFiles[language].push_back(ddiFile);
|
||||
if (firstForConfig) {
|
||||
this->Configs[config].DDIFiles[language].push_back(ddiFile);
|
||||
}
|
||||
}
|
||||
|
||||
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
|
||||
ppBuild.Variables);
|
||||
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), ppBuild,
|
||||
commandLineLengthLimit);
|
||||
this->GetGlobalGenerator()->WriteBuild(
|
||||
this->GetConfigFileStream(fileConfig), ppBuild, commandLineLengthLimit);
|
||||
}
|
||||
if (needDyndep) {
|
||||
std::string const dyndep = this->GetDyndepFilePath(language);
|
||||
std::string const dyndep = this->GetDyndepFilePath(language, config);
|
||||
objBuild.OrderOnlyDeps.push_back(dyndep);
|
||||
vars["dyndep"] = dyndep;
|
||||
}
|
||||
@@ -1163,15 +1195,15 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
|
||||
vars);
|
||||
|
||||
this->SetMsvcTargetPdbVariable(vars);
|
||||
this->SetMsvcTargetPdbVariable(vars, config);
|
||||
|
||||
objBuild.RspFile = objectFileName + ".rsp";
|
||||
|
||||
if (language == "Swift") {
|
||||
this->EmitSwiftDependencyInfo(source);
|
||||
this->EmitSwiftDependencyInfo(source, config);
|
||||
} else {
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(),
|
||||
objBuild, commandLineLengthLimit);
|
||||
this->GetGlobalGenerator()->WriteBuild(
|
||||
this->GetConfigFileStream(fileConfig), objBuild, commandLineLengthLimit);
|
||||
}
|
||||
|
||||
if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
|
||||
@@ -1181,11 +1213,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
std::transform(build.Outputs.begin(), build.Outputs.end(),
|
||||
build.Outputs.begin(), MapToNinjaPath());
|
||||
build.ExplicitDeps = objBuild.Outputs;
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
|
||||
this->GetGlobalGenerator()->WriteBuild(
|
||||
this->GetConfigFileStream(fileConfig), build);
|
||||
}
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
|
||||
void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
|
||||
const std::string& config)
|
||||
{
|
||||
Json::Value tdi(Json::objectValue);
|
||||
tdi["language"] = lang;
|
||||
@@ -1213,7 +1247,7 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
|
||||
Json::Value& tdi_include_dirs = tdi["include-dirs"] = Json::arrayValue;
|
||||
std::vector<std::string> includes;
|
||||
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
|
||||
lang, this->GetConfigName());
|
||||
lang, config);
|
||||
for (std::string const& i : includes) {
|
||||
// Convert the include directories the same way we do for -I flags.
|
||||
// See upstream ninja issue 1251.
|
||||
@@ -1222,22 +1256,22 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
|
||||
|
||||
Json::Value& tdi_linked_target_dirs = tdi["linked-target-dirs"] =
|
||||
Json::arrayValue;
|
||||
for (std::string const& l : this->GetLinkedTargetDirectories()) {
|
||||
for (std::string const& l : this->GetLinkedTargetDirectories(config)) {
|
||||
tdi_linked_target_dirs.append(l);
|
||||
}
|
||||
|
||||
std::string const tdin = this->GetTargetDependInfoPath(lang);
|
||||
std::string const tdin = this->GetTargetDependInfoPath(lang, config);
|
||||
cmGeneratedFileStream tdif(tdin);
|
||||
tdif << tdi;
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
|
||||
cmSourceFile const* source)
|
||||
cmSourceFile const* source, const std::string& config)
|
||||
{
|
||||
std::string const sourceFilePath =
|
||||
this->ConvertToNinjaPath(this->GetSourceFilePath(source));
|
||||
std::string const objectFilePath =
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source));
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
|
||||
std::string const swiftDepsPath = [source, objectFilePath]() -> std::string {
|
||||
if (const char* name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
|
||||
return name;
|
||||
@@ -1250,10 +1284,10 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
|
||||
}
|
||||
return objectFilePath + ".dia";
|
||||
}();
|
||||
std::string const makeDepsPath = [this, source]() -> std::string {
|
||||
std::string const makeDepsPath = [this, source, config]() -> std::string {
|
||||
cmLocalNinjaGenerator const* local = this->GetLocalGenerator();
|
||||
std::string const objectFileName =
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source));
|
||||
this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
|
||||
std::string const objectFileDir =
|
||||
cmSystemTools::GetFilenamePath(objectFileName);
|
||||
|
||||
@@ -1274,7 +1308,7 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
|
||||
entry["dependencies"] = makeDepsPath;
|
||||
entry["swift-dependencies"] = swiftDepsPath;
|
||||
entry["diagnostics"] = swiftDiaPath;
|
||||
SwiftOutputMap[sourceFilePath] = entry;
|
||||
this->Configs[config].SwiftOutputMap[sourceFilePath] = entry;
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::ExportObjectCompileCommand(
|
||||
@@ -1349,27 +1383,34 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
|
||||
this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName);
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::AdditionalCleanFiles()
|
||||
void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
|
||||
{
|
||||
if (const char* prop_value =
|
||||
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
|
||||
cmLocalNinjaGenerator* lg = this->LocalGenerator;
|
||||
std::vector<std::string> cleanFiles;
|
||||
cmExpandList(cmGeneratorExpression::Evaluate(
|
||||
prop_value, lg,
|
||||
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"),
|
||||
this->GeneratorTarget),
|
||||
cmExpandList(cmGeneratorExpression::Evaluate(prop_value, lg, config,
|
||||
this->GeneratorTarget),
|
||||
cleanFiles);
|
||||
std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
|
||||
cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator();
|
||||
for (std::string const& cleanFile : cleanFiles) {
|
||||
// Support relative paths
|
||||
gg->AddAdditionalCleanFile(
|
||||
cmSystemTools::CollapseFullPath(cleanFile, binaryDir));
|
||||
cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmNinjaDeps cmNinjaTargetGenerator::GetObjects(const std::string& config) const
|
||||
{
|
||||
auto const it = this->Configs.find(config);
|
||||
if (it != this->Configs.end()) {
|
||||
return it->second.Objects;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::EnsureDirectoryExists(
|
||||
const std::string& path) const
|
||||
{
|
||||
@@ -1392,7 +1433,7 @@ void cmNinjaTargetGenerator::EnsureParentDirectoryExists(
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
|
||||
cmSourceFile const& source, const char* pkgloc)
|
||||
cmSourceFile const& source, const char* pkgloc, const std::string& config)
|
||||
{
|
||||
// Skip OS X content when not building a Framework or Bundle.
|
||||
if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
|
||||
@@ -1400,7 +1441,8 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
|
||||
}
|
||||
|
||||
std::string macdir =
|
||||
this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
|
||||
this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
|
||||
config);
|
||||
|
||||
// Get the input file location.
|
||||
std::string input = source.GetFullPath();
|
||||
@@ -1412,11 +1454,11 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
|
||||
output = this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(output);
|
||||
|
||||
// Write a build statement to copy the content into the bundle.
|
||||
this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input,
|
||||
output);
|
||||
this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input, output,
|
||||
config);
|
||||
|
||||
// Add as a dependency to the target so that it gets called.
|
||||
this->Generator->ExtraFiles.push_back(std::move(output));
|
||||
this->Generator->Configs[config].ExtraFiles.push_back(std::move(output));
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::addPoolNinjaVariable(
|
||||
|
||||
@@ -38,16 +38,17 @@ public:
|
||||
/// Destructor.
|
||||
~cmNinjaTargetGenerator() override;
|
||||
|
||||
virtual void Generate() = 0;
|
||||
virtual void Generate(const std::string& config) = 0;
|
||||
|
||||
std::string GetTargetName() const;
|
||||
|
||||
bool NeedDepTypeMSVC(const std::string& lang) const;
|
||||
|
||||
protected:
|
||||
bool SetMsvcTargetPdbVariable(cmNinjaVars&) const;
|
||||
bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const;
|
||||
|
||||
cmGeneratedFileStream& GetBuildFileStream() const;
|
||||
cmGeneratedFileStream& GetConfigFileStream(const std::string& config) const;
|
||||
cmGeneratedFileStream& GetCommonFileStream() const;
|
||||
cmGeneratedFileStream& GetRulesFileStream() const;
|
||||
|
||||
cmGeneratorTarget* GetGeneratorTarget() const
|
||||
@@ -64,15 +65,18 @@ protected:
|
||||
|
||||
cmMakefile* GetMakefile() const { return this->Makefile; }
|
||||
|
||||
std::string LanguageCompilerRule(const std::string& lang) const;
|
||||
std::string LanguagePreprocessRule(std::string const& lang) const;
|
||||
std::string LanguageCompilerRule(const std::string& lang,
|
||||
const std::string& config) const;
|
||||
std::string LanguagePreprocessRule(std::string const& lang,
|
||||
const std::string& config) const;
|
||||
bool NeedExplicitPreprocessing(std::string const& lang) const;
|
||||
std::string LanguageDyndepRule(std::string const& lang) const;
|
||||
std::string LanguageDyndepRule(std::string const& lang,
|
||||
const std::string& config) const;
|
||||
bool NeedDyndep(std::string const& lang) const;
|
||||
bool UsePreprocessedSource(std::string const& lang) const;
|
||||
bool CompilePreprocessedSourceWithDefines(std::string const& lang) const;
|
||||
|
||||
std::string OrderDependsTargetForTarget();
|
||||
std::string OrderDependsTargetForTarget(const std::string& config);
|
||||
|
||||
std::string ComputeOrderDependsForTarget();
|
||||
|
||||
@@ -82,15 +86,19 @@ protected:
|
||||
* by LanguageFlagsVarName().
|
||||
*/
|
||||
std::string ComputeFlagsForObject(cmSourceFile const* source,
|
||||
const std::string& language);
|
||||
const std::string& language,
|
||||
const std::string& config);
|
||||
|
||||
void AddIncludeFlags(std::string& flags, std::string const& lang) override;
|
||||
void AddIncludeFlags(std::string& flags, std::string const& lang,
|
||||
const std::string& config) override;
|
||||
|
||||
std::string ComputeDefines(cmSourceFile const* source,
|
||||
const std::string& language);
|
||||
const std::string& language,
|
||||
const std::string& config);
|
||||
|
||||
std::string ComputeIncludes(cmSourceFile const* source,
|
||||
const std::string& language);
|
||||
const std::string& language,
|
||||
const std::string& config);
|
||||
|
||||
std::string ConvertToNinjaPath(const std::string& path) const
|
||||
{
|
||||
@@ -102,36 +110,51 @@ protected:
|
||||
}
|
||||
|
||||
/// @return the list of link dependency for the given target @a target.
|
||||
cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage) const;
|
||||
cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage,
|
||||
const std::string& config) const;
|
||||
|
||||
/// @return the source file path for the given @a source.
|
||||
std::string GetSourceFilePath(cmSourceFile const* source) const;
|
||||
|
||||
/// @return the object file path for the given @a source.
|
||||
std::string GetObjectFilePath(cmSourceFile const* source) const;
|
||||
std::string GetObjectFilePath(cmSourceFile const* source,
|
||||
const std::string& config) const;
|
||||
|
||||
/// @return the preprocessed source file path for the given @a source.
|
||||
std::string GetPreprocessedFilePath(cmSourceFile const* source) const;
|
||||
std::string GetPreprocessedFilePath(cmSourceFile const* source,
|
||||
const std::string& config) const;
|
||||
|
||||
/// @return the dyndep file path for this target.
|
||||
std::string GetDyndepFilePath(std::string const& lang) const;
|
||||
std::string GetDyndepFilePath(std::string const& lang,
|
||||
const std::string& config) const;
|
||||
|
||||
/// @return the target dependency scanner info file path
|
||||
std::string GetTargetDependInfoPath(std::string const& lang) const;
|
||||
std::string GetTargetDependInfoPath(std::string const& lang,
|
||||
const std::string& config) const;
|
||||
|
||||
/// @return the file path where the target named @a name is generated.
|
||||
std::string GetTargetFilePath(const std::string& name) const;
|
||||
std::string GetTargetFilePath(const std::string& name,
|
||||
const std::string& config) const;
|
||||
|
||||
/// @return the output path for the target.
|
||||
virtual std::string GetTargetOutputDir() const;
|
||||
virtual std::string GetTargetOutputDir(const std::string& config) const;
|
||||
|
||||
void WriteLanguageRules(const std::string& language);
|
||||
void WriteCompileRule(const std::string& language);
|
||||
void WriteObjectBuildStatements();
|
||||
void WriteObjectBuildStatement(cmSourceFile const* source);
|
||||
void WriteTargetDependInfo(std::string const& lang);
|
||||
void WriteLanguageRules(const std::string& language,
|
||||
const std::string& config);
|
||||
void WriteCompileRule(const std::string& language,
|
||||
const std::string& config);
|
||||
void WriteObjectBuildStatements(const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
bool firstForConfig);
|
||||
void WriteObjectBuildStatement(cmSourceFile const* source,
|
||||
const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
bool firstForConfig);
|
||||
void WriteTargetDependInfo(std::string const& lang,
|
||||
const std::string& config);
|
||||
|
||||
void EmitSwiftDependencyInfo(cmSourceFile const* source);
|
||||
void EmitSwiftDependencyInfo(cmSourceFile const* source,
|
||||
const std::string& config);
|
||||
|
||||
void ExportObjectCompileCommand(
|
||||
std::string const& language, std::string const& sourceFileName,
|
||||
@@ -139,9 +162,9 @@ protected:
|
||||
std::string const& objectFileDir, std::string const& flags,
|
||||
std::string const& defines, std::string const& includes);
|
||||
|
||||
void AdditionalCleanFiles();
|
||||
void AdditionalCleanFiles(const std::string& config);
|
||||
|
||||
cmNinjaDeps GetObjects() const { return this->Objects; }
|
||||
cmNinjaDeps GetObjects(const std::string& config) const;
|
||||
|
||||
void EnsureDirectoryExists(const std::string& dir) const;
|
||||
void EnsureParentDirectoryExists(const std::string& path) const;
|
||||
@@ -155,7 +178,8 @@ protected:
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(cmSourceFile const& source, const char* pkgloc) override;
|
||||
void operator()(cmSourceFile const& source, const char* pkgloc,
|
||||
const std::string& config) override;
|
||||
|
||||
private:
|
||||
cmNinjaTargetGenerator* Generator;
|
||||
@@ -174,14 +198,20 @@ protected:
|
||||
|
||||
private:
|
||||
cmLocalNinjaGenerator* LocalGenerator;
|
||||
/// List of object files for this target.
|
||||
cmNinjaDeps Objects;
|
||||
// Fortran Support
|
||||
std::map<std::string, cmNinjaDeps> DDIFiles;
|
||||
// Swift Support
|
||||
Json::Value SwiftOutputMap;
|
||||
std::vector<cmCustomCommand const*> CustomCommands;
|
||||
cmNinjaDeps ExtraFiles;
|
||||
|
||||
struct ByConfig
|
||||
{
|
||||
/// List of object files for this target.
|
||||
cmNinjaDeps Objects;
|
||||
// Fortran Support
|
||||
std::map<std::string, cmNinjaDeps> DDIFiles;
|
||||
// Swift Support
|
||||
Json::Value SwiftOutputMap;
|
||||
std::vector<cmCustomCommand const*> CustomCommands;
|
||||
cmNinjaDeps ExtraFiles;
|
||||
};
|
||||
|
||||
std::map<std::string, ByConfig> Configs;
|
||||
};
|
||||
|
||||
#endif // ! cmNinjaTargetGenerator_h
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalNinjaGenerator.h"
|
||||
#include "cmLocalNinjaGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmNinjaTypes.h"
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
|
||||
cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
|
||||
cmGeneratorTarget* target)
|
||||
@@ -31,14 +31,18 @@ cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
|
||||
|
||||
cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default;
|
||||
|
||||
void cmNinjaUtilityTargetGenerator::Generate()
|
||||
void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
|
||||
{
|
||||
cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
|
||||
cmLocalNinjaGenerator* lg = this->GetLocalGenerator();
|
||||
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
|
||||
|
||||
std::string configDir;
|
||||
if (genTarget->Target->IsPerConfig()) {
|
||||
configDir = gg->ConfigDirectory(config);
|
||||
}
|
||||
std::string utilCommandName =
|
||||
cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/",
|
||||
cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles", configDir, "/",
|
||||
this->GetTargetName(), ".util");
|
||||
utilCommandName = this->ConvertToNinjaPath(utilCommandName);
|
||||
|
||||
@@ -55,8 +59,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
|
||||
|
||||
for (std::vector<cmCustomCommand> const* cmdList : cmdLists) {
|
||||
for (cmCustomCommand const& ci : *cmdList) {
|
||||
cmCustomCommandGenerator ccg(ci, this->GetConfigName(), lg);
|
||||
lg->AppendCustomCommandDeps(ccg, deps);
|
||||
cmCustomCommandGenerator ccg(ci, config, lg);
|
||||
lg->AppendCustomCommandDeps(ccg, deps, config);
|
||||
lg->AppendCustomCommandLines(ccg, commands);
|
||||
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
|
||||
std::transform(ccByproducts.begin(), ccByproducts.end(),
|
||||
@@ -69,13 +73,11 @@ void cmNinjaUtilityTargetGenerator::Generate()
|
||||
}
|
||||
|
||||
{
|
||||
std::string const& config =
|
||||
this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
|
||||
std::vector<cmSourceFile*> sources;
|
||||
genTarget->GetSourceFiles(sources, config);
|
||||
for (cmSourceFile const* source : sources) {
|
||||
if (cmCustomCommand const* cc = source->GetCustomCommand()) {
|
||||
cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), lg);
|
||||
cmCustomCommandGenerator ccg(*cc, config, lg);
|
||||
lg->AddCustomCommandTarget(cc, genTarget);
|
||||
|
||||
// Depend on all custom command outputs.
|
||||
@@ -89,13 +91,21 @@ void cmNinjaUtilityTargetGenerator::Generate()
|
||||
}
|
||||
}
|
||||
|
||||
lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs);
|
||||
lg->AppendTargetDepends(genTarget, deps);
|
||||
std::string outputConfig;
|
||||
if (genTarget->Target->IsPerConfig()) {
|
||||
outputConfig = config;
|
||||
}
|
||||
lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs, outputConfig);
|
||||
if (genTarget->Target->GetType() != cmStateEnums::GLOBAL_TARGET) {
|
||||
lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(),
|
||||
config);
|
||||
}
|
||||
lg->AppendTargetDepends(genTarget, deps, config, config);
|
||||
|
||||
if (commands.empty()) {
|
||||
phonyBuild.Comment = "Utility command for " + this->GetTargetName();
|
||||
phonyBuild.ExplicitDeps = std::move(deps);
|
||||
gg->WriteBuild(this->GetBuildFileStream(), phonyBuild);
|
||||
gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
|
||||
} else {
|
||||
std::string command =
|
||||
lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
|
||||
@@ -118,6 +128,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
|
||||
lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
|
||||
cmOutputConverter::SHELL));
|
||||
cmSystemTools::ReplaceString(command, "$(ARGS)", "");
|
||||
command = gg->ExpandCFGIntDir(command, config);
|
||||
|
||||
if (command.find('$') != std::string::npos) {
|
||||
return;
|
||||
@@ -127,22 +138,32 @@ void cmNinjaUtilityTargetGenerator::Generate()
|
||||
gg->SeenCustomCommandOutput(util_output);
|
||||
}
|
||||
|
||||
std::string ccConfig;
|
||||
if (genTarget->Target->IsPerConfig() &&
|
||||
genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
|
||||
ccConfig = config;
|
||||
}
|
||||
gg->WriteCustomCommandBuild(command, desc,
|
||||
"Utility command for " + this->GetTargetName(),
|
||||
/*depfile*/ "", /*job_pool*/ "", uses_terminal,
|
||||
/*restat*/ true, util_outputs, deps);
|
||||
/*restat*/ true, util_outputs, ccConfig, deps);
|
||||
|
||||
phonyBuild.ExplicitDeps.push_back(utilCommandName);
|
||||
gg->WriteBuild(this->GetBuildFileStream(), phonyBuild);
|
||||
gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
|
||||
}
|
||||
|
||||
// Find ADDITIONAL_CLEAN_FILES
|
||||
this->AdditionalCleanFiles();
|
||||
this->AdditionalCleanFiles(config);
|
||||
|
||||
// Add an alias for the logical target name regardless of what directory
|
||||
// contains it. Skip this for GLOBAL_TARGET because they are meant to
|
||||
// be per-directory and have one at the top-level anyway.
|
||||
if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
|
||||
gg->AddTargetAlias(this->GetTargetName(), genTarget);
|
||||
gg->AddTargetAlias(this->GetTargetName(), genTarget, config);
|
||||
} else if (gg->IsMultiConfig() && genTarget->Target->IsPerConfig()) {
|
||||
cmNinjaBuild phonyAlias("phony");
|
||||
gg->AppendTargetOutputs(genTarget, phonyAlias.Outputs, "");
|
||||
phonyAlias.ExplicitDeps = phonyBuild.Outputs;
|
||||
gg->WriteBuild(this->GetConfigFileStream(config), phonyAlias);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "cmNinjaTargetGenerator.h"
|
||||
|
||||
class cmGeneratorTarget;
|
||||
@@ -15,7 +17,7 @@ public:
|
||||
cmNinjaUtilityTargetGenerator(cmGeneratorTarget* target);
|
||||
~cmNinjaUtilityTargetGenerator() override;
|
||||
|
||||
void Generate() override;
|
||||
void Generate(const std::string& config) override;
|
||||
};
|
||||
|
||||
#endif // ! cmNinjaUtilityTargetGenerator_h
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "cmOSXBundleGenerator.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
@@ -15,12 +14,10 @@
|
||||
|
||||
class cmSourceFile;
|
||||
|
||||
cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
|
||||
std::string configName)
|
||||
cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target)
|
||||
: GT(target)
|
||||
, Makefile(target->Target->GetMakefile())
|
||||
, LocalGenerator(target->GetLocalGenerator())
|
||||
, ConfigName(std::move(configName))
|
||||
, MacContentFolders(nullptr)
|
||||
{
|
||||
if (this->MustSkip()) {
|
||||
@@ -34,34 +31,34 @@ bool cmOSXBundleGenerator::MustSkip()
|
||||
}
|
||||
|
||||
void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
|
||||
std::string& outpath)
|
||||
std::string& outpath,
|
||||
const std::string& config)
|
||||
{
|
||||
if (this->MustSkip()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute bundle directory names.
|
||||
std::string out =
|
||||
cmStrCat(outpath, '/',
|
||||
this->GT->GetAppBundleDirectory(this->ConfigName,
|
||||
cmGeneratorTarget::FullLevel));
|
||||
std::string out = cmStrCat(
|
||||
outpath, '/',
|
||||
this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::FullLevel));
|
||||
cmSystemTools::MakeDirectory(out);
|
||||
this->Makefile->AddCMakeOutputFile(out);
|
||||
|
||||
// Configure the Info.plist file. Note that it needs the executable name
|
||||
// to be set.
|
||||
std::string plist =
|
||||
cmStrCat(outpath, '/',
|
||||
this->GT->GetAppBundleDirectory(this->ConfigName,
|
||||
cmGeneratorTarget::ContentLevel),
|
||||
"/Info.plist");
|
||||
std::string plist = cmStrCat(
|
||||
outpath, '/',
|
||||
this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::ContentLevel),
|
||||
"/Info.plist");
|
||||
this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist);
|
||||
this->Makefile->AddCMakeOutputFile(plist);
|
||||
outpath = out;
|
||||
}
|
||||
|
||||
void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
|
||||
const std::string& outpath)
|
||||
const std::string& outpath,
|
||||
const std::string& config)
|
||||
{
|
||||
if (this->MustSkip()) {
|
||||
return;
|
||||
@@ -70,15 +67,13 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
|
||||
assert(this->MacContentFolders);
|
||||
|
||||
// Compute the location of the top-level foo.framework directory.
|
||||
std::string contentdir =
|
||||
cmStrCat(outpath, '/',
|
||||
this->GT->GetFrameworkDirectory(this->ConfigName,
|
||||
cmGeneratorTarget::ContentLevel),
|
||||
'/');
|
||||
std::string contentdir = cmStrCat(
|
||||
outpath, '/',
|
||||
this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::ContentLevel),
|
||||
'/');
|
||||
|
||||
std::string newoutpath = outpath + "/" +
|
||||
this->GT->GetFrameworkDirectory(this->ConfigName,
|
||||
cmGeneratorTarget::FullLevel);
|
||||
this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::FullLevel);
|
||||
|
||||
std::string frameworkVersion = this->GT->GetFrameworkVersion();
|
||||
|
||||
@@ -156,27 +151,26 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
|
||||
}
|
||||
|
||||
void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
|
||||
const std::string& root)
|
||||
const std::string& root,
|
||||
const std::string& config)
|
||||
{
|
||||
if (this->MustSkip()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute bundle directory names.
|
||||
std::string out =
|
||||
cmStrCat(root, '/',
|
||||
this->GT->GetCFBundleDirectory(this->ConfigName,
|
||||
cmGeneratorTarget::FullLevel));
|
||||
std::string out = cmStrCat(
|
||||
root, '/',
|
||||
this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::FullLevel));
|
||||
cmSystemTools::MakeDirectory(out);
|
||||
this->Makefile->AddCMakeOutputFile(out);
|
||||
|
||||
// Configure the Info.plist file. Note that it needs the executable name
|
||||
// to be set.
|
||||
std::string plist =
|
||||
cmStrCat(root, '/',
|
||||
this->GT->GetCFBundleDirectory(this->ConfigName,
|
||||
cmGeneratorTarget::ContentLevel),
|
||||
"/Info.plist");
|
||||
std::string plist = cmStrCat(
|
||||
root, '/',
|
||||
this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::ContentLevel),
|
||||
"/Info.plist");
|
||||
std::string name = cmSystemTools::GetFilenameName(targetName);
|
||||
this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist);
|
||||
this->Makefile->AddCMakeOutputFile(plist);
|
||||
@@ -184,7 +178,7 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
|
||||
|
||||
void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
|
||||
std::vector<cmSourceFile const*> const& sources,
|
||||
MacOSXContentGeneratorType* generator)
|
||||
MacOSXContentGeneratorType* generator, const std::string& config)
|
||||
{
|
||||
if (this->MustSkip()) {
|
||||
return;
|
||||
@@ -194,20 +188,19 @@ void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
|
||||
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||
this->GT->GetTargetSourceFileFlags(source);
|
||||
if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
|
||||
(*generator)(*source, tsFlags.MacFolder);
|
||||
(*generator)(*source, tsFlags.MacFolder, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
|
||||
const char* pkgloc)
|
||||
const char* pkgloc, const std::string& config)
|
||||
{
|
||||
// Construct the full path to the content subdirectory.
|
||||
|
||||
std::string macdir =
|
||||
cmStrCat(this->GT->GetMacContentDirectory(
|
||||
this->ConfigName, cmStateEnums::RuntimeBinaryArtifact),
|
||||
'/', pkgloc);
|
||||
std::string macdir = cmStrCat(this->GT->GetMacContentDirectory(
|
||||
config, cmStateEnums::RuntimeBinaryArtifact),
|
||||
'/', pkgloc);
|
||||
cmSystemTools::MakeDirectory(macdir);
|
||||
|
||||
// Record use of this content location. Only the first level
|
||||
|
||||
@@ -17,29 +17,33 @@ class cmSourceFile;
|
||||
class cmOSXBundleGenerator
|
||||
{
|
||||
public:
|
||||
cmOSXBundleGenerator(cmGeneratorTarget* target, std::string configName);
|
||||
cmOSXBundleGenerator(cmGeneratorTarget* target);
|
||||
|
||||
// create an app bundle at a given root, and return
|
||||
// the directory within the bundle that contains the executable
|
||||
void CreateAppBundle(const std::string& targetName, std::string& root);
|
||||
void CreateAppBundle(const std::string& targetName, std::string& root,
|
||||
const std::string& config);
|
||||
|
||||
// create a framework at a given root
|
||||
void CreateFramework(const std::string& targetName, const std::string& root);
|
||||
void CreateFramework(const std::string& targetName, const std::string& root,
|
||||
const std::string& config);
|
||||
|
||||
// create a cf bundle at a given root
|
||||
void CreateCFBundle(const std::string& targetName, const std::string& root);
|
||||
void CreateCFBundle(const std::string& targetName, const std::string& root,
|
||||
const std::string& config);
|
||||
|
||||
struct MacOSXContentGeneratorType
|
||||
{
|
||||
virtual ~MacOSXContentGeneratorType() = default;
|
||||
virtual void operator()(cmSourceFile const& source,
|
||||
const char* pkgloc) = 0;
|
||||
virtual void operator()(cmSourceFile const& source, const char* pkgloc,
|
||||
const std::string& config) = 0;
|
||||
};
|
||||
|
||||
void GenerateMacOSXContentStatements(
|
||||
std::vector<cmSourceFile const*> const& sources,
|
||||
MacOSXContentGeneratorType* generator);
|
||||
std::string InitMacOSXContentDirectory(const char* pkgloc);
|
||||
MacOSXContentGeneratorType* generator, const std::string& config);
|
||||
std::string InitMacOSXContentDirectory(const char* pkgloc,
|
||||
const std::string& config);
|
||||
|
||||
void SetMacContentFolders(std::set<std::string>* macContentFolders)
|
||||
{
|
||||
@@ -53,7 +57,6 @@ private:
|
||||
cmGeneratorTarget* GT;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalGenerator* LocalGenerator;
|
||||
std::string ConfigName;
|
||||
std::set<std::string>* MacContentFolders;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,9 +43,10 @@ std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source,
|
||||
{
|
||||
std::string result(source);
|
||||
// Convert it to an output path.
|
||||
if (output == SHELL || output == WATCOMQUOTE) {
|
||||
if (output == SHELL || output == WATCOMQUOTE || output == NINJAMULTI) {
|
||||
result = this->ConvertDirectorySeparatorsForShell(source);
|
||||
result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
|
||||
result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE,
|
||||
output == NINJAMULTI);
|
||||
} else if (output == RESPONSE) {
|
||||
result = this->EscapeForShell(result, false, false, false);
|
||||
}
|
||||
@@ -79,9 +80,9 @@ static bool cmOutputConverterIsShellOperator(cm::string_view str)
|
||||
return (shellOperators.count(str) != 0);
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::EscapeForShell(cm::string_view str,
|
||||
bool makeVars, bool forEcho,
|
||||
bool useWatcomQuote) const
|
||||
std::string cmOutputConverter::EscapeForShell(
|
||||
cm::string_view str, bool makeVars, bool forEcho, bool useWatcomQuote,
|
||||
bool unescapeNinjaConfiguration) const
|
||||
{
|
||||
// Do not escape shell operators.
|
||||
if (cmOutputConverterIsShellOperator(str)) {
|
||||
@@ -95,6 +96,9 @@ std::string cmOutputConverter::EscapeForShell(cm::string_view str,
|
||||
} else if (!this->LinkScriptShell) {
|
||||
flags |= Shell_Flag_Make;
|
||||
}
|
||||
if (unescapeNinjaConfiguration) {
|
||||
flags |= Shell_Flag_UnescapeNinjaConfiguration;
|
||||
}
|
||||
if (makeVars) {
|
||||
flags |= Shell_Flag_AllowMakeVariables;
|
||||
}
|
||||
@@ -511,5 +515,14 @@ std::string cmOutputConverter::Shell__GetArgument(cm::string_view in,
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & Shell_Flag_UnescapeNinjaConfiguration) {
|
||||
std::string ninjaConfigReplace;
|
||||
if (flags & Shell_Flag_IsUnix) {
|
||||
ninjaConfigReplace += '\\';
|
||||
}
|
||||
ninjaConfigReplace += "$${CONFIGURATION}";
|
||||
cmSystemTools::ReplaceString(out, ninjaConfigReplace, "${CONFIGURATION}");
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
{
|
||||
SHELL,
|
||||
WATCOMQUOTE,
|
||||
NINJAMULTI,
|
||||
RESPONSE
|
||||
};
|
||||
std::string ConvertToOutputFormat(cm::string_view source,
|
||||
@@ -70,12 +71,14 @@ public:
|
||||
/** The target shell quoting uses extra single Quotes for Watcom tools. */
|
||||
Shell_Flag_WatcomQuote = (1 << 7),
|
||||
|
||||
Shell_Flag_IsUnix = (1 << 8)
|
||||
Shell_Flag_IsUnix = (1 << 8),
|
||||
|
||||
Shell_Flag_UnescapeNinjaConfiguration = (1 << 9),
|
||||
};
|
||||
|
||||
std::string EscapeForShell(cm::string_view str, bool makeVars = false,
|
||||
bool forEcho = false,
|
||||
bool useWatcomQuote = false) const;
|
||||
bool forEcho = false, bool useWatcomQuote = false,
|
||||
bool unescapeNinjaConfiguration = false) const;
|
||||
|
||||
static std::string EscapeForCMake(cm::string_view str);
|
||||
|
||||
|
||||
@@ -1042,9 +1042,16 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
}
|
||||
|
||||
// Compose command lines
|
||||
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
|
||||
{ cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
|
||||
this->AutogenTarget.InfoFile, "$<CONFIGURATION>" });
|
||||
// TODO: Refactor autogen to output a per-config mocs_compilation.cpp instead
|
||||
// of fiddling with the include directories
|
||||
std::vector<std::string> configs;
|
||||
this->GlobalGen->GetQtAutoGenConfigs(configs);
|
||||
cmCustomCommandLines commandLines;
|
||||
for (auto const& config : configs) {
|
||||
commandLines.push_back(cmMakeCommandLine(
|
||||
{ cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
|
||||
this->AutogenTarget.InfoFile, config }));
|
||||
}
|
||||
|
||||
// Use PRE_BUILD on demand
|
||||
bool usePRE_BUILD = false;
|
||||
|
||||
@@ -715,6 +715,16 @@ bool cmState::UseMSYSShell() const
|
||||
return this->MSYSShell;
|
||||
}
|
||||
|
||||
void cmState::SetNinjaMulti(bool ninjaMulti)
|
||||
{
|
||||
this->NinjaMulti = ninjaMulti;
|
||||
}
|
||||
|
||||
bool cmState::UseNinjaMulti() const
|
||||
{
|
||||
return this->NinjaMulti;
|
||||
}
|
||||
|
||||
unsigned int cmState::GetCacheMajorVersion() const
|
||||
{
|
||||
return this->CacheManager->GetCacheMajorVersion();
|
||||
|
||||
@@ -190,6 +190,8 @@ public:
|
||||
bool UseNMake() const;
|
||||
void SetMSYSShell(bool mSYSShell);
|
||||
bool UseMSYSShell() const;
|
||||
void SetNinjaMulti(bool ninjaMulti);
|
||||
bool UseNinjaMulti() const;
|
||||
|
||||
unsigned int GetCacheMajorVersion() const;
|
||||
unsigned int GetCacheMinorVersion() const;
|
||||
@@ -245,6 +247,7 @@ private:
|
||||
bool MinGWMake = false;
|
||||
bool NMake = false;
|
||||
bool MSYSShell = false;
|
||||
bool NinjaMulti = false;
|
||||
Mode CurrentMode = Unknown;
|
||||
};
|
||||
|
||||
|
||||
+8
-1
@@ -176,6 +176,7 @@ public:
|
||||
bool IsImportedTarget;
|
||||
bool ImportedGloballyVisible;
|
||||
bool BuildInterfaceIncludesAppended;
|
||||
bool PerConfig;
|
||||
std::set<BT<std::string>> Utilities;
|
||||
std::vector<cmCustomCommand> PreBuildCommands;
|
||||
std::vector<cmCustomCommand> PreLinkCommands;
|
||||
@@ -213,7 +214,7 @@ public:
|
||||
};
|
||||
|
||||
cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
Visibility vis, cmMakefile* mf)
|
||||
Visibility vis, cmMakefile* mf, bool perConfig)
|
||||
: impl(cm::make_unique<cmTargetInternals>())
|
||||
{
|
||||
assert(mf);
|
||||
@@ -229,6 +230,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
(vis == VisibilityImported || vis == VisibilityImportedGlobally);
|
||||
impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
|
||||
impl->BuildInterfaceIncludesAppended = false;
|
||||
impl->PerConfig = perConfig;
|
||||
|
||||
// Check whether this is a DLL platform.
|
||||
impl->IsDLLPlatform =
|
||||
@@ -1800,6 +1802,11 @@ bool cmTarget::IsImportedGloballyVisible() const
|
||||
return impl->ImportedGloballyVisible;
|
||||
}
|
||||
|
||||
bool cmTarget::IsPerConfig() const
|
||||
{
|
||||
return impl->PerConfig;
|
||||
}
|
||||
|
||||
const char* cmTarget::GetSuffixVariableInternal(
|
||||
cmStateEnums::ArtifactType artifact) const
|
||||
{
|
||||
|
||||
+2
-1
@@ -44,7 +44,7 @@ public:
|
||||
};
|
||||
|
||||
cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
Visibility vis, cmMakefile* mf);
|
||||
Visibility vis, cmMakefile* mf, bool perConfig);
|
||||
|
||||
cmTarget(cmTarget const&) = delete;
|
||||
cmTarget(cmTarget&&) noexcept;
|
||||
@@ -186,6 +186,7 @@ public:
|
||||
|
||||
bool IsImported() const;
|
||||
bool IsImportedGloballyVisible() const;
|
||||
bool IsPerConfig() const;
|
||||
|
||||
bool GetMappedConfig(std::string const& desired_config, const char** loc,
|
||||
const char** imp, std::string& suffix) const;
|
||||
|
||||
@@ -1919,6 +1919,7 @@ void cmake::AddDefaultGenerators()
|
||||
this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory());
|
||||
# endif
|
||||
this->Generators.push_back(cmGlobalNinjaGenerator::NewFactory());
|
||||
this->Generators.push_back(cmGlobalNinjaMultiGenerator::NewFactory());
|
||||
#endif
|
||||
#if defined(CMAKE_USE_WMAKE)
|
||||
this->Generators.push_back(cmGlobalWatcomWMakeGenerator::NewFactory());
|
||||
|
||||
+11
-9
@@ -211,6 +211,13 @@ if(BUILD_TESTING)
|
||||
#---------------------------------------------------------------------------
|
||||
# Add tests below here.
|
||||
|
||||
if(NOT DEFINED CMake_TEST_Qt5)
|
||||
set(CMake_TEST_Qt5 1)
|
||||
endif()
|
||||
if(CMake_TEST_Qt5)
|
||||
find_package(Qt5Widgets QUIET NO_MODULE)
|
||||
endif()
|
||||
|
||||
if(NOT CMake_TEST_EXTERNAL_CMAKE)
|
||||
add_subdirectory(CMakeLib)
|
||||
|
||||
@@ -1134,8 +1141,8 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
|
||||
|
||||
foreach(CPackDEBConfiguration IN LISTS DEB_CONFIGURATIONS_TO_TEST)
|
||||
set(CPackRun_CPackDEBConfiguration "-DCPackDEBConfiguration=${CPackDEBConfiguration}")
|
||||
add_test(${DEB_TEST_NAMES}-${CPackDEBConfiguration}
|
||||
${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
|
||||
add_test(NAME ${DEB_TEST_NAMES}-${CPackDEBConfiguration} COMMAND
|
||||
${CMAKE_CTEST_COMMAND} -C $<CONFIG>
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}"
|
||||
"${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}"
|
||||
@@ -1152,6 +1159,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
|
||||
"-D${DEB_TEST_NAMES}_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}"
|
||||
"${CPackRun_CPackGen}"
|
||||
"${CPackRun_CPackDEBConfiguration}"
|
||||
"-DCONFIG=$<CONFIG>"
|
||||
-P "${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}/RunCPackVerifyResult-${CPackDEBConfiguration}.cmake")
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}")
|
||||
endforeach()
|
||||
@@ -1331,12 +1339,6 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
|
||||
)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt")
|
||||
|
||||
if(NOT DEFINED CMake_TEST_Qt5)
|
||||
set(CMake_TEST_Qt5 1)
|
||||
endif()
|
||||
if(CMake_TEST_Qt5)
|
||||
find_package(Qt5Widgets QUIET NO_MODULE)
|
||||
endif()
|
||||
if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND)
|
||||
add_subdirectory(Qt5Autogen)
|
||||
endif()
|
||||
@@ -1868,7 +1870,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
|
||||
ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables)
|
||||
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Makefile" OR
|
||||
"${CMAKE_GENERATOR}" MATCHES "Ninja")
|
||||
"${CMAKE_GENERATOR}" MATCHES "^Ninja$")
|
||||
add_test(MakeClean ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/MakeClean"
|
||||
|
||||
@@ -45,7 +45,7 @@ function(run_cpack output_expected_file CPack_output_parent CPack_error_parent)
|
||||
|
||||
message("config_args = ${run_cpack_deb_CONFIG_ARGS}")
|
||||
message("config_verbose = ${run_cpack_deb_CONFIG_VERBOSE}")
|
||||
execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${run_cpack_deb_CONFIG_VERBOSE} -G ${CPackGen} ${run_cpack_deb_CONFIG_ARGS}
|
||||
execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${run_cpack_deb_CONFIG_VERBOSE} -G ${CPackGen} -C "${CONFIG}" ${run_cpack_deb_CONFIG_ARGS}
|
||||
RESULT_VARIABLE CPack_result
|
||||
OUTPUT_VARIABLE CPack_output
|
||||
ERROR_VARIABLE CPack_error
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
include_directories(${Library_MODDIR})
|
||||
include_directories(${External_BINARY_DIR})
|
||||
link_directories(${External_BINARY_DIR})
|
||||
link_directories(${External_BINARY_DIR}/${CMAKE_CFG_INTDIR})
|
||||
|
||||
add_executable(subdir_exe2 main.f90)
|
||||
target_link_libraries(subdir_exe2 subdir_mods subdir_mods2)
|
||||
|
||||
@@ -94,6 +94,6 @@ if (NOT incs STREQUAL ";/one/two")
|
||||
message(SEND_ERROR "Empty include_directories entry was not ignored.")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_GENERATOR STREQUAL Xcode AND NOT CMAKE_GENERATOR STREQUAL Ninja)
|
||||
if(NOT CMAKE_GENERATOR STREQUAL "Xcode" AND NOT CMAKE_GENERATOR MATCHES "Ninja")
|
||||
add_subdirectory(CMP0021)
|
||||
endif()
|
||||
|
||||
@@ -3,6 +3,12 @@ cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(InterfaceLibrary)
|
||||
|
||||
set(cfg_dir)
|
||||
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(_isMultiConfig)
|
||||
set(cfg_dir /$<CONFIG>)
|
||||
endif()
|
||||
|
||||
add_library(iface_nodepends INTERFACE)
|
||||
target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE)
|
||||
|
||||
@@ -32,7 +38,7 @@ add_library(item_iface INTERFACE IMPORTED)
|
||||
set_property(TARGET item_iface PROPERTY IMPORTED_LIBNAME item_real)
|
||||
add_dependencies(item_iface item_real)
|
||||
get_property(item_iface_dependencies TARGET item_iface PROPERTY MANUALLY_ADDED_DEPENDENCIES)
|
||||
link_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
link_directories(${CMAKE_CURRENT_BINARY_DIR}${cfg_dir})
|
||||
|
||||
add_executable(InterfaceLibrary definetestexe.cpp)
|
||||
target_link_libraries(InterfaceLibrary
|
||||
|
||||
+10
-4
@@ -2,13 +2,19 @@ cmake_minimum_required(VERSION 2.8)
|
||||
project(LinkDirectoryExternal C)
|
||||
|
||||
|
||||
set(cfg_dir)
|
||||
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(_isMultiConfig)
|
||||
set(cfg_dir /$<CONFIG>)
|
||||
endif()
|
||||
|
||||
add_executable(myexe2 myexe.c)
|
||||
set_property(TARGET myexe2 PROPERTY OUTPUT_NAME LinkDirectory2)
|
||||
target_link_directories(myexe2 PRIVATE lib "${CMAKE_CURRENT_SOURCE_DIR}/../lib")
|
||||
target_link_directories(myexe2 PRIVATE lib${cfg_dir} "${CMAKE_CURRENT_SOURCE_DIR}/../lib${cfg_dir}")
|
||||
target_link_libraries(myexe2 PRIVATE mylibA mylibB)
|
||||
|
||||
add_library (mylibs INTERFACE)
|
||||
target_link_directories(mylibs INTERFACE lib "${CMAKE_CURRENT_SOURCE_DIR}/../lib")
|
||||
target_link_directories(mylibs INTERFACE lib${cfg_dir} "${CMAKE_CURRENT_SOURCE_DIR}/../lib${cfg_dir}")
|
||||
target_link_libraries(mylibs INTERFACE mylibA mylibB)
|
||||
add_executable(myexe3 myexe.c)
|
||||
set_property(TARGET myexe3 PROPERTY OUTPUT_NAME LinkDirectory3)
|
||||
@@ -17,11 +23,11 @@ target_link_libraries(myexe3 PRIVATE mylibs)
|
||||
|
||||
# Test CMP0015 OLD behavior: -L../lib
|
||||
cmake_policy(SET CMP0015 OLD)
|
||||
link_directories(../lib)
|
||||
link_directories(../lib${cfg_dir})
|
||||
|
||||
# Test CMP0015 NEW behavior: -L${CMAKE_CURRENT_SOURCE_DIR}/lib
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
link_directories(lib)
|
||||
link_directories(lib${cfg_dir})
|
||||
|
||||
add_executable(myexe myexe.c)
|
||||
set_property(TARGET myexe PROPERTY OUTPUT_NAME LinkDirectory)
|
||||
|
||||
@@ -20,7 +20,7 @@ set(top "${OutDir_BINARY_DIR}")
|
||||
foreach(config ${configs})
|
||||
foreach(type archive runtime library)
|
||||
string(TOUPPER "${type}" TYPE)
|
||||
set(CMAKE_${TYPE}_OUTPUT_DIRECTORY_${config} "${top}/${type}")
|
||||
set(CMAKE_${TYPE}_OUTPUT_DIRECTORY_${config} "${top}/${type}/$<CONFIG>")
|
||||
file(REMOVE_RECURSE "${top}/${type}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
@@ -29,7 +29,7 @@ add_subdirectory(../COnly COnly)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT OutDir.h
|
||||
COMMAND ${CMAKE_COMMAND} -Dtop=${top} -P ${OutDir_SOURCE_DIR}/OutDir.cmake
|
||||
COMMAND ${CMAKE_COMMAND} -Dtop=${top} -Dcfg_dir=$<CONFIG> -P ${OutDir_SOURCE_DIR}/OutDir.cmake
|
||||
DEPENDS COnly ${OutDir_SOURCE_DIR}/OutDir.cmake
|
||||
)
|
||||
include_directories(${top})
|
||||
|
||||
@@ -3,17 +3,17 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a" ".so" ".sl" ".dylib" ".dll.a")
|
||||
|
||||
find_library(TESTC1_LIB
|
||||
NAMES testc1 testc1_test_debug_postfix
|
||||
PATHS ${top}/archive
|
||||
PATHS ${top}/archive/${cfg_dir}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
find_library(TESTC2_LIB
|
||||
NAMES testc2 testc2_test_debug_postfix
|
||||
PATHS ${top}/archive ${top}/library
|
||||
PATHS ${top}/archive/${cfg_dir} ${top}/library/${cfg_dir}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
find_program(CONLY_EXE
|
||||
NAMES COnly
|
||||
PATHS ${top}/runtime
|
||||
PATHS ${top}/runtime/${cfg_dir}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
file(RELATIVE_PATH TESTC1_LIB_FILE "${top}" "${TESTC1_LIB}")
|
||||
|
||||
@@ -125,7 +125,7 @@ endif()
|
||||
if(CMAKE_GENERATOR MATCHES "Make")
|
||||
add_RunCMake_test(Make -DMAKE_IS_GNU=${MAKE_IS_GNU})
|
||||
endif()
|
||||
if(CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
if(CMAKE_GENERATOR MATCHES "Ninja")
|
||||
set(Ninja_ARGS
|
||||
-DCMAKE_C_OUTPUT_EXTENSION=${CMAKE_C_OUTPUT_EXTENSION}
|
||||
-DCMAKE_SHARED_LIBRARY_PREFIX=${CMAKE_SHARED_LIBRARY_PREFIX}
|
||||
@@ -134,6 +134,13 @@ if(CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
list(APPEND Ninja_ARGS -DTEST_Fortran=1)
|
||||
endif()
|
||||
add_RunCMake_test(Ninja)
|
||||
set(NinjaMultiConfig_ARGS
|
||||
-DCYGWIN=${CYGWIN}
|
||||
)
|
||||
if(CMake_TEST_Qt5 AND Qt5Core_FOUND)
|
||||
list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_Qt5=1)
|
||||
endif()
|
||||
add_RunCMake_test(NinjaMultiConfig)
|
||||
endif()
|
||||
add_RunCMake_test(CTest)
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ function(run_cpack_test_common_ TEST_NAME types build SUBTEST_SUFFIX source PACK
|
||||
if(package_target)
|
||||
set(cpack_command_ ${CMAKE_COMMAND} --build "${RunCMake_TEST_BINARY_DIR}" --target package)
|
||||
else()
|
||||
set(cpack_command_ ${CMAKE_CPACK_COMMAND} ${pack_params_})
|
||||
set(cpack_command_ ${CMAKE_CPACK_COMMAND} ${pack_params_} -C Debug)
|
||||
endif()
|
||||
|
||||
# execute cpack
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
^\{
|
||||
"componentGroups" :[ ]
|
||||
("buildConfig" : "Debug",
|
||||
)? "componentGroups" :[ ]
|
||||
\{
|
||||
"f12" :[ ]
|
||||
\{
|
||||
|
||||
@@ -9,7 +9,7 @@ function(run_compiler_launcher lang)
|
||||
run_cmake(${lang})
|
||||
|
||||
set(RunCMake_TEST_OUTPUT_MERGE 1)
|
||||
if("${RunCMake_GENERATOR}" STREQUAL "Ninja")
|
||||
if("${RunCMake_GENERATOR}" MATCHES "Ninja")
|
||||
set(verbose_args -- -v)
|
||||
endif()
|
||||
run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
|
||||
|
||||
@@ -113,7 +113,7 @@ def check_cmake_generator(g):
|
||||
assert is_string(g["platform"])
|
||||
else:
|
||||
assert sorted(g.keys()) == ["multiConfig", "name"]
|
||||
assert is_bool(g["multiConfig"], matches(name, "^(Visual Studio |Xcode$)"))
|
||||
assert is_bool(g["multiConfig"], matches(name, "^(Visual Studio |Xcode$|Ninja Multi-Config$)"))
|
||||
|
||||
def check_index_object(indexEntry, kind, major, minor, check):
|
||||
assert is_dict(indexEntry)
|
||||
|
||||
@@ -621,12 +621,12 @@ def gen_check_directories(c, g):
|
||||
},
|
||||
]
|
||||
|
||||
if matches(g, "^Visual Studio "):
|
||||
if matches(g["name"], "^Visual Studio "):
|
||||
for e in expected:
|
||||
if e["parentSource"] is not None:
|
||||
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^ZERO_CHECK"), e["targetIds"])
|
||||
|
||||
elif g == "Xcode":
|
||||
elif g["name"] == "Xcode":
|
||||
if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
|
||||
for e in expected:
|
||||
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(link_imported_object_exe)"), e["targetIds"])
|
||||
@@ -5087,13 +5087,13 @@ def gen_check_targets(c, g, inSource):
|
||||
for s in e["sources"]:
|
||||
s["path"] = s["path"].replace("^.*/Tests/RunCMake/FileAPI/", "^", 1)
|
||||
if e["sourceGroups"] is not None:
|
||||
for g in e["sourceGroups"]:
|
||||
g["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in g["sourcePaths"]]
|
||||
for group in e["sourceGroups"]:
|
||||
group["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in group["sourcePaths"]]
|
||||
if e["compileGroups"] is not None:
|
||||
for g in e["compileGroups"]:
|
||||
g["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in g["sourcePaths"]]
|
||||
for group in e["compileGroups"]:
|
||||
group["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in group["sourcePaths"]]
|
||||
|
||||
if matches(g, "^Visual Studio "):
|
||||
if matches(g["name"], "^Visual Studio "):
|
||||
expected = filter_list(lambda e: e["name"] not in ("ZERO_CHECK") or e["id"] == "^ZERO_CHECK::@6890427a1f51a3e7e1df$", expected)
|
||||
for e in expected:
|
||||
if e["type"] == "UTILITY":
|
||||
@@ -5130,7 +5130,7 @@ def gen_check_targets(c, g, inSource):
|
||||
if matches(d["id"], "^\\^ZERO_CHECK::@"):
|
||||
d["id"] = "^ZERO_CHECK::@6890427a1f51a3e7e1df$"
|
||||
|
||||
elif g == "Xcode":
|
||||
elif g["name"] == "Xcode":
|
||||
if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
|
||||
expected = filter_list(lambda e: e["name"] not in ("link_imported_object_exe"), expected)
|
||||
for e in expected:
|
||||
@@ -5286,12 +5286,12 @@ def gen_check_projects(c, g):
|
||||
},
|
||||
]
|
||||
|
||||
if matches(g, "^Visual Studio "):
|
||||
if matches(g["name"], "^Visual Studio "):
|
||||
for e in expected:
|
||||
if e["parentName"] is not None:
|
||||
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^ZERO_CHECK"), e["targetIds"])
|
||||
|
||||
elif g == "Xcode":
|
||||
elif g["name"] == "Xcode":
|
||||
if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
|
||||
for e in expected:
|
||||
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(link_imported_object_exe)"), e["targetIds"])
|
||||
@@ -5327,7 +5327,7 @@ def check_object_codemodel(g):
|
||||
|
||||
inSource = os.path.dirname(o["paths"]["build"]) == o["paths"]["source"]
|
||||
|
||||
if matches(g, "^(Visual Studio |Xcode$)"):
|
||||
if g["multiConfig"]:
|
||||
assert sorted([c["name"] for c in o["configurations"]]) == ["Debug", "MinSizeRel", "RelWithDebInfo", "Release"]
|
||||
else:
|
||||
assert len(o["configurations"]) == 1
|
||||
@@ -5339,4 +5339,4 @@ def check_object_codemodel(g):
|
||||
|
||||
assert is_dict(index)
|
||||
assert sorted(index.keys()) == ["cmake", "objects", "reply"]
|
||||
check_objects(index["objects"], index["cmake"]["generator"]["name"])
|
||||
check_objects(index["objects"], index["cmake"]["generator"])
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
include(RunCMake)
|
||||
|
||||
set(RunCMake_GENERATOR "Ninja")
|
||||
set(RunCMake_GENERATOR_IS_MULTI_CONFIG 0)
|
||||
|
||||
# Detect ninja version so we know what tests can be supported.
|
||||
execute_process(
|
||||
COMMAND "${RunCMake_MAKE_PROGRAM}" --version
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
# Intentionally empty
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${RunCMake_TEST_BINARY_DIR}/global.txt
|
||||
${RunCMake_TEST_BINARY_DIR}/Debug.txt
|
||||
${RunCMake_TEST_BINARY_DIR}/Release.txt
|
||||
${RunCMake_TEST_BINARY_DIR}/MinSizeRel.txt
|
||||
${RunCMake_TEST_BINARY_DIR}/RelWithDebInfo.txt
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${RunCMake_TEST_BINARY_DIR}/Debug.txt
|
||||
${RunCMake_TEST_BINARY_DIR}/MinSizeRel.txt
|
||||
${RunCMake_TEST_BINARY_DIR}/RelWithDebInfo.txt
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
file(GENERATE OUTPUT $<CONFIG>.txt CONTENT "$<CONFIG>\n")
|
||||
file(TOUCH ${CMAKE_BINARY_DIR}/global.txt)
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES "$<CONFIG>.txt;global.txt")
|
||||
@@ -0,0 +1,10 @@
|
||||
enable_language(C)
|
||||
|
||||
add_executable(badmoc badmoc.c)
|
||||
target_compile_definitions(badmoc PRIVATE "CONFIG=\"$<CONFIG>\"")
|
||||
|
||||
add_executable(exe main.c)
|
||||
set_target_properties(exe PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTOMOC_EXECUTABLE $<TARGET_FILE:badmoc>
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
@@ -0,0 +1,16 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_FILE_mylib_Release}
|
||||
${TARGET_LINKER_FILE_mylib_Release}
|
||||
${TARGET_SONAME_FILE_mylib_Release}
|
||||
${TARGET_OBJECT_FILES_mylib_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_myobj_Release}
|
||||
|
||||
${TARGET_FILE_exeall_Release}
|
||||
${TARGET_EXE_FILE_exeall_Release}
|
||||
${TARGET_OBJECT_FILES_exeall_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_exenotall_Release}
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_exeall_Release}
|
||||
${TARGET_OBJECT_FILES_exenotall_Release}
|
||||
${TARGET_OBJECT_FILES_mylib_Release}
|
||||
${TARGET_OBJECT_FILES_myobj_Release}
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_FILE_mylib_Release}
|
||||
${TARGET_LINKER_FILE_mylib_Release}
|
||||
${TARGET_SONAME_FILE_mylib_Release}
|
||||
${TARGET_OBJECT_FILES_mylib_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_myobj_Release}
|
||||
|
||||
${TARGET_FILE_exeall_Release}
|
||||
${TARGET_EXE_FILE_exeall_Release}
|
||||
${TARGET_OBJECT_FILES_exeall_Release}
|
||||
|
||||
${TARGET_FILE_exenotall_Release}
|
||||
${TARGET_OBJECT_FILES_exenotall_Release}
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
enable_language(C)
|
||||
|
||||
add_executable(exeall main.c)
|
||||
set_target_properties(exeall PROPERTIES VERSION 1.0.0)
|
||||
add_executable(exenotall main.c)
|
||||
set_target_properties(exenotall PROPERTIES EXCLUDE_FROM_ALL TRUE)
|
||||
|
||||
add_library(mylib SHARED simplelib.c)
|
||||
set_target_properties(mylib PROPERTIES
|
||||
VERSION 1.0.0
|
||||
SOVERSION 1
|
||||
)
|
||||
|
||||
add_library(myobj OBJECT simplelib.c)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
|
||||
generate_output_files(exeall exenotall mylib myobj)
|
||||
@@ -0,0 +1,57 @@
|
||||
function(generate_output_files)
|
||||
set(content)
|
||||
foreach(tgt IN LISTS ARGN)
|
||||
get_property(type TARGET ${tgt} PROPERTY TYPE)
|
||||
|
||||
if(NOT type STREQUAL "OBJECT_LIBRARY")
|
||||
set(file " [==[$<TARGET_FILE:${tgt}>]==]")
|
||||
set(filename " [==[$<TARGET_FILE_NAME:${tgt}>]==]")
|
||||
else()
|
||||
set(file)
|
||||
set(filename)
|
||||
endif()
|
||||
string(APPEND content "set(TARGET_FILE_${tgt}_$<CONFIG>${file})\n")
|
||||
string(APPEND content "set(TARGET_FILE_NAME_${tgt}_$<CONFIG>${filename})\n")
|
||||
|
||||
if(type MATCHES "^(STATIC|MODULE|SHARED)_LIBRARY$")
|
||||
set(linker_file " [==[$<TARGET_LINKER_FILE:${tgt}>]==]")
|
||||
set(linker_filename " [==[$<TARGET_LINKER_FILE_NAME:${tgt}>]==]")
|
||||
else()
|
||||
set(linker_file)
|
||||
set(linker_filename)
|
||||
endif()
|
||||
string(APPEND content "set(TARGET_LINKER_FILE_${tgt}_$<CONFIG>${linker_file})\n")
|
||||
string(APPEND content "set(TARGET_LINKER_FILE_NAME_${tgt}_$<CONFIG>${linker_filename})\n")
|
||||
|
||||
if(NOT WIN32 AND NOT CYGWIN AND type MATCHES "^(SHARED_LIBRARY)$")
|
||||
set(soname_file " [==[$<TARGET_SONAME_FILE:${tgt}>]==]")
|
||||
set(soname_filename " [==[$<TARGET_SONAME_FILE_NAME:${tgt}>]==]")
|
||||
else()
|
||||
set(soname_file)
|
||||
set(soname_filename)
|
||||
endif()
|
||||
string(APPEND content "set(TARGET_SONAME_FILE_${tgt}_$<CONFIG>${soname_file})\n")
|
||||
string(APPEND content "set(TARGET_SONAME_FILE_NAME_${tgt}_$<CONFIG>${soname_filename})\n")
|
||||
|
||||
if(type MATCHES "^(EXECUTABLE)$")
|
||||
set(exe_file " [==[$<TARGET_FILE_DIR:${tgt}>/$<TARGET_FILE_PREFIX:${tgt}>$<TARGET_FILE_BASE_NAME:${tgt}>$<TARGET_FILE_SUFFIX:${tgt}>]==]")
|
||||
set(exe_filename " [==[$<TARGET_FILE_PREFIX:${tgt}>$<TARGET_FILE_BASE_NAME:${tgt}>$<TARGET_FILE_SUFFIX:${tgt}>]==]")
|
||||
else()
|
||||
set(exe_file)
|
||||
set(exe_filename)
|
||||
endif()
|
||||
string(APPEND content "set(TARGET_EXE_FILE_${tgt}_$<CONFIG>${exe_file})\n")
|
||||
string(APPEND content "set(TARGET_EXE_FILE_NAME_${tgt}_$<CONFIG>${exe_filename})\n")
|
||||
|
||||
string(APPEND content "set(TARGET_OBJECT_FILES_${tgt}_$<CONFIG> [==[$<TARGET_OBJECTS:${tgt}>]==])\n")
|
||||
endforeach()
|
||||
|
||||
file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/target_files_$<CONFIG>.cmake" CONTENT "${content}")
|
||||
|
||||
set(content)
|
||||
foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
|
||||
string(APPEND content "include(\${CMAKE_CURRENT_LIST_DIR}/target_files_${config}.cmake)\n")
|
||||
endforeach()
|
||||
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/target_files.cmake" "${content}")
|
||||
endfunction()
|
||||
@@ -0,0 +1,38 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${CONFIG_FILES}
|
||||
${GENERATED_FILES}
|
||||
|
||||
${TARGET_FILE_generator_Debug}
|
||||
${TARGET_OBJECT_FILES_generator_Debug}
|
||||
|
||||
${TARGET_FILE_generated_Debug}
|
||||
${TARGET_OBJECT_FILES_generated_Debug}
|
||||
|
||||
${TARGET_FILE_generatorlib_Debug}
|
||||
${TARGET_LINKER_FILE_generatorlib_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Debug}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_generator_Release}
|
||||
${TARGET_OBJECT_FILES_generated_Release}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Release}
|
||||
${TARGET_OBJECT_FILES_generatorobj_Release}
|
||||
${TARGET_OBJECT_FILES_emptyobj_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generated_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${CONFIG_FILES}
|
||||
|
||||
${TARGET_FILE_generator_Release}
|
||||
${TARGET_OBJECT_FILES_generator_Release}
|
||||
|
||||
${TARGET_FILE_generated_Release}
|
||||
${TARGET_OBJECT_FILES_generated_Release}
|
||||
|
||||
${TARGET_FILE_generatorlib_Release}
|
||||
${TARGET_LINKER_FILE_generatorlib_Release}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_generator_Debug}
|
||||
${TARGET_OBJECT_FILES_generated_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorobj_Debug}
|
||||
${TARGET_OBJECT_FILES_emptyobj_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generated_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
^Generator genex config definition: Debug
|
||||
Generator genex config include dir: Debug
|
||||
Generator library genex config definition: Debug
|
||||
Generator library genex config include dir: Debug
|
||||
Generator object genex config definition: Debug
|
||||
Generator object genex config include dir: Debug
|
||||
Generated genex config definition: Debug
|
||||
Generated genex config include dir: Debug
|
||||
Generated library genex config definition: Debug
|
||||
Generated library genex config include dir: Debug
|
||||
Generated object genex config definition: Debug
|
||||
Generated object genex config include dir: Debug$
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${CONFIG_FILES}
|
||||
${GENERATED_FILES}
|
||||
|
||||
${TARGET_FILE_generated_Debug}
|
||||
${TARGET_OBJECT_FILES_generated_Debug}
|
||||
|
||||
${TARGET_FILE_generatorlib_Debug}
|
||||
${TARGET_LINKER_FILE_generatorlib_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Debug}
|
||||
|
||||
${TARGET_FILE_generator_Release}
|
||||
${TARGET_OBJECT_FILES_generator_Release}
|
||||
|
||||
${TARGET_FILE_generatorlib_Release}
|
||||
${TARGET_LINKER_FILE_generatorlib_Release}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_generator_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generated_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generated_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
|
||||
)
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${CONFIG_FILES}
|
||||
|
||||
${TARGET_FILE_generator_Release}
|
||||
${TARGET_OBJECT_FILES_generator_Release}
|
||||
|
||||
${TARGET_FILE_generatorlib_Release}
|
||||
${TARGET_LINKER_FILE_generatorlib_Release}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_generator_Debug}
|
||||
${TARGET_OBJECT_FILES_generated_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorobj_Debug}
|
||||
${TARGET_OBJECT_FILES_emptyobj_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generated_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generated_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
|
||||
)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
^Generator genex config definition: Release
|
||||
Generator genex config include dir: Release
|
||||
Generator library genex config definition: Release
|
||||
Generator library genex config include dir: Release
|
||||
Generator object genex config definition: Release
|
||||
Generator object genex config include dir: Release
|
||||
Generated genex config definition: Debug
|
||||
Generated genex config include dir: Debug
|
||||
Generated library genex config definition: Debug
|
||||
Generated library genex config include dir: Debug
|
||||
Generated object genex config definition: Debug
|
||||
Generated object genex config include dir: Debug$
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${CONFIG_FILES}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_generator_Debug}
|
||||
${TARGET_OBJECT_FILES_generated_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorobj_Debug}
|
||||
${TARGET_OBJECT_FILES_emptyobj_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_Release}
|
||||
${TARGET_OBJECT_FILES_generated_Release}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Release}
|
||||
${TARGET_OBJECT_FILES_generatorobj_Release}
|
||||
${TARGET_OBJECT_FILES_emptyobj_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generated_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
^Generator genex config definition: Release
|
||||
Generator genex config include dir: Release
|
||||
Generator library genex config definition: Release
|
||||
Generator library genex config include dir: Release
|
||||
Generator object genex config definition: Release
|
||||
Generator object genex config include dir: Release
|
||||
Generated genex config definition: Release
|
||||
Generated genex config include dir: Release
|
||||
Generated library genex config definition: Release
|
||||
Generated library genex config include dir: Release
|
||||
Generated object genex config definition: Release
|
||||
Generated object genex config include dir: Release$
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
^Generator genex config definition: Debug
|
||||
Generator genex config include dir: Debug
|
||||
Generator library genex config definition: Debug
|
||||
Generator library genex config include dir: Debug
|
||||
Generator object genex config definition: Debug
|
||||
Generator object genex config include dir: Debug
|
||||
Generated genex config definition: Release
|
||||
Generated genex config include dir: Release
|
||||
Generated library genex config definition: Release
|
||||
Generated library genex config include dir: Release
|
||||
Generated object genex config definition: Release
|
||||
Generated object genex config include dir: Release$
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${CONFIG_FILES}
|
||||
${GENERATED_FILES}
|
||||
|
||||
${TARGET_FILE_generator_Debug}
|
||||
${TARGET_OBJECT_FILES_generator_Debug}
|
||||
|
||||
${TARGET_FILE_generatorlib_Debug}
|
||||
${TARGET_LINKER_FILE_generatorlib_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Debug}
|
||||
|
||||
${TARGET_FILE_generator_Release}
|
||||
${TARGET_OBJECT_FILES_generator_Release}
|
||||
|
||||
${TARGET_FILE_generated_Release}
|
||||
${TARGET_OBJECT_FILES_generated_Release}
|
||||
|
||||
${TARGET_FILE_generatorlib_Release}
|
||||
${TARGET_LINKER_FILE_generatorlib_Release}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_generated_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generated_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
|
||||
)
|
||||
@@ -0,0 +1,46 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${CONFIG_FILES}
|
||||
${GENERATED_FILES}
|
||||
|
||||
${TARGET_FILE_generator_Debug}
|
||||
${TARGET_OBJECT_FILES_generator_Debug}
|
||||
|
||||
${TARGET_FILE_generated_Debug}
|
||||
${TARGET_OBJECT_FILES_generated_Debug}
|
||||
|
||||
${TARGET_FILE_generatorlib_Debug}
|
||||
${TARGET_LINKER_FILE_generatorlib_Debug}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Debug}
|
||||
|
||||
${TARGET_FILE_generator_Release}
|
||||
${TARGET_OBJECT_FILES_generator_Release}
|
||||
|
||||
${TARGET_FILE_generated_Release}
|
||||
${TARGET_OBJECT_FILES_generated_Release}
|
||||
|
||||
${TARGET_FILE_generatorlib_Release}
|
||||
${TARGET_LINKER_FILE_generatorlib_Release}
|
||||
${TARGET_OBJECT_FILES_generatorlib_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_generatorobj_Release}
|
||||
|
||||
${TARGET_OBJECT_FILES_emptyobj_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_generator_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generated_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
|
||||
)
|
||||
@@ -0,0 +1,56 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(generatorlib STATIC generatorlib.c)
|
||||
add_library(generatorobj OBJECT generatorobj.c)
|
||||
add_library(emptyobj OBJECT empty.c)
|
||||
add_library(emptyobj2 OBJECT empty.c)
|
||||
|
||||
add_executable(generator generator.c $<TARGET_OBJECTS:generatorobj>)
|
||||
target_link_libraries(generator PRIVATE generatorlib)
|
||||
|
||||
add_custom_command(OUTPUT generated.c COMMAND generator generated.c)
|
||||
add_executable(generated ${CMAKE_BINARY_DIR}/generated.c $<TARGET_OBJECTS:generatorobj> $<TARGET_OBJECTS:emptyobj>)
|
||||
target_link_libraries(generated PRIVATE generatorlib)
|
||||
|
||||
file(GENERATE OUTPUT include/genex/$<CONFIG>/genex_config.h CONTENT
|
||||
"#ifndef GENEX_CONFIG_H
|
||||
#define GENEX_CONFIG_H
|
||||
|
||||
#define GENEX_CONFIG_INCLUDE_DIR \"$<CONFIG>\"
|
||||
|
||||
#endif /* GENEX_CONFIG_H */
|
||||
")
|
||||
file(GENERATE OUTPUT include/intdir/$<CONFIG>/intdir_config.h CONTENT
|
||||
"#ifndef INTDIR_CONFIG_H
|
||||
#define INTDIR_CONFIG_H
|
||||
|
||||
#define INTDIR_CONFIG_INCLUDE_DIR \"$<CONFIG>\"
|
||||
|
||||
#endif /* INTDIR_CONFIG_H */
|
||||
")
|
||||
|
||||
foreach(g generatorlib generatorobj generator generated)
|
||||
target_compile_definitions(${g} PRIVATE
|
||||
"GENEX_CONFIG_DEFINITION=\"$<CONFIG>\""
|
||||
# FIXME Get this working
|
||||
# "INTDIR_CONFIG_DEFINITION=\"${CMAKE_CFG_INTDIR}\""
|
||||
)
|
||||
target_include_directories(${g} PRIVATE
|
||||
"${CMAKE_BINARY_DIR}/include/genex/$<CONFIG>"
|
||||
# FIXME Get this working
|
||||
# "${CMAKE_BINARY_DIR}/include/intdir/${CMAKE_CFG_INTDIR}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
|
||||
generate_output_files(generatorlib generatorobj emptyobj generator generated)
|
||||
|
||||
file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(GENERATED_FILES [==[${CMAKE_BINARY_DIR}/generated.c]==])\n")
|
||||
set(genfiles)
|
||||
foreach(cfg Debug Release MinSizeRel RelWithDebInfo)
|
||||
list(APPEND genfiles
|
||||
${CMAKE_BINARY_DIR}/include/genex/${cfg}/genex_config.h
|
||||
${CMAKE_BINARY_DIR}/include/intdir/${cfg}/intdir_config.h
|
||||
)
|
||||
endforeach()
|
||||
file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(CONFIG_FILES [==[${genfiles}]==])\n")
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
${TARGET_DEPENDS_TopCommand}
|
||||
)
|
||||
check_file_contents("${TARGET_DEPENDS_TopCommand}" "^Genex config: Debug\nINTDIR config: Debug\n$")
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
${TARGET_DEPENDS_TopCommand}
|
||||
${TARGET_BYPRODUCTS_SubdirTarget}
|
||||
${TARGET_BYPRODUCTS_TopTarget}
|
||||
${TARGET_FILE_SubdirPostBuild_Debug}
|
||||
)
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
${TARGET_DEPENDS_TopCommand}
|
||||
${TARGET_BYPRODUCTS_SubdirTarget}
|
||||
${TARGET_BYPRODUCTS_TopTarget}
|
||||
)
|
||||
check_file_contents("${TARGET_BYPRODUCTS_TopTarget}" "^Genex config: Debug\nINTDIR config: Debug\n$")
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
${TARGET_DEPENDS_TopCommand}
|
||||
${TARGET_BYPRODUCTS_SubdirTarget}
|
||||
${TARGET_BYPRODUCTS_TopTarget}
|
||||
${TARGET_FILE_SubdirPostBuild_Debug}
|
||||
${TARGET_FILE_SubdirPostBuild_Release}
|
||||
${TARGET_BYPRODUCTS_SubdirPostBuild}
|
||||
${TARGET_BYPRODUCTS_TopTargetPostBuild}
|
||||
)
|
||||
check_file_contents("${TARGET_BYPRODUCTS_TopTargetPostBuild}" "^Genex config: Debug\nINTDIR config: Debug\n$")
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
)
|
||||
check_file_contents("${TARGET_DEPENDS_SubdirCommand}" "^Genex config: MinSizeRel\nINTDIR config: MinSizeRel\n$")
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
)
|
||||
check_file_contents("${TARGET_DEPENDS_SubdirCommand}" "^Genex config: Release\nINTDIR config: Release\n$")
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
${TARGET_DEPENDS_TopCommand}
|
||||
${TARGET_BYPRODUCTS_SubdirTarget}
|
||||
${TARGET_BYPRODUCTS_TopTarget}
|
||||
${TARGET_FILE_SubdirPostBuild_Debug}
|
||||
${TARGET_FILE_SubdirPostBuild_Release}
|
||||
${TARGET_BYPRODUCTS_SubdirPostBuild}
|
||||
)
|
||||
check_file_contents("${TARGET_BYPRODUCTS_SubdirPostBuild}" "^Genex config: Release\nINTDIR config: Release\n$")
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
${TARGET_DEPENDS_TopCommand}
|
||||
${TARGET_BYPRODUCTS_SubdirTarget}
|
||||
)
|
||||
check_file_contents("${TARGET_BYPRODUCTS_SubdirTarget}" "^Genex config: Release\nINTDIR config: Release\n$")
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_DEPENDS_SubdirCommand}
|
||||
${TARGET_DEPENDS_TopCommand}
|
||||
${TARGET_BYPRODUCTS_SubdirTarget}
|
||||
${TARGET_BYPRODUCTS_TopTarget}
|
||||
${TARGET_FILE_SubdirPostBuild_Debug}
|
||||
${TARGET_FILE_SubdirPostBuild_Release}
|
||||
${TARGET_BYPRODUCTS_SubdirPostBuild}
|
||||
${TARGET_BYPRODUCTS_TopTargetPostBuild}
|
||||
${TARGET_BYPRODUCTS_SubdirTargetPostBuild}
|
||||
)
|
||||
check_file_contents("${TARGET_BYPRODUCTS_SubdirTargetPostBuild}" "^Genex config: Release\nINTDIR config: Release\n$")
|
||||
@@ -0,0 +1,39 @@
|
||||
enable_language(C)
|
||||
|
||||
file(REMOVE "${CMAKE_BINARY_DIR}/target_files_custom.cmake")
|
||||
|
||||
function(get_write_file_command var filename)
|
||||
set(${var} ${CMAKE_COMMAND} -DOUTPUT_FILE=${filename} -DGENEX_CONFIG=$<CONFIG> -DINTDIR_CONFIG=${CMAKE_CFG_INTDIR} -P ${CMAKE_SOURCE_DIR}/WriteFile.cmake PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(create_targets prefix)
|
||||
get_write_file_command(cmd ${prefix}Command.txt)
|
||||
add_custom_command(OUTPUT ${prefix}Command.txt COMMAND ${cmd})
|
||||
add_custom_target(${prefix}Command DEPENDS ${prefix}Command.txt)
|
||||
|
||||
get_write_file_command(cmd ${prefix}Target.txt)
|
||||
add_custom_target(${prefix}Target COMMAND ${cmd} BYPRODUCTS ${prefix}Target.txt)
|
||||
|
||||
get_write_file_command(cmd ${prefix}PostBuild.txt)
|
||||
add_executable(${prefix}PostBuild ${CMAKE_SOURCE_DIR}/main.c)
|
||||
add_custom_command(TARGET ${prefix}PostBuild COMMAND ${cmd} BYPRODUCTS ${prefix}PostBuild.txt)
|
||||
|
||||
get_write_file_command(cmd ${prefix}TargetPostBuild.txt)
|
||||
add_custom_target(${prefix}TargetPostBuild)
|
||||
add_custom_command(TARGET ${prefix}TargetPostBuild COMMAND ${cmd} BYPRODUCTS ${prefix}TargetPostBuild.txt)
|
||||
|
||||
file(APPEND "${CMAKE_BINARY_DIR}/target_files_custom.cmake"
|
||||
"set(TARGET_DEPENDS_${prefix}Command [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}Command.txt]==])
|
||||
set(TARGET_BYPRODUCTS_${prefix}Target [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}Target.txt]==])
|
||||
set(TARGET_BYPRODUCTS_${prefix}PostBuild [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}PostBuild.txt]==])
|
||||
set(TARGET_BYPRODUCTS_${prefix}TargetPostBuild [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}TargetPostBuild.txt]==])
|
||||
")
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(CustomCommandsAndTargetsSubdir)
|
||||
|
||||
create_targets(Top)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
|
||||
generate_output_files(TopPostBuild SubdirPostBuild)
|
||||
file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "include(\${CMAKE_CURRENT_LIST_DIR}/target_files_custom.cmake)\n")
|
||||
@@ -0,0 +1 @@
|
||||
create_targets(Subdir)
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_FILE_exe_Debug}
|
||||
${TARGET_OBJECT_FILES_exe_Debug}
|
||||
|
||||
${TARGET_FILE_mylib_Release}
|
||||
${TARGET_LINKER_FILE_mylib_Debug}
|
||||
${TARGET_OBJECT_FILES_mylib_Debug}
|
||||
|
||||
${RunCMake_TEST_BINARY_DIR}/install/bin/Debug/${TARGET_FILE_NAME_exe_Debug}
|
||||
${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_FILE_NAME_mylib_Debug}
|
||||
${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_LINKER_FILE_NAME_mylib_Debug}
|
||||
|
||||
${TARGET_FILE_exe_Release}
|
||||
${TARGET_OBJECT_FILES_exe_Release}
|
||||
|
||||
${TARGET_FILE_mylib_Release}
|
||||
${TARGET_LINKER_FILE_mylib_Release}
|
||||
${TARGET_OBJECT_FILES_mylib_Release}
|
||||
|
||||
${RunCMake_TEST_BINARY_DIR}/install/bin/Release/${TARGET_FILE_NAME_exe_Release}
|
||||
${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_FILE_NAME_mylib_Release}
|
||||
${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_LINKER_FILE_NAME_mylib_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_exe_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_mylib_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_exe_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_mylib_RelWithDebInfo}
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
check_files("${RunCMake_TEST_BINARY_DIR}"
|
||||
INCLUDE
|
||||
${TARGET_FILE_exe_Release}
|
||||
${TARGET_OBJECT_FILES_exe_Release}
|
||||
|
||||
${TARGET_FILE_mylib_Release}
|
||||
${TARGET_LINKER_FILE_mylib_Release}
|
||||
${TARGET_OBJECT_FILES_mylib_Release}
|
||||
|
||||
${RunCMake_TEST_BINARY_DIR}/install/bin/Release/${TARGET_FILE_NAME_exe_Release}
|
||||
${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_FILE_NAME_mylib_Release}
|
||||
${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_LINKER_FILE_NAME_mylib_Release}
|
||||
|
||||
EXCLUDE
|
||||
${TARGET_OBJECT_FILES_exe_Debug}
|
||||
${TARGET_OBJECT_FILES_mylib_Debug}
|
||||
|
||||
${TARGET_OBJECT_FILES_exe_MinSizeRel}
|
||||
${TARGET_OBJECT_FILES_mylib_MinSizeRel}
|
||||
|
||||
${TARGET_OBJECT_FILES_exe_RelWithDebInfo}
|
||||
${TARGET_OBJECT_FILES_mylib_RelWithDebInfo}
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
enable_language(C)
|
||||
|
||||
add_executable(exe main.c)
|
||||
add_library(mylib STATIC simplelib.c)
|
||||
|
||||
install(TARGETS exe DESTINATION bin/$<CONFIG>)
|
||||
install(TARGETS mylib DESTINATION lib/$<CONFIG>)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
|
||||
generate_output_files(exe mylib)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user