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 ( const std::string
& name
,
123 const std::string
& value
,
125 std::string
GetEnvironmentVariable ( const std::string
& name
);
126 void ResolveVariablesInPath ( char* buf
,
127 const std::string
& path
);
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
,
219 const std::map
<std::string
, std::string
>* properties
= NULL
);
221 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
222 Backend
& GetBackend() { return *_backend
; }
223 void WriteConfigurationFile ();
224 void ExecuteInvocations ();
226 void ProcessXML ( const std::string
& path
);
227 Module
* LocateModule ( const std::string
& name
);
228 const Module
* LocateModule ( const std::string
& name
) const;
229 const std::string
& GetProjectFilename () const;
230 std::string
ResolveProperties ( const std::string
& s
) const;
232 std::string
ResolveNextProperty ( std::string
& s
) const;
233 const Property
* LookupProperty ( const std::string
& name
) const;
234 void SetConfigurationOption ( char* s
,
236 std::string
* alternativeName
);
237 void SetConfigurationOption ( char* s
,
240 void ProcessXMLSubElement ( const XMLElement
& e
,
241 const std::string
& path
,
242 ParseContext
& parseContext
);
244 // disable copy semantics
245 Project ( const Project
& );
246 Project
& operator = ( const Project
& );
257 KernelModeDriver
= 5,
277 EmbeddedTypeLib
= 26,
291 const Project
& project
;
292 const XMLElement
& node
;
293 std::string xmlbuildFile
;
296 std::string extension
;
297 std::string baseaddress
;
299 std::string buildtype
;
302 ImportLibrary
* importLibrary
;
305 bool underscoreSymbols
;
307 bool isDefaultEntryPoint
;
308 Bootstrap
* bootstrap
;
309 AutoRegister
* autoRegister
;
310 IfableData non_if_data
;
311 std::vector
<Invoke
*> invocations
;
312 std::vector
<Dependency
*> dependencies
;
313 std::vector
<CompilerFlag
*> compilerFlags
;
314 std::vector
<LinkerFlag
*> linkerFlags
;
315 std::vector
<StubbedComponent
*> stubbedComponents
;
316 LinkerScript
* linkerScript
;
321 std::string installBase
;
322 std::string installName
;
323 std::string aliasedModuleName
;
330 Module ( const Project
& project
,
331 const XMLElement
& moduleNode
,
332 const std::string
& modulePath
);
334 ModuleType
GetModuleType ( const std::string
& location
,
335 const XMLAttribute
& attribute
);
336 bool HasImportLibrary () const;
338 bool GenerateInOutputTree () const;
339 std::string
GetTargetName () const; // "foo.exe"
340 std::string
GetDependencyPath () const; // "path/foo.exe" or "path/libfoo.a"
341 std::string
GetBasePath () const; // "path"
342 std::string
GetPath () const; // "path/foo.exe"
343 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
344 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
345 std::string
GetEntryPoint(bool leadingUnderscore
) const;
346 void GetTargets ( string_list
& ) const;
347 std::string
GetInvocationTarget ( const int index
) const;
348 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
349 void InvokeModule () const;
351 void GetSourceFilenames ( string_list
& list
,
352 bool includeGeneratedFiles
) const;
354 std::string
GetDefaultModuleExtension () const;
355 std::string
GetDefaultModuleEntrypoint () const;
356 std::string
GetDefaultModuleBaseaddress () const;
357 std::string entrypoint
;
358 void ProcessXMLSubElement ( const XMLElement
& e
,
359 const std::string
& path
,
360 const std::string
& path_prefix
,
361 ParseContext
& parseContext
);
368 const Project
& project
;
369 const Module
* module
;
370 const XMLElement
* node
;
371 const Module
* baseModule
;
372 std::string directory
;
373 std::string basePath
;
376 Include ( const Project
& project
,
377 const XMLElement
* includeNode
);
378 Include ( const Project
& project
,
379 const Module
* module
,
380 const XMLElement
* includeNode
);
381 Include ( const Project
& project
,
382 std::string directory
,
383 std::string basePath
);
393 const Project
& project
;
394 const Module
* module
;
395 const XMLElement
* node
;
400 Define ( const Project
& project
,
401 const XMLElement
& defineNode
);
402 Define ( const Project
& project
,
403 const Module
* module
,
404 const XMLElement
& defineNode
);
405 Define ( const Project
& project
,
406 const Module
* module
,
407 const std::string name_
,
408 const std::string backend_
= "" );
420 std::string path_prefix
;
422 std::string switches
;
423 bool isPreCompiledHeader
;
425 File ( const std::string
& _name
,
427 std::string _switches
,
428 bool _isPreCompiledHeader
);
430 File ( const std::string
& _name
,
431 const std::string
& _path_prefix
,
433 std::string _switches
,
434 bool _isPreCompiledHeader
);
437 std::string
GetFullPath () const;
443 const XMLElement
*node
;
445 const Module
& module
;
447 const Module
* importedModule
;
449 Library ( const XMLElement
& _node
,
450 const Module
& _module
,
451 const std::string
& _name
);
452 Library ( const Module
& _module
,
453 const std::string
& _name
);
462 const XMLElement
& node
;
463 const Module
& module
;
464 const Module
* invokeModule
;
465 std::vector
<InvokeFile
*> input
;
466 std::vector
<InvokeFile
*> output
;
468 Invoke ( const XMLElement
& _node
,
469 const Module
& _module
);
472 void GetTargets ( string_list
& targets
) const;
473 std::string
GetParameters () const;
475 void ProcessXMLSubElement ( const XMLElement
& e
);
476 void ProcessXMLSubElementInput ( const XMLElement
& e
);
477 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
484 const XMLElement
& node
;
486 std::string switches
;
488 InvokeFile ( const XMLElement
& _node
,
489 const std::string
& _name
);
498 const XMLElement
& node
;
499 const Module
& module
;
500 const Module
* dependencyModule
;
502 Dependency ( const XMLElement
& _node
,
503 const Module
& _module
);
511 const XMLElement
& node
;
512 const Module
& module
;
514 std::string description
;
516 std::string copyright
;
521 Metadata ( const XMLElement
& _node
,
522 const Module
& _module
);
530 const XMLElement
& node
;
531 const Module
& module
;
532 std::string basename
;
533 std::string definition
;
536 ImportLibrary ( const XMLElement
& _node
,
537 const Module
& module
);
546 const XMLElement
& node
;
547 const Project
& project
;
548 const Module
* module
;
550 std::string property
, value
;
553 If ( const XMLElement
& node_
,
554 const Project
& project_
,
555 const Module
* module_
,
556 const bool negated_
= false );
566 const Project
& project
;
567 const Module
* module
;
568 const XMLElement
& node
;
571 CompilerFlag ( const Project
& project
,
572 const XMLElement
& compilerFlagNode
);
573 CompilerFlag ( const Project
& project
,
574 const Module
* module
,
575 const XMLElement
& compilerFlagNode
);
586 const Project
& project
;
587 const Module
* module
;
588 const XMLElement
& node
;
591 LinkerFlag ( const Project
& project
,
592 const XMLElement
& linkerFlagNode
);
593 LinkerFlag ( const Project
& project
,
594 const Module
* module
,
595 const XMLElement
& linkerFlagNode
);
606 const Project
& project
;
607 const Module
* module
;
608 const XMLElement
& node
;
609 const Module
* baseModule
;
610 std::string directory
;
611 std::string basePath
;
613 LinkerScript ( const Project
& project
,
614 const Module
* module
,
615 const XMLElement
& node
);
624 const Project
& project
;
625 const Module
* module
;
626 std::string name
, value
;
628 Property ( const XMLElement
& node_
,
629 const Project
& project_
,
630 const Module
* module_
);
632 Property ( const Project
& project_
,
633 const Module
* module_
,
634 const std::string
& name_
,
635 const std::string
& value_
);
641 class TestSupportCode
644 const Project
& project
;
646 TestSupportCode ( const Project
& project
);
648 void GenerateTestSupportCode ( bool verbose
);
650 bool IsTestModule ( const Module
& module
);
651 void GenerateTestSupportCodeForModule ( Module
& module
,
653 std::string
GetHooksFilename ( Module
& module
);
654 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
655 const StubbedComponent
& component
,
656 const StubbedSymbol
& symbol
);
657 char* WriteStubbedComponentToHooksFile ( char* buffer
,
658 const StubbedComponent
& component
);
659 void WriteHooksFile ( Module
& module
);
660 std::string
GetStubsFilename ( Module
& module
);
661 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
662 const StubbedComponent
& component
,
663 const StubbedSymbol
& symbol
,
665 char* WriteStubbedComponentToStubsFile ( char* buffer
,
666 const StubbedComponent
& component
,
668 void WriteStubsFile ( Module
& module
);
669 std::string
GetStartupFilename ( Module
& module
);
670 bool IsUnknownCharacter ( char ch
);
671 std::string
GetTestDispatcherName ( std::string filename
);
672 bool IsTestFile ( std::string
& filename
) const;
673 void GetSourceFilenames ( string_list
& list
,
674 Module
& module
) const;
675 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
677 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
679 void WriteStartupFile ( Module
& module
);
686 const Project
& project
;
689 WineResource ( const Project
& project
,
690 std::string bin2res
);
692 void UnpackResources ( bool verbose
);
694 bool IsSpecFile ( const File
& file
);
695 bool IsWineModule ( const Module
& module
);
696 bool IsResourceFile ( const File
& file
);
697 std::string
GetResourceFilename ( const Module
& module
);
698 void UnpackResourcesInModule ( Module
& module
,
706 SourceFile ( AutomaticDependency
* automaticDependency
,
707 const Module
& module
,
708 const std::string
& filename
,
710 bool isNonAutomaticDependency
);
711 SourceFile
* ParseFile ( const std::string
& normalizedFilename
);
713 std::string
Location () const;
714 std::vector
<SourceFile
*> files
;
715 AutomaticDependency
* automaticDependency
;
716 const Module
& module
;
717 std::string filename
;
718 std::string filenamePart
;
719 std::string directoryPart
;
720 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
721 bool isNonAutomaticDependency
;
722 std::string cachedDependencies
;
723 time_t lastWriteTime
;
724 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
725 SourceFile
* youngestFile
;
727 void GetDirectoryAndFilenameParts ();
730 void SkipWhitespace ();
731 bool ReadInclude ( std::string
& filename
,
732 bool& searchCurrentDirectory
,
734 bool IsIncludedFrom ( const std::string
& normalizedFilename
);
735 SourceFile
* GetParentSourceFile ();
736 bool CanProcessFile ( const std::string
& extension
);
737 bool IsParentOf ( const SourceFile
* parent
,
738 const SourceFile
* child
);
745 class AutomaticDependency
747 friend class SourceFileTest
;
749 const Project
& project
;
751 AutomaticDependency ( const Project
& project
);
752 ~AutomaticDependency ();
753 std::string
GetFilename ( const std::string
& filename
);
754 bool LocateIncludedFile ( const std::string
& directory
,
755 const std::string
& includedFilename
,
756 std::string
& resolvedFilename
);
757 bool LocateIncludedFile ( SourceFile
* sourceFile
,
758 const Module
& module
,
759 const std::string
& includedFilename
,
760 bool searchCurrentDirectory
,
762 std::string
& resolvedFilename
);
763 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
764 const std::string
& filename
,
765 SourceFile
* parentSourceFile
);
766 SourceFile
* RetrieveFromCache ( const std::string
& filename
);
767 void CheckAutomaticDependencies ( bool verbose
);
768 void CheckAutomaticDependenciesForModule ( Module
& module
,
771 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
772 void CheckAutomaticDependencies ( const Module
& module
,
774 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
775 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
776 const Module
& module
,
777 Include
& currentDirectory
,
778 bool searchCurrentDirectory
);
779 void GetModuleFiles ( const Module
& module
,
780 std::vector
<File
*>& files
) const;
782 void ParseFiles ( const Module
& module
);
783 void ParseFile ( const Module
& module
,
785 std::string
ReplaceVariable ( const std::string
& name
,
786 const std::string
& value
,
788 std::string
ResolveVariablesInPath ( const std::string
& path
);
789 std::map
<std::string
, SourceFile
*> sourcefile_map
;
796 const Project
& project
;
797 const Module
* module
;
798 const XMLElement
& node
;
800 std::string nameoncd
;
802 Bootstrap ( const Project
& project
,
803 const Module
* module
,
804 const XMLElement
& bootstrapNode
);
808 bool IsSupportedModuleType ( ModuleType type
);
810 static std::string
ReplaceVariable ( const std::string
& name
,
811 const std::string
& value
,
819 const Project
& project
;
820 const XMLElement
& node
;
823 std::string nameoncd
;
826 CDFile ( const Project
& project
,
827 const XMLElement
& bootstrapNode
,
828 const std::string
& path
);
831 std::string
GetPath () const;
833 static std::string
ReplaceVariable ( const std::string
& name
,
834 const std::string
& value
,
842 const Project
& project
;
843 const XMLElement
& node
;
849 InstallFile ( const Project
& project
,
850 const XMLElement
& bootstrapNode
,
851 const std::string
& path
);
854 std::string
GetPath () const;
861 const XMLElement
& node
;
862 const Module
& module
;
866 const XMLElement
& node
,
867 const Module
& module
,
873 class StubbedComponent
876 const Module
* module
;
877 const XMLElement
& node
;
879 std::vector
<StubbedSymbol
*> symbols
;
881 StubbedComponent ( const Module
* module_
,
882 const XMLElement
& stubbedComponentNode
);
883 ~StubbedComponent ();
885 void ProcessXMLSubElement ( const XMLElement
& e
);
892 const XMLElement
& node
;
895 std::string strippedName
;
897 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
901 std::string
StripSymbol ( std::string symbol
);
905 class CompilationUnit
908 const Project
* project
;
909 const Module
* module
;
910 const XMLElement
* node
;
912 std::vector
<File
*> files
;
914 CompilationUnit ( File
* file
);
915 CompilationUnit ( const Project
* project
,
916 const Module
* module
,
917 const XMLElement
* node
);
920 bool IsGeneratedFile () const;
921 bool HasFileWithExtension ( const std::string
& extension
) const;
922 bool IsFirstFile () const;
923 FileLocation
* GetFilename ( Directory
* intermediateDirectory
) const;
924 std::string
GetSwitches () const;
928 class CompilationUnitSupportCode
931 const Project
& project
;
933 CompilationUnitSupportCode ( const Project
& project
);
934 ~CompilationUnitSupportCode ();
935 void Generate ( bool verbose
);
937 void GenerateForModule ( Module
& module
,
939 std::string
GetCompilationUnitFilename ( Module
& module
,
940 CompilationUnit
& compilationUnit
);
941 void WriteCompilationUnitFile ( Module
& module
,
942 CompilationUnit
& compilationUnit
);
949 Directory
* directory
;
950 std::string filename
;
951 FileLocation ( Directory
* directory
,
952 std::string filename
);
956 enum AutoRegisterType
966 const Project
& project
;
967 const Module
* module
;
968 const XMLElement
& node
;
969 std::string infSection
;
970 AutoRegisterType type
;
971 AutoRegister ( const Project
& project_
,
972 const Module
* module_
,
973 const XMLElement
& node_
);
977 bool IsSupportedModuleType ( ModuleType type
);
978 AutoRegisterType
GetAutoRegisterType( std::string type
);
983 class SysSetupGenerator
986 const Project
& project
;
987 SysSetupGenerator ( const Project
& project
);
988 ~SysSetupGenerator ();
991 std::string
GetDirectoryId ( const Module
& module
);
992 std::string
GetFlags ( const Module
& module
);
993 void Generate ( HINF inf
,
994 const Module
& module
);
999 InitializeEnvironment ();
1002 Right ( const std::string
& s
, size_t n
);
1005 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
1008 ChangeSeparator ( const std::string
& s
,
1009 const char fromSeparator
,
1010 const char toSeparator
);
1013 FixSeparator ( const std::string
& s
);
1016 FixSeparatorForSystemCommand ( const std::string
& s
);
1019 DosSeparator ( const std::string
& s
);
1023 const std::string
& filename
,
1024 const std::string
& newExtension
);
1028 const Project
& project
,
1029 const std::string
& location
,
1030 const std::string
& path
,
1031 const std::string
& att_value
);
1034 GetExtension ( const std::string
& filename
);
1037 GetDirectory ( const std::string
& filename
);
1040 GetFilename ( const std::string
& filename
);
1043 NormalizeFilename ( const std::string
& filename
);
1046 ToLower ( std::string filename
);
1048 #endif /* __RBUILD_H */