|  | /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying | 
|  | file LICENSE.rst 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 "cmBuildOptions.h" | 
|  | #include "cmGeneratorTarget.h" | 
|  | #include "cmGlobalCommonGenerator.h" | 
|  | #include "cmGlobalGeneratorFactory.h" | 
|  | #include "cmStateSnapshot.h" | 
|  |  | 
|  | class cmGeneratedFileStream; | 
|  | class cmLocalGenerator; | 
|  | class cmLocalUnixMakefileGenerator3; | 
|  | class cmMakefile; | 
|  | class cmMakefileTargetGenerator; | 
|  | class cmake; | 
|  |  | 
|  | /** \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(cmGlobalUnixMakefileGenerator3 const&) = | 
|  | delete; | 
|  | cmGlobalUnixMakefileGenerator3& operator=( | 
|  | cmGlobalUnixMakefileGenerator3 const&) = 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; } | 
|  |  | 
|  | /** | 
|  | * Utilized to determine if this generator | 
|  | * supports linker dependency file. | 
|  | */ | 
|  | bool SupportsLinkerDependencyFile() const override { return true; } | 
|  |  | 
|  | /** Get the documentation entry for this generator.  */ | 
|  | static cmDocumentationEntry GetDocumentation(); | 
|  |  | 
|  | 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; | 
|  |  | 
|  | bool IsGNUMakeJobServerAware() const override { return true; } | 
|  |  | 
|  | /** | 
|  | * 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( | 
|  | std::string const& makeProgram, std::string const& projectName, | 
|  | std::string const& projectDir, std::vector<std::string> const& targetNames, | 
|  | std::string const& config, int jobs, bool verbose, | 
|  | cmBuildOptions const& buildOptions = cmBuildOptions(), | 
|  | std::vector<std::string> const& makeOptions = | 
|  | std::vector<std::string>()) override; | 
|  |  | 
|  | /** Record per-target progress information.  */ | 
|  | void RecordTargetProgress(cmMakefileTargetGenerator* tg); | 
|  |  | 
|  | void AddCXXCompileCommand(std::string const& sourceFile, | 
|  | std::string const& workingDirectory, | 
|  | std::string const& compileCommand, | 
|  | std::string const& objPath); | 
|  |  | 
|  | /** 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& rootLG, | 
|  | cmLocalUnixMakefileGenerator3& lg); | 
|  |  | 
|  | void WriteDirectoryRule2(std::ostream& ruleFileStream, | 
|  | cmLocalUnixMakefileGenerator3& rootLG, | 
|  | DirectoryTarget const& dt, char const* pass, | 
|  | bool check_all, bool check_relink, | 
|  | std::vector<std::string> const& commands = {}); | 
|  | void WriteDirectoryRules2(std::ostream& ruleFileStream, | 
|  | cmLocalUnixMakefileGenerator3& rootLG, | 
|  | DirectoryTarget const& dt); | 
|  |  | 
|  | void AppendGlobalTargetDepends(std::vector<std::string>& depends, | 
|  | cmGeneratorTarget* target); | 
|  |  | 
|  | void AppendCodegenTargetDepends(std::vector<std::string>& depends, | 
|  | cmGeneratorTarget* target); | 
|  |  | 
|  | // Target name hooks for superclass. | 
|  | char const* GetAllTargetName() const override { return "all"; } | 
|  | char const* GetInstallTargetName() const override { return "install"; } | 
|  | char const* GetInstallLocalTargetName() const override | 
|  | { | 
|  | return "install/local"; | 
|  | } | 
|  | char const* GetInstallStripTargetName() const override | 
|  | { | 
|  | return "install/strip"; | 
|  | } | 
|  | char const* GetPreinstallTargetName() const override { return "preinstall"; } | 
|  | char const* GetTestTargetName() const override { return "test"; } | 
|  | char const* GetPackageTargetName() const override { return "package"; } | 
|  | char const* GetPackageSourceTargetName() const override | 
|  | { | 
|  | return "package_source"; | 
|  | } | 
|  | char const* GetRebuildCacheTargetName() const override | 
|  | { | 
|  | return "rebuild_cache"; | 
|  | } | 
|  | char const* 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(cmLocalGenerator const& lg); | 
|  |  | 
|  | std::unique_ptr<cmGeneratedFileStream> CommandDatabase; | 
|  |  | 
|  | private: | 
|  | char const* GetBuildIgnoreErrorsFlag() const override { return "-i"; } | 
|  |  | 
|  | std::map<cmStateSnapshot, std::set<cmGeneratorTarget const*>, | 
|  | cmStateSnapshot::StrictWeakOrder> | 
|  | DirectoryTargetsMap; | 
|  | void InitializeProgressMarks() override; | 
|  | }; |