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