Files
CMake/Source/cmNinjaTargetGenerator.h
Evan Wilde e88509d0e8 Swift: Omit output-file-map when used as a linker
Swift is used as the linker for non-swift files because it needs to pull
files like swiftrt.o in when swift symbols are present to ensure that
the swift runtime is linked.

The swift driver uses clang as the underlying linker, which pulls in
crtbegin.o and friends when appropriate, so using Swift as a linker for
C/C++ libraries is fine.

The output-file-map was getting passed to all Swift invocations,
regardless of whether or not we generated one. This patch changes it so
that we only include the output-file-map in the Swift compiler
invocation if we have actually generated the file.
2022-10-28 16:44:26 -07:00

230 lines
8.2 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <cm3p/json/value.h>
#include "cmCommonTargetGenerator.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmNinjaTypes.h"
#include "cmOSXBundleGenerator.h"
class cmCustomCommand;
class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmLocalNinjaGenerator;
class cmMakefile;
class cmSourceFile;
class cmNinjaTargetGenerator : public cmCommonTargetGenerator
{
public:
/// Create a cmNinjaTargetGenerator according to the @a target's type.
static std::unique_ptr<cmNinjaTargetGenerator> New(
cmGeneratorTarget* target);
/// Build a NinjaTargetGenerator.
cmNinjaTargetGenerator(cmGeneratorTarget* target);
/// Destructor.
~cmNinjaTargetGenerator() override;
virtual void Generate(const std::string& config) = 0;
std::string GetTargetName() const;
protected:
bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const;
cmGeneratedFileStream& GetImplFileStream(const std::string& config) const;
cmGeneratedFileStream& GetCommonFileStream() const;
cmGeneratedFileStream& GetRulesFileStream() const;
cmGeneratorTarget* GetGeneratorTarget() const
{
return this->GeneratorTarget;
}
cmLocalNinjaGenerator* GetLocalGenerator() const
{
return this->LocalGenerator;
}
cmGlobalNinjaGenerator* GetGlobalGenerator() const;
cmMakefile* GetMakefile() const { return this->Makefile; }
std::string LanguageCompilerRule(const std::string& lang,
const std::string& config) const;
std::string LanguagePreprocessAndScanRule(std::string const& lang,
const std::string& config) const;
std::string LanguageScanRule(std::string const& lang,
const std::string& config) const;
std::string LanguageDyndepRule(std::string const& lang,
const std::string& config) const;
bool NeedDyndep(std::string const& lang, std::string const& config) const;
bool NeedExplicitPreprocessing(std::string const& lang) const;
bool CompileWithDefines(std::string const& lang) const;
bool NeedCxxModuleSupport(std::string const& lang,
std::string const& config) const;
std::string OrderDependsTargetForTarget(const std::string& config);
std::string ComputeOrderDependsForTarget();
/**
* Compute the flags for compilation of object files for a given @a language.
* @note Generally it is the value of the variable whose name is computed
* by LanguageFlagsVarName().
*/
std::string ComputeFlagsForObject(cmSourceFile const* source,
const std::string& language,
const std::string& config);
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& config);
std::string ComputeIncludes(cmSourceFile const* source,
const std::string& language,
const std::string& config);
std::string const& ConvertToNinjaPath(const std::string& path) const
{
return this->GetGlobalGenerator()->ConvertToNinjaPath(path);
}
cmGlobalNinjaGenerator::MapToNinjaPathImpl MapToNinjaPath() const
{
return this->GetGlobalGenerator()->MapToNinjaPath();
}
std::string ConvertToNinjaAbsPath(std::string path) const
{
return this->GetGlobalGenerator()->ConvertToNinjaAbsPath(std::move(path));
}
/// @return the list of link dependency for the given target @a target.
cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage,
const std::string& config,
bool ignoreType = false) const;
/// @return the source file path for the given @a source.
std::string GetCompiledSourceNinjaPath(cmSourceFile const* source) const;
/// @return the object file path for the given @a source.
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& config) const;
/// @return the dyndep file path for this target.
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& config) const;
/// @return the file path where the target named @a name is generated.
std::string GetTargetFilePath(const std::string& name,
const std::string& config) const;
/// @return the output path for the target.
virtual std::string GetTargetOutputDir(const std::string& config) const;
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,
const std::string& config);
void GenerateSwiftOutputFileMap(const std::string& config,
std::string& flags);
void ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
std::string const& objectDir, std::string const& objectFileName,
std::string const& objectFileDir, std::string const& flags,
std::string const& defines, std::string const& includes,
std::string const& outputConfig);
void AdditionalCleanFiles(const std::string& config);
cmNinjaDeps GetObjects(const std::string& config) const;
void EnsureDirectoryExists(const std::string& dir) const;
void EnsureParentDirectoryExists(const std::string& path) const;
// write rules for macOS Application Bundle content.
struct MacOSXContentGeneratorType
: cmOSXBundleGenerator::MacOSXContentGeneratorType
{
MacOSXContentGeneratorType(cmNinjaTargetGenerator* g,
std::string fileConfig)
: Generator(g)
, FileConfig(std::move(fileConfig))
{
}
void operator()(cmSourceFile const& source, const char* pkgloc,
const std::string& config) override;
private:
cmNinjaTargetGenerator* Generator;
std::string FileConfig;
};
friend struct MacOSXContentGeneratorType;
// Properly initialized by sub-classes.
std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
std::set<std::string> MacContentFolders;
void addPoolNinjaVariable(const std::string& pool_property,
cmGeneratorTarget* target, cmNinjaVars& vars);
bool ForceResponseFile();
private:
cmLocalNinjaGenerator* LocalGenerator;
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::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
};
std::map<std::string, ByConfig> Configs;
};