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