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