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
;
91 class AutomaticDependency
;
96 class StubbedComponent
;
98 class CompilationUnit
;
102 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 bool PrecompiledHeadersEnabled
;
163 std::string CheckDependenciesForModuleOnlyModule
;
164 std::string VSProjectVersion
;
165 std::string VSConfigurationType
;
166 bool UseVSVersionInPath
;
167 bool UseConfigurationInPath
;
168 bool MakeHandlesInstallDirectories
;
169 bool GenerateProxyMakefilesInSourceTree
;
176 static std::string
GetVariable ( const std::string
& name
);
177 static std::string
GetArch ();
178 static std::string
GetIntermediatePath ();
179 static std::string
GetOutputPath ();
180 static std::string
GetCdOutputPath ();
181 static std::string
GetInstallPath ();
182 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
183 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
184 const std::string
& defaultValue
);
188 class FileSupportCode
191 static void WriteIfChanged ( char* outbuf
,
192 const std::string
& filename
,
193 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::map
<std::string
, Property
*> properties
;
214 std::vector
<Module
*> modules
;
215 std::vector
<CompilerFlag
*> compilerFlags
;
216 int asmFiles
; // number of .asm files in compilationUnits
221 void ExtractModules( std::map
<std::string
, 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::map
<std::string
, Module
*> modules
;
238 IfableData non_if_data
;
239 IfableData host_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 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;
254 const Property
* LookupProperty ( const std::string
& name
) const;
256 std::string
ResolveNextProperty ( const std::string
& s
) const;
258 void ProcessXMLSubElement ( const XMLElement
& e
,
259 const std::string
& path
,
260 ParseContext
& parseContext
);
262 // disable copy semantics
263 Project ( const Project
& );
264 Project
& operator = ( const Project
& );
302 TypeDontCare
, // always at the end
315 CompilerTypeDontCare
,
323 DirectoryLocation directory
;
324 std::string relative_path
;
327 FileLocation ( const DirectoryLocation directory
,
328 const std::string
& relative_path
,
329 const std::string
& name
,
330 const XMLElement
*node
= NULL
);
332 FileLocation ( const FileLocation
& other
);
338 const Project
& project
;
339 const XMLElement
& node
;
340 std::string xmlbuildFile
;
343 std::string extension
;
344 std::string baseaddress
;
346 std::string buildtype
;
348 ImportLibrary
* importLibrary
;
350 Bootsector
* bootSector
;
352 bool underscoreSymbols
;
354 bool isDefaultEntryPoint
;
355 Bootstrap
* bootstrap
;
356 AutoRegister
* autoRegister
; // <autoregister> node
357 IfableData non_if_data
;
358 std::vector
<Invoke
*> invocations
;
359 std::vector
<Dependency
*> dependencies
;
360 std::vector
<CompilerFlag
*> compilerFlags
;
361 std::vector
<LinkerFlag
*> linkerFlags
;
362 std::vector
<StubbedComponent
*> stubbedComponents
;
363 LinkerScript
* linkerScript
;
367 std::string aliasedModuleName
;
374 FileLocation
*output
; // "path/foo.exe"
375 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
376 FileLocation
*install
;
377 std::string description
;
379 std::string layoutId
;
380 std::string layoutNameResId
;
382 Module ( const Project
& project
,
383 const XMLElement
& moduleNode
,
384 const std::string
& modulePath
);
386 ModuleType
GetModuleType ( const std::string
& location
,
387 const XMLAttribute
& attribute
);
388 bool HasImportLibrary () const;
390 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
391 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
392 std::string
GetEntryPoint(bool leadingUnderscore
) const;
393 void GetTargets ( string_list
& ) const;
394 std::string
GetInvocationTarget ( const int index
) const;
395 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
396 void InvokeModule () const;
399 void SetImportLibrary ( ImportLibrary
* importLibrary
);
400 DirectoryLocation
GetTargetDirectoryTree () const;
401 std::string
GetDefaultModuleExtension () const;
402 std::string
GetDefaultModuleEntrypoint () const;
403 std::string
GetDefaultModuleBaseaddress () const;
404 std::string
GetDefaultModuleCRT () const;
405 bool GetDefaultModuleIsCRT () const;
406 std::string entrypoint
;
407 void ProcessXMLSubElement ( const XMLElement
& e
,
408 DirectoryLocation directory
,
409 const std::string
& relative_path
,
410 ParseContext
& parseContext
);
411 bool GetBooleanAttribute ( const XMLElement
& moduleNode
,
413 bool default_value
= false );
420 FileLocation
*directory
;
422 Include ( const Project
& project
,
423 const XMLElement
* includeNode
);
424 Include ( const Project
& project
,
425 const XMLElement
* includeNode
,
426 const Module
* module
);
427 Include ( const Project
& project
,
428 DirectoryLocation directory
,
429 const std::string
& relative_path
);
433 const Project
& project
;
434 const XMLElement
* node
;
435 const Module
* module
;
436 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
443 const Project
& project
;
444 const Module
* module
;
445 const XMLElement
* node
;
451 Define ( const Project
& project
,
452 const XMLElement
& defineNode
);
453 Define ( const Project
& project
,
454 const Module
* module
,
455 const XMLElement
& defineNode
);
456 Define ( const Project
& project
,
457 const Module
* module
,
458 const std::string
& name_
,
459 const std::string
& backend_
= "" );
472 std::string switches
;
473 bool isPreCompiledHeader
;
475 File ( DirectoryLocation directory
,
476 const std::string
& relative_path
,
477 const std::string
& name
,
479 const std::string
& _switches
,
480 bool _isPreCompiledHeader
);
483 std::string
GetFullPath () const;
489 const XMLElement
*node
;
491 const Module
& module
;
493 const Module
* importedModule
;
495 Library ( const XMLElement
& _node
,
496 const Module
& _module
,
497 const std::string
& _name
);
498 Library ( const Module
& _module
,
499 const std::string
& _name
);
508 const XMLElement
& node
;
509 const Module
& module
;
510 const Module
* invokeModule
;
511 std::vector
<InvokeFile
*> input
;
512 std::vector
<InvokeFile
*> output
;
514 Invoke ( const XMLElement
& _node
,
515 const Module
& _module
);
518 void GetTargets ( string_list
& targets
) const;
519 std::string
GetParameters () const;
521 void ProcessXMLSubElement ( const XMLElement
& e
);
522 void ProcessXMLSubElementInput ( const XMLElement
& e
);
523 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
530 const XMLElement
& node
;
532 std::string switches
;
534 InvokeFile ( const XMLElement
& _node
,
535 const std::string
& _name
);
544 const XMLElement
& node
;
545 const Module
& module
;
546 const Module
* dependencyModule
;
548 Dependency ( const XMLElement
& _node
,
549 const Module
& _module
);
557 const XMLElement
& node
;
558 const Module
* module
;
559 const Module
* bootSectorModule
;
561 Bootsector ( const XMLElement
& _node
,
562 const Module
* _module
);
566 bool IsSupportedModuleType ( ModuleType type
);
572 const XMLElement
& node
;
573 const Module
& module
;
575 std::string description
;
577 std::string copyright
;
582 Metadata ( const XMLElement
& _node
,
583 const Module
& _module
);
588 class ImportLibrary
: public XmlNode
591 const Module
* module
;
593 FileLocation
*source
;
595 ImportLibrary ( const Project
& project
,
596 const XMLElement
& node
,
597 const Module
* module
);
605 const Project
& project
;
606 const Module
* module
;
607 const XMLElement
& node
;
609 CompilerType compiler
;
611 CompilerFlag ( const Project
& project
,
612 const XMLElement
& compilerFlagNode
);
613 CompilerFlag ( const Project
& project
,
614 const Module
* module
,
615 const XMLElement
& compilerFlagNode
);
626 const Project
& project
;
627 const Module
* module
;
628 const XMLElement
& node
;
631 LinkerFlag ( const Project
& project
,
632 const XMLElement
& linkerFlagNode
);
633 LinkerFlag ( const Project
& project
,
634 const Module
* module
,
635 const XMLElement
& linkerFlagNode
);
646 const XMLElement
& node
;
647 const Module
& module
;
648 const FileLocation
*file
;
650 LinkerScript ( const XMLElement
& node
,
651 const Module
& module
,
652 const FileLocation
*file
);
661 const Project
& project
;
662 const Module
* module
;
663 std::string name
, value
;
666 Property ( const XMLElement
& node_
,
667 const Project
& project_
,
668 const Module
* module_
);
670 Property ( const Project
& project_
,
671 const Module
* module_
,
672 const std::string
& name_
,
673 const std::string
& value_
);
679 class TestSupportCode
682 const Project
& project
;
684 TestSupportCode ( const Project
& project
);
686 void GenerateTestSupportCode ( bool verbose
);
688 bool IsTestModule ( const Module
& module
);
689 void GenerateTestSupportCodeForModule ( Module
& module
,
691 std::string
GetHooksFilename ( Module
& module
);
692 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
693 const StubbedComponent
& component
,
694 const StubbedSymbol
& symbol
);
695 char* WriteStubbedComponentToHooksFile ( char* buffer
,
696 const StubbedComponent
& component
);
697 void WriteHooksFile ( Module
& module
);
698 std::string
GetStubsFilename ( Module
& module
);
699 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
700 const StubbedComponent
& component
,
701 const StubbedSymbol
& symbol
,
703 char* WriteStubbedComponentToStubsFile ( char* buffer
,
704 const StubbedComponent
& component
,
706 void WriteStubsFile ( Module
& module
);
707 std::string
GetStartupFilename ( Module
& module
);
708 bool IsUnknownCharacter ( char ch
);
709 std::string
GetTestDispatcherName ( std::string filename
);
710 bool IsTestFile ( std::string
& filename
) const;
711 void GetSourceFilenames ( string_list
& list
,
712 Module
& module
) const;
713 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
715 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
717 void WriteStartupFile ( Module
& module
);
724 SourceFile ( AutomaticDependency
* automaticDependency
,
725 const Module
& module
,
727 SourceFile
* parent
);
729 std::vector
<SourceFile
*> files
; /* List of files included in this file */
731 AutomaticDependency
* automaticDependency
;
732 const Module
& module
;
733 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
734 time_t lastWriteTime
;
735 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
736 SourceFile
* youngestFile
;
740 void SkipWhitespace ();
741 bool ReadInclude ( std::string
& filename
,
742 bool& searchCurrentDirectory
,
744 bool IsIncludedFrom ( const File
& file
);
745 SourceFile
* ParseFile(const File
& file
);
746 bool CanProcessFile ( const File
& file
);
747 bool IsParentOf ( const SourceFile
* parent
,
748 const SourceFile
* child
);
755 class AutomaticDependency
757 friend class SourceFileTest
;
759 const Project
& project
;
761 AutomaticDependency ( const Project
& project
);
762 ~AutomaticDependency ();
763 bool LocateIncludedFile ( const FileLocation
& directory
,
764 const std::string
& includedFilename
);
765 bool LocateIncludedFile ( SourceFile
* sourceFile
,
766 const Module
& module
,
767 const std::string
& includedFilename
,
768 bool searchCurrentDirectory
,
770 File
& resolvedFile
);
771 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
773 SourceFile
* parentSourceFile
);
774 SourceFile
* RetrieveFromCache ( const File
& file
);
775 void CheckAutomaticDependencies ( bool verbose
);
776 void CheckAutomaticDependenciesForModule ( Module
& module
,
779 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
780 void CheckAutomaticDependencies ( const Module
& module
,
782 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
783 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
784 const Module
& module
);
785 void GetModuleFiles ( const Module
& module
,
786 std::vector
<File
*>& files
) const;
788 void ParseFiles ( const Module
& module
);
789 void ParseFile ( const Module
& module
,
791 std::map
<std::string
, SourceFile
*> sourcefile_map
;
798 const Project
& project
;
799 const Module
* module
;
800 const XMLElement
& node
;
802 std::string nameoncd
;
804 Bootstrap ( const Project
& project
,
805 const Module
* module
,
806 const XMLElement
& bootstrapNode
);
810 bool IsSupportedModuleType ( ModuleType type
);
812 static std::string
ReplaceVariable ( const std::string
& name
,
813 const std::string
& value
,
818 class CDFile
: public XmlNode
821 FileLocation
*source
;
822 FileLocation
*target
;
824 CDFile ( const Project
& project
,
825 const XMLElement
& bootstrapNode
,
826 const std::string
& path
);
829 static std::string
ReplaceVariable ( const std::string
& name
,
830 const std::string
& value
,
835 class InstallFile
: public XmlNode
838 FileLocation
*source
;
839 FileLocation
*target
;
841 InstallFile ( const Project
& project
,
842 const XMLElement
& bootstrapNode
,
843 const std::string
& path
);
851 const XMLElement
& node
;
852 const Module
& module
;
853 const FileLocation
*file
;
856 const XMLElement
& node
,
857 const Module
& module
,
858 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
901 CompilationUnit ( const File
* file
);
902 CompilationUnit ( const Project
* project
,
903 const Module
* module
,
904 const XMLElement
* node
);
907 bool IsGeneratedFile () const;
908 bool HasFileWithExtension ( const std::string
& extension
) const;
909 bool IsFirstFile () const;
910 const FileLocation
& GetFilename () const;
911 const std::string
& GetSwitches () const;
912 void AddFile ( const File
* file
);
913 const std::vector
<const File
*> GetFiles () const;
915 const Project
* project
;
916 const Module
* module
;
917 const XMLElement
* node
;
918 std::vector
<const File
*> files
;
919 FileLocation
*default_name
;
923 class CompilationUnitSupportCode
926 const Project
& project
;
928 CompilationUnitSupportCode ( const Project
& project
);
929 ~CompilationUnitSupportCode ();
930 void Generate ( bool verbose
);
932 void GenerateForModule ( Module
& module
,
934 std::string
GetCompilationUnitFilename ( Module
& module
,
935 CompilationUnit
& compilationUnit
);
936 void WriteCompilationUnitFile ( Module
& module
,
937 CompilationUnit
& compilationUnit
);
941 enum AutoRegisterType
948 class AutoRegister
: public XmlNode
951 const Module
* module
;
952 std::string infSection
;
953 AutoRegisterType type
;
954 AutoRegister ( const Project
& project_
,
955 const Module
* module_
,
956 const XMLElement
& node_
);
958 bool IsSupportedModuleType ( ModuleType type
);
959 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
964 class SysSetupGenerator
967 const Project
& project
;
968 SysSetupGenerator ( const Project
& project
);
969 ~SysSetupGenerator ();
972 std::string
GetDirectoryId ( const Module
& module
);
973 std::string
GetFlags ( const Module
& module
);
974 void Generate ( HINF inf
,
975 const Module
& module
);
980 InitializeEnvironment ();
983 Right ( const std::string
& s
, size_t n
);
986 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
989 ChangeSeparator ( const std::string
& s
,
990 const char fromSeparator
,
991 const char toSeparator
);
994 FixSeparator ( const std::string
& s
);
997 FixSeparatorForSystemCommand ( const std::string
& s
);
1000 DosSeparator ( const std::string
& s
);
1004 const std::string
& filename
,
1005 const std::string
& newExtension
);
1009 const Project
& project
,
1010 const std::string
& location
,
1011 const std::string
& path
,
1012 const std::string
& att_value
);
1015 GetExtension ( const FileLocation
& file
);
1018 NormalizeFilename ( const std::string
& filename
);
1021 ToLower ( std::string filename
);
1023 #endif /* __RBUILD_H */