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