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