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>
39 #include "exception.h"
42 typedef std::vector
<std::string
> string_list
;
44 extern std::string ExePrefix
;
45 extern std::string ExePostfix
;
46 extern std::string sSep
;
47 extern std::string sBadSep
;
52 #define DEF_EXEPREFIX ""
53 #define DEF_EXEPOSTFIX ".exe"
55 #define DEF_CBAD_SEP '/'
57 #define DEF_SBAD_SEP "/"
59 #define DEF_EXEPREFIX "./"
60 #define DEF_EXEPOSTFIX ""
62 #define DEF_CBAD_SEP '\\'
64 #define DEF_SBAD_SEP "\\"
67 #define MS_VS_DEF_VERSION "7.10"
86 class TestSupportCode
;
88 class AutomaticDependency
;
93 class StubbedComponent
;
95 class CompilationUnit
;
101 typedef std::map
<std::string
,Directory
*> directory_map
;
107 directory_map subdirs
;
108 Directory ( const std::string
& name
);
109 void Add ( const char* subdir
);
110 void GenerateTree ( const std::string
& parent
,
112 std::string
EscapeSpaces ( std::string path
);
113 void CreateRule ( FILE* f
,
114 const std::string
& parent
);
116 bool mkdir_p ( const char* path
);
117 std::string
ReplaceVariable ( std::string name
,
120 std::string
GetEnvironmentVariable ( const std::string
& name
);
121 void ResolveVariablesInPath ( char* buf
,
123 bool CreateDirectory ( std::string path
);
134 bool AutomaticDependencies
;
135 bool CheckDependenciesForModuleOnly
;
136 std::string CheckDependenciesForModuleOnlyModule
;
137 std::string VSProjectVersion
;
138 bool MakeHandlesInstallDirectories
;
139 bool GenerateProxyMakefilesInSourceTree
;
145 static std::string
GetVariable ( const std::string
& name
);
146 static std::string
GetIntermediatePath ();
147 static std::string
GetOutputPath ();
148 static std::string
GetInstallPath ();
149 static std::string
GetEnvironmentVariablePathOrDefault ( const std::string
& name
,
150 const std::string
& defaultValue
);
154 class FileSupportCode
157 static void WriteIfChanged ( char* outbuf
,
158 std::string filename
);
166 CompilationUnit
* compilationUnit
;
174 std::vector
<CompilationUnit
*> compilationUnits
;
175 std::vector
<File
*> files
;
176 std::vector
<Include
*> includes
;
177 std::vector
<Define
*> defines
;
178 std::vector
<Library
*> libraries
;
179 std::vector
<Property
*> properties
;
180 std::vector
<CompilerFlag
*> compilerFlags
;
181 std::vector
<If
*> ifs
;
190 XMLElement
*node
, *head
;
193 std::string makefile
;
194 XMLIncludes xmlbuildfiles
;
195 std::vector
<Module
*> modules
;
196 std::vector
<LinkerFlag
*> linkerFlags
;
197 std::vector
<CDFile
*> cdfiles
;
198 std::vector
<InstallFile
*> installfiles
;
199 IfableData non_if_data
;
201 Project ( const std::string
& filename
);
203 void WriteConfigurationFile ();
204 void ExecuteInvocations ();
205 void ProcessXML ( const std::string
& path
);
206 Module
* LocateModule ( const std::string
& name
);
207 const Module
* LocateModule ( const std::string
& name
) const;
208 std::string
GetProjectFilename () const;
209 std::string
ResolveProperties ( const std::string
& s
) const;
211 std::string
ResolveNextProperty ( std::string
& s
) const;
212 const Property
* LookupProperty ( const std::string
& name
) const;
213 void SetConfigurationOption ( char* s
,
215 std::string
* alternativeName
);
216 void SetConfigurationOption ( char* s
,
219 void ProcessXMLSubElement ( const XMLElement
& e
,
220 const std::string
& path
,
221 ParseContext
& parseContext
);
223 // disable copy semantics
224 Project ( const Project
& );
225 Project
& operator = ( const Project
& );
236 KernelModeDriver
= 5,
262 const Project
& project
;
263 const XMLElement
& node
;
264 std::string xmlbuildFile
;
267 std::string extension
;
268 std::string entrypoint
;
269 std::string baseaddress
;
272 ImportLibrary
* importLibrary
;
275 Bootstrap
* bootstrap
;
276 IfableData non_if_data
;
277 std::vector
<Invoke
*> invocations
;
278 std::vector
<Dependency
*> dependencies
;
279 std::vector
<CompilerFlag
*> compilerFlags
;
280 std::vector
<LinkerFlag
*> linkerFlags
;
281 std::vector
<StubbedComponent
*> stubbedComponents
;
282 LinkerScript
* linkerScript
;
287 std::string installBase
;
288 std::string installName
;
289 std::string aliasedModuleName
;
294 Module ( const Project
& project
,
295 const XMLElement
& moduleNode
,
296 const std::string
& modulePath
);
298 ModuleType
GetModuleType ( const std::string
& location
,
299 const XMLAttribute
& attribute
);
300 bool HasImportLibrary () const;
302 bool GenerateInOutputTree () const;
303 std::string
GetTargetName () const; // "foo.exe"
304 std::string
GetDependencyPath () const; // "path/foo.exe" or "path/libfoo.a"
305 std::string
GetBasePath () const; // "path"
306 std::string
GetPath () const; // "path/foo.exe"
307 std::string
GetPathWithPrefix ( const std::string
& prefix
) const; // "path/prefixfoo.exe"
308 void GetTargets ( string_list
& ) const;
309 std::string
GetInvocationTarget ( const int index
) const;
310 bool HasFileWithExtension ( const IfableData
&, const std::string
& extension
) const;
311 void InvokeModule () const;
313 void GetSourceFilenames ( string_list
& list
,
314 bool includeGeneratedFiles
) const;
316 std::string
GetDefaultModuleExtension () const;
317 std::string
GetDefaultModuleEntrypoint () const;
318 std::string
GetDefaultModuleBaseaddress () const;
319 void ProcessXMLSubElement ( const XMLElement
& e
,
320 const std::string
& path
,
321 ParseContext
& parseContext
);
328 const Project
& project
;
329 const Module
* module
;
330 const XMLElement
* node
;
331 const Module
* baseModule
;
332 std::string directory
;
333 std::string basePath
;
335 Include ( const Project
& project
,
336 const XMLElement
* includeNode
);
337 Include ( const Project
& project
,
338 const Module
* module
,
339 const XMLElement
* includeNode
);
340 Include ( const Project
& project
,
341 std::string directory
,
342 std::string basePath
);
352 const Project
& project
;
353 const Module
* module
;
354 const XMLElement
& node
;
358 Define ( const Project
& project
,
359 const XMLElement
& defineNode
);
360 Define ( const Project
& project
,
361 const Module
* module
,
362 const XMLElement
& defineNode
);
375 std::string switches
;
376 bool isPreCompiledHeader
;
378 File ( const std::string
& _name
,
380 std::string _switches
,
381 bool _isPreCompiledHeader
);
390 const XMLElement
& node
;
391 const Module
& module
;
393 const Module
* importedModule
;
395 Library ( const XMLElement
& _node
,
396 const Module
& _module
,
397 const std::string
& _name
);
406 const XMLElement
& node
;
407 const Module
& module
;
408 const Module
* invokeModule
;
409 std::vector
<InvokeFile
*> input
;
410 std::vector
<InvokeFile
*> output
;
412 Invoke ( const XMLElement
& _node
,
413 const Module
& _module
);
416 void GetTargets ( string_list
& targets
) const;
417 std::string
GetParameters () const;
419 void ProcessXMLSubElement ( const XMLElement
& e
);
420 void ProcessXMLSubElementInput ( const XMLElement
& e
);
421 void ProcessXMLSubElementOutput ( const XMLElement
& e
);
428 const XMLElement
& node
;
430 std::string switches
;
432 InvokeFile ( const XMLElement
& _node
,
433 const std::string
& _name
);
442 const XMLElement
& node
;
443 const Module
& module
;
444 const Module
* dependencyModule
;
446 Dependency ( const XMLElement
& _node
,
447 const Module
& _module
);
456 const XMLElement
& node
;
457 const Module
& module
;
458 std::string basename
;
459 std::string definition
;
461 ImportLibrary ( const XMLElement
& _node
,
462 const Module
& module
);
471 const XMLElement
& node
;
472 const Project
& project
;
473 const Module
* module
;
475 std::string property
, value
;
478 If ( const XMLElement
& node_
,
479 const Project
& project_
,
480 const Module
* module_
,
481 const bool negated_
= false );
491 const Project
& project
;
492 const Module
* module
;
493 const XMLElement
& node
;
496 CompilerFlag ( const Project
& project
,
497 const XMLElement
& compilerFlagNode
);
498 CompilerFlag ( const Project
& project
,
499 const Module
* module
,
500 const XMLElement
& compilerFlagNode
);
511 const Project
& project
;
512 const Module
* module
;
513 const XMLElement
& node
;
516 LinkerFlag ( const Project
& project
,
517 const XMLElement
& linkerFlagNode
);
518 LinkerFlag ( const Project
& project
,
519 const Module
* module
,
520 const XMLElement
& linkerFlagNode
);
531 const Project
& project
;
532 const Module
* module
;
533 const XMLElement
& node
;
534 const Module
* baseModule
;
535 std::string directory
;
536 std::string basePath
;
538 LinkerScript ( const Project
& project
,
539 const Module
* module
,
540 const XMLElement
& node
);
549 const XMLElement
& node
;
550 const Project
& project
;
551 const Module
* module
;
552 std::string name
, value
;
554 Property ( const XMLElement
& node_
,
555 const Project
& project_
,
556 const Module
* module_
);
562 class TestSupportCode
565 const Project
& project
;
567 TestSupportCode ( const Project
& project
);
569 void GenerateTestSupportCode ( bool verbose
);
571 bool IsTestModule ( const Module
& module
);
572 void GenerateTestSupportCodeForModule ( Module
& module
,
574 std::string
GetHooksFilename ( Module
& module
);
575 char* WriteStubbedSymbolToHooksFile ( char* buffer
,
576 const StubbedComponent
& component
,
577 const StubbedSymbol
& symbol
);
578 char* WriteStubbedComponentToHooksFile ( char* buffer
,
579 const StubbedComponent
& component
);
580 void WriteHooksFile ( Module
& module
);
581 std::string
GetStubsFilename ( Module
& module
);
582 char* WriteStubbedSymbolToStubsFile ( char* buffer
,
583 const StubbedComponent
& component
,
584 const StubbedSymbol
& symbol
,
586 char* WriteStubbedComponentToStubsFile ( char* buffer
,
587 const StubbedComponent
& component
,
589 void WriteStubsFile ( Module
& module
);
590 std::string
GetStartupFilename ( Module
& module
);
591 bool IsUnknownCharacter ( char ch
);
592 std::string
GetTestDispatcherName ( std::string filename
);
593 bool IsTestFile ( std::string
& filename
) const;
594 void GetSourceFilenames ( string_list
& list
,
595 Module
& module
) const;
596 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer
,
598 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer
,
600 void WriteStartupFile ( Module
& module
);
607 const Project
& project
;
610 WineResource ( const Project
& project
,
611 std::string bin2res
);
613 void UnpackResources ( bool verbose
);
615 bool IsSpecFile ( const File
& file
);
616 bool IsWineModule ( const Module
& module
);
617 bool IsResourceFile ( const File
& file
);
618 std::string
GetResourceFilename ( const Module
& module
);
619 void UnpackResourcesInModule ( Module
& module
,
627 SourceFile ( AutomaticDependency
* automaticDependency
,
628 const Module
& module
,
629 const std::string
& filename
,
631 bool isNonAutomaticDependency
);
632 SourceFile
* ParseFile ( const std::string
& normalizedFilename
);
634 std::string
Location () const;
635 std::vector
<SourceFile
*> files
;
636 AutomaticDependency
* automaticDependency
;
637 const Module
& module
;
638 std::string filename
;
639 std::string filenamePart
;
640 std::string directoryPart
;
641 std::vector
<SourceFile
*> parents
; /* List of files, this file is included from */
642 bool isNonAutomaticDependency
;
643 std::string cachedDependencies
;
644 time_t lastWriteTime
;
645 time_t youngestLastWriteTime
; /* Youngest last write time of this file and all children */
646 SourceFile
* youngestFile
;
648 void GetDirectoryAndFilenameParts ();
651 void SkipWhitespace ();
652 bool ReadInclude ( std::string
& filename
,
653 bool& searchCurrentDirectory
,
655 bool IsIncludedFrom ( const std::string
& normalizedFilename
);
656 SourceFile
* GetParentSourceFile ();
657 bool CanProcessFile ( const std::string
& extension
);
658 bool IsParentOf ( const SourceFile
* parent
,
659 const SourceFile
* child
);
666 class AutomaticDependency
668 friend class SourceFileTest
;
670 const Project
& project
;
672 AutomaticDependency ( const Project
& project
);
673 ~AutomaticDependency ();
674 std::string
GetFilename ( const std::string
& filename
);
675 bool LocateIncludedFile ( const std::string
& directory
,
676 const std::string
& includedFilename
,
677 std::string
& resolvedFilename
);
678 bool LocateIncludedFile ( SourceFile
* sourceFile
,
679 const Module
& module
,
680 const std::string
& includedFilename
,
681 bool searchCurrentDirectory
,
683 std::string
& resolvedFilename
);
684 SourceFile
* RetrieveFromCacheOrParse ( const Module
& module
,
685 const std::string
& filename
,
686 SourceFile
* parentSourceFile
);
687 SourceFile
* RetrieveFromCache ( const std::string
& filename
);
688 void CheckAutomaticDependencies ( bool verbose
);
689 void CheckAutomaticDependenciesForModule ( Module
& module
,
692 void GetModulesToCheck ( Module
& module
, std::vector
<const Module
*>& modules
);
693 void CheckAutomaticDependencies ( const Module
& module
,
695 void CheckAutomaticDependenciesForFile ( SourceFile
* sourceFile
);
696 void GetIncludeDirectories ( std::vector
<Include
*>& includes
,
697 const Module
& module
,
698 Include
& currentDirectory
,
699 bool searchCurrentDirectory
);
700 void GetModuleFiles ( const Module
& module
,
701 std::vector
<File
*>& files
) const;
703 void ParseFiles ( const Module
& module
);
704 void ParseFile ( const Module
& module
,
706 std::map
<std::string
, SourceFile
*> sourcefile_map
;
713 const Project
& project
;
714 const Module
* module
;
715 const XMLElement
& node
;
717 std::string nameoncd
;
719 Bootstrap ( const Project
& project
,
720 const Module
* module
,
721 const XMLElement
& bootstrapNode
);
725 bool IsSupportedModuleType ( ModuleType type
);
733 const Project
& project
;
734 const XMLElement
& node
;
737 std::string nameoncd
;
740 CDFile ( const Project
& project
,
741 const XMLElement
& bootstrapNode
,
742 const std::string
& path
);
745 std::string
GetPath () const;
752 const Project
& project
;
753 const XMLElement
& node
;
759 InstallFile ( const Project
& project
,
760 const XMLElement
& bootstrapNode
,
761 const std::string
& path
);
764 std::string
GetPath () const;
771 const XMLElement
& node
;
772 const Module
& module
;
776 const XMLElement
& node
,
777 const Module
& module
,
783 class StubbedComponent
786 const Module
* module
;
787 const XMLElement
& node
;
789 std::vector
<StubbedSymbol
*> symbols
;
791 StubbedComponent ( const Module
* module_
,
792 const XMLElement
& stubbedComponentNode
);
793 ~StubbedComponent ();
795 void ProcessXMLSubElement ( const XMLElement
& e
);
802 const XMLElement
& node
;
805 std::string strippedName
;
807 StubbedSymbol ( const XMLElement
& stubbedSymbolNode
);
811 std::string
StripSymbol ( std::string symbol
);
815 class CompilationUnit
818 const Project
* project
;
819 const Module
* module
;
820 const XMLElement
* node
;
822 std::vector
<File
*> files
;
824 CompilationUnit ( File
* file
);
825 CompilationUnit ( const Project
* project
,
826 const Module
* module
,
827 const XMLElement
* node
);
830 bool IsGeneratedFile () const;
831 bool HasFileWithExtension ( const std::string
& extension
) const;
832 bool IsFirstFile () const;
833 FileLocation
* GetFilename ( Directory
* intermediateDirectory
) const;
834 std::string
GetSwitches () const;
838 class CompilationUnitSupportCode
841 const Project
& project
;
843 CompilationUnitSupportCode ( const Project
& project
);
844 ~CompilationUnitSupportCode ();
845 void Generate ( bool verbose
);
847 void GenerateForModule ( Module
& module
,
849 std::string
GetCompilationUnitFilename ( Module
& module
,
850 CompilationUnit
& compilationUnit
);
851 void WriteCompilationUnitFile ( Module
& module
,
852 CompilationUnit
& compilationUnit
);
859 Directory
* directory
;
860 std::string filename
;
861 FileLocation ( Directory
* directory
,
862 std::string filename
);
867 InitializeEnvironment ();
870 Right ( const std::string
& s
, size_t n
);
873 Replace ( const std::string
& s
, const std::string
& find
, const std::string
& with
);
876 FixSeparator ( const std::string
& s
);
879 FixSeparatorForSystemCommand ( const std::string
& s
);
882 DosSeparator ( const std::string
& s
);
886 const std::string
& filename
,
887 const std::string
& newExtension
);
891 const std::string
& location
,
892 const std::string
& path
,
893 const std::string
& att_value
);
896 GetExtension ( const std::string
& filename
);
899 GetDirectory ( const std::string
& filename
);
902 GetFilename ( const std::string
& filename
);
905 NormalizeFilename ( const std::string
& filename
);
907 #endif /* __RBUILD_H */