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
);
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
;
217 int asmFiles
; // number of .asm files in compilationUnits
222 void ExtractModules( std::vector
<Module
*> &modules
);
228 XMLElement
*node
, *head
;
231 const Configuration
& configuration
;
233 std::string makefile
;
234 XMLIncludes xmlbuildfiles
;
235 std::vector
<LinkerFlag
*> linkerFlags
;
236 std::vector
<CDFile
*> cdfiles
;
237 std::vector
<InstallFile
*> installfiles
;
238 std::vector
<Module
*> modules
;
239 IfableData non_if_data
;
241 Project ( const Configuration
& configuration
,
242 const std::string
& filename
,
243 const std::map
<std::string
, std::string
>* properties
= NULL
);
245 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
246 Backend
& GetBackend() { return *_backend
; }
247 void WriteConfigurationFile ();
248 void ExecuteInvocations ();
250 void ProcessXML ( const std::string
& path
);
251 Module
* LocateModule ( const std::string
& name
);
252 const Module
* LocateModule ( const std::string
& name
) const;
253 const std::string
& GetProjectFilename () const;
254 std::string
ResolveProperties ( const std::string
& s
) const;
256 std::string
ResolveNextProperty ( const std::string
& s
) const;
257 const Property
* LookupProperty ( const std::string
& name
) const;
258 void SetConfigurationOption ( char* s
,
260 std::string alternativeName
);
261 void SetConfigurationOption ( char* s
,
264 void ProcessXMLSubElement ( const XMLElement
& e
,
265 const std::string
& path
,
266 ParseContext
& parseContext
);
268 // disable copy semantics
269 Project ( const Project
& );
270 Project
& operator = ( const Project
& );
281 KernelModeDriver
= 5,
301 EmbeddedTypeLib
= 26,
318 CompilerTypeDontCare
,
326 DirectoryLocation directory
;
327 std::string relative_path
;
330 FileLocation ( const DirectoryLocation directory
,
331 const std::string
& relative_path
,
332 const std::string
& name
,
333 const XMLElement
*node
= NULL
);
335 FileLocation ( const FileLocation
& other
);
341 const Project
& project
;
342 const XMLElement
& node
;
343 std::string xmlbuildFile
;
346 std::string extension
;
347 std::string baseaddress
;
349 std::string buildtype
;
351 ImportLibrary
* importLibrary
;
354 bool underscoreSymbols
;
356 bool isDefaultEntryPoint
;
357 Bootstrap
* bootstrap
;
358 AutoRegister
* autoRegister
; // <autoregister> node
359 IfableData non_if_data
;
360 std::vector
<Invoke
*> invocations
;
361 std::vector
<Dependency
*> dependencies
;
362 std::vector
<CompilerFlag
*> compilerFlags
;
363 std::vector
<LinkerFlag
*> linkerFlags
;
364 std::vector
<StubbedComponent
*> stubbedComponents
;
365 LinkerScript
* linkerScript
;
370 std::string aliasedModuleName
;
374 FileLocation
*output
; // "path/foo.exe"
375 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
376 FileLocation
*install
;
378 Module ( const Project
& project
,
379 const XMLElement
& moduleNode
,
380 const std::string
& modulePath
);
382 ModuleType
GetModuleType ( const std::string
& location
,
383 const XMLAttribute
& attribute
);
384 bool HasImportLibrary () const;
386 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
387 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
388 std::string
GetEntryPoint(bool leadingUnderscore
) const;
389 void GetTargets ( string_list
& ) const;
390 std::string
GetInvocationTarget ( const int index
) const;
391 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
392 void InvokeModule () const;
395 void SetImportLibrary ( ImportLibrary
* importLibrary
);
396 DirectoryLocation
GetTargetDirectoryTree () const;
397 std::string
GetDefaultModuleExtension () const;
398 std::string
GetDefaultModuleEntrypoint () const;
399 std::string
GetDefaultModuleBaseaddress () const;
400 std::string entrypoint
;
401 void ProcessXMLSubElement ( const XMLElement
& e
,
402 DirectoryLocation directory
,
403 const std::string
& relative_path
,
404 ParseContext
& parseContext
);
411 FileLocation
*directory
;
413 Include ( const Project
& project
,
414 const XMLElement
* includeNode
);
415 Include ( const Project
& project
,
416 const XMLElement
* includeNode
,
417 const Module
* module
);
418 Include ( const Project
& project
,
419 DirectoryLocation directory
,
420 const std::string
& relative_path
);
424 const Project
& project
;
425 const XMLElement
* node
;
426 const Module
* module
;
427 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
434 const Project
& project
;
435 const Module
* module
;
436 const XMLElement
* node
;
442 Define ( const Project
& project
,
443 const XMLElement
& defineNode
);
444 Define ( const Project
& project
,
445 const Module
* module
,
446 const XMLElement
& defineNode
);
447 Define ( const Project
& project
,
448 const Module
* module
,
449 const std::string
& name_
,
450 const std::string
& backend_
= "" );
463 std::string switches
;
464 bool isPreCompiledHeader
;
466 File ( DirectoryLocation directory
,
467 const std::string
& relative_path
,
468 const std::string
& name
,
470 const std::string
& _switches
,
471 bool _isPreCompiledHeader
);
474 std::string
GetFullPath () const;
480 const XMLElement
*node
;
482 const Module
& module
;
484 const Module
* importedModule
;
486 Library ( const XMLElement
& _node
,
487 const Module
& _module
,
488 const std::string
& _name
);
489 Library ( const Module
& _module
,
490 const std::string
& _name
);
499 const XMLElement
& node
;
500 const Module
& module
;
501 const Module
* invokeModule
;
502 std::vector
<InvokeFile
*> input
;
503 std::vector
<InvokeFile
*> output
;
505 Invoke ( const XMLElement
& _node
,
506 const Module
& _module
);
509 void GetTargets ( string_list
& targets
) const;
510 std::string
GetParameters () const;
512 void ProcessXMLSubElement ( const XMLElement
& e
);
513 void ProcessXMLSubElementInput ( const XMLElement
& e
);
514 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
521 const XMLElement
& node
;
523 std::string switches
;
525 InvokeFile ( const XMLElement
& _node
,
526 const std::string
& _name
);
535 const XMLElement
& node
;
536 const Module
& module
;
537 const Module
* dependencyModule
;
539 Dependency ( const XMLElement
& _node
,
540 const Module
& _module
);
548 const XMLElement
& node
;
549 const Module
& module
;
551 std::string description
;
553 std::string copyright
;
558 Metadata ( const XMLElement
& _node
,
559 const Module
& _module
);
564 class ImportLibrary
: public XmlNode
567 const Module
& module
;
569 FileLocation
*source
;
571 ImportLibrary ( const Project
& project
,
572 const XMLElement
& node
,
573 const Module
& module
);
581 const XMLElement
& node
;
582 const Project
& project
;
583 const Module
* module
;
585 std::string property
, value
;
588 If ( const XMLElement
& node_
,
589 const Project
& project_
,
590 const Module
* module_
,
591 const bool negated_
= false );
601 const Project
& project
;
602 const Module
* module
;
603 const XMLElement
& node
;
605 CompilerType compiler
;
607 CompilerFlag ( const Project
& project
,
608 const XMLElement
& compilerFlagNode
);
609 CompilerFlag ( const Project
& project
,
610 const Module
* module
,
611 const XMLElement
& compilerFlagNode
);
622 const Project
& project
;
623 const Module
* module
;
624 const XMLElement
& node
;
627 LinkerFlag ( const Project
& project
,
628 const XMLElement
& linkerFlagNode
);
629 LinkerFlag ( const Project
& project
,
630 const Module
* module
,
631 const XMLElement
& linkerFlagNode
);
642 const XMLElement
& node
;
643 const Module
& module
;
644 const FileLocation
*file
;
646 LinkerScript ( const XMLElement
& node
,
647 const Module
& module
,
648 const FileLocation
*file
);
657 const Project
& project
;
658 const Module
* module
;
659 std::string name
, value
;
661 Property ( const XMLElement
& node_
,
662 const Project
& project_
,
663 const Module
* module_
);
665 Property ( const Project
& project_
,
666 const Module
* module_
,
667 const std::string
& name_
,
668 const std::string
& value_
);
674 class TestSupportCode
677 const Project
& project
;
679 TestSupportCode ( const Project
& project
);
681 void GenerateTestSupportCode ( bool verbose
);
683 bool IsTestModule ( const Module
& module
);
684 void GenerateTestSupportCodeForModule ( Module
& module
,
686 std::string
GetHooksFilename ( Module
& module
);
687 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
688 const StubbedComponent
& component
,
689 const StubbedSymbol
& symbol
);
690 char* WriteStubbedComponentToHooksFile ( char* buffer
,
691 const StubbedComponent
& component
);
692 void WriteHooksFile ( Module
& module
);
693 std::string
GetStubsFilename ( Module
& module
);
694 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
695 const StubbedComponent
& component
,
696 const StubbedSymbol
& symbol
,
698 char* WriteStubbedComponentToStubsFile ( char* buffer
,
699 const StubbedComponent
& component
,
701 void WriteStubsFile ( Module
& module
);
702 std::string
GetStartupFilename ( Module
& module
);
703 bool IsUnknownCharacter ( char ch
);
704 std::string
GetTestDispatcherName ( std::string filename
);
705 bool IsTestFile ( std::string
& filename
) const;
706 void GetSourceFilenames ( string_list
& list
,
707 Module
& module
) const;
708 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
710 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
712 void WriteStartupFile ( Module
& module
);
719 SourceFile ( AutomaticDependency
* automaticDependency
,
720 const Module
& module
,
722 SourceFile
* parent
);
724 std::vector
<SourceFile
*> files
; /* List of files included in this file */
726 AutomaticDependency
* automaticDependency
;
727 const Module
& module
;
728 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
729 time_t lastWriteTime
;
730 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
731 SourceFile
* youngestFile
;
735 void SkipWhitespace ();
736 bool ReadInclude ( std::string
& filename
,
737 bool& searchCurrentDirectory
,
739 bool IsIncludedFrom ( const File
& file
);
740 SourceFile
* ParseFile(const File
& file
);
741 bool CanProcessFile ( const File
& file
);
742 bool IsParentOf ( const SourceFile
* parent
,
743 const SourceFile
* child
);
750 class AutomaticDependency
752 friend class SourceFileTest
;
754 const Project
& project
;
756 AutomaticDependency ( const Project
& project
);
757 ~AutomaticDependency ();
758 bool LocateIncludedFile ( const FileLocation
& directory
,
759 const std::string
& includedFilename
);
760 bool LocateIncludedFile ( SourceFile
* sourceFile
,
761 const Module
& module
,
762 const std::string
& includedFilename
,
763 bool searchCurrentDirectory
,
765 File
& resolvedFile
);
766 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
768 SourceFile
* parentSourceFile
);
769 SourceFile
* RetrieveFromCache ( const File
& file
);
770 void CheckAutomaticDependencies ( bool verbose
);
771 void CheckAutomaticDependenciesForModule ( Module
& module
,
774 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
775 void CheckAutomaticDependencies ( const Module
& module
,
777 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
778 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
779 const Module
& module
);
780 void GetModuleFiles ( const Module
& module
,
781 std::vector
<File
*>& files
) const;
783 void ParseFiles ( const Module
& module
);
784 void ParseFile ( const Module
& module
,
786 std::map
<std::string
, SourceFile
*> sourcefile_map
;
793 const Project
& project
;
794 const Module
* module
;
795 const XMLElement
& node
;
797 std::string nameoncd
;
799 Bootstrap ( const Project
& project
,
800 const Module
* module
,
801 const XMLElement
& bootstrapNode
);
805 bool IsSupportedModuleType ( ModuleType type
);
807 static std::string
ReplaceVariable ( const std::string
& name
,
808 const std::string
& value
,
813 class CDFile
: public XmlNode
816 FileLocation
*source
;
817 FileLocation
*target
;
819 CDFile ( const Project
& project
,
820 const XMLElement
& bootstrapNode
,
821 const std::string
& path
);
824 static std::string
ReplaceVariable ( const std::string
& name
,
825 const std::string
& value
,
830 class InstallFile
: public XmlNode
833 FileLocation
*source
;
834 FileLocation
*target
;
836 InstallFile ( const Project
& project
,
837 const XMLElement
& bootstrapNode
,
838 const std::string
& path
);
846 const XMLElement
& node
;
847 const Module
& module
;
848 const FileLocation
*file
;
851 const XMLElement
& node
,
852 const Module
& module
,
853 const FileLocation
*file
);
859 class StubbedComponent
862 const Module
* module
;
863 const XMLElement
& node
;
865 std::vector
<StubbedSymbol
*> symbols
;
867 StubbedComponent ( const Module
* module_
,
868 const XMLElement
& stubbedComponentNode
);
869 ~StubbedComponent ();
871 void ProcessXMLSubElement ( const XMLElement
& e
);
878 const XMLElement
& node
;
881 std::string strippedName
;
883 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
887 std::string
StripSymbol ( std::string symbol
);
891 class CompilationUnit
896 CompilationUnit ( const File
* file
);
897 CompilationUnit ( const Project
* project
,
898 const Module
* module
,
899 const XMLElement
* node
);
902 bool IsGeneratedFile () const;
903 bool HasFileWithExtension ( const std::string
& extension
) const;
904 bool IsFirstFile () const;
905 const FileLocation
& GetFilename () const;
906 const std::string
& GetSwitches () const;
907 void AddFile ( const File
* file
);
908 const std::vector
<const File
*> GetFiles () const;
910 const Project
* project
;
911 const Module
* module
;
912 const XMLElement
* node
;
913 std::vector
<const File
*> files
;
914 FileLocation
*default_name
;
918 class CompilationUnitSupportCode
921 const Project
& project
;
923 CompilationUnitSupportCode ( const Project
& project
);
924 ~CompilationUnitSupportCode ();
925 void Generate ( bool verbose
);
927 void GenerateForModule ( Module
& module
,
929 std::string
GetCompilationUnitFilename ( Module
& module
,
930 CompilationUnit
& compilationUnit
);
931 void WriteCompilationUnitFile ( Module
& module
,
932 CompilationUnit
& compilationUnit
);
936 enum AutoRegisterType
943 class AutoRegister
: public XmlNode
946 const Module
* module
;
947 std::string infSection
;
948 AutoRegisterType type
;
949 AutoRegister ( const Project
& project_
,
950 const Module
* module_
,
951 const XMLElement
& node_
);
953 bool IsSupportedModuleType ( ModuleType type
);
954 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
959 class SysSetupGenerator
962 const Project
& project
;
963 SysSetupGenerator ( const Project
& project
);
964 ~SysSetupGenerator ();
967 std::string
GetDirectoryId ( const Module
& module
);
968 std::string
GetFlags ( const Module
& module
);
969 void Generate ( HINF inf
,
970 const Module
& module
);
975 InitializeEnvironment ();
978 Right ( const std::string
& s
, size_t n
);
981 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
984 ChangeSeparator ( const std::string
& s
,
985 const char fromSeparator
,
986 const char toSeparator
);
989 FixSeparator ( const std::string
& s
);
992 FixSeparatorForSystemCommand ( const std::string
& s
);
995 DosSeparator ( const std::string
& s
);
999 const std::string
& filename
,
1000 const std::string
& newExtension
);
1004 const Project
& project
,
1005 const std::string
& location
,
1006 const std::string
& path
,
1007 const std::string
& att_value
);
1010 GetExtension ( const FileLocation
& file
);
1013 NormalizeFilename ( const std::string
& filename
);
1016 ToLower ( std::string filename
);
1018 #endif /* __RBUILD_H */