/*========================================================================= Program: CMake - Cross-Platform Makefile Generator Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef cmLocalUnixMakefileGenerator2_h #define cmLocalUnixMakefileGenerator2_h #include "cmLocalGenerator.h" class cmCustomCommand; class cmDependInformation; class cmDepends; class cmMakeDepend; class cmTarget; class cmSourceFile; /** \class cmLocalUnixMakefileGenerator2 * \brief Write a LocalUnix makefiles. * * cmLocalUnixMakefileGenerator2 produces a LocalUnix makefile from its * member m_Makefile. */ class cmLocalUnixMakefileGenerator2 : public cmLocalGenerator { public: ///! Set cache only and recurse to false by default. cmLocalUnixMakefileGenerator2(); virtual ~cmLocalUnixMakefileGenerator2(); /** Set the command used when there are no dependencies or rules for a target. This is used to avoid errors on some make implementations. */ void SetEmptyCommand(const char* cmd); /** * Set to true if the shell being used is the windows shell. * This controls if statements in the makefile and the SHELL variable. * The default is false. */ void SetWindowsShell(bool v) {m_WindowsShell = v;} /** * Set the string used to include one makefile into another default * is include. */ void SetIncludeDirective(const char* s) { m_IncludeDirective = s; } /** * Set the flag used to keep the make program silent. */ void SetMakeSilentFlag(const char* s) { m_MakeSilentFlag = s; } /** * Set max makefile variable size, default is 0 which means unlimited. */ void SetMakefileVariableSize(int s) { m_MakefileVariableSize = s; } /** * If ignore lib prefix is true, then do not strip lib from the name * of a library. */ void SetIgnoreLibPrefix(bool s) { m_IgnoreLibPrefix = s; } /** * If true, then explicitly pass MAKEFLAGS on the make all target for makes * that do not use environment variables. * */ void SetPassMakeflags(bool s){m_PassMakeflags = s;} /** * Generate the makefile for this directory. fromTheTop indicates if this * is being invoked as part of a global Generate or specific to this * directory. The difference is that when done from the Top we might skip * some steps to save time, such as dependency generation for the * makefiles. This is done by a direct invocation from make. */ virtual void Generate(bool fromTheTop); /** Called from command-line hook to scan dependencies. */ static bool ScanDependencies(std::vector const& args); /** Called from command-line hook to check dependencies. */ static void CheckDependencies(cmMakefile* mf); protected: void GenerateMakefile(); void GenerateCMakefile(); void GenerateDirectoryInformationFile(); void GenerateTargetRuleFile(const cmTarget& target); void GenerateObjectRuleFile(const cmTarget& target, const cmSourceFile& source, std::vector& objects, std::vector& provides_requires); void GenerateCustomRuleFile(const cmCustomCommand& cc); void GenerateUtilityRuleFile(const cmTarget& target); bool GenerateDependsMakeFile(const std::string& lang, const char* objFile, std::string& depMakeFile, std::string& depMarkFile); void WriteMakeRule(std::ostream& os, const char* comment, const char* preEcho, const char* target, const std::vector& depends, const std::vector& commands, const char* postEcho=0); void WriteDivider(std::ostream& os); void WriteDisclaimer(std::ostream& os); void WriteMakeVariables(std::ostream& makefileStream); void WriteSpecialTargetsTop(std::ostream& makefileStream); void WriteSpecialTargetsBottom(std::ostream& makefileStream); void WriteRuleFileIncludes(std::ostream& makefileStream); void WriteAllRules(std::ostream& makefileStream); void WritePassRules(std::ostream& makefileStream, const char* pass); void WriteDriverRules(std::ostream& makefileStream, const char* pass, const char* local1, const char* local2=0); void WriteSubdirRules(std::ostream& makefileStream, const char* pass); void WriteSubdirRule(std::ostream& makefileStream, const char* pass, const char* subdir, std::string& last); void WriteSubdirDriverRule(std::ostream& makefileStream, const char* pass, const char* order, const std::string& last); void WriteLocalRule(std::ostream& ruleFileStream, const char* pass, const char* dependency); void WriteConvenienceRules(std::ostream& ruleFileStream, const cmTarget& target, const char* targetOutPath); void WriteConvenienceRule(std::ostream& ruleFileStream, const char* realTarget, const char* helpTarget); void WriteExecutableRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, const std::vector& objects, const std::vector& external_objects, const std::vector& provides_requires); void WriteStaticLibraryRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, const std::vector& objects, const std::vector& external_objects, const std::vector& provides_requires); void WriteSharedLibraryRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, const std::vector& objects, const std::vector& external_objects, const std::vector& provides_requires); void WriteModuleLibraryRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, const std::vector& objects, const std::vector& external_objects, const std::vector& provides_requires); void WriteLibraryRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, const std::vector& objects, const std::vector& external_objects, const char* linkRuleVar, const char* extraLinkFlags, const std::vector& provides_requires); void WriteObjectsVariable(std::ostream& ruleFileStream, const cmTarget& target, const std::vector& objects, const std::vector& external_objects, std::string& variableName, std::string& variableNameExternal); void WriteTargetDependsRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, const std::vector& objects); void WriteTargetCleanRule(std::ostream& ruleFileStream, const cmTarget& target, const std::vector& files); void WriteTargetRequiresRule(std::ostream& ruleFileStream, const cmTarget& target, const std::vector& provides_requires); void WriteLocalCleanRule(std::ostream& makefileStream); void WriteCMakeArgument(std::ostream& os, const char* s); std::string GetTargetDirectory(const cmTarget& target); std::string GetSubdirTargetName(const char* pass, const char* subdir); std::string GetObjectFileName(const cmTarget& target, const cmSourceFile& source); const char* GetSourceFileLanguage(const cmSourceFile& source); std::string ConvertToFullPath(const std::string& localPath); std::string ConvertToRelativePath(const char* p); std::string ConvertToRelativeOutputPath(const char* p); void ConfigureOutputPaths(); void FormatOutputPath(std::string& path, const char* name); bool ComparePath(const char* c1, const char* c2); void AppendTargetDepends(std::vector& depends, const cmTarget& target); void AppendAnyDepend(std::vector& depends, const char* name); void AppendCustomDepends(std::vector& depends, const std::vector& ccs); void AppendCustomDepend(std::vector& depends, const cmCustomCommand& cc); void AppendCustomCommands(std::vector& commands, const std::vector& ccs); void AppendCustomCommand(std::vector& commands, const cmCustomCommand& cc); void AppendCleanCommand(std::vector& commands, const std::vector& files); //========================================================================== void OutputEcho(std::ostream& fout, const char* msg); bool SamePath(const char* path1, const char* path2); std::string GetBaseTargetName(const cmTarget& t); void GetLibraryNames(const cmTarget& t, std::string& name, std::string& soName, std::string& realName, std::string& baseName); std::string ConvertToMakeTarget(const char* tgt); std::string& CreateSafeUniqueObjectFileName(const char* sin); std::string CreateMakeVariable(const char* sin, const char* s2in); //========================================================================== std::string GetRecursiveMakeCall(const char* tgt); void WriteJumpAndBuildRules(std::ostream& makefileStream); static cmDepends* GetDependsChecker(const std::string& lang, const char* dir, const char* objFile); private: // Map from target name to build directory containing it for // jump-and-build targets. struct RemoteTarget { std::string m_BuildDirectory; std::string m_FilePath; }; std::map m_JumpAndBuild; // List the files for which to check dependency integrity. Each // language has its own list because integrity may be checked // differently. struct IntegrityCheckSet: public std::set {}; std::map m_CheckDependFiles; // Command used when a rule has no dependencies or commands. std::vector m_EmptyCommands; //========================================================================== // Configuration settings. int m_MakefileVariableSize; std::map m_MakeVariableMap; std::map m_ShortMakeVariableMap; std::map m_UniqueObjectNamesMap; std::string m_IncludeDirective; std::string m_MakeSilentFlag; std::string m_ExecutableOutputPath; std::string m_LibraryOutputPath; bool m_PassMakeflags; //========================================================================== // List of make rule files that need to be included by the makefile. std::vector m_IncludeRuleFiles; // Set of custom rule files that have been generated. std::set m_CustomRuleFiles; // Set of object file names that will be built in this directory. std::set m_ObjectFiles; // The prefix required of a path to be converted to a relative path. // No sequence of ../.. will ever go past this path. std::string m_RelativePathTop; // The pre-split current output directory. std::vector m_CurrentOutputDirectoryComponents; }; #endif