Build and run tests
[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
282 File ( const std::string& _name,
283 bool _first,
284 std::string _switches );
285
286 void ProcessXML();
287 bool IsGeneratedFile () const;
288 };
289
290
291 class Library
292 {
293 public:
294 const XMLElement& node;
295 const Module& module;
296 std::string name;
297 const Module* imported_module;
298
299 Library ( const XMLElement& _node,
300 const Module& _module,
301 const std::string& _name );
302
303 void ProcessXML();
304 };
305
306
307 class Invoke
308 {
309 public:
310 const XMLElement& node;
311 const Module& module;
312 const Module* invokeModule;
313 std::vector<InvokeFile*> input;
314 std::vector<InvokeFile*> output;
315
316 Invoke ( const XMLElement& _node,
317 const Module& _module );
318
319 void ProcessXML();
320 void GetTargets ( string_list& targets ) const;
321 std::string GetParameters () const;
322 private:
323 void ProcessXMLSubElement ( const XMLElement& e );
324 void ProcessXMLSubElementInput ( const XMLElement& e );
325 void ProcessXMLSubElementOutput ( const XMLElement& e );
326 };
327
328
329 class InvokeFile
330 {
331 public:
332 const XMLElement& node;
333 std::string name;
334 std::string switches;
335
336 InvokeFile ( const XMLElement& _node,
337 const std::string& _name );
338
339 void ProcessXML ();
340 };
341
342
343 class Dependency
344 {
345 public:
346 const XMLElement& node;
347 const Module& module;
348 const Module* dependencyModule;
349
350 Dependency ( const XMLElement& _node,
351 const Module& _module );
352
353 void ProcessXML();
354 };
355
356
357 class ImportLibrary
358 {
359 public:
360 const XMLElement& node;
361 const Module& module;
362 std::string basename;
363 std::string definition;
364
365 ImportLibrary ( const XMLElement& _node,
366 const Module& module );
367
368 void ProcessXML ();
369 };
370
371
372 class If
373 {
374 public:
375 const XMLElement& node;
376 const Project& project;
377 const Module* module;
378 std::string property, value;
379 IfableData data;
380
381 If ( const XMLElement& node_,
382 const Project& project_,
383 const Module* module_ );
384 ~If();
385
386 void ProcessXML();
387 };
388
389
390 class CompilerFlag
391 {
392 public:
393 const Project& project;
394 const Module* module;
395 const XMLElement& node;
396 std::string flag;
397
398 CompilerFlag ( const Project& project,
399 const XMLElement& compilerFlagNode );
400 CompilerFlag ( const Project& project,
401 const Module* module,
402 const XMLElement& compilerFlagNode );
403 ~CompilerFlag ();
404 void ProcessXML();
405 private:
406 void Initialize();
407 };
408
409
410 class LinkerFlag
411 {
412 public:
413 const Project& project;
414 const Module* module;
415 const XMLElement& node;
416 std::string flag;
417
418 LinkerFlag ( const Project& project,
419 const XMLElement& linkerFlagNode );
420 LinkerFlag ( const Project& project,
421 const Module* module,
422 const XMLElement& linkerFlagNode );
423 ~LinkerFlag ();
424 void ProcessXML();
425 private:
426 void Initialize();
427 };
428
429
430 class Property
431 {
432 public:
433 const XMLElement& node;
434 const Project& project;
435 const Module* module;
436 std::string name, value;
437
438 Property ( const XMLElement& node_,
439 const Project& project_,
440 const Module* module_ );
441
442 void ProcessXML();
443 };
444
445
446 class TestSupportCode
447 {
448 public:
449 const Project& project;
450
451 TestSupportCode ( const Project& project );
452 ~TestSupportCode ();
453 void GenerateTestSupportCode ( bool verbose );
454 private:
455 bool IsTestModule ( const Module& module );
456 void GenerateTestSupportCodeForModule ( Module& module,
457 bool verbose );
458 std::string GetHooksFilename ( Module& module );
459 char* WriteStubbedSymbolToHooksFile ( char* buffer,
460 const StubbedComponent& component,
461 const StubbedSymbol& symbol );
462 char* WriteStubbedComponentToHooksFile ( char* buffer,
463 const StubbedComponent& component );
464 void WriteHooksFile ( Module& module );
465 std::string GetStubsFilename ( Module& module );
466 char* WriteStubbedSymbolToStubsFile ( char* buffer,
467 const StubbedComponent& component,
468 const StubbedSymbol& symbol,
469 int stubIndex );
470 char* WriteStubbedComponentToStubsFile ( char* buffer,
471 const StubbedComponent& component,
472 int* stubIndex );
473 void WriteStubsFile ( Module& module );
474 std::string GetStartupFilename ( Module& module );
475 std::string GetTestDispatcherName ( std::string filename );
476 bool IsTestFile ( std::string& filename ) const;
477 void GetSourceFilenames ( string_list& list,
478 Module& module ) const;
479 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer,
480 Module& module );
481 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer,
482 Module& module );
483 void WriteStartupFile ( Module& module );
484 };
485
486
487 class WineResource
488 {
489 public:
490 const Project& project;
491 std::string bin2res;
492
493 WineResource ( const Project& project,
494 std::string bin2res );
495 ~WineResource ();
496 void UnpackResources ( bool verbose );
497 private:
498 bool IsSpecFile ( const File& file );
499 bool IsWineModule ( const Module& module );
500 bool IsResourceFile ( const File& file );
501 std::string GetResourceFilename ( const Module& module );
502 void UnpackResourcesInModule ( Module& module,
503 bool verbose );
504 };
505
506
507 class SourceFile
508 {
509 public:
510 SourceFile ( AutomaticDependency* automaticDependency,
511 Module& module,
512 const std::string& filename,
513 SourceFile* parent,
514 bool isNonAutomaticDependency );
515 SourceFile* ParseFile ( const std::string& normalizedFilename );
516 void Parse ();
517 std::string Location () const;
518 std::vector<SourceFile*> files;
519 AutomaticDependency* automaticDependency;
520 Module& module;
521 std::string filename;
522 std::string filenamePart;
523 std::string directoryPart;
524 std::vector<SourceFile*> parents; /* List of files, this file is included from */
525 bool isNonAutomaticDependency;
526 std::string cachedDependencies;
527 time_t lastWriteTime;
528 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
529 SourceFile* youngestFile;
530 private:
531 void GetDirectoryAndFilenameParts ();
532 void Close ();
533 void Open ();
534 void SkipWhitespace ();
535 bool ReadInclude ( std::string& filename,
536 bool& includeNext );
537 bool IsIncludedFrom ( const std::string& normalizedFilename );
538 SourceFile* GetParentSourceFile ();
539 bool CanProcessFile ( const std::string& extension );
540 bool IsParentOf ( const SourceFile* parent,
541 const SourceFile* child );
542 std::string buf;
543 const char *p;
544 const char *end;
545 };
546
547
548 class AutomaticDependency
549 {
550 friend class SourceFileTest;
551 public:
552 const Project& project;
553
554 AutomaticDependency ( const Project& project );
555 ~AutomaticDependency ();
556 void Process ();
557 std::string GetFilename ( const std::string& filename );
558 bool LocateIncludedFile ( const std::string& directory,
559 const std::string& includedFilename,
560 std::string& resolvedFilename );
561 bool LocateIncludedFile ( SourceFile* sourceFile,
562 Module& module,
563 const std::string& includedFilename,
564 bool includeNext,
565 std::string& resolvedFilename );
566 SourceFile* RetrieveFromCacheOrParse ( Module& module,
567 const std::string& filename,
568 SourceFile* parentSourceFile );
569 SourceFile* RetrieveFromCache ( const std::string& filename );
570 void CheckAutomaticDependencies ( bool verbose );
571 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
572 private:
573 void ProcessModule ( Module& module );
574 void ProcessFile ( Module& module,
575 const File& file );
576 std::map<std::string, SourceFile*> sourcefile_map;
577 };
578
579
580 class Bootstrap
581 {
582 public:
583 const Project& project;
584 const Module* module;
585 const XMLElement& node;
586 std::string base;
587 std::string nameoncd;
588
589 Bootstrap ( const Project& project,
590 const Module* module,
591 const XMLElement& bootstrapNode );
592 ~Bootstrap ();
593 void ProcessXML();
594 private:
595 bool IsSupportedModuleType ( ModuleType type );
596 void Initialize();
597 };
598
599
600 class CDFile
601 {
602 public:
603 const Project& project;
604 const XMLElement& node;
605 std::string name;
606 std::string base;
607 std::string nameoncd;
608 std::string path;
609
610 CDFile ( const Project& project,
611 const XMLElement& bootstrapNode,
612 const std::string& path );
613 ~CDFile ();
614 void ProcessXML();
615 std::string GetPath () const;
616 };
617
618
619 class InstallFile
620 {
621 public:
622 const Project& project;
623 const XMLElement& node;
624 std::string name;
625 std::string base;
626 std::string newname;
627 std::string path;
628
629 InstallFile ( const Project& project,
630 const XMLElement& bootstrapNode,
631 const std::string& path );
632 ~InstallFile ();
633 void ProcessXML ();
634 std::string GetPath () const;
635 };
636
637
638 class PchFile
639 {
640 public:
641 const XMLElement& node;
642 const Module& module;
643 std::string header;
644
645 PchFile (
646 const XMLElement& node,
647 const Module& module,
648 const std::string& header );
649 void ProcessXML();
650 };
651
652
653 class StubbedComponent
654 {
655 public:
656 const Module* module;
657 const XMLElement& node;
658 std::string name;
659 std::vector<StubbedSymbol*> symbols;
660
661 StubbedComponent ( const Module* module_,
662 const XMLElement& stubbedComponentNode );
663 ~StubbedComponent ();
664 void ProcessXML ();
665 void ProcessXMLSubElement ( const XMLElement& e );
666 };
667
668
669 class StubbedSymbol
670 {
671 public:
672 const XMLElement& node;
673 std::string symbol;
674 std::string newname;
675 std::string strippedName;
676
677 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
678 ~StubbedSymbol ();
679 void ProcessXML();
680 private:
681 std::string StripSymbol ( std::string symbol );
682 };
683
684 extern std::string
685 FixSeparator ( const std::string& s );
686
687 extern std::string
688 ReplaceExtension (
689 const std::string& filename,
690 const std::string& newExtension );
691
692 extern std::string
693 GetSubPath (
694 const std::string& location,
695 const std::string& path,
696 const std::string& att_value );
697
698 extern std::string
699 GetExtension ( const std::string& filename );
700
701 extern std::string
702 GetDirectory ( const std::string& filename );
703
704 extern std::string
705 GetFilename ( const std::string& filename );
706
707 extern std::string
708 NormalizeFilename ( const std::string& filename );
709
710 #endif /* __RBUILD_H */