Extract WINE resources at compile-time
[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/*WIN32*/
10 #include <sys/stat.h>
11 #include <time.h>
12 #ifdef _MSC_VER
13 #include <sys/utime.h>
14 #else/*_MSC_VER*/
15 #include <utime.h>
16 #ifdef WIN32
17 #include <process.h>
18 #endif/*WIN32*/
19 #endif/*_MSC_VER*/
20
21 #include "ssprintf.h"
22 #include "exception.h"
23 #include "XML.h"
24
25 typedef std::vector<std::string> string_list;
26
27 #ifdef WIN32
28 #define EXEPREFIX ""
29 #define EXEPOSTFIX ".exe"
30 #define CSEP '\\'
31 #define CBAD_SEP '/'
32 #define SSEP "\\"
33 #define SBAD_SEP "/"
34 #else
35 #define EXEPREFIX "./"
36 #define EXEPOSTFIX ""
37 #define CSEP '/'
38 #define CBAD_SEP '\\'
39 #define SSEP "/"
40 #define SBAD_SEP "\\"
41 #endif
42
43 class Project;
44 class IfableData;
45 class Module;
46 class Include;
47 class Define;
48 class File;
49 class Library;
50 class Invoke;
51 class InvokeFile;
52 class Dependency;
53 class ImportLibrary;
54 class If;
55 class CompilerFlag;
56 class LinkerFlag;
57 class Property;
58 class WineResource;
59 class AutomaticDependency;
60 class Bootstrap;
61 class CDFile;
62 class InstallFile;
63 class PchFile;
64 class StubbedComponent;
65 class StubbedSymbol;
66
67 class SourceFileTest;
68
69 class IfableData
70 {
71 public:
72 std::vector<File*> files;
73 std::vector<Include*> includes;
74 std::vector<Define*> defines;
75 std::vector<Library*> libraries;
76 std::vector<Property*> properties;
77 std::vector<CompilerFlag*> compilerFlags;
78 std::vector<If*> ifs;
79
80 ~IfableData();
81 void ProcessXML();
82 };
83
84 class Project
85 {
86 std::string xmlfile;
87 XMLElement *node, *head;
88 public:
89 std::string name;
90 std::string makefile;
91 XMLIncludes xmlbuildfiles;
92 std::vector<Module*> modules;
93 std::vector<LinkerFlag*> linkerFlags;
94 std::vector<CDFile*> cdfiles;
95 std::vector<InstallFile*> installfiles;
96 IfableData non_if_data;
97
98 Project ( const std::string& filename );
99 ~Project ();
100 void WriteConfigurationFile ();
101 void ExecuteInvocations ();
102 void ProcessXML ( const std::string& path );
103 Module* LocateModule ( const std::string& name );
104 const Module* LocateModule ( const std::string& name ) const;
105 std::string GetProjectFilename () const;
106 private:
107 const Property* LookupProperty ( const std::string& name ) const;
108 void SetConfigurationOption ( char* s,
109 std::string name,
110 std::string* alternativeName );
111 void SetConfigurationOption ( char* s,
112 std::string name );
113 void WriteIfChanged ( char* outbuf,
114 std::string filename );
115 void ReadXml ();
116 void ProcessXMLSubElement ( const XMLElement& e,
117 const std::string& path,
118 If* pIf = NULL );
119
120 // disable copy semantics
121 Project ( const Project& );
122 Project& operator = ( const Project& );
123 };
124
125
126 enum ModuleType
127 {
128 BuildTool = 0,
129 StaticLibrary = 1,
130 ObjectLibrary = 2,
131 Kernel = 3,
132 KernelModeDLL = 4,
133 KernelModeDriver = 5,
134 NativeDLL = 6,
135 NativeCUI = 7,
136 Win32DLL = 8,
137 Win32CUI = 9,
138 Win32GUI = 10,
139 BootLoader = 11,
140 BootSector = 12,
141 Iso = 13,
142 LiveIso = 14,
143 Test = 15,
144 RpcServer = 16,
145 RpcClient = 17
146 };
147
148 enum HostType
149 {
150 HostFalse,
151 HostDefault,
152 HostTrue
153 };
154
155 class Module
156 {
157 public:
158 const Project& project;
159 const XMLElement& node;
160 std::string xmlbuildFile;
161 std::string name;
162 std::string extension;
163 std::string entrypoint;
164 std::string baseaddress;
165 std::string path;
166 ModuleType type;
167 ImportLibrary* importLibrary;
168 bool mangledSymbols;
169 Bootstrap* bootstrap;
170 IfableData non_if_data;
171 std::vector<Invoke*> invocations;
172 std::vector<Dependency*> dependencies;
173 std::vector<CompilerFlag*> compilerFlags;
174 std::vector<LinkerFlag*> linkerFlags;
175 std::vector<StubbedComponent*> stubbedComponents;
176 PchFile* pch;
177 bool cplusplus;
178 std::string prefix;
179 HostType host;
180 std::string installBase;
181 std::string installName;
182 bool useWRC;
183 bool enableWarnings;
184
185 Module ( const Project& project,
186 const XMLElement& moduleNode,
187 const std::string& modulePath );
188 ~Module ();
189 ModuleType GetModuleType ( const std::string& location,
190 const XMLAttribute& attribute );
191 bool HasImportLibrary () const;
192 bool IsDLL () const;
193 std::string GetTargetName () const;
194 std::string GetDependencyPath () const;
195 std::string GetBasePath () const;
196 std::string GetPath () const;
197 std::string GetPathWithPrefix ( const std::string& prefix ) const;
198 void GetTargets ( string_list& ) const;
199 std::string GetInvocationTarget ( const int index ) const;
200 bool HasFileWithExtension ( const IfableData&, const std::string& extension ) const;
201 void InvokeModule () const;
202 void ProcessXML ();
203 private:
204 std::string GetDefaultModuleExtension () const;
205 std::string GetDefaultModuleEntrypoint () const;
206 std::string GetDefaultModuleBaseaddress () const;
207 void ProcessXMLSubElement ( const XMLElement& e,
208 const std::string& path,
209 If* pIf = NULL );
210 };
211
212
213 class Include
214 {
215 public:
216 const Project& project;
217 const Module* module;
218 const XMLElement& node;
219 std::string directory;
220 std::string basePath;
221
222 Include ( const Project& project,
223 const XMLElement& includeNode );
224 Include ( const Project& project,
225 const Module* module,
226 const XMLElement& includeNode );
227 ~Include ();
228 void ProcessXML();
229 private:
230 void Initialize();
231 };
232
233
234 class Define
235 {
236 public:
237 const Project& project;
238 const Module* module;
239 const XMLElement& node;
240 std::string name;
241 std::string value;
242
243 Define ( const Project& project,
244 const XMLElement& defineNode );
245 Define ( const Project& project,
246 const Module* module,
247 const XMLElement& defineNode );
248 ~Define();
249 void ProcessXML();
250 private:
251 void Initialize();
252 };
253
254
255 class File
256 {
257 public:
258 std::string name;
259 bool first;
260 std::string switches;
261
262 File ( const std::string& _name,
263 bool _first,
264 std::string _switches );
265
266 void ProcessXML();
267 };
268
269
270 class Library
271 {
272 public:
273 const XMLElement& node;
274 const Module& module;
275 std::string name;
276 const Module* imported_module;
277
278 Library ( const XMLElement& _node,
279 const Module& _module,
280 const std::string& _name );
281
282 void ProcessXML();
283 };
284
285
286 class Invoke
287 {
288 public:
289 const XMLElement& node;
290 const Module& module;
291 const Module* invokeModule;
292 std::vector<InvokeFile*> input;
293 std::vector<InvokeFile*> output;
294
295 Invoke ( const XMLElement& _node,
296 const Module& _module );
297
298 void ProcessXML();
299 void GetTargets ( string_list& targets ) const;
300 std::string GetParameters () const;
301 private:
302 void ProcessXMLSubElement ( const XMLElement& e );
303 void ProcessXMLSubElementInput ( const XMLElement& e );
304 void ProcessXMLSubElementOutput ( const XMLElement& e );
305 };
306
307
308 class InvokeFile
309 {
310 public:
311 const XMLElement& node;
312 std::string name;
313 std::string switches;
314
315 InvokeFile ( const XMLElement& _node,
316 const std::string& _name );
317
318 void ProcessXML ();
319 };
320
321
322 class Dependency
323 {
324 public:
325 const XMLElement& node;
326 const Module& module;
327 const Module* dependencyModule;
328
329 Dependency ( const XMLElement& _node,
330 const Module& _module );
331
332 void ProcessXML();
333 };
334
335
336 class ImportLibrary
337 {
338 public:
339 const XMLElement& node;
340 const Module& module;
341 std::string basename;
342 std::string definition;
343
344 ImportLibrary ( const XMLElement& _node,
345 const Module& module );
346
347 void ProcessXML ();
348 };
349
350
351 class If
352 {
353 public:
354 const XMLElement& node;
355 const Project& project;
356 const Module* module;
357 std::string property, value;
358 IfableData data;
359
360 If ( const XMLElement& node_,
361 const Project& project_,
362 const Module* module_ );
363 ~If();
364
365 void ProcessXML();
366 };
367
368
369 class CompilerFlag
370 {
371 public:
372 const Project& project;
373 const Module* module;
374 const XMLElement& node;
375 std::string flag;
376
377 CompilerFlag ( const Project& project,
378 const XMLElement& compilerFlagNode );
379 CompilerFlag ( const Project& project,
380 const Module* module,
381 const XMLElement& compilerFlagNode );
382 ~CompilerFlag ();
383 void ProcessXML();
384 private:
385 void Initialize();
386 };
387
388
389 class LinkerFlag
390 {
391 public:
392 const Project& project;
393 const Module* module;
394 const XMLElement& node;
395 std::string flag;
396
397 LinkerFlag ( const Project& project,
398 const XMLElement& linkerFlagNode );
399 LinkerFlag ( const Project& project,
400 const Module* module,
401 const XMLElement& linkerFlagNode );
402 ~LinkerFlag ();
403 void ProcessXML();
404 private:
405 void Initialize();
406 };
407
408
409 class Property
410 {
411 public:
412 const XMLElement& node;
413 const Project& project;
414 const Module* module;
415 std::string name, value;
416
417 Property ( const XMLElement& node_,
418 const Project& project_,
419 const Module* module_ );
420
421 void ProcessXML();
422 };
423
424
425 class WineResource
426 {
427 public:
428 const Project& project;
429 std::string bin2res;
430
431 WineResource ( const Project& project,
432 std::string bin2res );
433 ~WineResource ();
434 void UnpackResources ( bool verbose );
435 private:
436 bool IsSpecFile ( const File& file );
437 bool IsWineModule ( const Module& module );
438 bool IsResourceFile ( const File& file );
439 std::string GetResourceFilename ( const Module& module );
440 void UnpackResourcesInModule ( Module& module,
441 bool verbose );
442 };
443
444
445 class SourceFile
446 {
447 public:
448 SourceFile ( AutomaticDependency* automaticDependency,
449 Module& module,
450 const std::string& filename,
451 SourceFile* parent,
452 bool isNonAutomaticDependency );
453 SourceFile* ParseFile ( const std::string& normalizedFilename );
454 void Parse ();
455 std::string Location () const;
456 std::vector<SourceFile*> files;
457 AutomaticDependency* automaticDependency;
458 Module& module;
459 std::string filename;
460 std::string filenamePart;
461 std::string directoryPart;
462 std::vector<SourceFile*> parents; /* List of files, this file is included from */
463 bool isNonAutomaticDependency;
464 std::string cachedDependencies;
465 time_t lastWriteTime;
466 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
467 SourceFile* youngestFile;
468 private:
469 void GetDirectoryAndFilenameParts ();
470 void Close ();
471 void Open ();
472 void SkipWhitespace ();
473 bool ReadInclude ( std::string& filename,
474 bool& includeNext );
475 bool IsIncludedFrom ( const std::string& normalizedFilename );
476 SourceFile* GetParentSourceFile ();
477 bool CanProcessFile ( const std::string& extension );
478 bool IsParentOf ( const SourceFile* parent,
479 const SourceFile* child );
480 std::string buf;
481 const char *p;
482 const char *end;
483 };
484
485
486 class AutomaticDependency
487 {
488 friend class SourceFileTest;
489 public:
490 const Project& project;
491
492 AutomaticDependency ( const Project& project );
493 ~AutomaticDependency ();
494 void Process ();
495 std::string GetFilename ( const std::string& filename );
496 bool LocateIncludedFile ( const std::string& directory,
497 const std::string& includedFilename,
498 std::string& resolvedFilename );
499 bool LocateIncludedFile ( SourceFile* sourceFile,
500 Module& module,
501 const std::string& includedFilename,
502 bool includeNext,
503 std::string& resolvedFilename );
504 SourceFile* RetrieveFromCacheOrParse ( Module& module,
505 const std::string& filename,
506 SourceFile* parentSourceFile );
507 SourceFile* RetrieveFromCache ( const std::string& filename );
508 void CheckAutomaticDependencies ( bool verbose );
509 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
510 private:
511 void ProcessModule ( Module& module );
512 void ProcessFile ( Module& module,
513 const File& file );
514 std::map<std::string, SourceFile*> sourcefile_map;
515 };
516
517
518 class Bootstrap
519 {
520 public:
521 const Project& project;
522 const Module* module;
523 const XMLElement& node;
524 std::string base;
525 std::string nameoncd;
526
527 Bootstrap ( const Project& project,
528 const Module* module,
529 const XMLElement& bootstrapNode );
530 ~Bootstrap ();
531 void ProcessXML();
532 private:
533 bool IsSupportedModuleType ( ModuleType type );
534 void Initialize();
535 };
536
537
538 class CDFile
539 {
540 public:
541 const Project& project;
542 const XMLElement& node;
543 std::string name;
544 std::string base;
545 std::string nameoncd;
546 std::string path;
547
548 CDFile ( const Project& project,
549 const XMLElement& bootstrapNode,
550 const std::string& path );
551 ~CDFile ();
552 void ProcessXML();
553 std::string GetPath () const;
554 };
555
556
557 class InstallFile
558 {
559 public:
560 const Project& project;
561 const XMLElement& node;
562 std::string name;
563 std::string base;
564 std::string newname;
565 std::string path;
566
567 InstallFile ( const Project& project,
568 const XMLElement& bootstrapNode,
569 const std::string& path );
570 ~InstallFile ();
571 void ProcessXML ();
572 std::string GetPath () const;
573 };
574
575
576 class PchFile
577 {
578 public:
579 const XMLElement& node;
580 const Module& module;
581 std::string header;
582
583 PchFile (
584 const XMLElement& node,
585 const Module& module,
586 const std::string& header );
587 void ProcessXML();
588 };
589
590
591 class StubbedComponent
592 {
593 public:
594 const Module* module;
595 const XMLElement& node;
596 std::string name;
597 std::vector<StubbedSymbol*> symbols;
598
599 StubbedComponent ( const Module* module_,
600 const XMLElement& stubbedComponentNode );
601 ~StubbedComponent ();
602 void ProcessXML ();
603 void ProcessXMLSubElement ( const XMLElement& e );
604 };
605
606
607 class StubbedSymbol
608 {
609 public:
610 const XMLElement& node;
611 std::string symbol;
612 std::string newname;
613
614 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
615 ~StubbedSymbol ();
616 void ProcessXML();
617 };
618
619 extern std::string
620 FixSeparator ( const std::string& s );
621
622 extern std::string
623 ReplaceExtension (
624 const std::string& filename,
625 const std::string& newExtension );
626
627 extern std::string
628 GetSubPath (
629 const std::string& location,
630 const std::string& path,
631 const std::string& att_value );
632
633 extern std::string
634 GetExtension ( const std::string& filename );
635
636 extern std::string
637 GetDirectory ( const std::string& filename );
638
639 extern std::string
640 NormalizeFilename ( const std::string& filename );
641
642 #endif /* __RBUILD_H */