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