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