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
;
93 class AutomaticDependency
;
98 class StubbedComponent
;
100 class CompilationUnit
;
104 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
);
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
,
159 bool AutomaticDependencies
;
160 bool CheckDependenciesForModuleOnly
;
161 bool CompilationUnitsEnabled
;
162 std::string CheckDependenciesForModuleOnlyModule
;
163 std::string VSProjectVersion
;
164 std::string VSConfigurationType
;
165 bool UseVSVersionInPath
;
166 bool UseConfigurationInPath
;
167 bool MakeHandlesInstallDirectories
;
168 bool GenerateProxyMakefilesInSourceTree
;
175 static std::string
GetVariable ( const std::string
& name
);
176 static std::string
GetArch ();
177 static std::string
GetIntermediatePath ();
178 static std::string
GetOutputPath ();
179 static std::string
GetCdOutputPath ();
180 static std::string
GetInstallPath ();
181 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
182 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
183 const std::string
& defaultValue
);
187 class FileSupportCode
190 static void WriteIfChanged ( char* outbuf
,
191 const std::string
& filename
,
192 bool ignoreError
= false );
200 CompilationUnit
* compilationUnit
;
208 std::vector
<CompilationUnit
*> compilationUnits
;
209 std::vector
<File
*> files
;
210 std::vector
<Include
*> includes
;
211 std::vector
<Define
*> defines
;
212 std::vector
<Library
*> libraries
;
213 std::vector
<Property
*> properties
;
214 std::vector
<Module
*> modules
;
215 std::vector
<CompilerFlag
*> compilerFlags
;
216 std::vector
<If
*> ifs
;
220 void ExtractModules( std::vector
<Module
*> &modules
);
226 XMLElement
*node
, *head
;
229 const Configuration
& configuration
;
231 std::string makefile
;
232 XMLIncludes xmlbuildfiles
;
233 std::vector
<LinkerFlag
*> linkerFlags
;
234 std::vector
<CDFile
*> cdfiles
;
235 std::vector
<InstallFile
*> installfiles
;
236 std::vector
<Module
*> modules
;
237 IfableData non_if_data
;
239 Project ( const Configuration
& configuration
,
240 const std::string
& filename
,
241 const std::map
<std::string
, std::string
>* properties
= NULL
);
243 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
244 Backend
& GetBackend() { return *_backend
; }
245 void WriteConfigurationFile ();
246 void ExecuteInvocations ();
248 void ProcessXML ( const std::string
& path
);
249 Module
* LocateModule ( const std::string
& name
);
250 const Module
* LocateModule ( const std::string
& name
) const;
251 const std::string
& GetProjectFilename () const;
252 std::string
ResolveProperties ( const std::string
& s
) const;
254 std::string
ResolveNextProperty ( const std::string
& s
) const;
255 const Property
* LookupProperty ( const std::string
& name
) const;
256 void SetConfigurationOption ( char* s
,
258 std::string
* alternativeName
);
259 void SetConfigurationOption ( char* s
,
262 void ProcessXMLSubElement ( const XMLElement
& e
,
263 const std::string
& path
,
264 ParseContext
& parseContext
);
266 // disable copy semantics
267 Project ( const Project
& );
268 Project
& operator = ( const Project
& );
279 KernelModeDriver
= 5,
299 EmbeddedTypeLib
= 26,
313 DirectoryLocation directory
;
314 std::string relative_path
;
317 FileLocation ( const DirectoryLocation directory
,
318 const std::string
& relative_path
,
319 const std::string
& name
,
320 const XMLElement
*node
= NULL
);
322 FileLocation ( const FileLocation
& other
);
328 const Project
& project
;
329 const XMLElement
& node
;
330 std::string xmlbuildFile
;
333 std::string extension
;
334 std::string baseaddress
;
336 std::string buildtype
;
338 ImportLibrary
* importLibrary
;
341 bool underscoreSymbols
;
343 bool isDefaultEntryPoint
;
344 Bootstrap
* bootstrap
;
345 AutoRegister
* autoRegister
; // <autoregister> node
346 IfableData non_if_data
;
347 std::vector
<Invoke
*> invocations
;
348 std::vector
<Dependency
*> dependencies
;
349 std::vector
<CompilerFlag
*> compilerFlags
;
350 std::vector
<LinkerFlag
*> linkerFlags
;
351 std::vector
<StubbedComponent
*> stubbedComponents
;
352 LinkerScript
* linkerScript
;
357 std::string aliasedModuleName
;
362 FileLocation
*output
; // "path/foo.exe"
363 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
364 FileLocation
*install
;
366 Module ( const Project
& project
,
367 const XMLElement
& moduleNode
,
368 const std::string
& modulePath
);
370 ModuleType
GetModuleType ( const std::string
& location
,
371 const XMLAttribute
& attribute
);
372 bool HasImportLibrary () const;
374 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
375 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
376 std::string
GetEntryPoint(bool leadingUnderscore
) const;
377 void GetTargets ( string_list
& ) const;
378 std::string
GetInvocationTarget ( const int index
) const;
379 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
380 void InvokeModule () const;
383 void SetImportLibrary ( ImportLibrary
* importLibrary
);
384 DirectoryLocation
GetTargetDirectoryTree () const;
385 std::string
GetDefaultModuleExtension () const;
386 std::string
GetDefaultModuleEntrypoint () const;
387 std::string
GetDefaultModuleBaseaddress () const;
388 std::string entrypoint
;
389 void ProcessXMLSubElement ( const XMLElement
& e
,
390 DirectoryLocation directory
,
391 const std::string
& relative_path
,
392 ParseContext
& parseContext
);
399 FileLocation
*directory
;
401 Include ( const Project
& project
,
402 const XMLElement
* includeNode
);
403 Include ( const Project
& project
,
404 const XMLElement
* includeNode
,
405 const Module
* module
);
406 Include ( const Project
& project
,
407 DirectoryLocation directory
,
408 const std::string
& relative_path
);
412 const Project
& project
;
413 const XMLElement
* node
;
414 const Module
* module
;
415 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
422 const Project
& project
;
423 const Module
* module
;
424 const XMLElement
* node
;
429 Define ( const Project
& project
,
430 const XMLElement
& defineNode
);
431 Define ( const Project
& project
,
432 const Module
* module
,
433 const XMLElement
& defineNode
);
434 Define ( const Project
& project
,
435 const Module
* module
,
436 const std::string name_
,
437 const std::string backend_
= "" );
450 std::string switches
;
451 bool isPreCompiledHeader
;
453 File ( DirectoryLocation directory
,
454 const std::string
& relative_path
,
455 const std::string
& name
,
457 const std::string
& _switches
,
458 bool _isPreCompiledHeader
);
461 std::string
GetFullPath () const;
467 const XMLElement
*node
;
469 const Module
& module
;
471 const Module
* importedModule
;
473 Library ( const XMLElement
& _node
,
474 const Module
& _module
,
475 const std::string
& _name
);
476 Library ( const Module
& _module
,
477 const std::string
& _name
);
486 const XMLElement
& node
;
487 const Module
& module
;
488 const Module
* invokeModule
;
489 std::vector
<InvokeFile
*> input
;
490 std::vector
<InvokeFile
*> output
;
492 Invoke ( const XMLElement
& _node
,
493 const Module
& _module
);
496 void GetTargets ( string_list
& targets
) const;
497 std::string
GetParameters () const;
499 void ProcessXMLSubElement ( const XMLElement
& e
);
500 void ProcessXMLSubElementInput ( const XMLElement
& e
);
501 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
508 const XMLElement
& node
;
510 std::string switches
;
512 InvokeFile ( const XMLElement
& _node
,
513 const std::string
& _name
);
522 const XMLElement
& node
;
523 const Module
& module
;
524 const Module
* dependencyModule
;
526 Dependency ( const XMLElement
& _node
,
527 const Module
& _module
);
535 const XMLElement
& node
;
536 const Module
& module
;
538 std::string description
;
540 std::string copyright
;
545 Metadata ( const XMLElement
& _node
,
546 const Module
& _module
);
551 class ImportLibrary
: public XmlNode
554 const Module
& module
;
556 FileLocation
*source
;
558 ImportLibrary ( const Project
& project
,
559 const XMLElement
& node
,
560 const Module
& module
);
567 const XMLElement
& node
;
568 const Project
& project
;
569 const Module
* module
;
571 std::string property
, value
;
574 If ( const XMLElement
& node_
,
575 const Project
& project_
,
576 const Module
* module_
,
577 const bool negated_
= false );
587 const Project
& project
;
588 const Module
* module
;
589 const XMLElement
& node
;
592 CompilerFlag ( const Project
& project
,
593 const XMLElement
& compilerFlagNode
);
594 CompilerFlag ( const Project
& project
,
595 const Module
* module
,
596 const XMLElement
& compilerFlagNode
);
607 const Project
& project
;
608 const Module
* module
;
609 const XMLElement
& node
;
612 LinkerFlag ( const Project
& project
,
613 const XMLElement
& linkerFlagNode
);
614 LinkerFlag ( const Project
& project
,
615 const Module
* module
,
616 const XMLElement
& linkerFlagNode
);
627 const Project
& project
;
628 const Module
* module
;
629 const XMLElement
& node
;
630 const Module
* baseModule
;
631 std::string directory
;
632 std::string basePath
;
634 LinkerScript ( const Project
& project
,
635 const Module
* module
,
636 const XMLElement
& node
);
645 const Project
& project
;
646 const Module
* module
;
647 std::string name
, value
;
649 Property ( const XMLElement
& node_
,
650 const Project
& project_
,
651 const Module
* module_
);
653 Property ( const Project
& project_
,
654 const Module
* module_
,
655 const std::string
& name_
,
656 const std::string
& value_
);
662 class TestSupportCode
665 const Project
& project
;
667 TestSupportCode ( const Project
& project
);
669 void GenerateTestSupportCode ( bool verbose
);
671 bool IsTestModule ( const Module
& module
);
672 void GenerateTestSupportCodeForModule ( Module
& module
,
674 std::string
GetHooksFilename ( Module
& module
);
675 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
676 const StubbedComponent
& component
,
677 const StubbedSymbol
& symbol
);
678 char* WriteStubbedComponentToHooksFile ( char* buffer
,
679 const StubbedComponent
& component
);
680 void WriteHooksFile ( Module
& module
);
681 std::string
GetStubsFilename ( Module
& module
);
682 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
683 const StubbedComponent
& component
,
684 const StubbedSymbol
& symbol
,
686 char* WriteStubbedComponentToStubsFile ( char* buffer
,
687 const StubbedComponent
& component
,
689 void WriteStubsFile ( Module
& module
);
690 std::string
GetStartupFilename ( Module
& module
);
691 bool IsUnknownCharacter ( char ch
);
692 std::string
GetTestDispatcherName ( std::string filename
);
693 bool IsTestFile ( std::string
& filename
) const;
694 void GetSourceFilenames ( string_list
& list
,
695 Module
& module
) const;
696 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
698 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
700 void WriteStartupFile ( Module
& module
);
707 const Project
& project
;
710 WineResource ( const Project
& project
,
711 std::string bin2res
);
713 void UnpackResources ( bool verbose
);
715 bool IsSpecFile ( const File
& file
);
716 bool IsWineModule ( const Module
& module
);
717 bool IsResourceFile ( const File
& file
);
718 std::string
GetResourceFilename ( const Module
& module
);
719 void UnpackResourcesInModule ( Module
& module
,
727 SourceFile ( AutomaticDependency
* automaticDependency
,
728 const Module
& module
,
730 SourceFile
* parent
);
732 std::vector
<SourceFile
*> files
; /* List of files included in this file */
734 AutomaticDependency
* automaticDependency
;
735 const Module
& module
;
736 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
737 time_t lastWriteTime
;
738 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
739 SourceFile
* youngestFile
;
743 void SkipWhitespace ();
744 bool ReadInclude ( std::string
& filename
,
745 bool& searchCurrentDirectory
,
747 bool IsIncludedFrom ( const File
& file
);
748 SourceFile
* ParseFile(const File
& file
);
749 bool CanProcessFile ( const File
& file
);
750 bool IsParentOf ( const SourceFile
* parent
,
751 const SourceFile
* child
);
758 class AutomaticDependency
760 friend class SourceFileTest
;
762 const Project
& project
;
764 AutomaticDependency ( const Project
& project
);
765 ~AutomaticDependency ();
766 bool LocateIncludedFile ( const FileLocation
& directory
,
767 const std::string
& includedFilename
);
768 bool LocateIncludedFile ( SourceFile
* sourceFile
,
769 const Module
& module
,
770 const std::string
& includedFilename
,
771 bool searchCurrentDirectory
,
773 File
& resolvedFile
);
774 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
776 SourceFile
* parentSourceFile
);
777 SourceFile
* RetrieveFromCache ( const File
& file
);
778 void CheckAutomaticDependencies ( bool verbose
);
779 void CheckAutomaticDependenciesForModule ( Module
& module
,
782 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
783 void CheckAutomaticDependencies ( const Module
& module
,
785 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
786 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
787 const Module
& module
);
788 void GetModuleFiles ( const Module
& module
,
789 std::vector
<File
*>& files
) const;
791 void ParseFiles ( const Module
& module
);
792 void ParseFile ( const Module
& module
,
794 std::map
<std::string
, SourceFile
*> sourcefile_map
;
801 const Project
& project
;
802 const Module
* module
;
803 const XMLElement
& node
;
805 std::string nameoncd
;
807 Bootstrap ( const Project
& project
,
808 const Module
* module
,
809 const XMLElement
& bootstrapNode
);
813 bool IsSupportedModuleType ( ModuleType type
);
815 static std::string
ReplaceVariable ( const std::string
& name
,
816 const std::string
& value
,
821 class CDFile
: public XmlNode
824 FileLocation
*source
;
825 FileLocation
*target
;
827 CDFile ( const Project
& project
,
828 const XMLElement
& bootstrapNode
,
829 const std::string
& path
);
831 static std::string
ReplaceVariable ( const std::string
& name
,
832 const std::string
& value
,
837 class InstallFile
: public XmlNode
840 FileLocation
*source
;
841 FileLocation
*target
;
843 InstallFile ( const Project
& project
,
844 const XMLElement
& bootstrapNode
,
845 const std::string
& path
);
852 const XMLElement
& node
;
853 const Module
& module
;
857 const XMLElement
& node
,
858 const Module
& module
,
859 const FileLocation
& file
);
864 class StubbedComponent
867 const Module
* module
;
868 const XMLElement
& node
;
870 std::vector
<StubbedSymbol
*> symbols
;
872 StubbedComponent ( const Module
* module_
,
873 const XMLElement
& stubbedComponentNode
);
874 ~StubbedComponent ();
876 void ProcessXMLSubElement ( const XMLElement
& e
);
883 const XMLElement
& node
;
886 std::string strippedName
;
888 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
892 std::string
StripSymbol ( std::string symbol
);
896 class CompilationUnit
899 const Project
* project
;
900 const Module
* module
;
901 const XMLElement
* node
;
903 std::vector
<File
*> files
;
905 CompilationUnit ( File
* file
);
906 CompilationUnit ( const Project
* project
,
907 const Module
* module
,
908 const XMLElement
* node
);
911 bool IsGeneratedFile () const;
912 bool HasFileWithExtension ( const std::string
& extension
) const;
913 bool IsFirstFile () const;
914 const FileLocation
* GetFilename () const;
915 std::string
GetSwitches () const;
917 std::string local_name
;
921 class CompilationUnitSupportCode
924 const Project
& project
;
926 CompilationUnitSupportCode ( const Project
& project
);
927 ~CompilationUnitSupportCode ();
928 void Generate ( bool verbose
);
930 void GenerateForModule ( Module
& module
,
932 std::string
GetCompilationUnitFilename ( Module
& module
,
933 CompilationUnit
& compilationUnit
);
934 void WriteCompilationUnitFile ( Module
& module
,
935 CompilationUnit
& compilationUnit
);
939 enum AutoRegisterType
946 class AutoRegister
: public XmlNode
949 const Module
* module
;
950 std::string infSection
;
951 AutoRegisterType type
;
952 AutoRegister ( const Project
& project_
,
953 const Module
* module_
,
954 const XMLElement
& node_
);
956 bool IsSupportedModuleType ( ModuleType type
);
957 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
962 class SysSetupGenerator
965 const Project
& project
;
966 SysSetupGenerator ( const Project
& project
);
967 ~SysSetupGenerator ();
970 std::string
GetDirectoryId ( const Module
& module
);
971 std::string
GetFlags ( const Module
& module
);
972 void Generate ( HINF inf
,
973 const Module
& module
);
978 InitializeEnvironment ();
981 Right ( const std::string
& s
, size_t n
);
984 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
987 ChangeSeparator ( const std::string
& s
,
988 const char fromSeparator
,
989 const char toSeparator
);
992 FixSeparator ( const std::string
& s
);
995 FixSeparatorForSystemCommand ( const std::string
& s
);
998 DosSeparator ( const std::string
& s
);
1002 const std::string
& filename
,
1003 const std::string
& newExtension
);
1007 const Project
& project
,
1008 const std::string
& location
,
1009 const std::string
& path
,
1010 const std::string
& att_value
);
1013 GetExtension ( const FileLocation
& file
);
1016 NormalizeFilename ( const std::string
& filename
);
1019 ToLower ( std::string filename
);
1021 #endif /* __RBUILD_H */