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
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
,
165 DependenciesType Dependencies
;
166 bool CheckDependenciesForModuleOnly
;
167 bool CompilationUnitsEnabled
;
168 bool PrecompiledHeadersEnabled
;
169 std::string CheckDependenciesForModuleOnlyModule
;
170 std::string VSProjectVersion
;
171 std::string VSConfigurationType
;
172 bool UseVSVersionInPath
;
173 bool UseConfigurationInPath
;
174 bool MakeHandlesInstallDirectories
;
175 bool GenerateProxyMakefilesInSourceTree
;
182 static std::string
GetVariable ( const std::string
& name
);
183 static std::string
GetArch ();
184 static std::string
GetIntermediatePath ();
185 static std::string
GetOutputPath ();
186 static std::string
GetCdOutputPath ();
187 static std::string
GetInstallPath ();
188 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
189 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
190 const std::string
& defaultValue
);
194 class FileSupportCode
197 static void WriteIfChanged ( char* outbuf
,
198 const std::string
& filename
,
199 bool ignoreError
= false );
206 CompilationUnit
* compilationUnit
;
214 std::vector
<CompilationUnit
*> compilationUnits
;
215 std::vector
<File
*> files
;
216 std::vector
<Include
*> includes
;
217 std::vector
<Define
*> defines
;
218 std::vector
<Library
*> libraries
;
219 std::map
<std::string
, Property
*> properties
;
220 std::vector
<Module
*> modules
;
221 std::vector
<CompilerFlag
*> compilerFlags
;
222 int asmFiles
; // number of .asm files in compilationUnits
227 void ExtractModules( std::map
<std::string
, Module
*> &modules
);
233 XMLElement
*node
, *head
;
236 const Configuration
& configuration
;
238 std::string makefile
;
239 XMLIncludes xmlbuildfiles
;
240 std::vector
<LinkerFlag
*> linkerFlags
;
241 std::vector
<CDFile
*> cdfiles
;
242 std::vector
<InstallFile
*> installfiles
;
243 std::map
<std::string
, Module
*> modules
;
244 IfableData non_if_data
;
245 IfableData host_non_if_data
;
247 bool allowWarningsSet
;
249 Project ( const Configuration
& configuration
,
250 const std::string
& filename
,
251 const std::map
<std::string
, std::string
>* properties
= NULL
);
253 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
254 Backend
& GetBackend() { return *_backend
; }
255 void ExecuteInvocations ();
257 void ProcessXML ( const std::string
& path
);
258 Module
* LocateModule ( const std::string
& name
);
259 const Module
* LocateModule ( const std::string
& name
) const;
260 const std::string
& GetProjectFilename () const;
261 std::string
ResolveProperties ( const std::string
& s
) const;
262 const Property
* LookupProperty ( const std::string
& name
) const;
264 std::string
ResolveNextProperty ( const std::string
& s
) const;
266 void ProcessXMLSubElement ( const XMLElement
& e
,
267 const std::string
& path
,
268 ParseContext
& parseContext
);
270 // disable copy semantics
271 Project ( const Project
& );
272 Project
& operator = ( const Project
& );
311 TypeDontCare
, // always at the end
338 DirectoryLocation directory
;
339 std::string relative_path
;
342 FileLocation ( const DirectoryLocation directory
,
343 const std::string
& relative_path
,
344 const std::string
& name
,
345 const XMLElement
*node
= NULL
);
347 FileLocation ( const FileLocation
& other
);
353 const Project
& project
;
354 const XMLElement
& node
;
355 std::string xmlbuildFile
;
358 std::string extension
;
359 std::string baseaddress
;
361 std::string buildtype
;
363 ImportLibrary
* importLibrary
;
365 Bootsector
* bootSector
;
367 bool underscoreSymbols
;
369 bool isDefaultEntryPoint
;
370 Bootstrap
* bootstrap
;
371 AutoRegister
* autoRegister
; // <autoregister> node
372 IfableData non_if_data
;
373 std::vector
<Invoke
*> invocations
;
374 std::vector
<Dependency
*> dependencies
;
375 std::vector
<CompilerFlag
*> compilerFlags
;
376 std::vector
<LinkerFlag
*> linkerFlags
;
377 std::vector
<StubbedComponent
*> stubbedComponents
;
378 LinkerScript
* linkerScript
;
382 std::string aliasedModuleName
;
389 FileLocation
*output
; // "path/foo.exe"
390 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
391 FileLocation
*install
;
392 std::string description
;
394 std::string layoutId
;
395 std::string layoutNameResId
;
397 Module ( const Project
& project
,
398 const XMLElement
& moduleNode
,
399 const std::string
& modulePath
);
401 ModuleType
GetModuleType ( const std::string
& location
,
402 const XMLAttribute
& attribute
);
403 bool HasImportLibrary () const;
405 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
406 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
407 std::string
GetEntryPoint(bool leadingUnderscore
) const;
408 void GetTargets ( string_list
& ) const;
409 std::string
GetInvocationTarget ( const int index
) const;
410 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
411 void InvokeModule () const;
413 std::string
GetDllName() const;
415 void SetImportLibrary ( ImportLibrary
* importLibrary
);
416 DirectoryLocation
GetTargetDirectoryTree () const;
417 std::string
GetDefaultModuleExtension () const;
418 std::string
GetDefaultModuleEntrypoint () const;
419 std::string
GetDefaultModuleBaseaddress () const;
420 std::string
GetDefaultModuleCRT () const;
421 bool GetDefaultModuleIsCRT () const;
422 std::string entrypoint
;
423 void ProcessXMLSubElement ( const XMLElement
& e
,
424 DirectoryLocation directory
,
425 const std::string
& relative_path
,
426 ParseContext
& parseContext
);
427 bool GetBooleanAttribute ( const XMLElement
& moduleNode
,
429 bool default_value
= false );
432 class CompilerDirective
435 std::bitset
<CompilerTypesCount
> compilersSet
;
438 void SetCompiler ( CompilerType compiler
);
439 void UnsetCompiler ( CompilerType compiler
);
440 void SetAllCompilers ();
441 void UnsetAllCompilers ();
443 void ParseCompilers ( const XMLElement
& node
, const std::string
& defaultValue
);
445 bool IsCompilerSet ( CompilerType compiler
) const;
448 class Include
: public CompilerDirective
451 FileLocation
*directory
;
453 Include ( const Project
& project
,
454 const XMLElement
* includeNode
);
455 Include ( const Project
& project
,
456 const XMLElement
* includeNode
,
457 const Module
* module
);
458 Include ( const Project
& project
,
459 DirectoryLocation directory
,
460 const std::string
& relative_path
);
464 const Project
& project
;
465 const XMLElement
* node
;
466 const Module
* module
;
467 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
472 class Define
: public CompilerDirective
475 const Project
& project
;
476 const Module
* module
;
477 const XMLElement
* node
;
479 std::string arguments
;
484 Define ( const Project
& project
,
485 const XMLElement
& defineNode
);
486 Define ( const Project
& project
,
487 const Module
* module
,
488 const XMLElement
& defineNode
);
489 Define ( const Project
& project
,
490 const Module
* module
,
491 const std::string
& name_
,
492 const std::string
& backend_
= "",
493 bool redefine_
= false );
506 std::string switches
;
507 bool isPreCompiledHeader
;
509 File ( DirectoryLocation directory
,
510 const std::string
& relative_path
,
511 const std::string
& name
,
513 const std::string
& _switches
,
514 bool _isPreCompiledHeader
);
517 std::string
GetFullPath () const;
523 const XMLElement
*node
;
525 const Module
& module
;
527 const Module
* importedModule
;
529 Library ( const XMLElement
& _node
,
530 const Module
& _module
,
531 const std::string
& _name
);
532 Library ( const Module
& _module
,
533 const std::string
& _name
);
542 const XMLElement
& node
;
543 const Module
& module
;
544 const Module
* invokeModule
;
545 std::vector
<InvokeFile
*> input
;
546 std::vector
<InvokeFile
*> output
;
548 Invoke ( const XMLElement
& _node
,
549 const Module
& _module
);
552 void GetTargets ( string_list
& targets
) const;
553 std::string
GetParameters () const;
555 void ProcessXMLSubElement ( const XMLElement
& e
);
556 void ProcessXMLSubElementInput ( const XMLElement
& e
);
557 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
564 const XMLElement
& node
;
566 std::string switches
;
568 InvokeFile ( const XMLElement
& _node
,
569 const std::string
& _name
);
578 const XMLElement
& node
;
579 const Module
& module
;
580 const Module
* dependencyModule
;
582 Dependency ( const XMLElement
& _node
,
583 const Module
& _module
);
591 const XMLElement
& node
;
592 const Module
* module
;
593 const Module
* bootSectorModule
;
595 Bootsector ( const XMLElement
& _node
,
596 const Module
* _module
);
600 bool IsSupportedModuleType ( ModuleType type
);
606 const XMLElement
& node
;
607 const Module
& module
;
609 std::string description
;
611 std::string copyright
;
616 Metadata ( const XMLElement
& _node
,
617 const Module
& _module
);
622 class ImportLibrary
: public XmlNode
625 const Module
* module
;
627 FileLocation
*source
;
629 ImportLibrary ( const Project
& project
,
630 const XMLElement
& node
,
631 const Module
* module
);
636 class CompilerFlag
: public CompilerDirective
639 const Project
& project
;
640 const Module
* module
;
641 const XMLElement
& node
;
644 CompilerFlag ( const Project
& project
,
645 const XMLElement
& compilerFlagNode
);
646 CompilerFlag ( const Project
& project
,
647 const Module
* module
,
648 const XMLElement
& compilerFlagNode
);
659 const Project
& project
;
660 const Module
* module
;
661 const XMLElement
& node
;
664 LinkerFlag ( const Project
& project
,
665 const XMLElement
& linkerFlagNode
);
666 LinkerFlag ( const Project
& project
,
667 const Module
* module
,
668 const XMLElement
& linkerFlagNode
);
679 const XMLElement
& node
;
680 const Module
& module
;
681 const FileLocation
*file
;
683 LinkerScript ( const XMLElement
& node
,
684 const Module
& module
,
685 const FileLocation
*file
);
694 const Project
& project
;
695 const Module
* module
;
696 std::string name
, value
;
699 Property ( const XMLElement
& node_
,
700 const Project
& project_
,
701 const Module
* module_
);
703 Property ( const Project
& project_
,
704 const Module
* module_
,
705 const std::string
& name_
,
706 const std::string
& value_
);
712 class TestSupportCode
715 const Project
& project
;
717 TestSupportCode ( const Project
& project
);
719 void GenerateTestSupportCode ( bool verbose
);
721 bool IsTestModule ( const Module
& module
);
722 void GenerateTestSupportCodeForModule ( Module
& module
,
724 std::string
GetHooksFilename ( Module
& module
);
725 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
726 const StubbedComponent
& component
,
727 const StubbedSymbol
& symbol
);
728 char* WriteStubbedComponentToHooksFile ( char* buffer
,
729 const StubbedComponent
& component
);
730 void WriteHooksFile ( Module
& module
);
731 std::string
GetStubsFilename ( Module
& module
);
732 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
733 const StubbedComponent
& component
,
734 const StubbedSymbol
& symbol
,
736 char* WriteStubbedComponentToStubsFile ( char* buffer
,
737 const StubbedComponent
& component
,
739 void WriteStubsFile ( Module
& module
);
740 std::string
GetStartupFilename ( Module
& module
);
741 bool IsUnknownCharacter ( char ch
);
742 std::string
GetTestDispatcherName ( std::string filename
);
743 bool IsTestFile ( std::string
& filename
) const;
744 void GetSourceFilenames ( string_list
& list
,
745 Module
& module
) const;
746 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
748 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
750 void WriteStartupFile ( Module
& module
);
757 SourceFile ( AutomaticDependency
* automaticDependency
,
758 const Module
& module
,
760 SourceFile
* parent
);
762 std::vector
<SourceFile
*> files
; /* List of files included in this file */
764 AutomaticDependency
* automaticDependency
;
765 const Module
& module
;
766 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
767 time_t lastWriteTime
;
768 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
769 SourceFile
* youngestFile
;
773 void SkipWhitespace ();
774 bool ReadInclude ( std::string
& filename
,
775 bool& searchCurrentDirectory
,
777 bool IsIncludedFrom ( const File
& file
);
778 SourceFile
* ParseFile(const File
& file
);
779 bool CanProcessFile ( const File
& file
);
780 bool IsParentOf ( const SourceFile
* parent
,
781 const SourceFile
* child
);
788 class AutomaticDependency
790 friend class SourceFileTest
;
792 const Project
& project
;
794 AutomaticDependency ( const Project
& project
);
795 ~AutomaticDependency ();
796 bool LocateIncludedFile ( const FileLocation
& directory
,
797 const std::string
& includedFilename
);
798 bool LocateIncludedFile ( SourceFile
* sourceFile
,
799 const Module
& module
,
800 const std::string
& includedFilename
,
801 bool searchCurrentDirectory
,
803 File
& resolvedFile
);
804 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
806 SourceFile
* parentSourceFile
);
807 SourceFile
* RetrieveFromCache ( const File
& file
);
808 void CheckAutomaticDependencies ( bool verbose
);
809 void CheckAutomaticDependenciesForModule ( Module
& module
,
812 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
813 void CheckAutomaticDependencies ( const Module
& module
,
815 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
816 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
817 const Module
& module
);
818 void GetModuleFiles ( const Module
& module
,
819 std::vector
<File
*>& files
) const;
821 void ParseFiles ( const Module
& module
);
822 void ParseFile ( const Module
& module
,
824 std::map
<std::string
, SourceFile
*> sourcefile_map
;
831 const Project
& project
;
832 const Module
* module
;
833 const XMLElement
& node
;
835 std::string nameoncd
;
837 Bootstrap ( const Project
& project
,
838 const Module
* module
,
839 const XMLElement
& bootstrapNode
);
843 bool IsSupportedModuleType ( ModuleType type
);
845 static std::string
ReplaceVariable ( const std::string
& name
,
846 const std::string
& value
,
851 class CDFile
: public XmlNode
854 FileLocation
*source
;
855 FileLocation
*target
;
857 CDFile ( const Project
& project
,
858 const XMLElement
& bootstrapNode
,
859 const std::string
& path
);
862 static std::string
ReplaceVariable ( const std::string
& name
,
863 const std::string
& value
,
868 class InstallFile
: public XmlNode
871 FileLocation
*source
;
872 FileLocation
*target
;
874 InstallFile ( const Project
& project
,
875 const XMLElement
& bootstrapNode
,
876 const std::string
& path
);
884 const XMLElement
& node
;
885 const Module
& module
;
886 const FileLocation
*file
;
889 const XMLElement
& node
,
890 const Module
& module
,
891 const FileLocation
*file
);
897 class StubbedComponent
900 const Module
* module
;
901 const XMLElement
& node
;
903 std::vector
<StubbedSymbol
*> symbols
;
905 StubbedComponent ( const Module
* module_
,
906 const XMLElement
& stubbedComponentNode
);
907 ~StubbedComponent ();
909 void ProcessXMLSubElement ( const XMLElement
& e
);
916 const XMLElement
& node
;
919 std::string strippedName
;
921 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
925 std::string
StripSymbol ( std::string symbol
);
929 class CompilationUnit
934 CompilationUnit ( const File
* file
);
935 CompilationUnit ( const Project
* project
,
936 const Module
* module
,
937 const XMLElement
* node
);
940 bool IsGeneratedFile () const;
941 bool HasFileWithExtension ( const std::string
& extension
) const;
942 bool IsFirstFile () const;
943 const FileLocation
& GetFilename () const;
944 const std::string
& GetSwitches () const;
945 void AddFile ( const File
* file
);
946 const std::vector
<const File
*> GetFiles () const;
948 const Project
* project
;
949 const Module
* module
;
950 const XMLElement
* node
;
951 std::vector
<const File
*> files
;
952 FileLocation
*default_name
;
956 class CompilationUnitSupportCode
959 const Project
& project
;
961 CompilationUnitSupportCode ( const Project
& project
);
962 ~CompilationUnitSupportCode ();
963 void Generate ( bool verbose
);
965 void GenerateForModule ( Module
& module
,
967 std::string
GetCompilationUnitFilename ( Module
& module
,
968 CompilationUnit
& compilationUnit
);
969 void WriteCompilationUnitFile ( Module
& module
,
970 CompilationUnit
& compilationUnit
);
974 enum AutoRegisterType
981 class AutoRegister
: public XmlNode
984 const Module
* module
;
985 std::string infSection
;
986 AutoRegisterType type
;
987 AutoRegister ( const Project
& project_
,
988 const Module
* module_
,
989 const XMLElement
& node_
);
991 bool IsSupportedModuleType ( ModuleType type
);
992 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
997 class SysSetupGenerator
1000 const Project
& project
;
1001 SysSetupGenerator ( const Project
& project
);
1002 ~SysSetupGenerator ();
1005 std::string
GetDirectoryId ( const Module
& module
);
1006 std::string
GetFlags ( const Module
& module
);
1007 void Generate ( HINF inf
,
1008 const Module
& module
);
1013 InitializeEnvironment ();
1016 Right ( const std::string
& s
, size_t n
);
1019 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
1022 ChangeSeparator ( const std::string
& s
,
1023 const char fromSeparator
,
1024 const char toSeparator
);
1027 FixSeparator ( const std::string
& s
);
1030 FixSeparatorForSystemCommand ( const std::string
& s
);
1033 DosSeparator ( const std::string
& s
);
1037 const std::string
& filename
,
1038 const std::string
& newExtension
);
1042 const Project
& project
,
1043 const std::string
& location
,
1044 const std::string
& path
,
1045 const std::string
& att_value
);
1048 GetExtension ( const FileLocation
& file
);
1051 NormalizeFilename ( const std::string
& filename
);
1054 ToLower ( std::string filename
);
1056 #endif /* __RBUILD_H */