Support 'make livecd'
[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
258 File ( const std::string& _name, bool _first );
259
260 void ProcessXML();
261 };
262
263
264 class Library
265 {
266 public:
267 const XMLElement& node;
268 const Module& module;
269 std::string name;
270 const Module* imported_module;
271
272 Library ( const XMLElement& _node,
273 const Module& _module,
274 const std::string& _name );
275
276 void ProcessXML();
277 };
278
279
280 class Invoke
281 {
282 public:
283 const XMLElement& node;
284 const Module& module;
285 const Module* invokeModule;
286 std::vector<InvokeFile*> input;
287 std::vector<InvokeFile*> output;
288
289 Invoke ( const XMLElement& _node,
290 const Module& _module );
291
292 void ProcessXML();
293 void GetTargets ( string_list& targets ) const;
294 std::string GetParameters () const;
295 private:
296 void ProcessXMLSubElement ( const XMLElement& e );
297 void ProcessXMLSubElementInput ( const XMLElement& e );
298 void ProcessXMLSubElementOutput ( const XMLElement& e );
299 };
300
301
302 class InvokeFile
303 {
304 public:
305 const XMLElement& node;
306 std::string name;
307 std::string switches;
308
309 InvokeFile ( const XMLElement& _node,
310 const std::string& _name );
311
312 void ProcessXML ();
313 };
314
315
316 class Dependency
317 {
318 public:
319 const XMLElement& node;
320 const Module& module;
321 const Module* dependencyModule;
322
323 Dependency ( const XMLElement& _node,
324 const Module& _module );
325
326 void ProcessXML();
327 };
328
329
330 class ImportLibrary
331 {
332 public:
333 const XMLElement& node;
334 const Module& module;
335 std::string basename;
336 std::string definition;
337
338 ImportLibrary ( const XMLElement& _node,
339 const Module& module );
340
341 void ProcessXML ();
342 };
343
344
345 class If
346 {
347 public:
348 const XMLElement& node;
349 const Project& project;
350 const Module* module;
351 std::string property, value;
352 IfableData data;
353
354 If ( const XMLElement& node_,
355 const Project& project_,
356 const Module* module_ );
357 ~If();
358
359 void ProcessXML();
360 };
361
362
363 class CompilerFlag
364 {
365 public:
366 const Project& project;
367 const Module* module;
368 const XMLElement& node;
369 std::string flag;
370
371 CompilerFlag ( const Project& project,
372 const XMLElement& compilerFlagNode );
373 CompilerFlag ( const Project& project,
374 const Module* module,
375 const XMLElement& compilerFlagNode );
376 ~CompilerFlag ();
377 void ProcessXML();
378 private:
379 void Initialize();
380 };
381
382
383 class LinkerFlag
384 {
385 public:
386 const Project& project;
387 const Module* module;
388 const XMLElement& node;
389 std::string flag;
390
391 LinkerFlag ( const Project& project,
392 const XMLElement& linkerFlagNode );
393 LinkerFlag ( const Project& project,
394 const Module* module,
395 const XMLElement& linkerFlagNode );
396 ~LinkerFlag ();
397 void ProcessXML();
398 private:
399 void Initialize();
400 };
401
402
403 class Property
404 {
405 public:
406 const XMLElement& node;
407 const Project& project;
408 const Module* module;
409 std::string name, value;
410
411 Property ( const XMLElement& node_,
412 const Project& project_,
413 const Module* module_ );
414
415 void ProcessXML();
416 };
417
418
419 class SourceFile
420 {
421 public:
422 SourceFile ( AutomaticDependency* automaticDependency,
423 Module& module,
424 const std::string& filename,
425 SourceFile* parent,
426 bool isNonAutomaticDependency );
427 SourceFile* ParseFile ( const std::string& normalizedFilename );
428 void Parse ();
429 std::string Location () const;
430 std::vector<SourceFile*> files;
431 AutomaticDependency* automaticDependency;
432 Module& module;
433 std::string filename;
434 std::string filenamePart;
435 std::string directoryPart;
436 std::vector<SourceFile*> parents; /* List of files, this file is included from */
437 bool isNonAutomaticDependency;
438 std::string cachedDependencies;
439 time_t lastWriteTime;
440 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
441 SourceFile* youngestFile;
442 private:
443 void GetDirectoryAndFilenameParts ();
444 void Close ();
445 void Open ();
446 void SkipWhitespace ();
447 bool ReadInclude ( std::string& filename,
448 bool& includeNext );
449 bool IsIncludedFrom ( const std::string& normalizedFilename );
450 SourceFile* GetParentSourceFile ();
451 bool CanProcessFile ( const std::string& extension );
452 bool IsParentOf ( const SourceFile* parent,
453 const SourceFile* child );
454 std::string buf;
455 const char *p;
456 const char *end;
457 };
458
459
460 class AutomaticDependency
461 {
462 friend class SourceFileTest;
463 public:
464 const Project& project;
465
466 AutomaticDependency ( const Project& project );
467 ~AutomaticDependency ();
468 void Process ();
469 std::string GetFilename ( const std::string& filename );
470 bool LocateIncludedFile ( const std::string& directory,
471 const std::string& includedFilename,
472 std::string& resolvedFilename );
473 bool LocateIncludedFile ( SourceFile* sourceFile,
474 Module& module,
475 const std::string& includedFilename,
476 bool includeNext,
477 std::string& resolvedFilename );
478 SourceFile* RetrieveFromCacheOrParse ( Module& module,
479 const std::string& filename,
480 SourceFile* parentSourceFile );
481 SourceFile* RetrieveFromCache ( const std::string& filename );
482 void CheckAutomaticDependencies ( bool verbose );
483 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
484 private:
485 void ProcessModule ( Module& module );
486 void ProcessFile ( Module& module,
487 const File& file );
488 std::map<std::string, SourceFile*> sourcefile_map;
489 };
490
491
492 class Bootstrap
493 {
494 public:
495 const Project& project;
496 const Module* module;
497 const XMLElement& node;
498 std::string base;
499 std::string nameoncd;
500
501 Bootstrap ( const Project& project,
502 const Module* module,
503 const XMLElement& bootstrapNode );
504 ~Bootstrap ();
505 void ProcessXML();
506 private:
507 bool IsSupportedModuleType ( ModuleType type );
508 void Initialize();
509 };
510
511
512 class CDFile
513 {
514 public:
515 const Project& project;
516 const XMLElement& node;
517 std::string name;
518 std::string base;
519 std::string nameoncd;
520 std::string path;
521
522 CDFile ( const Project& project,
523 const XMLElement& bootstrapNode,
524 const std::string& path );
525 ~CDFile ();
526 void ProcessXML();
527 std::string GetPath () const;
528 };
529
530
531 class InstallFile
532 {
533 public:
534 const Project& project;
535 const XMLElement& node;
536 std::string name;
537 std::string base;
538 std::string newname;
539 std::string path;
540
541 InstallFile ( const Project& project,
542 const XMLElement& bootstrapNode,
543 const std::string& path );
544 ~InstallFile ();
545 void ProcessXML ();
546 std::string GetPath () const;
547 };
548
549
550 class PchFile
551 {
552 public:
553 const XMLElement& node;
554 const Module& module;
555 std::string header;
556
557 PchFile (
558 const XMLElement& node,
559 const Module& module,
560 const std::string& header );
561 void ProcessXML();
562 };
563
564
565 class StubbedComponent
566 {
567 public:
568 const Module* module;
569 const XMLElement& node;
570 std::string name;
571 std::vector<StubbedSymbol*> symbols;
572
573 StubbedComponent ( const Module* module_,
574 const XMLElement& stubbedComponentNode );
575 ~StubbedComponent ();
576 void ProcessXML ();
577 void ProcessXMLSubElement ( const XMLElement& e );
578 };
579
580
581 class StubbedSymbol
582 {
583 public:
584 const XMLElement& node;
585 std::string symbol;
586 std::string newname;
587
588 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
589 ~StubbedSymbol ();
590 void ProcessXML();
591 };
592
593 extern std::string
594 FixSeparator ( const std::string& s );
595
596 extern std::string
597 ReplaceExtension (
598 const std::string& filename,
599 const std::string& newExtension );
600
601 extern std::string
602 GetSubPath (
603 const std::string& location,
604 const std::string& path,
605 const std::string& att_value );
606
607 extern std::string
608 GetExtension ( const std::string& filename );
609
610 extern std::string
611 GetDirectory ( const std::string& filename );
612
613 extern std::string
614 NormalizeFilename ( const std::string& filename );
615
616 #endif /* __RBUILD_H */