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
;
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
);
137 void Add ( const char* subdir
);
138 void GenerateTree ( DirectoryLocation root
,
140 void CreateRule ( FILE* f
,
141 const std::string
& parent
);
143 bool mkdir_p ( const char* path
);
144 bool CreateDirectory ( const std::string
& path
);
145 std::string
EscapeSpaces ( const std::string
& path
);
146 void GenerateTree ( const std::string
& parent
,
158 bool AutomaticDependencies
;
159 bool CheckDependenciesForModuleOnly
;
160 bool CompilationUnitsEnabled
;
161 std::string CheckDependenciesForModuleOnlyModule
;
162 std::string VSProjectVersion
;
163 std::string VSConfigurationType
;
164 bool UseVSVersionInPath
;
165 bool UseConfigurationInPath
;
166 bool MakeHandlesInstallDirectories
;
167 bool GenerateProxyMakefilesInSourceTree
;
174 static std::string
GetVariable ( const std::string
& name
);
175 static std::string
GetArch ();
176 static std::string
GetIntermediatePath ();
177 static std::string
GetOutputPath ();
178 static std::string
GetCdOutputPath ();
179 static std::string
GetInstallPath ();
180 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
181 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
182 const std::string
& defaultValue
);
186 class FileSupportCode
189 static void WriteIfChanged ( char* outbuf
,
190 const std::string
& filename
,
191 bool ignoreError
= false );
199 CompilationUnit
* compilationUnit
;
207 std::vector
<CompilationUnit
*> compilationUnits
;
208 std::vector
<File
*> files
;
209 std::vector
<Include
*> includes
;
210 std::vector
<Define
*> defines
;
211 std::vector
<Library
*> libraries
;
212 std::vector
<Property
*> properties
;
213 std::vector
<Module
*> modules
;
214 std::vector
<CompilerFlag
*> compilerFlags
;
215 std::vector
<If
*> ifs
;
216 int asmFiles
; // number of .asm files in compilationUnits
221 void ExtractModules( std::vector
<Module
*> &modules
);
227 XMLElement
*node
, *head
;
230 const Configuration
& configuration
;
232 std::string makefile
;
233 XMLIncludes xmlbuildfiles
;
234 std::vector
<LinkerFlag
*> linkerFlags
;
235 std::vector
<CDFile
*> cdfiles
;
236 std::vector
<InstallFile
*> installfiles
;
237 std::vector
<Module
*> modules
;
238 IfableData non_if_data
;
240 Project ( const Configuration
& configuration
,
241 const std::string
& filename
,
242 const std::map
<std::string
, std::string
>* properties
= NULL
);
244 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
245 Backend
& GetBackend() { return *_backend
; }
246 void WriteConfigurationFile ();
247 void ExecuteInvocations ();
249 void ProcessXML ( const std::string
& path
);
250 Module
* LocateModule ( const std::string
& name
);
251 const Module
* LocateModule ( const std::string
& name
) const;
252 const std::string
& GetProjectFilename () const;
253 std::string
ResolveProperties ( const std::string
& s
) const;
255 std::string
ResolveNextProperty ( const std::string
& s
) const;
256 const Property
* LookupProperty ( const std::string
& name
) const;
257 void SetConfigurationOption ( char* s
,
259 std::string
* alternativeName
);
260 void SetConfigurationOption ( char* s
,
263 void ProcessXMLSubElement ( const XMLElement
& e
,
264 const std::string
& path
,
265 ParseContext
& parseContext
);
267 // disable copy semantics
268 Project ( const Project
& );
269 Project
& operator = ( const Project
& );
280 KernelModeDriver
= 5,
300 EmbeddedTypeLib
= 26,
317 DirectoryLocation directory
;
318 std::string relative_path
;
321 FileLocation ( const DirectoryLocation directory
,
322 const std::string
& relative_path
,
323 const std::string
& name
,
324 const XMLElement
*node
= NULL
);
326 FileLocation ( const FileLocation
& other
);
332 const Project
& project
;
333 const XMLElement
& node
;
334 std::string xmlbuildFile
;
337 std::string extension
;
338 std::string baseaddress
;
340 std::string buildtype
;
342 ImportLibrary
* importLibrary
;
345 bool underscoreSymbols
;
347 bool isDefaultEntryPoint
;
348 Bootstrap
* bootstrap
;
349 AutoRegister
* autoRegister
; // <autoregister> node
350 IfableData non_if_data
;
351 std::vector
<Invoke
*> invocations
;
352 std::vector
<Dependency
*> dependencies
;
353 std::vector
<CompilerFlag
*> compilerFlags
;
354 std::vector
<LinkerFlag
*> linkerFlags
;
355 std::vector
<StubbedComponent
*> stubbedComponents
;
356 LinkerScript
* linkerScript
;
361 std::string aliasedModuleName
;
365 FileLocation
*output
; // "path/foo.exe"
366 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
367 FileLocation
*install
;
369 Module ( const Project
& project
,
370 const XMLElement
& moduleNode
,
371 const std::string
& modulePath
);
373 ModuleType
GetModuleType ( const std::string
& location
,
374 const XMLAttribute
& attribute
);
375 bool HasImportLibrary () const;
377 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
378 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
379 std::string
GetEntryPoint(bool leadingUnderscore
) const;
380 void GetTargets ( string_list
& ) const;
381 std::string
GetInvocationTarget ( const int index
) const;
382 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
383 void InvokeModule () const;
386 void SetImportLibrary ( ImportLibrary
* importLibrary
);
387 DirectoryLocation
GetTargetDirectoryTree () const;
388 std::string
GetDefaultModuleExtension () const;
389 std::string
GetDefaultModuleEntrypoint () const;
390 std::string
GetDefaultModuleBaseaddress () const;
391 std::string entrypoint
;
392 void ProcessXMLSubElement ( const XMLElement
& e
,
393 DirectoryLocation directory
,
394 const std::string
& relative_path
,
395 ParseContext
& parseContext
);
402 FileLocation
*directory
;
404 Include ( const Project
& project
,
405 const XMLElement
* includeNode
);
406 Include ( const Project
& project
,
407 const XMLElement
* includeNode
,
408 const Module
* module
);
409 Include ( const Project
& project
,
410 DirectoryLocation directory
,
411 const std::string
& relative_path
);
415 const Project
& project
;
416 const XMLElement
* node
;
417 const Module
* module
;
418 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
425 const Project
& project
;
426 const Module
* module
;
427 const XMLElement
* node
;
433 Define ( const Project
& project
,
434 const XMLElement
& defineNode
);
435 Define ( const Project
& project
,
436 const Module
* module
,
437 const XMLElement
& defineNode
);
438 Define ( const Project
& project
,
439 const Module
* module
,
440 const std::string
& name_
,
441 const std::string
& backend_
= "" );
454 std::string switches
;
455 bool isPreCompiledHeader
;
457 File ( DirectoryLocation directory
,
458 const std::string
& relative_path
,
459 const std::string
& name
,
461 const std::string
& _switches
,
462 bool _isPreCompiledHeader
);
465 std::string
GetFullPath () const;
471 const XMLElement
*node
;
473 const Module
& module
;
475 const Module
* importedModule
;
477 Library ( const XMLElement
& _node
,
478 const Module
& _module
,
479 const std::string
& _name
);
480 Library ( const Module
& _module
,
481 const std::string
& _name
);
490 const XMLElement
& node
;
491 const Module
& module
;
492 const Module
* invokeModule
;
493 std::vector
<InvokeFile
*> input
;
494 std::vector
<InvokeFile
*> output
;
496 Invoke ( const XMLElement
& _node
,
497 const Module
& _module
);
500 void GetTargets ( string_list
& targets
) const;
501 std::string
GetParameters () const;
503 void ProcessXMLSubElement ( const XMLElement
& e
);
504 void ProcessXMLSubElementInput ( const XMLElement
& e
);
505 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
512 const XMLElement
& node
;
514 std::string switches
;
516 InvokeFile ( const XMLElement
& _node
,
517 const std::string
& _name
);
526 const XMLElement
& node
;
527 const Module
& module
;
528 const Module
* dependencyModule
;
530 Dependency ( const XMLElement
& _node
,
531 const Module
& _module
);
539 const XMLElement
& node
;
540 const Module
& module
;
542 std::string description
;
544 std::string copyright
;
549 Metadata ( const XMLElement
& _node
,
550 const Module
& _module
);
555 class ImportLibrary
: public XmlNode
558 const Module
& module
;
560 FileLocation
*source
;
562 ImportLibrary ( const Project
& project
,
563 const XMLElement
& node
,
564 const Module
& module
);
571 const XMLElement
& node
;
572 const Project
& project
;
573 const Module
* module
;
575 std::string property
, value
;
578 If ( const XMLElement
& node_
,
579 const Project
& project_
,
580 const Module
* module_
,
581 const bool negated_
= false );
591 const Project
& project
;
592 const Module
* module
;
593 const XMLElement
& node
;
596 CompilerFlag ( const Project
& project
,
597 const XMLElement
& compilerFlagNode
);
598 CompilerFlag ( const Project
& project
,
599 const Module
* module
,
600 const XMLElement
& compilerFlagNode
);
611 const Project
& project
;
612 const Module
* module
;
613 const XMLElement
& node
;
616 LinkerFlag ( const Project
& project
,
617 const XMLElement
& linkerFlagNode
);
618 LinkerFlag ( const Project
& project
,
619 const Module
* module
,
620 const XMLElement
& linkerFlagNode
);
631 const XMLElement
& node
;
632 const Module
& module
;
635 LinkerScript ( const XMLElement
& node
,
636 const Module
& module
,
637 const FileLocation
& file
);
646 const Project
& project
;
647 const Module
* module
;
648 std::string name
, value
;
650 Property ( const XMLElement
& node_
,
651 const Project
& project_
,
652 const Module
* module_
);
654 Property ( const Project
& project_
,
655 const Module
* module_
,
656 const std::string
& name_
,
657 const std::string
& value_
);
663 class TestSupportCode
666 const Project
& project
;
668 TestSupportCode ( const Project
& project
);
670 void GenerateTestSupportCode ( bool verbose
);
672 bool IsTestModule ( const Module
& module
);
673 void GenerateTestSupportCodeForModule ( Module
& module
,
675 std::string
GetHooksFilename ( Module
& module
);
676 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
677 const StubbedComponent
& component
,
678 const StubbedSymbol
& symbol
);
679 char* WriteStubbedComponentToHooksFile ( char* buffer
,
680 const StubbedComponent
& component
);
681 void WriteHooksFile ( Module
& module
);
682 std::string
GetStubsFilename ( Module
& module
);
683 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
684 const StubbedComponent
& component
,
685 const StubbedSymbol
& symbol
,
687 char* WriteStubbedComponentToStubsFile ( char* buffer
,
688 const StubbedComponent
& component
,
690 void WriteStubsFile ( Module
& module
);
691 std::string
GetStartupFilename ( Module
& module
);
692 bool IsUnknownCharacter ( char ch
);
693 std::string
GetTestDispatcherName ( std::string filename
);
694 bool IsTestFile ( std::string
& filename
) const;
695 void GetSourceFilenames ( string_list
& list
,
696 Module
& module
) const;
697 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
699 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
701 void WriteStartupFile ( Module
& module
);
708 SourceFile ( AutomaticDependency
* automaticDependency
,
709 const Module
& module
,
711 SourceFile
* parent
);
713 std::vector
<SourceFile
*> files
; /* List of files included in this file */
715 AutomaticDependency
* automaticDependency
;
716 const Module
& module
;
717 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
718 time_t lastWriteTime
;
719 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
720 SourceFile
* youngestFile
;
724 void SkipWhitespace ();
725 bool ReadInclude ( std::string
& filename
,
726 bool& searchCurrentDirectory
,
728 bool IsIncludedFrom ( const File
& file
);
729 SourceFile
* ParseFile(const File
& file
);
730 bool CanProcessFile ( const File
& file
);
731 bool IsParentOf ( const SourceFile
* parent
,
732 const SourceFile
* child
);
739 class AutomaticDependency
741 friend class SourceFileTest
;
743 const Project
& project
;
745 AutomaticDependency ( const Project
& project
);
746 ~AutomaticDependency ();
747 bool LocateIncludedFile ( const FileLocation
& directory
,
748 const std::string
& includedFilename
);
749 bool LocateIncludedFile ( SourceFile
* sourceFile
,
750 const Module
& module
,
751 const std::string
& includedFilename
,
752 bool searchCurrentDirectory
,
754 File
& resolvedFile
);
755 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
757 SourceFile
* parentSourceFile
);
758 SourceFile
* RetrieveFromCache ( const File
& file
);
759 void CheckAutomaticDependencies ( bool verbose
);
760 void CheckAutomaticDependenciesForModule ( Module
& module
,
763 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
764 void CheckAutomaticDependencies ( const Module
& module
,
766 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
767 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
768 const Module
& module
);
769 void GetModuleFiles ( const Module
& module
,
770 std::vector
<File
*>& files
) const;
772 void ParseFiles ( const Module
& module
);
773 void ParseFile ( const Module
& module
,
775 std::map
<std::string
, SourceFile
*> sourcefile_map
;
782 const Project
& project
;
783 const Module
* module
;
784 const XMLElement
& node
;
786 std::string nameoncd
;
788 Bootstrap ( const Project
& project
,
789 const Module
* module
,
790 const XMLElement
& bootstrapNode
);
794 bool IsSupportedModuleType ( ModuleType type
);
796 static std::string
ReplaceVariable ( const std::string
& name
,
797 const std::string
& value
,
802 class CDFile
: public XmlNode
805 FileLocation
*source
;
806 FileLocation
*target
;
808 CDFile ( const Project
& project
,
809 const XMLElement
& bootstrapNode
,
810 const std::string
& path
);
812 static std::string
ReplaceVariable ( const std::string
& name
,
813 const std::string
& value
,
818 class InstallFile
: public XmlNode
821 FileLocation
*source
;
822 FileLocation
*target
;
824 InstallFile ( const Project
& project
,
825 const XMLElement
& bootstrapNode
,
826 const std::string
& path
);
833 const XMLElement
& node
;
834 const Module
& module
;
838 const XMLElement
& node
,
839 const Module
& module
,
840 const FileLocation
& file
);
845 class StubbedComponent
848 const Module
* module
;
849 const XMLElement
& node
;
851 std::vector
<StubbedSymbol
*> symbols
;
853 StubbedComponent ( const Module
* module_
,
854 const XMLElement
& stubbedComponentNode
);
855 ~StubbedComponent ();
857 void ProcessXMLSubElement ( const XMLElement
& e
);
864 const XMLElement
& node
;
867 std::string strippedName
;
869 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
873 std::string
StripSymbol ( std::string symbol
);
877 class CompilationUnit
882 CompilationUnit ( const File
* file
);
883 CompilationUnit ( const Project
* project
,
884 const Module
* module
,
885 const XMLElement
* node
);
888 bool IsGeneratedFile () const;
889 bool HasFileWithExtension ( const std::string
& extension
) const;
890 bool IsFirstFile () const;
891 const FileLocation
& GetFilename () const;
892 const std::string
& GetSwitches () const;
893 void AddFile ( const File
* file
);
894 const std::vector
<const File
*> GetFiles () const;
896 const Project
* project
;
897 const Module
* module
;
898 const XMLElement
* node
;
899 std::vector
<const File
*> files
;
900 FileLocation
*default_name
;
904 class CompilationUnitSupportCode
907 const Project
& project
;
909 CompilationUnitSupportCode ( const Project
& project
);
910 ~CompilationUnitSupportCode ();
911 void Generate ( bool verbose
);
913 void GenerateForModule ( Module
& module
,
915 std::string
GetCompilationUnitFilename ( Module
& module
,
916 CompilationUnit
& compilationUnit
);
917 void WriteCompilationUnitFile ( Module
& module
,
918 CompilationUnit
& compilationUnit
);
922 enum AutoRegisterType
929 class AutoRegister
: public XmlNode
932 const Module
* module
;
933 std::string infSection
;
934 AutoRegisterType type
;
935 AutoRegister ( const Project
& project_
,
936 const Module
* module_
,
937 const XMLElement
& node_
);
939 bool IsSupportedModuleType ( ModuleType type
);
940 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
945 class SysSetupGenerator
948 const Project
& project
;
949 SysSetupGenerator ( const Project
& project
);
950 ~SysSetupGenerator ();
953 std::string
GetDirectoryId ( const Module
& module
);
954 std::string
GetFlags ( const Module
& module
);
955 void Generate ( HINF inf
,
956 const Module
& module
);
961 InitializeEnvironment ();
964 Right ( const std::string
& s
, size_t n
);
967 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
970 ChangeSeparator ( const std::string
& s
,
971 const char fromSeparator
,
972 const char toSeparator
);
975 FixSeparator ( const std::string
& s
);
978 FixSeparatorForSystemCommand ( const std::string
& s
);
981 DosSeparator ( const std::string
& s
);
985 const std::string
& filename
,
986 const std::string
& newExtension
);
990 const Project
& project
,
991 const std::string
& location
,
992 const std::string
& path
,
993 const std::string
& att_value
);
996 GetExtension ( const FileLocation
& file
);
999 NormalizeFilename ( const std::string
& filename
);
1002 ToLower ( std::string filename
);
1004 #endif /* __RBUILD_H */