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 along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 "9.00"
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
,
151 enum DependenciesType
154 AutomaticDependencies
,
184 DependenciesType Dependencies
;
185 bool CheckDependenciesForModuleOnly
;
186 bool CompilationUnitsEnabled
;
187 bool PrecompiledHeadersEnabled
;
188 std::string CheckDependenciesForModuleOnlyModule
;
189 std::string VSProjectVersion
;
190 std::string VSConfigurationType
;
191 bool UseVSVersionInPath
;
192 bool UseConfigurationInPath
;
193 bool MakeHandlesInstallDirectories
;
194 bool GenerateProxyMakefilesInSourceTree
;
196 CompilerSet Compiler
;
203 static std::string
GetVariable ( const std::string
& name
);
204 static std::string
GetArch ();
205 static std::string
GetIntermediatePath ();
206 static std::string
GetOutputPath ();
207 static std::string
GetSourcePath ();
208 static std::string
GetCdOutputPath ();
209 static std::string
GetInstallPath ();
210 static std::string
GetAutomakeFile ( const std::string
& defaultFile
);
211 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
212 const std::string
& defaultValue
);
216 class FileSupportCode
219 static void WriteIfChanged ( char* outbuf
,
220 const std::string
& filename
,
221 bool ignoreError
= false );
228 CompilationUnit
* compilationUnit
;
236 std::vector
<CompilationUnit
*> compilationUnits
;
237 std::vector
<File
*> files
;
238 std::vector
<Include
*> includes
;
239 std::vector
<Define
*> defines
;
240 std::vector
<Library
*> libraries
;
241 std::map
<std::string
, Property
*> properties
;
242 std::vector
<Module
*> modules
;
243 std::vector
<CompilerFlag
*> compilerFlags
;
244 int asmFiles
; // number of .asm files in compilationUnits
249 void ExtractModules( std::map
<std::string
, Module
*> &modules
);
255 XMLElement
*node
, *head
;
258 const Configuration
& configuration
;
260 std::string makefile
;
261 XMLIncludes xmlbuildfiles
;
262 std::vector
<LinkerFlag
*> linkerFlags
;
263 std::vector
<CDFile
*> cdfiles
;
264 std::vector
<InstallFile
*> installfiles
;
265 std::map
<std::string
, Module
*> modules
;
266 IfableData non_if_data
;
267 IfableData host_non_if_data
;
269 bool allowWarningsSet
;
271 Project ( const Configuration
& configuration
,
272 const std::string
& filename
,
273 const std::map
<std::string
, std::string
>* properties
= NULL
);
275 void SetBackend ( Backend
* backend
) { _backend
= backend
; }
276 Backend
& GetBackend() { return *_backend
; }
277 void ExecuteInvocations ();
279 void ProcessXML ( const std::string
& path
);
280 Module
* LocateModule ( const std::string
& name
);
281 const Module
* LocateModule ( const std::string
& name
) const;
282 const std::string
& GetProjectFilename () const;
283 std::string
ResolveProperties ( const std::string
& s
) const;
284 const Property
* LookupProperty ( const std::string
& name
) const;
285 std::string
GetCompilerSet () const;
286 std::string
GetLinkerSet () const;
287 void GenerateInstallerFileList();
289 std::string
ResolveNextProperty ( const std::string
& s
) const;
291 void ProcessXMLSubElement ( const XMLElement
& e
,
292 const std::string
& path
,
293 ParseContext
& parseContext
);
295 // disable copy semantics
296 Project ( const Project
& );
297 Project
& operator = ( const Project
& );
334 TypeDontCare
, // always at the end
361 DirectoryLocation directory
;
362 std::string relative_path
;
365 FileLocation ( const DirectoryLocation directory
,
366 const std::string
& relative_path
,
367 const std::string
& name
,
368 const XMLElement
*node
= NULL
);
370 FileLocation ( const FileLocation
& other
);
376 const Project
& project
;
377 const XMLElement
& node
;
378 std::string xmlbuildFile
;
381 std::string extension
;
382 std::string baseaddress
;
384 std::string buildtype
;
386 ImportLibrary
* importLibrary
;
387 ImportLibrary
* delayImportLibrary
;
389 Bootsector
* bootSector
;
391 bool isDefaultEntryPoint
;
392 Bootstrap
* bootstrap
;
393 AutoRegister
* autoRegister
; // <autoregister> node
394 IfableData non_if_data
;
395 std::vector
<Invoke
*> invocations
;
396 std::vector
<Dependency
*> dependencies
;
397 std::vector
<CompilerFlag
*> compilerFlags
;
398 std::vector
<LinkerFlag
*> linkerFlags
;
399 std::vector
<StubbedComponent
*> stubbedComponents
;
400 std::vector
<CDFile
*> cdfiles
;
401 LinkerScript
* linkerScript
;
405 std::string aliasedModuleName
;
412 std::string installbase
;
413 FileLocation
*output
; // "path/foo.exe"
414 FileLocation
*dependency
; // "path/foo.exe" or "path/libfoo.a"
415 FileLocation
*install
;
416 std::string description
;
418 std::string layoutId
;
419 std::string layoutNameResId
;
421 Module ( const Project
& project
,
422 const XMLElement
& moduleNode
,
423 const std::string
& modulePath
);
425 ModuleType
GetModuleType ( const std::string
& location
,
426 const XMLAttribute
& attribute
);
427 bool HasImportLibrary () const;
429 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
430 std::string
GetPathToBaseDir() const; // "../" offset to rootdirectory
431 std::string
GetEntryPoint() const;
432 void GetTargets ( string_list
& ) const;
433 std::string
GetInvocationTarget ( const int index
) const;
434 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
435 void InvokeModule () const;
437 std::string
GetDllName() const;
438 SpecFileType
IsSpecDefinitionFile () const;
440 void SetImportLibrary ( ImportLibrary
* importLibrary
);
441 void SetDelayImportLibrary ( ImportLibrary
* importLibrary
);
442 DirectoryLocation
GetTargetDirectoryTree () const;
443 std::string
GetDefaultModuleExtension () const;
444 std::string
GetDefaultModuleEntrypoint () const;
445 std::string
GetDefaultModuleBaseaddress () const;
446 std::string
GetDefaultModuleCRT () const;
447 bool GetDefaultModuleIsCRT () const;
448 std::string entrypoint
;
449 void ProcessXMLSubElement ( const XMLElement
& e
,
450 DirectoryLocation directory
,
451 const std::string
& relative_path
,
452 ParseContext
& parseContext
);
453 bool GetBooleanAttribute ( const XMLElement
& moduleNode
,
455 bool default_value
= false );
458 class ToolsetDirective
464 void ParseToolsets ( const Project
& project
, const XMLElement
& node
);
467 virtual ~ToolsetDirective() { }
468 bool IsEnabled () const;
471 class CompilerDirective
474 std::bitset
<CompilerTypesCount
> compilersSet
;
478 void ParseCompilers ( const XMLElement
& node
, const std::string
& defaultValue
);
481 CompilerDirective (): enabled ( true ) { }
482 virtual ~CompilerDirective() { }
483 void SetCompiler ( CompilerType compiler
);
484 void UnsetCompiler ( CompilerType compiler
);
485 void SetAllCompilers ();
486 void UnsetAllCompilers ();
487 bool IsCompilerSet ( CompilerType compiler
) const;
490 class Include
: public CompilerDirective
, public ToolsetDirective
493 FileLocation
*directory
;
495 Include ( const Project
& project
,
496 const XMLElement
* includeNode
);
497 Include ( const Project
& project
,
498 const XMLElement
* includeNode
,
499 const Module
* module
);
500 Include ( const Project
& project
,
501 DirectoryLocation directory
,
502 const std::string
& relative_path
);
506 const Project
& project
;
507 const XMLElement
* node
;
508 const Module
* module
;
509 DirectoryLocation
GetDefaultDirectoryTree ( const Module
* module
) const;
514 class Define
: public CompilerDirective
, public ToolsetDirective
517 const Project
& project
;
518 const Module
* module
;
519 const XMLElement
* node
;
521 std::string arguments
;
526 Define ( const Project
& project
,
527 const XMLElement
& defineNode
);
528 Define ( const Project
& project
,
529 const Module
* module
,
530 const XMLElement
& defineNode
);
531 Define ( const Project
& project
,
532 const Module
* module
,
533 const std::string
& name_
,
534 const std::string
& backend_
= "",
535 bool redefine_
= false );
548 std::string switches
;
549 bool isPreCompiledHeader
;
551 File ( DirectoryLocation directory
,
552 const std::string
& relative_path
,
553 const std::string
& name
,
555 const std::string
& _switches
,
556 bool _isPreCompiledHeader
);
559 std::string
GetFullPath () const;
565 const XMLElement
*node
;
567 const Module
& module
;
569 const Module
* importedModule
;
572 Library ( const XMLElement
& _node
,
573 const Module
& _module
,
574 const std::string
& _name
);
575 Library ( const Module
& _module
,
576 const std::string
& _name
);
585 const XMLElement
& node
;
586 const Module
& module
;
587 const Module
* invokeModule
;
588 std::vector
<InvokeFile
*> input
;
589 std::vector
<InvokeFile
*> output
;
591 Invoke ( const XMLElement
& _node
,
592 const Module
& _module
);
595 void GetTargets ( string_list
& targets
) const;
596 std::string
GetParameters () const;
598 void ProcessXMLSubElement ( const XMLElement
& e
);
599 void ProcessXMLSubElementInput ( const XMLElement
& e
);
600 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
607 const XMLElement
& node
;
609 std::string switches
;
611 InvokeFile ( const XMLElement
& _node
,
612 const std::string
& _name
);
621 const XMLElement
& node
;
622 const Module
& module
;
623 const Module
* dependencyModule
;
625 Dependency ( const XMLElement
& _node
,
626 const Module
& _module
);
634 const XMLElement
& node
;
635 const Module
* module
;
636 const Module
* bootSectorModule
;
638 Bootsector ( const XMLElement
& _node
,
639 const Module
* _module
);
643 bool IsSupportedModuleType ( ModuleType type
);
649 const XMLElement
& node
;
650 const Module
& module
;
652 std::string description
;
654 std::string copyright
;
659 Metadata ( const XMLElement
& _node
,
660 const Module
& _module
);
665 class ImportLibrary
: public XmlNode
668 const Module
* module
;
670 FileLocation
*source
;
671 FileLocation
*target
;
673 ImportLibrary ( const Project
& project
,
674 const XMLElement
& node
,
675 const Module
* module
,
681 class CompilerFlag
: public CompilerDirective
, public ToolsetDirective
684 const Project
& project
;
685 const Module
* module
;
686 const XMLElement
& node
;
689 CompilerFlag ( const Project
& project
,
690 const XMLElement
& compilerFlagNode
);
691 CompilerFlag ( const Project
& project
,
692 const Module
* module
,
693 const XMLElement
& compilerFlagNode
);
701 class LinkerFlag
: public ToolsetDirective
704 const Project
& project
;
705 const Module
* module
;
706 const XMLElement
& node
;
709 LinkerFlag ( const Project
& project
,
710 const XMLElement
& linkerFlagNode
);
711 LinkerFlag ( const Project
& project
,
712 const Module
* module
,
713 const XMLElement
& linkerFlagNode
);
724 const XMLElement
& node
;
725 const Module
& module
;
726 const FileLocation
*file
;
728 LinkerScript ( const XMLElement
& node
,
729 const Module
& module
,
730 const FileLocation
*file
);
739 const Project
& project
;
740 const Module
* module
;
741 std::string name
, value
;
744 Property ( const XMLElement
& node_
,
745 const Project
& project_
,
746 const Module
* module_
);
748 Property ( const Project
& project_
,
749 const Module
* module_
,
750 const std::string
& name_
,
751 const std::string
& value_
);
757 class TestSupportCode
760 const Project
& project
;
762 TestSupportCode ( const Project
& project
);
764 void GenerateTestSupportCode ( bool verbose
);
766 bool IsTestModule ( const Module
& module
);
767 void GenerateTestSupportCodeForModule ( Module
& module
,
769 std::string
GetHooksFilename ( Module
& module
);
770 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
771 const StubbedComponent
& component
,
772 const StubbedSymbol
& symbol
);
773 char* WriteStubbedComponentToHooksFile ( char* buffer
,
774 const StubbedComponent
& component
);
775 void WriteHooksFile ( Module
& module
);
776 std::string
GetStubsFilename ( Module
& module
);
777 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
778 const StubbedComponent
& component
,
779 const StubbedSymbol
& symbol
,
781 char* WriteStubbedComponentToStubsFile ( char* buffer
,
782 const StubbedComponent
& component
,
784 void WriteStubsFile ( Module
& module
);
785 std::string
GetStartupFilename ( Module
& module
);
786 bool IsUnknownCharacter ( char ch
);
787 std::string
GetTestDispatcherName ( std::string filename
);
788 bool IsTestFile ( std::string
& filename
) const;
789 void GetSourceFilenames ( string_list
& list
,
790 Module
& module
) const;
791 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
793 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
795 void WriteStartupFile ( Module
& module
);
802 SourceFile ( AutomaticDependency
* automaticDependency
,
803 const Module
& module
,
805 SourceFile
* parent
);
807 std::vector
<SourceFile
*> files
; /* List of files included in this file */
809 AutomaticDependency
* automaticDependency
;
810 const Module
& module
;
811 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
812 time_t lastWriteTime
;
813 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
814 SourceFile
* youngestFile
;
818 void SkipWhitespace ();
819 bool ReadInclude ( std::string
& filename
,
820 bool& searchCurrentDirectory
,
822 bool IsIncludedFrom ( const File
& file
);
823 SourceFile
* ParseFile(const File
& file
);
824 bool CanProcessFile ( const File
& file
);
825 bool IsParentOf ( const SourceFile
* parent
,
826 const SourceFile
* child
);
833 class AutomaticDependency
835 friend class SourceFileTest
;
837 const Project
& project
;
839 AutomaticDependency ( const Project
& project
);
840 ~AutomaticDependency ();
841 bool LocateIncludedFile ( const FileLocation
& directory
,
842 const std::string
& includedFilename
);
843 bool LocateIncludedFile ( SourceFile
* sourceFile
,
844 const Module
& module
,
845 const std::string
& includedFilename
,
846 bool searchCurrentDirectory
,
848 File
& resolvedFile
);
849 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
851 SourceFile
* parentSourceFile
);
852 SourceFile
* RetrieveFromCache ( const File
& file
);
853 void CheckAutomaticDependencies ( bool verbose
);
854 void CheckAutomaticDependenciesForModule ( Module
& module
,
857 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
858 void CheckAutomaticDependencies ( const Module
& module
,
860 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
861 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
862 const Module
& module
);
863 void GetModuleFiles ( const Module
& module
,
864 std::vector
<File
*>& files
) const;
866 void ParseFiles ( const Module
& module
);
867 void ParseFile ( const Module
& module
,
869 std::map
<std::string
, SourceFile
*> sourcefile_map
;
876 const Project
& project
;
877 const Module
* module
;
878 const XMLElement
& node
;
880 std::string nameoncd
;
882 Bootstrap ( const Project
& project
,
883 const Module
* module
,
884 const XMLElement
& bootstrapNode
);
888 bool IsSupportedModuleType ( ModuleType type
);
890 static std::string
ReplaceVariable ( const std::string
& name
,
891 const std::string
& value
,
896 class CDFile
: public XmlNode
899 FileLocation
*source
;
900 FileLocation
*target
;
902 CDFile ( const Project
& project
,
903 const XMLElement
& bootstrapNode
,
904 const std::string
& path
);
907 static std::string
ReplaceVariable ( const std::string
& name
,
908 const std::string
& value
,
913 class InstallFile
: public XmlNode
916 FileLocation
*source
;
917 FileLocation
*target
;
918 std::string installbase
;
920 InstallFile ( const Project
& project
,
921 const XMLElement
& bootstrapNode
,
922 const std::string
& path
);
930 const XMLElement
& node
;
931 const Module
& module
;
932 const FileLocation
*file
;
935 const XMLElement
& node
,
936 const Module
& module
,
937 const FileLocation
*file
);
943 class StubbedComponent
946 const Module
* module
;
947 const XMLElement
& node
;
949 std::vector
<StubbedSymbol
*> symbols
;
951 StubbedComponent ( const Module
* module_
,
952 const XMLElement
& stubbedComponentNode
);
953 ~StubbedComponent ();
955 void ProcessXMLSubElement ( const XMLElement
& e
);
962 const XMLElement
& node
;
965 std::string strippedName
;
967 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
971 std::string
StripSymbol ( std::string symbol
);
975 class CompilationUnit
980 CompilationUnit ( const File
* file
);
981 CompilationUnit ( const Project
* project
,
982 const Module
* module
,
983 const XMLElement
* node
);
986 bool IsGeneratedFile () const;
987 bool HasFileWithExtension ( const std::string
& extension
) const;
988 bool IsFirstFile () const;
989 const FileLocation
& GetFilename () const;
990 const std::string
& GetSwitches () const;
991 void AddFile ( const File
* file
);
992 const std::vector
<const File
*> GetFiles () const;
994 const Project
* project
;
995 const Module
* module
;
996 const XMLElement
* node
;
997 std::vector
<const File
*> files
;
998 FileLocation
*default_name
;
1002 class CompilationUnitSupportCode
1005 const Project
& project
;
1007 CompilationUnitSupportCode ( const Project
& project
);
1008 ~CompilationUnitSupportCode ();
1009 void Generate ( bool verbose
);
1011 void GenerateForModule ( Module
& module
,
1013 std::string
GetCompilationUnitFilename ( Module
& module
,
1014 CompilationUnit
& compilationUnit
);
1015 void WriteCompilationUnitFile ( Module
& module
,
1016 CompilationUnit
& compilationUnit
);
1020 enum AutoRegisterType
1027 class AutoRegister
: public XmlNode
1030 const Module
* module
;
1031 std::string infSection
;
1032 AutoRegisterType type
;
1033 AutoRegister ( const Project
& project_
,
1034 const Module
* module_
,
1035 const XMLElement
& node_
);
1037 bool IsSupportedModuleType ( ModuleType type
);
1038 AutoRegisterType
GetAutoRegisterType( const std::string
& type
);
1043 class SysSetupGenerator
1046 const Project
& project
;
1047 SysSetupGenerator ( const Project
& project
);
1048 ~SysSetupGenerator ();
1051 std::string
GetDirectoryId ( const Module
& module
);
1052 std::string
GetFlags ( const Module
& module
);
1053 void Generate ( HINF inf
,
1054 const Module
& module
);
1059 InitializeEnvironment ();
1062 Right ( const std::string
& s
, size_t n
);
1065 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
1068 ChangeSeparator ( const std::string
& s
,
1069 const char fromSeparator
,
1070 const char toSeparator
);
1073 FixSeparator ( const std::string
& s
);
1076 FixSeparatorForSystemCommand ( const std::string
& s
);
1079 DosSeparator ( const std::string
& s
);
1083 const std::string
& filename
,
1084 const std::string
& newExtension
);
1088 const Project
& project
,
1089 const std::string
& location
,
1090 const std::string
& path
,
1091 const std::string
& att_value
);
1094 GetExtension ( const FileLocation
& file
);
1097 NormalizeFilename ( const std::string
& filename
);
1100 ToLower ( std::string filename
);