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