2 * Copyright (C) 2005 Casper S. Hornstrup
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <sys/utime.h>
41 #include "exception.h"
44 class Backend
; // forward declaration
46 typedef std::vector
<std::string
> string_list
;
48 extern std::string ExePrefix
;
49 extern std::string ExePostfix
;
50 extern std::string sSep
;
51 extern std::string sBadSep
;
56 #define DEF_EXEPREFIX ""
57 #define DEF_EXEPOSTFIX ".exe"
59 #define DEF_CBAD_SEP '/'
61 #define DEF_SBAD_SEP "/"
63 #define DEF_EXEPREFIX "./"
64 #define DEF_EXEPOSTFIX ""
66 #define DEF_CBAD_SEP '\\'
68 #define DEF_SBAD_SEP "\\"
71 #define MS_VS_DEF_VERSION "7.10"
90 class TestSupportCode
;
91 class AutomaticDependency
;
96 class StubbedComponent
;
98 class CompilationUnit
;
102 class SourceFileTest
;
106 typedef std::map
<std::string
,Directory
*> directory_map
;
111 const Project
& project
;
112 const XMLElement
& node
;
114 XmlNode ( const Project
& project_
,
115 const XMLElement
& node_
);
119 virtual void ProcessXML();
122 enum DirectoryLocation
125 IntermediateDirectory
,
135 directory_map subdirs
;
136 Directory ( const std::string
& name
);
138 void Add ( const char* subdir
);
139 void GenerateTree ( DirectoryLocation root
,
141 void CreateRule ( FILE* f
,
142 const std::string
& parent
);
144 bool mkdir_p ( const char* path
);
145 bool CreateDirectory ( const std::string
& path
);
146 std::string
EscapeSpaces ( const std::string
& path
);
147 void GenerateTree ( const std::string
& parent
,
151 enum DependenciesType
154 AutomaticDependencies
,
177 DependenciesType Dependencies
;
178 bool CheckDependenciesForModuleOnly
;
179 bool CompilationUnitsEnabled
;
180 bool PrecompiledHeadersEnabled
;
181 std::string CheckDependenciesForModuleOnlyModule
;
182 std::string VSProjectVersion
;
183 std::string VSConfigurationType
;
184 bool UseVSVersionInPath
;
185 bool UseConfigurationInPath
;
186 bool MakeHandlesInstallDirectories
;
187 bool GenerateProxyMakefilesInSourceTree
;
189 CompilerSet Compiler
;
196 static std::string
GetVariable ( const std::string
& name
);
197 static std::string
GetArch ();
198 static std::string
GetIntermediatePath ();
199 static std::string
GetOutputPath ();
200 static std::string
GetCdOutputPath ();
201 static std::string
GetInstallPath ();
202 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
203 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
204 const std::string
& defaultValue
);
208 class FileSupportCode
211 static void WriteIfChanged ( char* outbuf
,
212 const std::string
& filename
,
213 bool ignoreError
= false );
220 CompilationUnit
* compilationUnit
;
228 std::vector
<CompilationUnit
*> compilationUnits
;
229 std::vector
<File
*> files
;
230 std::vector
<Include
*> includes
;
231 std::vector
<Define
*> defines
;
232 std::vector
<Library
*> libraries
;
233 std::map
<std::string
, Property
*> properties
;
234 std::vector
<Module
*> modules
;
235 std::vector
<CompilerFlag
*> compilerFlags
;
236 int asmFiles
; // number of .asm files in compilationUnits
241 void ExtractModules( std::map
<std::string
, Module
*> &modules
);
247 XMLElement
*node
, *head
;
250 const Configuration
& configuration
;
252 std::string makefile
;
253 XMLIncludes xmlbuildfiles
;
254 std::vector
<LinkerFlag
*> linkerFlags
;
255 std::vector
<CDFile
*> cdfiles
;
256 std::vector
<InstallFile
*> installfiles
;
257 std::map
<std::string
, Module
*> modules
;
258 IfableData non_if_data
;
259 IfableData host_non_if_data
;
261 bool allowWarningsSet
;
263 Project ( const Configuration
& configuration
,
264 const std::string
& filename
,
265 const std::map
<std::string
, std::string
>* properties
= NULL
);
267 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
268 Backend
& GetBackend() { return *_backend
; }
269 void ExecuteInvocations ();
271 void ProcessXML ( const std::string
& path
);
272 Module
* LocateModule ( const std::string
& name
);
273 const Module
* LocateModule ( const std::string
& name
) const;
274 const std::string
& GetProjectFilename () const;
275 std::string
ResolveProperties ( const std::string
& s
) const;
276 const Property
* LookupProperty ( const std::string
& name
) const;
277 std::string
GetCompilerSet () const;
278 std::string
GetLinkerSet () const;
279 void GenerateInstallerFileList();
281 std::string
ResolveNextProperty ( const std::string
& s
) const;
283 void ProcessXMLSubElement ( const XMLElement
& e
,
284 const std::string
& path
,
285 ParseContext
& parseContext
);
287 // disable copy semantics
288 Project ( const Project
& );
289 Project
& operator = ( const Project
& );
326 TypeDontCare
, // always at the end
353 DirectoryLocation directory
;
354 std::string relative_path
;
357 FileLocation ( const DirectoryLocation directory
,
358 const std::string
& relative_path
,
359 const std::string
& name
,
360 const XMLElement
*node
= NULL
);
362 FileLocation ( const FileLocation
& other
);
368 const Project
& project
;
369 const XMLElement
& node
;
370 std::string xmlbuildFile
;
373 std::string extension
;
374 std::string baseaddress
;
376 std::string buildtype
;
378 ImportLibrary
* importLibrary
;
379 ImportLibrary
* delayImportLibrary
;
381 Bootsector
* bootSector
;
383 bool isDefaultEntryPoint
;
384 Bootstrap
* bootstrap
;
385 AutoRegister
* autoRegister
; // <autoregister> node
386 IfableData non_if_data
;
387 std::vector
<Invoke
*> invocations
;
388 std::vector
<Dependency
*> dependencies
;
389 std::vector
<CompilerFlag
*> compilerFlags
;
390 std::vector
<LinkerFlag
*> linkerFlags
;
391 std::vector
<StubbedComponent
*> stubbedComponents
;
392 std::vector
<CDFile
*> cdfiles
;
393 LinkerScript
* linkerScript
;
397 std::string aliasedModuleName
;
404 std::string installbase
;
405 FileLocation
*output
; // "path/foo.exe"
406 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
407 FileLocation
*install
;
408 std::string description
;
410 std::string layoutId
;
411 std::string layoutNameResId
;
413 Module ( const Project
& project
,
414 const XMLElement
& moduleNode
,
415 const std::string
& modulePath
);
417 ModuleType
GetModuleType ( const std::string
& location
,
418 const XMLAttribute
& attribute
);
419 bool HasImportLibrary () const;
421 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
422 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
423 std::string
GetEntryPoint() const;
424 void GetTargets ( string_list
& ) const;
425 std::string
GetInvocationTarget ( const int index
) const;
426 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
427 void InvokeModule () const;
429 std::string
GetDllName() const;
431 void SetImportLibrary ( ImportLibrary
* importLibrary
);
432 void SetDelayImportLibrary ( ImportLibrary
* importLibrary
);
433 DirectoryLocation
GetTargetDirectoryTree () const;
434 std::string
GetDefaultModuleExtension () const;
435 std::string
GetDefaultModuleEntrypoint () const;
436 std::string
GetDefaultModuleBaseaddress () const;
437 std::string
GetDefaultModuleCRT () const;
438 bool GetDefaultModuleIsCRT () const;
439 std::string entrypoint
;
440 void ProcessXMLSubElement ( const XMLElement
& e
,
441 DirectoryLocation directory
,
442 const std::string
& relative_path
,
443 ParseContext
& parseContext
);
444 bool GetBooleanAttribute ( const XMLElement
& moduleNode
,
446 bool default_value
= false );
449 class ToolsetDirective
455 void ParseToolsets ( const Project
& project
, const XMLElement
& node
);
458 virtual ~ToolsetDirective() { }
459 bool IsEnabled () const;
462 class CompilerDirective
465 std::bitset
<CompilerTypesCount
> compilersSet
;
469 void ParseCompilers ( const XMLElement
& node
, const std::string
& defaultValue
);
472 CompilerDirective (): enabled ( true ) { }
473 virtual ~CompilerDirective() { }
474 void SetCompiler ( CompilerType compiler
);
475 void UnsetCompiler ( CompilerType compiler
);
476 void SetAllCompilers ();
477 void UnsetAllCompilers ();
478 bool IsCompilerSet ( CompilerType compiler
) const;
481 class Include
: public CompilerDirective
, public ToolsetDirective
484 FileLocation
*directory
;
486 Include ( const Project
& project
,
487 const XMLElement
* includeNode
);
488 Include ( const Project
& project
,
489 const XMLElement
* includeNode
,
490 const Module
* module
);
491 Include ( const Project
& project
,
492 DirectoryLocation directory
,
493 const std::string
& relative_path
);
497 const Project
& project
;
498 const XMLElement
* node
;
499 const Module
* module
;
500 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
505 class Define
: public CompilerDirective
, public ToolsetDirective
508 const Project
& project
;
509 const Module
* module
;
510 const XMLElement
* node
;
512 std::string arguments
;
517 Define ( const Project
& project
,
518 const XMLElement
& defineNode
);
519 Define ( const Project
& project
,
520 const Module
* module
,
521 const XMLElement
& defineNode
);
522 Define ( const Project
& project
,
523 const Module
* module
,
524 const std::string
& name_
,
525 const std::string
& backend_
= "",
526 bool redefine_
= false );
539 std::string switches
;
540 bool isPreCompiledHeader
;
542 File ( DirectoryLocation directory
,
543 const std::string
& relative_path
,
544 const std::string
& name
,
546 const std::string
& _switches
,
547 bool _isPreCompiledHeader
);
550 std::string
GetFullPath () const;
556 const XMLElement
*node
;
558 const Module
& module
;
560 const Module
* importedModule
;
563 Library ( const XMLElement
& _node
,
564 const Module
& _module
,
565 const std::string
& _name
);
566 Library ( const Module
& _module
,
567 const std::string
& _name
);
576 const XMLElement
& node
;
577 const Module
& module
;
578 const Module
* invokeModule
;
579 std::vector
<InvokeFile
*> input
;
580 std::vector
<InvokeFile
*> output
;
582 Invoke ( const XMLElement
& _node
,
583 const Module
& _module
);
586 void GetTargets ( string_list
& targets
) const;
587 std::string
GetParameters () const;
589 void ProcessXMLSubElement ( const XMLElement
& e
);
590 void ProcessXMLSubElementInput ( const XMLElement
& e
);
591 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
598 const XMLElement
& node
;
600 std::string switches
;
602 InvokeFile ( const XMLElement
& _node
,
603 const std::string
& _name
);
612 const XMLElement
& node
;
613 const Module
& module
;
614 const Module
* dependencyModule
;
616 Dependency ( const XMLElement
& _node
,
617 const Module
& _module
);
625 const XMLElement
& node
;
626 const Module
* module
;
627 const Module
* bootSectorModule
;
629 Bootsector ( const XMLElement
& _node
,
630 const Module
* _module
);
634 bool IsSupportedModuleType ( ModuleType type
);
640 const XMLElement
& node
;
641 const Module
& module
;
643 std::string description
;
645 std::string copyright
;
650 Metadata ( const XMLElement
& _node
,
651 const Module
& _module
);
656 class ImportLibrary
: public XmlNode
659 const Module
* module
;
661 FileLocation
*source
;
662 FileLocation
*target
;
664 ImportLibrary ( const Project
& project
,
665 const XMLElement
& node
,
666 const Module
* module
,
672 class CompilerFlag
: public CompilerDirective
, public ToolsetDirective
675 const Project
& project
;
676 const Module
* module
;
677 const XMLElement
& node
;
680 CompilerFlag ( const Project
& project
,
681 const XMLElement
& compilerFlagNode
);
682 CompilerFlag ( const Project
& project
,
683 const Module
* module
,
684 const XMLElement
& compilerFlagNode
);
692 class LinkerFlag
: public ToolsetDirective
695 const Project
& project
;
696 const Module
* module
;
697 const XMLElement
& node
;
700 LinkerFlag ( const Project
& project
,
701 const XMLElement
& linkerFlagNode
);
702 LinkerFlag ( const Project
& project
,
703 const Module
* module
,
704 const XMLElement
& linkerFlagNode
);
715 const XMLElement
& node
;
716 const Module
& module
;
717 const FileLocation
*file
;
719 LinkerScript ( const XMLElement
& node
,
720 const Module
& module
,
721 const FileLocation
*file
);
730 const Project
& project
;
731 const Module
* module
;
732 std::string name
, value
;
735 Property ( const XMLElement
& node_
,
736 const Project
& project_
,
737 const Module
* module_
);
739 Property ( const Project
& project_
,
740 const Module
* module_
,
741 const std::string
& name_
,
742 const std::string
& value_
);
748 class TestSupportCode
751 const Project
& project
;
753 TestSupportCode ( const Project
& project
);
755 void GenerateTestSupportCode ( bool verbose
);
757 bool IsTestModule ( const Module
& module
);
758 void GenerateTestSupportCodeForModule ( Module
& module
,
760 std::string
GetHooksFilename ( Module
& module
);
761 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
762 const StubbedComponent
& component
,
763 const StubbedSymbol
& symbol
);
764 char* WriteStubbedComponentToHooksFile ( char* buffer
,
765 const StubbedComponent
& component
);
766 void WriteHooksFile ( Module
& module
);
767 std::string
GetStubsFilename ( Module
& module
);
768 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
769 const StubbedComponent
& component
,
770 const StubbedSymbol
& symbol
,
772 char* WriteStubbedComponentToStubsFile ( char* buffer
,
773 const StubbedComponent
& component
,
775 void WriteStubsFile ( Module
& module
);
776 std::string
GetStartupFilename ( Module
& module
);
777 bool IsUnknownCharacter ( char ch
);
778 std::string
GetTestDispatcherName ( std::string filename
);
779 bool IsTestFile ( std::string
& filename
) const;
780 void GetSourceFilenames ( string_list
& list
,
781 Module
& module
) const;
782 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
784 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
786 void WriteStartupFile ( Module
& module
);
793 SourceFile ( AutomaticDependency
* automaticDependency
,
794 const Module
& module
,
796 SourceFile
* parent
);
798 std::vector
<SourceFile
*> files
; /* List of files included in this file */
800 AutomaticDependency
* automaticDependency
;
801 const Module
& module
;
802 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
803 time_t lastWriteTime
;
804 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
805 SourceFile
* youngestFile
;
809 void SkipWhitespace ();
810 bool ReadInclude ( std::string
& filename
,
811 bool& searchCurrentDirectory
,
813 bool IsIncludedFrom ( const File
& file
);
814 SourceFile
* ParseFile(const File
& file
);
815 bool CanProcessFile ( const File
& file
);
816 bool IsParentOf ( const SourceFile
* parent
,
817 const SourceFile
* child
);
824 class AutomaticDependency
826 friend class SourceFileTest
;
828 const Project
& project
;
830 AutomaticDependency ( const Project
& project
);
831 ~AutomaticDependency ();
832 bool LocateIncludedFile ( const FileLocation
& directory
,
833 const std::string
& includedFilename
);
834 bool LocateIncludedFile ( SourceFile
* sourceFile
,
835 const Module
& module
,
836 const std::string
& includedFilename
,
837 bool searchCurrentDirectory
,
839 File
& resolvedFile
);
840 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
842 SourceFile
* parentSourceFile
);
843 SourceFile
* RetrieveFromCache ( const File
& file
);
844 void CheckAutomaticDependencies ( bool verbose
);
845 void CheckAutomaticDependenciesForModule ( Module
& module
,
848 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
849 void CheckAutomaticDependencies ( const Module
& module
,
851 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
852 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
853 const Module
& module
);
854 void GetModuleFiles ( const Module
& module
,
855 std::vector
<File
*>& files
) const;
857 void ParseFiles ( const Module
& module
);
858 void ParseFile ( const Module
& module
,
860 std::map
<std::string
, SourceFile
*> sourcefile_map
;
867 const Project
& project
;
868 const Module
* module
;
869 const XMLElement
& node
;
871 std::string nameoncd
;
873 Bootstrap ( const Project
& project
,
874 const Module
* module
,
875 const XMLElement
& bootstrapNode
);
879 bool IsSupportedModuleType ( ModuleType type
);
881 static std::string
ReplaceVariable ( const std::string
& name
,
882 const std::string
& value
,
887 class CDFile
: public XmlNode
890 FileLocation
*source
;
891 FileLocation
*target
;
893 CDFile ( const Project
& project
,
894 const XMLElement
& bootstrapNode
,
895 const std::string
& path
);
898 static std::string
ReplaceVariable ( const std::string
& name
,
899 const std::string
& value
,
904 class InstallFile
: public XmlNode
907 FileLocation
*source
;
908 FileLocation
*target
;
909 std::string installbase
;
911 InstallFile ( const Project
& project
,
912 const XMLElement
& bootstrapNode
,
913 const std::string
& path
);
921 const XMLElement
& node
;
922 const Module
& module
;
923 const FileLocation
*file
;
926 const XMLElement
& node
,
927 const Module
& module
,
928 const FileLocation
*file
);
934 class StubbedComponent
937 const Module
* module
;
938 const XMLElement
& node
;
940 std::vector
<StubbedSymbol
*> symbols
;
942 StubbedComponent ( const Module
* module_
,
943 const XMLElement
& stubbedComponentNode
);
944 ~StubbedComponent ();
946 void ProcessXMLSubElement ( const XMLElement
& e
);
953 const XMLElement
& node
;
956 std::string strippedName
;
958 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
962 std::string
StripSymbol ( std::string symbol
);
966 class CompilationUnit
971 CompilationUnit ( const File
* file
);
972 CompilationUnit ( const Project
* project
,
973 const Module
* module
,
974 const XMLElement
* node
);
977 bool IsGeneratedFile () const;
978 bool HasFileWithExtension ( const std::string
& extension
) const;
979 bool IsFirstFile () const;
980 const FileLocation
& GetFilename () const;
981 const std::string
& GetSwitches () const;
982 void AddFile ( const File
* file
);
983 const std::vector
<const File
*> GetFiles () const;
985 const Project
* project
;
986 const Module
* module
;
987 const XMLElement
* node
;
988 std::vector
<const File
*> files
;
989 FileLocation
*default_name
;
993 class CompilationUnitSupportCode
996 const Project
& project
;
998 CompilationUnitSupportCode ( const Project
& project
);
999 ~CompilationUnitSupportCode ();
1000 void Generate ( bool verbose
);
1002 void GenerateForModule ( Module
& module
,
1004 std::string
GetCompilationUnitFilename ( Module
& module
,
1005 CompilationUnit
& compilationUnit
);
1006 void WriteCompilationUnitFile ( Module
& module
,
1007 CompilationUnit
& compilationUnit
);
1011 enum AutoRegisterType
1018 class AutoRegister
: public XmlNode
1021 const Module
* module
;
1022 std::string infSection
;
1023 AutoRegisterType type
;
1024 AutoRegister ( const Project
& project_
,
1025 const Module
* module_
,
1026 const XMLElement
& node_
);
1028 bool IsSupportedModuleType ( ModuleType type
);
1029 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
1034 class SysSetupGenerator
1037 const Project
& project
;
1038 SysSetupGenerator ( const Project
& project
);
1039 ~SysSetupGenerator ();
1042 std::string
GetDirectoryId ( const Module
& module
);
1043 std::string
GetFlags ( const Module
& module
);
1044 void Generate ( HINF inf
,
1045 const Module
& module
);
1050 InitializeEnvironment ();
1053 Right ( const std::string
& s
, size_t n
);
1056 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
1059 ChangeSeparator ( const std::string
& s
,
1060 const char fromSeparator
,
1061 const char toSeparator
);
1064 FixSeparator ( const std::string
& s
);
1067 FixSeparatorForSystemCommand ( const std::string
& s
);
1070 DosSeparator ( const std::string
& s
);
1074 const std::string
& filename
,
1075 const std::string
& newExtension
);
1079 const Project
& project
,
1080 const std::string
& location
,
1081 const std::string
& path
,
1082 const std::string
& att_value
);
1085 GetExtension ( const FileLocation
& file
);
1088 NormalizeFilename ( const std::string
& filename
);
1091 ToLower ( std::string filename
);
1093 #endif /* __RBUILD_H */