diff options
Diffstat (limited to 'Source/cmGlobalUnixMakefileGenerator3.h')
-rw-r--r-- | Source/cmGlobalUnixMakefileGenerator3.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h new file mode 100644 index 0000000..94ee476 --- /dev/null +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -0,0 +1,285 @@ +/* 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 <cstddef> +#include <iosfwd> +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include "cmGeneratorTarget.h" +#include "cmGlobalCommonGenerator.h" +#include "cmGlobalGeneratorFactory.h" +#include "cmStateSnapshot.h" + +class cmGeneratedFileStream; +class cmLocalGenerator; +class cmLocalUnixMakefileGenerator3; +class cmMakefile; +class cmMakefileTargetGenerator; +class cmake; +struct cmDocumentationEntry; + +/** \class cmGlobalUnixMakefileGenerator3 + * \brief Write a Unix makefiles. + * + * cmGlobalUnixMakefileGenerator3 manages UNIX build process for a tree + + + The basic approach of this generator is to produce Makefiles that will all + be run with the current working directory set to the Home Output + directory. The one exception to this is the subdirectory Makefiles which are + created as a convenience and just cd up to the Home Output directory and + invoke the main Makefiles. + + The make process starts with Makefile. Makefile should only contain the + targets the user is likely to invoke directly from a make command line. No + internal targets should be in this file. Makefile2 contains the internal + targets that are required to make the process work. + + Makefile2 in turn will recursively make targets in the correct order. Each + target has its own directory \<target\>.dir and its own makefile build.make in + that directory. Also in that directory is a couple makefiles per source file + used by the target. Typically these are named source.obj.build.make and + source.obj.build.depend.make. The source.obj.build.make contains the rules + for building, cleaning, and computing dependencies for the given source + file. The build.depend.make contains additional dependencies that were + computed during dependency scanning. An additional file called + source.obj.depend is used as a marker to indicate when dependencies must be + rescanned. + + Rules for custom commands follow the same model as rules for source files. + + */ + +class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator +{ +public: + cmGlobalUnixMakefileGenerator3(cmake* cm); + static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory() + { + return std::unique_ptr<cmGlobalGeneratorFactory>( + new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>()); + } + + ~cmGlobalUnixMakefileGenerator3() override; + + cmGlobalUnixMakefileGenerator3(const cmGlobalUnixMakefileGenerator3&) = + delete; + cmGlobalUnixMakefileGenerator3& operator=( + const cmGlobalUnixMakefileGenerator3&) = delete; + + //! Get the name for the generator. + std::string GetName() const override + { + return cmGlobalUnixMakefileGenerator3::GetActualName(); + } + static std::string GetActualName() { return "Unix Makefiles"; } + + /** + * Utilized by the generator factory to determine if this generator + * supports toolsets. + */ + static bool SupportsToolset() { return false; } + + /** + * Utilized by the generator factory to determine if this generator + * supports platforms. + */ + static bool SupportsPlatform() { return false; } + + /** + * Utilized to determine if this generator + * supports DEPFILE option. + */ + bool SupportsCustomCommandDepfile() const override { return true; } + + /** Get the documentation entry for this generator. */ + static void GetDocumentation(cmDocumentationEntry& entry); + + std::unique_ptr<cmLocalGenerator> CreateLocalGenerator( + cmMakefile* mf) override; + + /** + * Try to determine system information such as shared library + * extension, pthreads, byte order etc. + */ + void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*, + bool optional) override; + + void Configure() override; + + /** + * Generate the all required files for building this project/tree. This + * basically creates a series of LocalGenerators for each directory and + * requests that they Generate. + */ + void Generate() override; + + void WriteMainCMakefileLanguageRules( + cmGeneratedFileStream& cmakefileStream, + std::vector<std::unique_ptr<cmLocalGenerator>>&); + + // write out the help rule listing the valid targets + void WriteHelpRule(std::ostream& ruleFileStream, + cmLocalUnixMakefileGenerator3*); + + // write the top level target rules + void WriteConvenienceRules(std::ostream& ruleFileStream, + std::set<std::string>& emitted); + + // Make tool supports dependency files generated by compiler + bool SupportsCompilerDependencies() const + { + return this->ToolSupportsCompilerDependencies; + } + + // Make tool supports long line dependencies + bool SupportsLongLineDependencies() const + { + return this->ToolSupportsLongLineDependencies; + } + + /** Get the command to use for a target that has no rule. This is + used for multiple output dependencies and for cmake_force. */ + std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; } + + /** Get the fake dependency to use when a rule has no real commands + or dependencies. */ + std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; } + + /** + * Convert a file path to a Makefile target or dependency with + * escaping and quoting suitable for the generator's make tool. + */ + std::string ConvertToMakefilePath(std::string const& path) const; + + // change the build command for speed + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; + + /** Record per-target progress information. */ + void RecordTargetProgress(cmMakefileTargetGenerator* tg); + + void AddCXXCompileCommand(const std::string& sourceFile, + const std::string& workingDirectory, + const std::string& compileCommand); + + /** Does the make tool tolerate .NOTPARALLEL? */ + virtual bool AllowNotParallel() const { return true; } + + /** Does the make tool tolerate .DELETE_ON_ERROR? */ + virtual bool AllowDeleteOnError() const { return true; } + + /** Does the make tool interpret '\#' as '#'? */ + virtual bool CanEscapeOctothorpe() const; + + bool IsIPOSupported() const override { return true; } + + void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override; + + std::string IncludeDirective; + std::string LineContinueDirective; + bool DefineWindowsNULL; + bool PassMakeflags; + bool UnixCD; + +protected: + void WriteMainMakefile2(); + void WriteMainCMakefile(); + + void WriteConvenienceRules2(std::ostream& ruleFileStream, + cmLocalUnixMakefileGenerator3&); + + void WriteDirectoryRule2(std::ostream& ruleFileStream, + DirectoryTarget const& dt, const char* pass, + bool check_all, bool check_relink, + std::vector<std::string> const& commands = {}); + void WriteDirectoryRules2(std::ostream& ruleFileStream, + DirectoryTarget const& dt); + + void AppendGlobalTargetDepends(std::vector<std::string>& depends, + cmGeneratorTarget* target); + + // Target name hooks for superclass. + const char* GetAllTargetName() const override { return "all"; } + const char* GetInstallTargetName() const override { return "install"; } + const char* GetInstallLocalTargetName() const override + { + return "install/local"; + } + const char* GetInstallStripTargetName() const override + { + return "install/strip"; + } + const char* GetPreinstallTargetName() const override { return "preinstall"; } + const char* GetTestTargetName() const override { return "test"; } + const char* GetPackageTargetName() const override { return "package"; } + const char* GetPackageSourceTargetName() const override + { + return "package_source"; + } + const char* GetRebuildCacheTargetName() const override + { + return "rebuild_cache"; + } + const char* GetCleanTargetName() const override { return "clean"; } + + bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; } + + // Specify if the make tool is able to consume dependency files + // generated by the compiler + bool ToolSupportsCompilerDependencies = true; + + // some Make generator, such as Borland not support long line dependencies, + // we add SupportsLongLineDependencies to predicate. + bool ToolSupportsLongLineDependencies = true; + + // Some make programs (Borland) do not keep a rule if there are no + // dependencies or commands. This is a problem for creating rules + // that might not do anything but might have other dependencies + // added later. If non-empty this variable holds a fake dependency + // that can be added. + std::string EmptyRuleHackDepends; + + // Some make programs (Watcom) do not like rules with no commands. + // If non-empty this variable holds a bogus command that may be put + // in the rule to satisfy the make program. + std::string EmptyRuleHackCommand; + + // Store per-target progress counters. + struct TargetProgress + { + unsigned long NumberOfActions = 0; + std::string VariableFile; + std::vector<unsigned long> Marks; + void WriteProgressVariables(unsigned long total, unsigned long& current); + }; + using ProgressMapType = std::map<cmGeneratorTarget const*, TargetProgress, + cmGeneratorTarget::StrictTargetComparison>; + ProgressMapType ProgressMap; + + size_t CountProgressMarksInTarget( + cmGeneratorTarget const* target, + std::set<cmGeneratorTarget const*>& emitted); + size_t CountProgressMarksInAll(const cmLocalGenerator& lg); + + std::unique_ptr<cmGeneratedFileStream> CommandDatabase; + +private: + const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; } + + std::map<cmStateSnapshot, std::set<cmGeneratorTarget const*>, + cmStateSnapshot::StrictWeakOrder> + DirectoryTargetsMap; + void InitializeProgressMarks() override; +}; |