PCH 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
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
135 class Module
136 {
137 public:
138 const Project& project;
139 const XMLElement& node;
140 std::string name;
141 std::string extension;
142 std::string entrypoint;
143 std::string baseaddress;
144 std::string path;
145 ModuleType type;
146 ImportLibrary* importLibrary;
147 bool mangledSymbols;
148 Bootstrap* bootstrap;
149 IfableData non_if_data;
150 std::vector<Invoke*> invocations;
151 std::vector<Dependency*> dependencies;
152 std::vector<CompilerFlag*> compilerFlags;
153 std::vector<LinkerFlag*> linkerFlags;
154 PchFile* pch;
155
156 Module ( const Project& project,
157 const XMLElement& moduleNode,
158 const std::string& modulePath );
159 ~Module ();
160 ModuleType GetModuleType ( const std::string& location,
161 const XMLAttribute& attribute );
162 bool HasImportLibrary () const;
163 std::string GetTargetName () const;
164 std::string GetDependencyPath () const;
165 std::string GetBasePath () const;
166 std::string GetPath () const;
167 std::string GetPathWithPrefix ( const std::string& prefix ) const;
168 std::string GetTargets () const;
169 std::string GetInvocationTarget ( const int index ) const;
170 bool HasFileWithExtension ( const IfableData&, const std::string& extension ) const;
171 void InvokeModule () const;
172 void ProcessXML ();
173 private:
174 std::string GetDefaultModuleExtension () const;
175 std::string GetDefaultModuleEntrypoint () const;
176 std::string GetDefaultModuleBaseaddress () const;
177 void ProcessXMLSubElement ( const XMLElement& e,
178 const std::string& path,
179 If* pIf = NULL );
180 };
181
182
183 class Include
184 {
185 public:
186 const Project& project;
187 const Module* module;
188 const XMLElement& node;
189 std::string directory;
190 std::string basePath;
191
192 Include ( const Project& project,
193 const XMLElement& includeNode );
194 Include ( const Project& project,
195 const Module* module,
196 const XMLElement& includeNode );
197 ~Include ();
198 void ProcessXML();
199 private:
200 void Initialize();
201 };
202
203
204 class Define
205 {
206 public:
207 const Project& project;
208 const Module* module;
209 const XMLElement& node;
210 std::string name;
211 std::string value;
212
213 Define ( const Project& project,
214 const XMLElement& defineNode );
215 Define ( const Project& project,
216 const Module* module,
217 const XMLElement& defineNode );
218 ~Define();
219 void ProcessXML();
220 private:
221 void Initialize();
222 };
223
224
225 class File
226 {
227 public:
228 std::string name;
229 bool first;
230
231 File ( const std::string& _name, bool _first );
232
233 void ProcessXML();
234 };
235
236
237 class Library
238 {
239 public:
240 const XMLElement& node;
241 const Module& module;
242 std::string name;
243 const Module* imported_module;
244
245 Library ( const XMLElement& _node,
246 const Module& _module,
247 const std::string& _name );
248
249 void ProcessXML();
250 };
251
252
253 class Invoke
254 {
255 public:
256 const XMLElement& node;
257 const Module& module;
258 const Module* invokeModule;
259 std::vector<InvokeFile*> input;
260 std::vector<InvokeFile*> output;
261
262 Invoke ( const XMLElement& _node,
263 const Module& _module );
264
265 void ProcessXML();
266 std::string GetTargets () const;
267 std::string GetParameters () const;
268 private:
269 void ProcessXMLSubElement ( const XMLElement& e );
270 void ProcessXMLSubElementInput ( const XMLElement& e );
271 void ProcessXMLSubElementOutput ( const XMLElement& e );
272 };
273
274
275 class InvokeFile
276 {
277 public:
278 const XMLElement& node;
279 std::string name;
280 std::string switches;
281
282 InvokeFile ( const XMLElement& _node,
283 const std::string& _name );
284
285 void ProcessXML ();
286 };
287
288
289 class Dependency
290 {
291 public:
292 const XMLElement& node;
293 const Module& module;
294 const Module* dependencyModule;
295
296 Dependency ( const XMLElement& _node,
297 const Module& _module );
298
299 void ProcessXML();
300 };
301
302
303 class ImportLibrary
304 {
305 public:
306 const XMLElement& node;
307 const Module& module;
308 std::string basename;
309 std::string definition;
310
311 ImportLibrary ( const XMLElement& _node,
312 const Module& module );
313
314 void ProcessXML ();
315 };
316
317
318 class If
319 {
320 public:
321 const XMLElement& node;
322 const Project& project;
323 const Module* module;
324 std::string property, value;
325 IfableData data;
326
327 If ( const XMLElement& node_,
328 const Project& project_,
329 const Module* module_ );
330 ~If();
331
332 void ProcessXML();
333 };
334
335
336 class CompilerFlag
337 {
338 public:
339 const Project& project;
340 const Module* module;
341 const XMLElement& node;
342 std::string flag;
343
344 CompilerFlag ( const Project& project,
345 const XMLElement& compilerFlagNode );
346 CompilerFlag ( const Project& project,
347 const Module* module,
348 const XMLElement& compilerFlagNode );
349 ~CompilerFlag ();
350 void ProcessXML();
351 private:
352 void Initialize();
353 };
354
355
356 class LinkerFlag
357 {
358 public:
359 const Project& project;
360 const Module* module;
361 const XMLElement& node;
362 std::string flag;
363
364 LinkerFlag ( const Project& project,
365 const XMLElement& linkerFlagNode );
366 LinkerFlag ( const Project& project,
367 const Module* module,
368 const XMLElement& linkerFlagNode );
369 ~LinkerFlag ();
370 void ProcessXML();
371 private:
372 void Initialize();
373 };
374
375
376 class Property
377 {
378 public:
379 const XMLElement& node;
380 const Project& project;
381 const Module* module;
382 std::string name, value;
383
384 Property ( const XMLElement& node_,
385 const Project& project_,
386 const Module* module_ );
387
388 void ProcessXML();
389 };
390
391
392 class SourceFile
393 {
394 public:
395 SourceFile ( AutomaticDependency* automaticDependency,
396 Module& module,
397 const std::string& filename,
398 SourceFile* parent,
399 bool isNonAutomaticDependency );
400 SourceFile* ParseFile ( const std::string& normalizedFilename );
401 void Parse ();
402 std::string Location () const;
403 std::vector<SourceFile*> files;
404 AutomaticDependency* automaticDependency;
405 Module& module;
406 std::string filename;
407 std::string filenamePart;
408 std::string directoryPart;
409 std::vector<SourceFile*> parents; /* List of files, this file is included from */
410 bool isNonAutomaticDependency;
411 std::string cachedDependencies;
412 time_t lastWriteTime;
413 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
414 SourceFile* youngestFile;
415 private:
416 void GetDirectoryAndFilenameParts ();
417 void Close ();
418 void Open ();
419 void SkipWhitespace ();
420 bool ReadInclude ( std::string& filename,
421 bool& includeNext );
422 bool IsIncludedFrom ( const std::string& normalizedFilename );
423 SourceFile* GetParentSourceFile ();
424 bool CanProcessFile ( const std::string& extension );
425 bool IsParentOf ( const SourceFile* parent,
426 const SourceFile* child );
427 std::string buf;
428 const char *p;
429 const char *end;
430 };
431
432
433 class AutomaticDependency
434 {
435 friend class SourceFileTest;
436 public:
437 const Project& project;
438
439 AutomaticDependency ( const Project& project );
440 ~AutomaticDependency ();
441 void Process ();
442 std::string GetFilename ( const std::string& filename );
443 bool LocateIncludedFile ( const std::string& directory,
444 const std::string& includedFilename,
445 std::string& resolvedFilename );
446 bool LocateIncludedFile ( SourceFile* sourceFile,
447 Module& module,
448 const std::string& includedFilename,
449 bool includeNext,
450 std::string& resolvedFilename );
451 SourceFile* RetrieveFromCacheOrParse ( Module& module,
452 const std::string& filename,
453 SourceFile* parentSourceFile );
454 SourceFile* RetrieveFromCache ( const std::string& filename );
455 void CheckAutomaticDependencies ();
456 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
457 private:
458 void ProcessModule ( Module& module );
459 void ProcessFile ( Module& module,
460 const File& file );
461 std::map<std::string, SourceFile*> sourcefile_map;
462 };
463
464
465 class Bootstrap
466 {
467 public:
468 const Project& project;
469 const Module* module;
470 const XMLElement& node;
471 std::string base;
472 std::string nameoncd;
473
474 Bootstrap ( const Project& project,
475 const Module* module,
476 const XMLElement& bootstrapNode );
477 ~Bootstrap ();
478 void ProcessXML();
479 private:
480 bool IsSupportedModuleType ( ModuleType type );
481 void Initialize();
482 };
483
484
485 class CDFile
486 {
487 public:
488 const Project& project;
489 const XMLElement& node;
490 std::string name;
491 std::string base;
492 std::string nameoncd;
493 std::string path;
494
495 CDFile ( const Project& project,
496 const XMLElement& bootstrapNode,
497 const std::string& path );
498 ~CDFile ();
499 void ProcessXML();
500 std::string GetPath () const;
501 };
502
503
504 class PchFile
505 {
506 public:
507 const XMLElement& node;
508 const Module& module;
509 std::string header;
510
511 PchFile (
512 const XMLElement& node,
513 const Module& module,
514 const std::string& header );
515 void ProcessXML();
516 };
517
518
519 extern std::string
520 FixSeparator ( const std::string& s );
521
522 extern std::string
523 GetExtension ( const std::string& filename );
524
525 extern std::string
526 GetDirectory ( const std::string& filename );
527
528 extern std::string
529 NormalizeFilename ( const std::string& filename );
530
531 #endif /* __RBUILD_H */