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
;
92 class AutomaticDependency
;
97 class StubbedComponent
;
99 class CompilationUnit
;
103 class SourceFileTest
;
106 typedef std::map
<std::string
,Directory
*> directory_map
;
112 directory_map subdirs
;
113 Directory ( const std::string
& name
);
114 void Add ( const char* subdir
);
115 void GenerateTree ( const std::string
& parent
,
117 std::string
EscapeSpaces ( std::string path
);
118 void CreateRule ( FILE* f
,
119 const std::string
& parent
);
121 bool mkdir_p ( const char* path
);
122 std::string
ReplaceVariable ( std::string name
,
125 std::string
GetEnvironmentVariable ( const std::string
& name
);
126 void ResolveVariablesInPath ( char* buf
,
128 bool CreateDirectory ( std::string path
);
139 bool AutomaticDependencies
;
140 bool CheckDependenciesForModuleOnly
;
141 bool CompilationUnitsEnabled
;
142 std::string CheckDependenciesForModuleOnlyModule
;
143 std::string VSProjectVersion
;
144 std::string VSConfigurationType
;
145 bool UseVSVersionInPath
;
146 bool UseConfigurationInPath
;
147 bool MakeHandlesInstallDirectories
;
148 bool GenerateProxyMakefilesInSourceTree
;
155 static std::string
GetVariable ( const std::string
& name
);
156 static std::string
GetIntermediatePath ();
157 static std::string
GetOutputPath ();
158 static std::string
GetCdOutputPath ();
159 static std::string
GetInstallPath ();
160 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
161 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
162 const std::string
& defaultValue
);
166 class FileSupportCode
169 static void WriteIfChanged ( char* outbuf
,
170 std::string filename
);
178 CompilationUnit
* compilationUnit
;
186 std::vector
<CompilationUnit
*> compilationUnits
;
187 std::vector
<File
*> files
;
188 std::vector
<Include
*> includes
;
189 std::vector
<Define
*> defines
;
190 std::vector
<Library
*> libraries
;
191 std::vector
<Property
*> properties
;
192 std::vector
<Module
*> modules
;
193 std::vector
<CompilerFlag
*> compilerFlags
;
194 std::vector
<If
*> ifs
;
198 void ExtractModules( std::vector
<Module
*> &modules
);
204 XMLElement
*node
, *head
;
207 const Configuration
& configuration
;
209 std::string makefile
;
210 XMLIncludes xmlbuildfiles
;
211 std::vector
<LinkerFlag
*> linkerFlags
;
212 std::vector
<CDFile
*> cdfiles
;
213 std::vector
<InstallFile
*> installfiles
;
214 std::vector
<Module
*> modules
;
215 IfableData non_if_data
;
217 Project ( const Configuration
& configuration
,
218 const std::string
& filename
);
220 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
221 Backend
& GetBackend() { return *_backend
; }
222 void WriteConfigurationFile ();
223 void ExecuteInvocations ();
225 void ProcessXML ( const std::string
& path
);
226 Module
* LocateModule ( const std::string
& name
);
227 const Module
* LocateModule ( const std::string
& name
) const;
228 const std::string
& GetProjectFilename () const;
229 std::string
ResolveProperties ( const std::string
& s
) const;
231 std::string
ResolveNextProperty ( std::string
& s
) const;
232 const Property
* LookupProperty ( const std::string
& name
) const;
233 void SetConfigurationOption ( char* s
,
235 std::string
* alternativeName
);
236 void SetConfigurationOption ( char* s
,
239 void ProcessXMLSubElement ( const XMLElement
& e
,
240 const std::string
& path
,
241 ParseContext
& parseContext
);
243 // disable copy semantics
244 Project ( const Project
& );
245 Project
& operator = ( const Project
& );
256 KernelModeDriver
= 5,
289 const Project
& project
;
290 const XMLElement
& node
;
291 std::string xmlbuildFile
;
294 std::string extension
;
295 std::string baseaddress
;
299 ImportLibrary
* importLibrary
;
301 bool underscoreSymbols
;
303 bool isDefaultEntryPoint
;
304 Bootstrap
* bootstrap
;
305 AutoRegister
* autoRegister
;
306 IfableData non_if_data
;
307 std::vector
<Invoke
*> invocations
;
308 std::vector
<Dependency
*> dependencies
;
309 std::vector
<CompilerFlag
*> compilerFlags
;
310 std::vector
<LinkerFlag
*> linkerFlags
;
311 std::vector
<StubbedComponent
*> stubbedComponents
;
312 LinkerScript
* linkerScript
;
317 std::string installBase
;
318 std::string installName
;
319 std::string aliasedModuleName
;
326 Module ( const Project
& project
,
327 const XMLElement
& moduleNode
,
328 const std::string
& modulePath
);
330 ModuleType
GetModuleType ( const std::string
& location
,
331 const XMLAttribute
& attribute
);
332 bool HasImportLibrary () const;
334 bool GenerateInOutputTree () const;
335 std::string
GetTargetName () const; // "foo.exe"
336 std::string
GetDependencyPath () const; // "path/foo.exe" or "path/libfoo.a"
337 std::string
GetBasePath () const; // "path"
338 std::string
GetPath () const; // "path/foo.exe"
339 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
340 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
341 std::string
GetEntryPoint(bool leadingUnderscore
) const;
342 void GetTargets ( string_list
& ) const;
343 std::string
GetInvocationTarget ( const int index
) const;
344 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
345 void InvokeModule () const;
347 void GetSourceFilenames ( string_list
& list
,
348 bool includeGeneratedFiles
) const;
350 std::string
GetDefaultModuleExtension () const;
351 std::string
GetDefaultModuleEntrypoint () const;
352 std::string
GetDefaultModuleBaseaddress () const;
353 std::string entrypoint
;
354 void ProcessXMLSubElement ( const XMLElement
& e
,
355 const std::string
& path
,
356 ParseContext
& parseContext
);
363 const Project
& project
;
364 const Module
* module
;
365 const XMLElement
* node
;
366 const Module
* baseModule
;
367 std::string directory
;
368 std::string basePath
;
371 Include ( const Project
& project
,
372 const XMLElement
* includeNode
);
373 Include ( const Project
& project
,
374 const Module
* module
,
375 const XMLElement
* includeNode
);
376 Include ( const Project
& project
,
377 std::string directory
,
378 std::string basePath
);
388 const Project
& project
;
389 const Module
* module
;
390 const XMLElement
* node
;
394 Define ( const Project
& project
,
395 const XMLElement
& defineNode
);
396 Define ( const Project
& project
,
397 const Module
* module
,
398 const XMLElement
& defineNode
);
399 Define ( const Project
& project
,
400 const Module
* module
,
401 const std::string name_
);
414 std::string switches
;
415 bool isPreCompiledHeader
;
417 File ( const std::string
& _name
,
419 std::string _switches
,
420 bool _isPreCompiledHeader
);
428 const XMLElement
*node
;
430 const Module
& module
;
432 const Module
* importedModule
;
434 Library ( const XMLElement
& _node
,
435 const Module
& _module
,
436 const std::string
& _name
);
437 Library ( const Module
& _module
,
438 const std::string
& _name
);
447 const XMLElement
& node
;
448 const Module
& module
;
449 const Module
* invokeModule
;
450 std::vector
<InvokeFile
*> input
;
451 std::vector
<InvokeFile
*> output
;
453 Invoke ( const XMLElement
& _node
,
454 const Module
& _module
);
457 void GetTargets ( string_list
& targets
) const;
458 std::string
GetParameters () const;
460 void ProcessXMLSubElement ( const XMLElement
& e
);
461 void ProcessXMLSubElementInput ( const XMLElement
& e
);
462 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
469 const XMLElement
& node
;
471 std::string switches
;
473 InvokeFile ( const XMLElement
& _node
,
474 const std::string
& _name
);
483 const XMLElement
& node
;
484 const Module
& module
;
485 const Module
* dependencyModule
;
487 Dependency ( const XMLElement
& _node
,
488 const Module
& _module
);
497 const XMLElement
& node
;
498 const Module
& module
;
499 std::string basename
;
500 std::string definition
;
503 ImportLibrary ( const XMLElement
& _node
,
504 const Module
& module
);
513 const XMLElement
& node
;
514 const Project
& project
;
515 const Module
* module
;
517 std::string property
, value
;
520 If ( const XMLElement
& node_
,
521 const Project
& project_
,
522 const Module
* module_
,
523 const bool negated_
= false );
533 const Project
& project
;
534 const Module
* module
;
535 const XMLElement
& node
;
538 CompilerFlag ( const Project
& project
,
539 const XMLElement
& compilerFlagNode
);
540 CompilerFlag ( const Project
& project
,
541 const Module
* module
,
542 const XMLElement
& compilerFlagNode
);
553 const Project
& project
;
554 const Module
* module
;
555 const XMLElement
& node
;
558 LinkerFlag ( const Project
& project
,
559 const XMLElement
& linkerFlagNode
);
560 LinkerFlag ( const Project
& project
,
561 const Module
* module
,
562 const XMLElement
& linkerFlagNode
);
573 const Project
& project
;
574 const Module
* module
;
575 const XMLElement
& node
;
576 const Module
* baseModule
;
577 std::string directory
;
578 std::string basePath
;
580 LinkerScript ( const Project
& project
,
581 const Module
* module
,
582 const XMLElement
& node
);
591 const XMLElement
& node
;
592 const Project
& project
;
593 const Module
* module
;
594 std::string name
, value
;
596 Property ( const XMLElement
& node_
,
597 const Project
& project_
,
598 const Module
* module_
);
604 class TestSupportCode
607 const Project
& project
;
609 TestSupportCode ( const Project
& project
);
611 void GenerateTestSupportCode ( bool verbose
);
613 bool IsTestModule ( const Module
& module
);
614 void GenerateTestSupportCodeForModule ( Module
& module
,
616 std::string
GetHooksFilename ( Module
& module
);
617 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
618 const StubbedComponent
& component
,
619 const StubbedSymbol
& symbol
);
620 char* WriteStubbedComponentToHooksFile ( char* buffer
,
621 const StubbedComponent
& component
);
622 void WriteHooksFile ( Module
& module
);
623 std::string
GetStubsFilename ( Module
& module
);
624 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
625 const StubbedComponent
& component
,
626 const StubbedSymbol
& symbol
,
628 char* WriteStubbedComponentToStubsFile ( char* buffer
,
629 const StubbedComponent
& component
,
631 void WriteStubsFile ( Module
& module
);
632 std::string
GetStartupFilename ( Module
& module
);
633 bool IsUnknownCharacter ( char ch
);
634 std::string
GetTestDispatcherName ( std::string filename
);
635 bool IsTestFile ( std::string
& filename
) const;
636 void GetSourceFilenames ( string_list
& list
,
637 Module
& module
) const;
638 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
640 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
642 void WriteStartupFile ( Module
& module
);
649 const Project
& project
;
652 WineResource ( const Project
& project
,
653 std::string bin2res
);
655 void UnpackResources ( bool verbose
);
657 bool IsSpecFile ( const File
& file
);
658 bool IsWineModule ( const Module
& module
);
659 bool IsResourceFile ( const File
& file
);
660 std::string
GetResourceFilename ( const Module
& module
);
661 void UnpackResourcesInModule ( Module
& module
,
669 SourceFile ( AutomaticDependency
* automaticDependency
,
670 const Module
& module
,
671 const std::string
& filename
,
673 bool isNonAutomaticDependency
);
674 SourceFile
* ParseFile ( const std::string
& normalizedFilename
);
676 std::string
Location () const;
677 std::vector
<SourceFile
*> files
;
678 AutomaticDependency
* automaticDependency
;
679 const Module
& module
;
680 std::string filename
;
681 std::string filenamePart
;
682 std::string directoryPart
;
683 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
684 bool isNonAutomaticDependency
;
685 std::string cachedDependencies
;
686 time_t lastWriteTime
;
687 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
688 SourceFile
* youngestFile
;
690 void GetDirectoryAndFilenameParts ();
693 void SkipWhitespace ();
694 bool ReadInclude ( std::string
& filename
,
695 bool& searchCurrentDirectory
,
697 bool IsIncludedFrom ( const std::string
& normalizedFilename
);
698 SourceFile
* GetParentSourceFile ();
699 bool CanProcessFile ( const std::string
& extension
);
700 bool IsParentOf ( const SourceFile
* parent
,
701 const SourceFile
* child
);
708 class AutomaticDependency
710 friend class SourceFileTest
;
712 const Project
& project
;
714 AutomaticDependency ( const Project
& project
);
715 ~AutomaticDependency ();
716 std::string
GetFilename ( const std::string
& filename
);
717 bool LocateIncludedFile ( const std::string
& directory
,
718 const std::string
& includedFilename
,
719 std::string
& resolvedFilename
);
720 bool LocateIncludedFile ( SourceFile
* sourceFile
,
721 const Module
& module
,
722 const std::string
& includedFilename
,
723 bool searchCurrentDirectory
,
725 std::string
& resolvedFilename
);
726 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
727 const std::string
& filename
,
728 SourceFile
* parentSourceFile
);
729 SourceFile
* RetrieveFromCache ( const std::string
& filename
);
730 void CheckAutomaticDependencies ( bool verbose
);
731 void CheckAutomaticDependenciesForModule ( Module
& module
,
734 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
735 void CheckAutomaticDependencies ( const Module
& module
,
737 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
738 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
739 const Module
& module
,
740 Include
& currentDirectory
,
741 bool searchCurrentDirectory
);
742 void GetModuleFiles ( const Module
& module
,
743 std::vector
<File
*>& files
) const;
745 void ParseFiles ( const Module
& module
);
746 void ParseFile ( const Module
& module
,
748 std::map
<std::string
, SourceFile
*> sourcefile_map
;
755 const Project
& project
;
756 const Module
* module
;
757 const XMLElement
& node
;
759 std::string nameoncd
;
761 Bootstrap ( const Project
& project
,
762 const Module
* module
,
763 const XMLElement
& bootstrapNode
);
767 bool IsSupportedModuleType ( ModuleType type
);
769 static std::string
ReplaceVariable ( const std::string
& name
,
770 const std::string
& value
,
778 const Project
& project
;
779 const XMLElement
& node
;
782 std::string nameoncd
;
785 CDFile ( const Project
& project
,
786 const XMLElement
& bootstrapNode
,
787 const std::string
& path
);
790 std::string
GetPath () const;
792 static std::string
ReplaceVariable ( const std::string
& name
,
793 const std::string
& value
,
801 const Project
& project
;
802 const XMLElement
& node
;
808 InstallFile ( const Project
& project
,
809 const XMLElement
& bootstrapNode
,
810 const std::string
& path
);
813 std::string
GetPath () const;
820 const XMLElement
& node
;
821 const Module
& module
;
825 const XMLElement
& node
,
826 const Module
& module
,
832 class StubbedComponent
835 const Module
* module
;
836 const XMLElement
& node
;
838 std::vector
<StubbedSymbol
*> symbols
;
840 StubbedComponent ( const Module
* module_
,
841 const XMLElement
& stubbedComponentNode
);
842 ~StubbedComponent ();
844 void ProcessXMLSubElement ( const XMLElement
& e
);
851 const XMLElement
& node
;
854 std::string strippedName
;
856 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
860 std::string
StripSymbol ( std::string symbol
);
864 class CompilationUnit
867 const Project
* project
;
868 const Module
* module
;
869 const XMLElement
* node
;
871 std::vector
<File
*> files
;
873 CompilationUnit ( File
* file
);
874 CompilationUnit ( const Project
* project
,
875 const Module
* module
,
876 const XMLElement
* node
);
879 bool IsGeneratedFile () const;
880 bool HasFileWithExtension ( const std::string
& extension
) const;
881 bool IsFirstFile () const;
882 FileLocation
* GetFilename ( Directory
* intermediateDirectory
) const;
883 std::string
GetSwitches () const;
887 class CompilationUnitSupportCode
890 const Project
& project
;
892 CompilationUnitSupportCode ( const Project
& project
);
893 ~CompilationUnitSupportCode ();
894 void Generate ( bool verbose
);
896 void GenerateForModule ( Module
& module
,
898 std::string
GetCompilationUnitFilename ( Module
& module
,
899 CompilationUnit
& compilationUnit
);
900 void WriteCompilationUnitFile ( Module
& module
,
901 CompilationUnit
& compilationUnit
);
908 Directory
* directory
;
909 std::string filename
;
910 FileLocation ( Directory
* directory
,
911 std::string filename
);
915 enum AutoRegisterType
925 const Project
& project
;
926 const Module
* module
;
927 const XMLElement
& node
;
928 std::string infSection
;
929 AutoRegisterType type
;
930 AutoRegister ( const Project
& project_
,
931 const Module
* module_
,
932 const XMLElement
& node_
);
936 bool IsSupportedModuleType ( ModuleType type
);
937 AutoRegisterType
GetAutoRegisterType( std::string type
);
942 class SysSetupGenerator
945 const Project
& project
;
946 SysSetupGenerator ( const Project
& project
);
947 ~SysSetupGenerator ();
950 std::string
GetDirectoryId ( const Module
& module
);
951 std::string
GetFlags ( const Module
& module
);
952 void Generate ( HINF inf
,
953 const Module
& module
);
958 InitializeEnvironment ();
961 Right ( const std::string
& s
, size_t n
);
964 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
967 ChangeSeparator ( const std::string
& s
,
968 const char fromSeparator
,
969 const char toSeparator
);
972 FixSeparator ( const std::string
& s
);
975 FixSeparatorForSystemCommand ( const std::string
& s
);
978 DosSeparator ( const std::string
& s
);
982 const std::string
& filename
,
983 const std::string
& newExtension
);
987 const std::string
& location
,
988 const std::string
& path
,
989 const std::string
& att_value
);
992 GetExtension ( const std::string
& filename
);
995 GetDirectory ( const std::string
& filename
);
998 GetFilename ( const std::string
& filename
);
1001 NormalizeFilename ( const std::string
& filename
);
1004 ToLower ( std::string filename
);
1006 #endif /* __RBUILD_H */