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