Generate proxy makefiles in output tree.
[reactos.git] / reactos / tools / rbuild / rbuild.h
1 #ifndef __RBUILD_H
2 #define __RBUILD_H
3
4 #include "pch.h"
5
6 #ifdef WIN32
7 #include <direct.h>
8 #include <io.h>
9 #endif/*WIN32*/
10 #include <sys/stat.h>
11 #include <time.h>
12 #ifdef _MSC_VER
13 #include <sys/utime.h>
14 #else/*_MSC_VER*/
15 #include <utime.h>
16 #ifdef WIN32
17 #include <process.h>
18 #endif/*WIN32*/
19 #endif/*_MSC_VER*/
20
21 #include "ssprintf.h"
22 #include "exception.h"
23 #include "XML.h"
24
25 typedef std::vector<std::string> string_list;
26
27 #ifdef WIN32
28 #define EXEPREFIX ""
29 #define EXEPOSTFIX ".exe"
30 #define CSEP '\\'
31 #define CBAD_SEP '/'
32 #define SSEP "\\"
33 #define SBAD_SEP "/"
34 #else
35 #define EXEPREFIX "./"
36 #define EXEPOSTFIX ""
37 #define CSEP '/'
38 #define CBAD_SEP '\\'
39 #define SSEP "/"
40 #define SBAD_SEP "\\"
41 #endif
42
43 class Project;
44 class IfableData;
45 class Module;
46 class Include;
47 class Define;
48 class File;
49 class Library;
50 class Invoke;
51 class InvokeFile;
52 class Dependency;
53 class ImportLibrary;
54 class If;
55 class CompilerFlag;
56 class LinkerFlag;
57 class Property;
58 class TestSupportCode;
59 class WineResource;
60 class AutomaticDependency;
61 class Bootstrap;
62 class CDFile;
63 class InstallFile;
64 class PchFile;
65 class StubbedComponent;
66 class StubbedSymbol;
67
68 class SourceFileTest;
69
70
71 class Configuration
72 {
73 public:
74 Configuration ();
75 ~Configuration ();
76 bool Verbose;
77 bool CleanAsYouGo;
78 bool AutomaticDependencies;
79 bool MakeHandlesInstallDirectories;
80 bool GenerateProxyMakefilesInSourceTree;
81 };
82
83 class Environment
84 {
85 public:
86 static std::string GetVariable ( const std::string& name );
87 static std::string GetIntermediatePath ();
88 static std::string GetOutputPath ();
89 static std::string GetInstallPath ();
90 static std::string GetEnvironmentVariablePathOrDefault ( const std::string& name,
91 const std::string& defaultValue );
92 };
93
94 class FileSupportCode
95 {
96 public:
97 static void WriteIfChanged ( char* outbuf,
98 std::string filename );
99 };
100
101 class IfableData
102 {
103 public:
104 std::vector<File*> files;
105 std::vector<Include*> includes;
106 std::vector<Define*> defines;
107 std::vector<Library*> libraries;
108 std::vector<Property*> properties;
109 std::vector<CompilerFlag*> compilerFlags;
110 std::vector<If*> ifs;
111
112 ~IfableData();
113 void ProcessXML();
114 };
115
116 class Project
117 {
118 std::string xmlfile;
119 XMLElement *node, *head;
120 public:
121 std::string name;
122 std::string makefile;
123 XMLIncludes xmlbuildfiles;
124 std::vector<Module*> modules;
125 std::vector<LinkerFlag*> linkerFlags;
126 std::vector<CDFile*> cdfiles;
127 std::vector<InstallFile*> installfiles;
128 IfableData non_if_data;
129
130 Project ( const std::string& filename );
131 ~Project ();
132 void WriteConfigurationFile ();
133 void ExecuteInvocations ();
134 void ProcessXML ( const std::string& path );
135 Module* LocateModule ( const std::string& name );
136 const Module* LocateModule ( const std::string& name ) const;
137 std::string GetProjectFilename () const;
138 std::string ResolveProperties ( const std::string& s ) const;
139 private:
140 std::string ResolveNextProperty ( std::string& s ) const;
141 const Property* LookupProperty ( const std::string& name ) const;
142 void SetConfigurationOption ( char* s,
143 std::string name,
144 std::string* alternativeName );
145 void SetConfigurationOption ( char* s,
146 std::string name );
147 void ReadXml ();
148 void ProcessXMLSubElement ( const XMLElement& e,
149 const std::string& path,
150 If* pIf = NULL );
151
152 // disable copy semantics
153 Project ( const Project& );
154 Project& operator = ( const Project& );
155 };
156
157
158 enum ModuleType
159 {
160 BuildTool = 0,
161 StaticLibrary = 1,
162 ObjectLibrary = 2,
163 Kernel = 3,
164 KernelModeDLL = 4,
165 KernelModeDriver = 5,
166 NativeDLL = 6,
167 NativeCUI = 7,
168 Win32DLL = 8,
169 Win32CUI = 9,
170 Win32GUI = 10,
171 BootLoader = 11,
172 BootSector = 12,
173 Iso = 13,
174 LiveIso = 14,
175 Test = 15,
176 RpcServer = 16,
177 RpcClient = 17
178 };
179
180 enum HostType
181 {
182 HostFalse,
183 HostDefault,
184 HostTrue
185 };
186
187 class Module
188 {
189 public:
190 const Project& project;
191 const XMLElement& node;
192 std::string xmlbuildFile;
193 std::string name;
194 std::string extension;
195 std::string entrypoint;
196 std::string baseaddress;
197 std::string path;
198 ModuleType type;
199 ImportLibrary* importLibrary;
200 bool mangledSymbols;
201 Bootstrap* bootstrap;
202 IfableData non_if_data;
203 std::vector<Invoke*> invocations;
204 std::vector<Dependency*> dependencies;
205 std::vector<CompilerFlag*> compilerFlags;
206 std::vector<LinkerFlag*> linkerFlags;
207 std::vector<StubbedComponent*> stubbedComponents;
208 PchFile* pch;
209 bool cplusplus;
210 std::string prefix;
211 HostType host;
212 std::string installBase;
213 std::string installName;
214 bool useWRC;
215 bool enableWarnings;
216 bool enabled;
217
218 Module ( const Project& project,
219 const XMLElement& moduleNode,
220 const std::string& modulePath );
221 ~Module ();
222 ModuleType GetModuleType ( const std::string& location,
223 const XMLAttribute& attribute );
224 bool HasImportLibrary () const;
225 bool IsDLL () const;
226 bool GenerateInOutputTree () const;
227 std::string GetTargetName () const;
228 std::string GetDependencyPath () const;
229 std::string GetBasePath () const;
230 std::string GetPath () const;
231 std::string GetPathWithPrefix ( const std::string& prefix ) const;
232 void GetTargets ( string_list& ) const;
233 std::string GetInvocationTarget ( const int index ) const;
234 bool HasFileWithExtension ( const IfableData&, const std::string& extension ) const;
235 void InvokeModule () const;
236 void ProcessXML ();
237 void GetSourceFilenames ( string_list& list,
238 bool includeGeneratedFiles ) const;
239 private:
240 std::string GetDefaultModuleExtension () const;
241 std::string GetDefaultModuleEntrypoint () const;
242 std::string GetDefaultModuleBaseaddress () const;
243 void ProcessXMLSubElement ( const XMLElement& e,
244 const std::string& path,
245 If* pIf = NULL );
246 };
247
248
249 class Include
250 {
251 public:
252 const Project& project;
253 const Module* module;
254 const XMLElement& node;
255 std::string directory;
256 std::string basePath;
257
258 Include ( const Project& project,
259 const XMLElement& includeNode );
260 Include ( const Project& project,
261 const Module* module,
262 const XMLElement& includeNode );
263 ~Include ();
264 void ProcessXML();
265 private:
266 void Initialize();
267 };
268
269
270 class Define
271 {
272 public:
273 const Project& project;
274 const Module* module;
275 const XMLElement& node;
276 std::string name;
277 std::string value;
278
279 Define ( const Project& project,
280 const XMLElement& defineNode );
281 Define ( const Project& project,
282 const Module* module,
283 const XMLElement& defineNode );
284 ~Define();
285 void ProcessXML();
286 private:
287 void Initialize();
288 };
289
290
291 class File
292 {
293 public:
294 std::string name;
295 bool first;
296 std::string switches;
297 bool isPreCompiledHeader;
298
299 File ( const std::string& _name,
300 bool _first,
301 std::string _switches,
302 bool _isPreCompiledHeader );
303
304 void ProcessXML();
305 bool IsGeneratedFile () const;
306 };
307
308
309 class Library
310 {
311 public:
312 const XMLElement& node;
313 const Module& module;
314 std::string name;
315 const Module* imported_module;
316
317 Library ( const XMLElement& _node,
318 const Module& _module,
319 const std::string& _name );
320
321 void ProcessXML();
322 };
323
324
325 class Invoke
326 {
327 public:
328 const XMLElement& node;
329 const Module& module;
330 const Module* invokeModule;
331 std::vector<InvokeFile*> input;
332 std::vector<InvokeFile*> output;
333
334 Invoke ( const XMLElement& _node,
335 const Module& _module );
336
337 void ProcessXML();
338 void GetTargets ( string_list& targets ) const;
339 std::string GetParameters () const;
340 private:
341 void ProcessXMLSubElement ( const XMLElement& e );
342 void ProcessXMLSubElementInput ( const XMLElement& e );
343 void ProcessXMLSubElementOutput ( const XMLElement& e );
344 };
345
346
347 class InvokeFile
348 {
349 public:
350 const XMLElement& node;
351 std::string name;
352 std::string switches;
353
354 InvokeFile ( const XMLElement& _node,
355 const std::string& _name );
356
357 void ProcessXML ();
358 };
359
360
361 class Dependency
362 {
363 public:
364 const XMLElement& node;
365 const Module& module;
366 const Module* dependencyModule;
367
368 Dependency ( const XMLElement& _node,
369 const Module& _module );
370
371 void ProcessXML();
372 };
373
374
375 class ImportLibrary
376 {
377 public:
378 const XMLElement& node;
379 const Module& module;
380 std::string basename;
381 std::string definition;
382
383 ImportLibrary ( const XMLElement& _node,
384 const Module& module );
385
386 void ProcessXML ();
387 };
388
389
390 class If
391 {
392 public:
393 const XMLElement& node;
394 const Project& project;
395 const Module* module;
396 std::string property, value;
397 IfableData data;
398
399 If ( const XMLElement& node_,
400 const Project& project_,
401 const Module* module_ );
402 ~If();
403
404 void ProcessXML();
405 };
406
407
408 class CompilerFlag
409 {
410 public:
411 const Project& project;
412 const Module* module;
413 const XMLElement& node;
414 std::string flag;
415
416 CompilerFlag ( const Project& project,
417 const XMLElement& compilerFlagNode );
418 CompilerFlag ( const Project& project,
419 const Module* module,
420 const XMLElement& compilerFlagNode );
421 ~CompilerFlag ();
422 void ProcessXML();
423 private:
424 void Initialize();
425 };
426
427
428 class LinkerFlag
429 {
430 public:
431 const Project& project;
432 const Module* module;
433 const XMLElement& node;
434 std::string flag;
435
436 LinkerFlag ( const Project& project,
437 const XMLElement& linkerFlagNode );
438 LinkerFlag ( const Project& project,
439 const Module* module,
440 const XMLElement& linkerFlagNode );
441 ~LinkerFlag ();
442 void ProcessXML();
443 private:
444 void Initialize();
445 };
446
447
448 class Property
449 {
450 public:
451 const XMLElement& node;
452 const Project& project;
453 const Module* module;
454 std::string name, value;
455
456 Property ( const XMLElement& node_,
457 const Project& project_,
458 const Module* module_ );
459
460 void ProcessXML();
461 };
462
463
464 class TestSupportCode
465 {
466 public:
467 const Project& project;
468
469 TestSupportCode ( const Project& project );
470 ~TestSupportCode ();
471 void GenerateTestSupportCode ( bool verbose );
472 private:
473 bool IsTestModule ( const Module& module );
474 void GenerateTestSupportCodeForModule ( Module& module,
475 bool verbose );
476 std::string GetHooksFilename ( Module& module );
477 char* WriteStubbedSymbolToHooksFile ( char* buffer,
478 const StubbedComponent& component,
479 const StubbedSymbol& symbol );
480 char* WriteStubbedComponentToHooksFile ( char* buffer,
481 const StubbedComponent& component );
482 void WriteHooksFile ( Module& module );
483 std::string GetStubsFilename ( Module& module );
484 char* WriteStubbedSymbolToStubsFile ( char* buffer,
485 const StubbedComponent& component,
486 const StubbedSymbol& symbol,
487 int stubIndex );
488 char* WriteStubbedComponentToStubsFile ( char* buffer,
489 const StubbedComponent& component,
490 int* stubIndex );
491 void WriteStubsFile ( Module& module );
492 std::string GetStartupFilename ( Module& module );
493 std::string GetTestDispatcherName ( std::string filename );
494 bool IsTestFile ( std::string& filename ) const;
495 void GetSourceFilenames ( string_list& list,
496 Module& module ) const;
497 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer,
498 Module& module );
499 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer,
500 Module& module );
501 void WriteStartupFile ( Module& module );
502 };
503
504
505 class WineResource
506 {
507 public:
508 const Project& project;
509 std::string bin2res;
510
511 WineResource ( const Project& project,
512 std::string bin2res );
513 ~WineResource ();
514 void UnpackResources ( bool verbose );
515 private:
516 bool IsSpecFile ( const File& file );
517 bool IsWineModule ( const Module& module );
518 bool IsResourceFile ( const File& file );
519 std::string GetResourceFilename ( const Module& module );
520 void UnpackResourcesInModule ( Module& module,
521 bool verbose );
522 };
523
524
525 class SourceFile
526 {
527 public:
528 SourceFile ( AutomaticDependency* automaticDependency,
529 Module& module,
530 const std::string& filename,
531 SourceFile* parent,
532 bool isNonAutomaticDependency );
533 SourceFile* ParseFile ( const std::string& normalizedFilename );
534 void Parse ();
535 std::string Location () const;
536 std::vector<SourceFile*> files;
537 AutomaticDependency* automaticDependency;
538 Module& module;
539 std::string filename;
540 std::string filenamePart;
541 std::string directoryPart;
542 std::vector<SourceFile*> parents; /* List of files, this file is included from */
543 bool isNonAutomaticDependency;
544 std::string cachedDependencies;
545 time_t lastWriteTime;
546 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
547 SourceFile* youngestFile;
548 private:
549 void GetDirectoryAndFilenameParts ();
550 void Close ();
551 void Open ();
552 void SkipWhitespace ();
553 bool ReadInclude ( std::string& filename,
554 bool& includeNext );
555 bool IsIncludedFrom ( const std::string& normalizedFilename );
556 SourceFile* GetParentSourceFile ();
557 bool CanProcessFile ( const std::string& extension );
558 bool IsParentOf ( const SourceFile* parent,
559 const SourceFile* child );
560 std::string buf;
561 const char *p;
562 const char *end;
563 };
564
565
566 class AutomaticDependency
567 {
568 friend class SourceFileTest;
569 public:
570 const Project& project;
571
572 AutomaticDependency ( const Project& project );
573 ~AutomaticDependency ();
574 void Process ();
575 std::string GetFilename ( const std::string& filename );
576 bool LocateIncludedFile ( const std::string& directory,
577 const std::string& includedFilename,
578 std::string& resolvedFilename );
579 bool LocateIncludedFile ( SourceFile* sourceFile,
580 Module& module,
581 const std::string& includedFilename,
582 bool includeNext,
583 std::string& resolvedFilename );
584 SourceFile* RetrieveFromCacheOrParse ( Module& module,
585 const std::string& filename,
586 SourceFile* parentSourceFile );
587 SourceFile* RetrieveFromCache ( const std::string& filename );
588 void CheckAutomaticDependencies ( bool verbose );
589 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
590 private:
591 void GetModuleFiles ( Module& module,
592 std::vector<File*>& files ) const;
593 void ProcessModule ( Module& module );
594 void ProcessFile ( Module& module,
595 const File& file );
596 std::map<std::string, SourceFile*> sourcefile_map;
597 };
598
599
600 class Bootstrap
601 {
602 public:
603 const Project& project;
604 const Module* module;
605 const XMLElement& node;
606 std::string base;
607 std::string nameoncd;
608
609 Bootstrap ( const Project& project,
610 const Module* module,
611 const XMLElement& bootstrapNode );
612 ~Bootstrap ();
613 void ProcessXML();
614 private:
615 bool IsSupportedModuleType ( ModuleType type );
616 void Initialize();
617 };
618
619
620 class CDFile
621 {
622 public:
623 const Project& project;
624 const XMLElement& node;
625 std::string name;
626 std::string base;
627 std::string nameoncd;
628 std::string path;
629
630 CDFile ( const Project& project,
631 const XMLElement& bootstrapNode,
632 const std::string& path );
633 ~CDFile ();
634 void ProcessXML();
635 std::string GetPath () const;
636 };
637
638
639 class InstallFile
640 {
641 public:
642 const Project& project;
643 const XMLElement& node;
644 std::string name;
645 std::string base;
646 std::string newname;
647 std::string path;
648
649 InstallFile ( const Project& project,
650 const XMLElement& bootstrapNode,
651 const std::string& path );
652 ~InstallFile ();
653 void ProcessXML ();
654 std::string GetPath () const;
655 };
656
657
658 class PchFile
659 {
660 public:
661 const XMLElement& node;
662 const Module& module;
663 File file;
664
665 PchFile (
666 const XMLElement& node,
667 const Module& module,
668 const File file );
669 void ProcessXML();
670 };
671
672
673 class StubbedComponent
674 {
675 public:
676 const Module* module;
677 const XMLElement& node;
678 std::string name;
679 std::vector<StubbedSymbol*> symbols;
680
681 StubbedComponent ( const Module* module_,
682 const XMLElement& stubbedComponentNode );
683 ~StubbedComponent ();
684 void ProcessXML ();
685 void ProcessXMLSubElement ( const XMLElement& e );
686 };
687
688
689 class StubbedSymbol
690 {
691 public:
692 const XMLElement& node;
693 std::string symbol;
694 std::string newname;
695 std::string strippedName;
696
697 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
698 ~StubbedSymbol ();
699 void ProcessXML();
700 private:
701 std::string StripSymbol ( std::string symbol );
702 };
703
704 extern std::string
705 FixSeparator ( const std::string& s );
706
707 extern std::string
708 ReplaceExtension (
709 const std::string& filename,
710 const std::string& newExtension );
711
712 extern std::string
713 GetSubPath (
714 const std::string& location,
715 const std::string& path,
716 const std::string& att_value );
717
718 extern std::string
719 GetExtension ( const std::string& filename );
720
721 extern std::string
722 GetDirectory ( const std::string& filename );
723
724 extern std::string
725 GetFilename ( const std::string& filename );
726
727 extern std::string
728 NormalizeFilename ( const std::string& filename );
729
730 #endif /* __RBUILD_H */