e3d9c4d0f5c6bca85b1b063ecacca06e44c8966e
[reactos.git] / reactos / tools / rbuild / rbuild.h
1 /*
2 * Copyright (C) 2005 Casper S. Hornstrup
3 *
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.
8 *
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.
13 *
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.
17 */
18 #ifndef __RBUILD_H
19 #define __RBUILD_H
20
21 #include "pch.h"
22
23 #ifdef WIN32
24 #include <direct.h>
25 #include <io.h>
26 #endif/*WIN32*/
27 #include <sys/stat.h>
28 #include <time.h>
29 #ifdef _MSC_VER
30 #include <sys/utime.h>
31 #else/*_MSC_VER*/
32 #include <utime.h>
33 #ifdef WIN32
34 #include <process.h>
35 #endif/*WIN32*/
36 #endif/*_MSC_VER*/
37
38 #include "ssprintf.h"
39 #include "exception.h"
40 #include "XML.h"
41
42 typedef std::vector<std::string> string_list;
43
44 extern std::string ExePrefix;
45 extern std::string ExePostfix;
46 extern std::string sSep;
47 extern std::string sBadSep;
48 extern char cSep;
49 extern char cBadSep;
50
51 #ifdef WIN32
52 #define DEF_EXEPREFIX ""
53 #define DEF_EXEPOSTFIX ".exe"
54 #define DEF_CSEP '\\'
55 #define DEF_CBAD_SEP '/'
56 #define DEF_SSEP "\\"
57 #define DEF_SBAD_SEP "/"
58 #else
59 #define DEF_EXEPREFIX "./"
60 #define DEF_EXEPOSTFIX ""
61 #define DEF_CSEP '/'
62 #define DEF_CBAD_SEP '\\'
63 #define DEF_SSEP "/"
64 #define DEF_SBAD_SEP "\\"
65 #endif
66
67 #define MS_VS_DEF_VERSION "7.10"
68
69 class Directory;
70 class Project;
71 class IfableData;
72 class Module;
73 class Include;
74 class Define;
75 class File;
76 class Library;
77 class Invoke;
78 class InvokeFile;
79 class Dependency;
80 class ImportLibrary;
81 class If;
82 class CompilerFlag;
83 class LinkerFlag;
84 class LinkerScript;
85 class Property;
86 class TestSupportCode;
87 class WineResource;
88 class AutomaticDependency;
89 class Bootstrap;
90 class CDFile;
91 class InstallFile;
92 class PchFile;
93 class StubbedComponent;
94 class StubbedSymbol;
95 class CompilationUnit;
96 class FileLocation;
97
98 class SourceFileTest;
99
100
101 typedef std::map<std::string,Directory*> directory_map;
102
103 class Directory
104 {
105 public:
106 std::string name;
107 directory_map subdirs;
108 Directory ( const std::string& name );
109 void Add ( const char* subdir );
110 void GenerateTree ( const std::string& parent,
111 bool verbose );
112 std::string EscapeSpaces ( std::string path );
113 void CreateRule ( FILE* f,
114 const std::string& parent );
115 private:
116 bool mkdir_p ( const char* path );
117 std::string ReplaceVariable ( std::string name,
118 std::string value,
119 std::string path );
120 std::string GetEnvironmentVariable ( const std::string& name );
121 void ResolveVariablesInPath ( char* buf,
122 std::string path );
123 bool CreateDirectory ( std::string path );
124 };
125
126
127 class Configuration
128 {
129 public:
130 Configuration ();
131 ~Configuration ();
132 bool Verbose;
133 bool CleanAsYouGo;
134 bool AutomaticDependencies;
135 bool CheckDependenciesForModuleOnly;
136 std::string CheckDependenciesForModuleOnlyModule;
137 std::string VSProjectVersion;
138 bool MakeHandlesInstallDirectories;
139 bool GenerateProxyMakefilesInSourceTree;
140 };
141
142 class Environment
143 {
144 public:
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 );
151 };
152
153
154 class FileSupportCode
155 {
156 public:
157 static void WriteIfChanged ( char* outbuf,
158 std::string filename );
159 };
160
161
162 class ParseContext
163 {
164 public:
165 If* ifData;
166 CompilationUnit* compilationUnit;
167 ParseContext ();
168 };
169
170
171 class IfableData
172 {
173 public:
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;
182
183 ~IfableData();
184 void ProcessXML();
185 };
186
187 class Project
188 {
189 std::string xmlfile;
190 XMLElement *node, *head;
191 public:
192 std::string name;
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;
200
201 Project ( const std::string& filename );
202 ~Project ();
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;
210 private:
211 std::string ResolveNextProperty ( std::string& s ) const;
212 const Property* LookupProperty ( const std::string& name ) const;
213 void SetConfigurationOption ( char* s,
214 std::string name,
215 std::string* alternativeName );
216 void SetConfigurationOption ( char* s,
217 std::string name );
218 void ReadXml ();
219 void ProcessXMLSubElement ( const XMLElement& e,
220 const std::string& path,
221 ParseContext& parseContext );
222
223 // disable copy semantics
224 Project ( const Project& );
225 Project& operator = ( const Project& );
226 };
227
228
229 enum ModuleType
230 {
231 BuildTool = 0,
232 StaticLibrary = 1,
233 ObjectLibrary = 2,
234 Kernel = 3,
235 KernelModeDLL = 4,
236 KernelModeDriver = 5,
237 NativeDLL = 6,
238 NativeCUI = 7,
239 Win32DLL = 8,
240 Win32CUI = 9,
241 Win32GUI = 10,
242 BootLoader = 11,
243 BootSector = 12,
244 Iso = 13,
245 LiveIso = 14,
246 Test = 15,
247 RpcServer = 16,
248 RpcClient = 17,
249 Alias = 18
250 };
251
252 enum HostType
253 {
254 HostFalse,
255 HostDefault,
256 HostTrue
257 };
258
259 class Module
260 {
261 public:
262 const Project& project;
263 const XMLElement& node;
264 std::string xmlbuildFile;
265 std::string name;
266 std::string guid;
267 std::string extension;
268 std::string entrypoint;
269 std::string baseaddress;
270 std::string path;
271 ModuleType type;
272 ImportLibrary* importLibrary;
273 bool mangledSymbols;
274 bool isUnicode;
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;
283 PchFile* pch;
284 bool cplusplus;
285 std::string prefix;
286 HostType host;
287 std::string installBase;
288 std::string installName;
289 std::string aliasedModuleName;
290 bool useWRC;
291 bool allowWarnings;
292 bool enabled;
293
294 Module ( const Project& project,
295 const XMLElement& moduleNode,
296 const std::string& modulePath );
297 ~Module ();
298 ModuleType GetModuleType ( const std::string& location,
299 const XMLAttribute& attribute );
300 bool HasImportLibrary () const;
301 bool IsDLL () 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;
312 void ProcessXML ();
313 void GetSourceFilenames ( string_list& list,
314 bool includeGeneratedFiles ) const;
315 private:
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 );
322 };
323
324
325 class Include
326 {
327 public:
328 const Project& project;
329 const Module* module;
330 const XMLElement* node;
331 const Module* baseModule;
332 std::string directory;
333 std::string basePath;
334
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 );
343 ~Include ();
344 void ProcessXML();
345 private:
346 };
347
348
349 class Define
350 {
351 public:
352 const Project& project;
353 const Module* module;
354 const XMLElement& node;
355 std::string name;
356 std::string value;
357
358 Define ( const Project& project,
359 const XMLElement& defineNode );
360 Define ( const Project& project,
361 const Module* module,
362 const XMLElement& defineNode );
363 ~Define();
364 void ProcessXML();
365 private:
366 void Initialize();
367 };
368
369
370 class File
371 {
372 public:
373 std::string name;
374 bool first;
375 std::string switches;
376 bool isPreCompiledHeader;
377
378 File ( const std::string& _name,
379 bool _first,
380 std::string _switches,
381 bool _isPreCompiledHeader );
382
383 void ProcessXML();
384 };
385
386
387 class Library
388 {
389 public:
390 const XMLElement& node;
391 const Module& module;
392 std::string name;
393 const Module* importedModule;
394
395 Library ( const XMLElement& _node,
396 const Module& _module,
397 const std::string& _name );
398
399 void ProcessXML();
400 };
401
402
403 class Invoke
404 {
405 public:
406 const XMLElement& node;
407 const Module& module;
408 const Module* invokeModule;
409 std::vector<InvokeFile*> input;
410 std::vector<InvokeFile*> output;
411
412 Invoke ( const XMLElement& _node,
413 const Module& _module );
414
415 void ProcessXML();
416 void GetTargets ( string_list& targets ) const;
417 std::string GetParameters () const;
418 private:
419 void ProcessXMLSubElement ( const XMLElement& e );
420 void ProcessXMLSubElementInput ( const XMLElement& e );
421 void ProcessXMLSubElementOutput ( const XMLElement& e );
422 };
423
424
425 class InvokeFile
426 {
427 public:
428 const XMLElement& node;
429 std::string name;
430 std::string switches;
431
432 InvokeFile ( const XMLElement& _node,
433 const std::string& _name );
434
435 void ProcessXML ();
436 };
437
438
439 class Dependency
440 {
441 public:
442 const XMLElement& node;
443 const Module& module;
444 const Module* dependencyModule;
445
446 Dependency ( const XMLElement& _node,
447 const Module& _module );
448
449 void ProcessXML();
450 };
451
452
453 class ImportLibrary
454 {
455 public:
456 const XMLElement& node;
457 const Module& module;
458 std::string basename;
459 std::string definition;
460
461 ImportLibrary ( const XMLElement& _node,
462 const Module& module );
463
464 void ProcessXML ();
465 };
466
467
468 class If
469 {
470 public:
471 const XMLElement& node;
472 const Project& project;
473 const Module* module;
474 const bool negated;
475 std::string property, value;
476 IfableData data;
477
478 If ( const XMLElement& node_,
479 const Project& project_,
480 const Module* module_,
481 const bool negated_ = false );
482 ~If();
483
484 void ProcessXML();
485 };
486
487
488 class CompilerFlag
489 {
490 public:
491 const Project& project;
492 const Module* module;
493 const XMLElement& node;
494 std::string flag;
495
496 CompilerFlag ( const Project& project,
497 const XMLElement& compilerFlagNode );
498 CompilerFlag ( const Project& project,
499 const Module* module,
500 const XMLElement& compilerFlagNode );
501 ~CompilerFlag ();
502 void ProcessXML();
503 private:
504 void Initialize();
505 };
506
507
508 class LinkerFlag
509 {
510 public:
511 const Project& project;
512 const Module* module;
513 const XMLElement& node;
514 std::string flag;
515
516 LinkerFlag ( const Project& project,
517 const XMLElement& linkerFlagNode );
518 LinkerFlag ( const Project& project,
519 const Module* module,
520 const XMLElement& linkerFlagNode );
521 ~LinkerFlag ();
522 void ProcessXML();
523 private:
524 void Initialize();
525 };
526
527
528 class LinkerScript
529 {
530 public:
531 const Project& project;
532 const Module* module;
533 const XMLElement& node;
534 const Module* baseModule;
535 std::string directory;
536 std::string basePath;
537
538 LinkerScript ( const Project& project,
539 const Module* module,
540 const XMLElement& node );
541 ~LinkerScript ();
542 void ProcessXML();
543 };
544
545
546 class Property
547 {
548 public:
549 const XMLElement& node;
550 const Project& project;
551 const Module* module;
552 std::string name, value;
553
554 Property ( const XMLElement& node_,
555 const Project& project_,
556 const Module* module_ );
557
558 void ProcessXML();
559 };
560
561
562 class TestSupportCode
563 {
564 public:
565 const Project& project;
566
567 TestSupportCode ( const Project& project );
568 ~TestSupportCode ();
569 void GenerateTestSupportCode ( bool verbose );
570 private:
571 bool IsTestModule ( const Module& module );
572 void GenerateTestSupportCodeForModule ( Module& module,
573 bool verbose );
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,
585 int stubIndex );
586 char* WriteStubbedComponentToStubsFile ( char* buffer,
587 const StubbedComponent& component,
588 int* stubIndex );
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,
597 Module& module );
598 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer,
599 Module& module );
600 void WriteStartupFile ( Module& module );
601 };
602
603
604 class WineResource
605 {
606 public:
607 const Project& project;
608 std::string bin2res;
609
610 WineResource ( const Project& project,
611 std::string bin2res );
612 ~WineResource ();
613 void UnpackResources ( bool verbose );
614 private:
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,
620 bool verbose );
621 };
622
623
624 class SourceFile
625 {
626 public:
627 SourceFile ( AutomaticDependency* automaticDependency,
628 const Module& module,
629 const std::string& filename,
630 SourceFile* parent,
631 bool isNonAutomaticDependency );
632 SourceFile* ParseFile ( const std::string& normalizedFilename );
633 void Parse ();
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;
647 private:
648 void GetDirectoryAndFilenameParts ();
649 void Close ();
650 void Open ();
651 void SkipWhitespace ();
652 bool ReadInclude ( std::string& filename,
653 bool& searchCurrentDirectory,
654 bool& includeNext );
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 );
660 std::string buf;
661 const char *p;
662 const char *end;
663 };
664
665
666 class AutomaticDependency
667 {
668 friend class SourceFileTest;
669 public:
670 const Project& project;
671
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,
682 bool includeNext,
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,
690 bool verbose );
691 private:
692 void GetModulesToCheck ( Module& module, std::vector<const Module*>& modules );
693 void CheckAutomaticDependencies ( const Module& module,
694 bool verbose );
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;
702 void ParseFiles ();
703 void ParseFiles ( const Module& module );
704 void ParseFile ( const Module& module,
705 const File& file );
706 std::map<std::string, SourceFile*> sourcefile_map;
707 };
708
709
710 class Bootstrap
711 {
712 public:
713 const Project& project;
714 const Module* module;
715 const XMLElement& node;
716 std::string base;
717 std::string nameoncd;
718
719 Bootstrap ( const Project& project,
720 const Module* module,
721 const XMLElement& bootstrapNode );
722 ~Bootstrap ();
723 void ProcessXML();
724 private:
725 bool IsSupportedModuleType ( ModuleType type );
726 void Initialize();
727 };
728
729
730 class CDFile
731 {
732 public:
733 const Project& project;
734 const XMLElement& node;
735 std::string name;
736 std::string base;
737 std::string nameoncd;
738 std::string path;
739
740 CDFile ( const Project& project,
741 const XMLElement& bootstrapNode,
742 const std::string& path );
743 ~CDFile ();
744 void ProcessXML();
745 std::string GetPath () const;
746 };
747
748
749 class InstallFile
750 {
751 public:
752 const Project& project;
753 const XMLElement& node;
754 std::string name;
755 std::string base;
756 std::string newname;
757 std::string path;
758
759 InstallFile ( const Project& project,
760 const XMLElement& bootstrapNode,
761 const std::string& path );
762 ~InstallFile ();
763 void ProcessXML ();
764 std::string GetPath () const;
765 };
766
767
768 class PchFile
769 {
770 public:
771 const XMLElement& node;
772 const Module& module;
773 File file;
774
775 PchFile (
776 const XMLElement& node,
777 const Module& module,
778 const File file );
779 void ProcessXML();
780 };
781
782
783 class StubbedComponent
784 {
785 public:
786 const Module* module;
787 const XMLElement& node;
788 std::string name;
789 std::vector<StubbedSymbol*> symbols;
790
791 StubbedComponent ( const Module* module_,
792 const XMLElement& stubbedComponentNode );
793 ~StubbedComponent ();
794 void ProcessXML ();
795 void ProcessXMLSubElement ( const XMLElement& e );
796 };
797
798
799 class StubbedSymbol
800 {
801 public:
802 const XMLElement& node;
803 std::string symbol;
804 std::string newname;
805 std::string strippedName;
806
807 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
808 ~StubbedSymbol ();
809 void ProcessXML();
810 private:
811 std::string StripSymbol ( std::string symbol );
812 };
813
814
815 class CompilationUnit
816 {
817 public:
818 const Project* project;
819 const Module* module;
820 const XMLElement* node;
821 std::string name;
822 std::vector<File*> files;
823
824 CompilationUnit ( File* file );
825 CompilationUnit ( const Project* project,
826 const Module* module,
827 const XMLElement* node );
828 ~CompilationUnit ();
829 void ProcessXML();
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;
835 };
836
837
838 class CompilationUnitSupportCode
839 {
840 public:
841 const Project& project;
842
843 CompilationUnitSupportCode ( const Project& project );
844 ~CompilationUnitSupportCode ();
845 void Generate ( bool verbose );
846 private:
847 void GenerateForModule ( Module& module,
848 bool verbose );
849 std::string GetCompilationUnitFilename ( Module& module,
850 CompilationUnit& compilationUnit );
851 void WriteCompilationUnitFile ( Module& module,
852 CompilationUnit& compilationUnit );
853 };
854
855
856 class FileLocation
857 {
858 public:
859 Directory* directory;
860 std::string filename;
861 FileLocation ( Directory* directory,
862 std::string filename );
863 };
864
865
866 extern void
867 InitializeEnvironment ();
868
869 extern std::string
870 Right ( const std::string& s, size_t n );
871
872 extern std::string
873 Replace ( const std::string& s, const std::string& find, const std::string& with );
874
875 extern std::string
876 FixSeparator ( const std::string& s );
877
878 extern std::string
879 FixSeparatorForSystemCommand ( const std::string& s );
880
881 extern std::string
882 DosSeparator ( const std::string& s );
883
884 extern std::string
885 ReplaceExtension (
886 const std::string& filename,
887 const std::string& newExtension );
888
889 extern std::string
890 GetSubPath (
891 const std::string& location,
892 const std::string& path,
893 const std::string& att_value );
894
895 extern std::string
896 GetExtension ( const std::string& filename );
897
898 extern std::string
899 GetDirectory ( const std::string& filename );
900
901 extern std::string
902 GetFilename ( const std::string& filename );
903
904 extern std::string
905 NormalizeFilename ( const std::string& filename );
906
907 #endif /* __RBUILD_H */