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"
91 class TestSupportCode
;
92 class AutomaticDependency
;
97 class StubbedComponent
;
99 class CompilationUnit
;
103 class SourceFileTest
;
107 typedef std::map
<std::string
,Directory
*> directory_map
;
112 const Project
& project
;
113 const XMLElement
& node
;
115 XmlNode ( const Project
& project_
,
116 const XMLElement
& node_
);
120 virtual void ProcessXML();
123 enum DirectoryLocation
126 IntermediateDirectory
,
136 directory_map subdirs
;
137 Directory ( const std::string
& name
);
139 void Add ( const char* subdir
);
140 void GenerateTree ( DirectoryLocation root
,
142 void CreateRule ( FILE* f
,
143 const std::string
& parent
);
145 bool mkdir_p ( const char* path
);
146 bool CreateDirectory ( const std::string
& path
);
147 std::string
EscapeSpaces ( const std::string
& path
);
148 void GenerateTree ( const std::string
& parent
,
160 bool AutomaticDependencies
;
161 bool CheckDependenciesForModuleOnly
;
162 bool CompilationUnitsEnabled
;
163 bool PrecompiledHeadersEnabled
;
164 std::string CheckDependenciesForModuleOnlyModule
;
165 std::string VSProjectVersion
;
166 std::string VSConfigurationType
;
167 bool UseVSVersionInPath
;
168 bool UseConfigurationInPath
;
169 bool MakeHandlesInstallDirectories
;
170 bool GenerateProxyMakefilesInSourceTree
;
177 static std::string
GetVariable ( const std::string
& name
);
178 static std::string
GetArch ();
179 static std::string
GetIntermediatePath ();
180 static std::string
GetOutputPath ();
181 static std::string
GetCdOutputPath ();
182 static std::string
GetInstallPath ();
183 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
184 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
185 const std::string
& defaultValue
);
189 class FileSupportCode
192 static void WriteIfChanged ( char* outbuf
,
193 const std::string
& filename
,
194 bool ignoreError
= false );
202 CompilationUnit
* compilationUnit
;
210 std::vector
<CompilationUnit
*> compilationUnits
;
211 std::vector
<File
*> files
;
212 std::vector
<Include
*> includes
;
213 std::vector
<Define
*> defines
;
214 std::vector
<Library
*> libraries
;
215 std::vector
<Property
*> properties
;
216 std::vector
<Module
*> modules
;
217 std::vector
<CompilerFlag
*> compilerFlags
;
218 std::vector
<If
*> ifs
;
219 int asmFiles
; // number of .asm files in compilationUnits
224 void ExtractModules( std::vector
<Module
*> &modules
);
230 XMLElement
*node
, *head
;
233 const Configuration
& configuration
;
235 std::string makefile
;
236 XMLIncludes xmlbuildfiles
;
237 std::vector
<LinkerFlag
*> linkerFlags
;
238 std::vector
<CDFile
*> cdfiles
;
239 std::vector
<InstallFile
*> installfiles
;
240 std::vector
<Module
*> modules
;
241 IfableData non_if_data
;
243 Project ( const Configuration
& configuration
,
244 const std::string
& filename
,
245 const std::map
<std::string
, std::string
>* properties
= NULL
);
247 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
248 Backend
& GetBackend() { return *_backend
; }
249 void WriteConfigurationFile ();
250 void ExecuteInvocations ();
252 void ProcessXML ( const std::string
& path
);
253 Module
* LocateModule ( const std::string
& name
);
254 const Module
* LocateModule ( const std::string
& name
) const;
255 const std::string
& GetProjectFilename () const;
256 std::string
ResolveProperties ( const std::string
& s
) const;
258 std::string
ResolveNextProperty ( const std::string
& s
) const;
259 const Property
* LookupProperty ( const std::string
& name
) const;
260 void SetConfigurationOption ( char* s
,
262 std::string alternativeName
);
263 void SetConfigurationOption ( char* s
,
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
& );
310 TypeDontCare
, // always at the end
323 CompilerTypeDontCare
,
331 DirectoryLocation directory
;
332 std::string relative_path
;
335 FileLocation ( const DirectoryLocation directory
,
336 const std::string
& relative_path
,
337 const std::string
& name
,
338 const XMLElement
*node
= NULL
);
340 FileLocation ( const FileLocation
& other
);
346 const Project
& project
;
347 const XMLElement
& node
;
348 std::string xmlbuildFile
;
351 std::string extension
;
352 std::string baseaddress
;
354 std::string buildtype
;
356 ImportLibrary
* importLibrary
;
358 Bootsector
* bootSector
;
360 bool underscoreSymbols
;
362 bool isDefaultEntryPoint
;
363 Bootstrap
* bootstrap
;
364 AutoRegister
* autoRegister
; // <autoregister> node
365 IfableData non_if_data
;
366 std::vector
<Invoke
*> invocations
;
367 std::vector
<Dependency
*> dependencies
;
368 std::vector
<CompilerFlag
*> compilerFlags
;
369 std::vector
<LinkerFlag
*> linkerFlags
;
370 std::vector
<StubbedComponent
*> stubbedComponents
;
371 LinkerScript
* linkerScript
;
376 std::string aliasedModuleName
;
380 FileLocation
*output
; // "path/foo.exe"
381 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
382 FileLocation
*install
;
383 std::string description
;
385 std::string layoutId
;
386 std::string layoutNameResId
;
388 Module ( const Project
& project
,
389 const XMLElement
& moduleNode
,
390 const std::string
& modulePath
);
392 ModuleType
GetModuleType ( const std::string
& location
,
393 const XMLAttribute
& attribute
);
394 bool HasImportLibrary () const;
396 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
397 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
398 std::string
GetEntryPoint(bool leadingUnderscore
) const;
399 void GetTargets ( string_list
& ) const;
400 std::string
GetInvocationTarget ( const int index
) const;
401 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
402 void InvokeModule () const;
405 void SetImportLibrary ( ImportLibrary
* importLibrary
);
406 DirectoryLocation
GetTargetDirectoryTree () const;
407 std::string
GetDefaultModuleExtension () const;
408 std::string
GetDefaultModuleEntrypoint () const;
409 std::string
GetDefaultModuleBaseaddress () const;
410 std::string entrypoint
;
411 void ProcessXMLSubElement ( const XMLElement
& e
,
412 DirectoryLocation directory
,
413 const std::string
& relative_path
,
414 ParseContext
& parseContext
);
421 FileLocation
*directory
;
423 Include ( const Project
& project
,
424 const XMLElement
* includeNode
);
425 Include ( const Project
& project
,
426 const XMLElement
* includeNode
,
427 const Module
* module
);
428 Include ( const Project
& project
,
429 DirectoryLocation directory
,
430 const std::string
& relative_path
);
434 const Project
& project
;
435 const XMLElement
* node
;
436 const Module
* module
;
437 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
444 const Project
& project
;
445 const Module
* module
;
446 const XMLElement
* node
;
452 Define ( const Project
& project
,
453 const XMLElement
& defineNode
);
454 Define ( const Project
& project
,
455 const Module
* module
,
456 const XMLElement
& defineNode
);
457 Define ( const Project
& project
,
458 const Module
* module
,
459 const std::string
& name_
,
460 const std::string
& backend_
= "" );
473 std::string switches
;
474 bool isPreCompiledHeader
;
476 File ( DirectoryLocation directory
,
477 const std::string
& relative_path
,
478 const std::string
& name
,
480 const std::string
& _switches
,
481 bool _isPreCompiledHeader
);
484 std::string
GetFullPath () const;
490 const XMLElement
*node
;
492 const Module
& module
;
494 const Module
* importedModule
;
496 Library ( const XMLElement
& _node
,
497 const Module
& _module
,
498 const std::string
& _name
);
499 Library ( const Module
& _module
,
500 const std::string
& _name
);
509 const XMLElement
& node
;
510 const Module
& module
;
511 const Module
* invokeModule
;
512 std::vector
<InvokeFile
*> input
;
513 std::vector
<InvokeFile
*> output
;
515 Invoke ( const XMLElement
& _node
,
516 const Module
& _module
);
519 void GetTargets ( string_list
& targets
) const;
520 std::string
GetParameters () const;
522 void ProcessXMLSubElement ( const XMLElement
& e
);
523 void ProcessXMLSubElementInput ( const XMLElement
& e
);
524 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
531 const XMLElement
& node
;
533 std::string switches
;
535 InvokeFile ( const XMLElement
& _node
,
536 const std::string
& _name
);
545 const XMLElement
& node
;
546 const Module
& module
;
547 const Module
* dependencyModule
;
549 Dependency ( const XMLElement
& _node
,
550 const Module
& _module
);
558 const XMLElement
& node
;
559 const Module
* module
;
560 const Module
* bootSectorModule
;
562 Bootsector ( const XMLElement
& _node
,
563 const Module
* _module
);
567 bool IsSupportedModuleType ( ModuleType type
);
573 const XMLElement
& node
;
574 const Module
& module
;
576 std::string description
;
578 std::string copyright
;
583 Metadata ( const XMLElement
& _node
,
584 const Module
& _module
);
589 class ImportLibrary
: public XmlNode
592 const Module
* module
;
594 FileLocation
*source
;
596 ImportLibrary ( const Project
& project
,
597 const XMLElement
& node
,
598 const Module
* module
);
606 const XMLElement
& node
;
607 const Project
& project
;
608 const Module
* module
;
610 std::string property
, value
;
613 If ( const XMLElement
& node_
,
614 const Project
& project_
,
615 const Module
* module_
,
616 const bool negated_
= false );
626 const Project
& project
;
627 const Module
* module
;
628 const XMLElement
& node
;
630 CompilerType compiler
;
632 CompilerFlag ( const Project
& project
,
633 const XMLElement
& compilerFlagNode
);
634 CompilerFlag ( const Project
& project
,
635 const Module
* module
,
636 const XMLElement
& compilerFlagNode
);
647 const Project
& project
;
648 const Module
* module
;
649 const XMLElement
& node
;
652 LinkerFlag ( const Project
& project
,
653 const XMLElement
& linkerFlagNode
);
654 LinkerFlag ( const Project
& project
,
655 const Module
* module
,
656 const XMLElement
& linkerFlagNode
);
667 const XMLElement
& node
;
668 const Module
& module
;
669 const FileLocation
*file
;
671 LinkerScript ( const XMLElement
& node
,
672 const Module
& module
,
673 const FileLocation
*file
);
682 const Project
& project
;
683 const Module
* module
;
684 std::string name
, value
;
687 Property ( const XMLElement
& node_
,
688 const Project
& project_
,
689 const Module
* module_
);
691 Property ( const Project
& project_
,
692 const Module
* module_
,
693 const std::string
& name_
,
694 const std::string
& value_
);
700 class TestSupportCode
703 const Project
& project
;
705 TestSupportCode ( const Project
& project
);
707 void GenerateTestSupportCode ( bool verbose
);
709 bool IsTestModule ( const Module
& module
);
710 void GenerateTestSupportCodeForModule ( Module
& module
,
712 std::string
GetHooksFilename ( Module
& module
);
713 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
714 const StubbedComponent
& component
,
715 const StubbedSymbol
& symbol
);
716 char* WriteStubbedComponentToHooksFile ( char* buffer
,
717 const StubbedComponent
& component
);
718 void WriteHooksFile ( Module
& module
);
719 std::string
GetStubsFilename ( Module
& module
);
720 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
721 const StubbedComponent
& component
,
722 const StubbedSymbol
& symbol
,
724 char* WriteStubbedComponentToStubsFile ( char* buffer
,
725 const StubbedComponent
& component
,
727 void WriteStubsFile ( Module
& module
);
728 std::string
GetStartupFilename ( Module
& module
);
729 bool IsUnknownCharacter ( char ch
);
730 std::string
GetTestDispatcherName ( std::string filename
);
731 bool IsTestFile ( std::string
& filename
) const;
732 void GetSourceFilenames ( string_list
& list
,
733 Module
& module
) const;
734 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
736 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
738 void WriteStartupFile ( Module
& module
);
745 SourceFile ( AutomaticDependency
* automaticDependency
,
746 const Module
& module
,
748 SourceFile
* parent
);
750 std::vector
<SourceFile
*> files
; /* List of files included in this file */
752 AutomaticDependency
* automaticDependency
;
753 const Module
& module
;
754 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
755 time_t lastWriteTime
;
756 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
757 SourceFile
* youngestFile
;
761 void SkipWhitespace ();
762 bool ReadInclude ( std::string
& filename
,
763 bool& searchCurrentDirectory
,
765 bool IsIncludedFrom ( const File
& file
);
766 SourceFile
* ParseFile(const File
& file
);
767 bool CanProcessFile ( const File
& file
);
768 bool IsParentOf ( const SourceFile
* parent
,
769 const SourceFile
* child
);
776 class AutomaticDependency
778 friend class SourceFileTest
;
780 const Project
& project
;
782 AutomaticDependency ( const Project
& project
);
783 ~AutomaticDependency ();
784 bool LocateIncludedFile ( const FileLocation
& directory
,
785 const std::string
& includedFilename
);
786 bool LocateIncludedFile ( SourceFile
* sourceFile
,
787 const Module
& module
,
788 const std::string
& includedFilename
,
789 bool searchCurrentDirectory
,
791 File
& resolvedFile
);
792 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
794 SourceFile
* parentSourceFile
);
795 SourceFile
* RetrieveFromCache ( const File
& file
);
796 void CheckAutomaticDependencies ( bool verbose
);
797 void CheckAutomaticDependenciesForModule ( Module
& module
,
800 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
801 void CheckAutomaticDependencies ( const Module
& module
,
803 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
804 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
805 const Module
& module
);
806 void GetModuleFiles ( const Module
& module
,
807 std::vector
<File
*>& files
) const;
809 void ParseFiles ( const Module
& module
);
810 void ParseFile ( const Module
& module
,
812 std::map
<std::string
, SourceFile
*> sourcefile_map
;
819 const Project
& project
;
820 const Module
* module
;
821 const XMLElement
& node
;
823 std::string nameoncd
;
825 Bootstrap ( const Project
& project
,
826 const Module
* module
,
827 const XMLElement
& bootstrapNode
);
831 bool IsSupportedModuleType ( ModuleType type
);
833 static std::string
ReplaceVariable ( const std::string
& name
,
834 const std::string
& value
,
839 class CDFile
: public XmlNode
842 FileLocation
*source
;
843 FileLocation
*target
;
845 CDFile ( const Project
& project
,
846 const XMLElement
& bootstrapNode
,
847 const std::string
& path
);
850 static std::string
ReplaceVariable ( const std::string
& name
,
851 const std::string
& value
,
856 class InstallFile
: public XmlNode
859 FileLocation
*source
;
860 FileLocation
*target
;
862 InstallFile ( const Project
& project
,
863 const XMLElement
& bootstrapNode
,
864 const std::string
& path
);
872 const XMLElement
& node
;
873 const Module
& module
;
874 const FileLocation
*file
;
877 const XMLElement
& node
,
878 const Module
& module
,
879 const FileLocation
*file
);
885 class StubbedComponent
888 const Module
* module
;
889 const XMLElement
& node
;
891 std::vector
<StubbedSymbol
*> symbols
;
893 StubbedComponent ( const Module
* module_
,
894 const XMLElement
& stubbedComponentNode
);
895 ~StubbedComponent ();
897 void ProcessXMLSubElement ( const XMLElement
& e
);
904 const XMLElement
& node
;
907 std::string strippedName
;
909 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
913 std::string
StripSymbol ( std::string symbol
);
917 class CompilationUnit
922 CompilationUnit ( const File
* file
);
923 CompilationUnit ( const Project
* project
,
924 const Module
* module
,
925 const XMLElement
* node
);
928 bool IsGeneratedFile () const;
929 bool HasFileWithExtension ( const std::string
& extension
) const;
930 bool IsFirstFile () const;
931 const FileLocation
& GetFilename () const;
932 const std::string
& GetSwitches () const;
933 void AddFile ( const File
* file
);
934 const std::vector
<const File
*> GetFiles () const;
936 const Project
* project
;
937 const Module
* module
;
938 const XMLElement
* node
;
939 std::vector
<const File
*> files
;
940 FileLocation
*default_name
;
944 class CompilationUnitSupportCode
947 const Project
& project
;
949 CompilationUnitSupportCode ( const Project
& project
);
950 ~CompilationUnitSupportCode ();
951 void Generate ( bool verbose
);
953 void GenerateForModule ( Module
& module
,
955 std::string
GetCompilationUnitFilename ( Module
& module
,
956 CompilationUnit
& compilationUnit
);
957 void WriteCompilationUnitFile ( Module
& module
,
958 CompilationUnit
& compilationUnit
);
962 enum AutoRegisterType
969 class AutoRegister
: public XmlNode
972 const Module
* module
;
973 std::string infSection
;
974 AutoRegisterType type
;
975 AutoRegister ( const Project
& project_
,
976 const Module
* module_
,
977 const XMLElement
& node_
);
979 bool IsSupportedModuleType ( ModuleType type
);
980 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
985 class SysSetupGenerator
988 const Project
& project
;
989 SysSetupGenerator ( const Project
& project
);
990 ~SysSetupGenerator ();
993 std::string
GetDirectoryId ( const Module
& module
);
994 std::string
GetFlags ( const Module
& module
);
995 void Generate ( HINF inf
,
996 const Module
& module
);
1001 InitializeEnvironment ();
1004 Right ( const std::string
& s
, size_t n
);
1007 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
1010 ChangeSeparator ( const std::string
& s
,
1011 const char fromSeparator
,
1012 const char toSeparator
);
1015 FixSeparator ( const std::string
& s
);
1018 FixSeparatorForSystemCommand ( const std::string
& s
);
1021 DosSeparator ( const std::string
& s
);
1025 const std::string
& filename
,
1026 const std::string
& newExtension
);
1030 const Project
& project
,
1031 const std::string
& location
,
1032 const std::string
& path
,
1033 const std::string
& att_value
);
1036 GetExtension ( const FileLocation
& file
);
1039 NormalizeFilename ( const std::string
& filename
);
1042 ToLower ( std::string filename
);
1044 #endif /* __RBUILD_H */