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