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