366c83e2d0f9a79257a5df8a24703b5a16cfb14d
[reactos.git] / reactos / tools / rbuild / rbuild.h
1 /*
2 * Copyright (C) 2005 Casper S. Hornstrup
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 #ifndef __RBUILD_H
19 #define __RBUILD_H
20
21 #include "pch.h"
22
23 #ifdef WIN32
24 #include <direct.h>
25 #include <io.h>
26 #endif/*WIN32*/
27 #include <sys/stat.h>
28 #include <time.h>
29 #ifdef _MSC_VER
30 #include <sys/utime.h>
31 #else/*_MSC_VER*/
32 #include <utime.h>
33 #ifdef WIN32
34 #include <process.h>
35 #endif/*WIN32*/
36 #endif/*_MSC_VER*/
37
38 #include "ssprintf.h"
39 #include "exception.h"
40 #include "XML.h"
41
42 typedef std::vector<std::string> string_list;
43
44 #ifdef WIN32
45 #define EXEPREFIX ""
46 #define EXEPOSTFIX ".exe"
47 #define CSEP '\\'
48 #define CBAD_SEP '/'
49 #define SSEP "\\"
50 #define SBAD_SEP "/"
51 #else
52 #define EXEPREFIX "./"
53 #define EXEPOSTFIX ""
54 #define CSEP '/'
55 #define CBAD_SEP '\\'
56 #define SSEP "/"
57 #define SBAD_SEP "\\"
58 #endif
59
60 class Project;
61 class IfableData;
62 class Module;
63 class Include;
64 class Define;
65 class File;
66 class Library;
67 class Invoke;
68 class InvokeFile;
69 class Dependency;
70 class ImportLibrary;
71 class If;
72 class CompilerFlag;
73 class LinkerFlag;
74 class Property;
75 class TestSupportCode;
76 class WineResource;
77 class AutomaticDependency;
78 class Bootstrap;
79 class CDFile;
80 class InstallFile;
81 class PchFile;
82 class StubbedComponent;
83 class StubbedSymbol;
84
85 class SourceFileTest;
86
87
88 class Configuration
89 {
90 public:
91 Configuration ();
92 ~Configuration ();
93 bool Verbose;
94 bool CleanAsYouGo;
95 bool AutomaticDependencies;
96 bool CheckDependenciesForModuleOnly;
97 std::string CheckDependenciesForModuleOnlyModule;
98 bool MakeHandlesInstallDirectories;
99 bool GenerateProxyMakefilesInSourceTree;
100 };
101
102 class Environment
103 {
104 public:
105 static std::string GetVariable ( const std::string& name );
106 static std::string GetIntermediatePath ();
107 static std::string GetOutputPath ();
108 static std::string GetInstallPath ();
109 static std::string GetEnvironmentVariablePathOrDefault ( const std::string& name,
110 const std::string& defaultValue );
111 };
112
113 class FileSupportCode
114 {
115 public:
116 static void WriteIfChanged ( char* outbuf,
117 std::string filename );
118 };
119
120 class IfableData
121 {
122 public:
123 std::vector<File*> files;
124 std::vector<Include*> includes;
125 std::vector<Define*> defines;
126 std::vector<Library*> libraries;
127 std::vector<Property*> properties;
128 std::vector<CompilerFlag*> compilerFlags;
129 std::vector<If*> ifs;
130
131 ~IfableData();
132 void ProcessXML();
133 };
134
135 class Project
136 {
137 std::string xmlfile;
138 XMLElement *node, *head;
139 public:
140 std::string name;
141 std::string makefile;
142 XMLIncludes xmlbuildfiles;
143 std::vector<Module*> modules;
144 std::vector<LinkerFlag*> linkerFlags;
145 std::vector<CDFile*> cdfiles;
146 std::vector<InstallFile*> installfiles;
147 IfableData non_if_data;
148
149 Project ( const std::string& filename );
150 ~Project ();
151 void WriteConfigurationFile ();
152 void ExecuteInvocations ();
153 void ProcessXML ( const std::string& path );
154 Module* LocateModule ( const std::string& name );
155 const Module* LocateModule ( const std::string& name ) const;
156 std::string GetProjectFilename () const;
157 std::string ResolveProperties ( const std::string& s ) const;
158 private:
159 std::string ResolveNextProperty ( std::string& s ) const;
160 const Property* LookupProperty ( const std::string& name ) const;
161 void SetConfigurationOption ( char* s,
162 std::string name,
163 std::string* alternativeName );
164 void SetConfigurationOption ( char* s,
165 std::string name );
166 void ReadXml ();
167 void ProcessXMLSubElement ( const XMLElement& e,
168 const std::string& path,
169 If* pIf = NULL );
170
171 // disable copy semantics
172 Project ( const Project& );
173 Project& operator = ( const Project& );
174 };
175
176
177 enum ModuleType
178 {
179 BuildTool = 0,
180 StaticLibrary = 1,
181 ObjectLibrary = 2,
182 Kernel = 3,
183 KernelModeDLL = 4,
184 KernelModeDriver = 5,
185 NativeDLL = 6,
186 NativeCUI = 7,
187 Win32DLL = 8,
188 Win32CUI = 9,
189 Win32GUI = 10,
190 BootLoader = 11,
191 BootSector = 12,
192 Iso = 13,
193 LiveIso = 14,
194 Test = 15,
195 RpcServer = 16,
196 RpcClient = 17,
197 Alias = 18
198 };
199
200 enum HostType
201 {
202 HostFalse,
203 HostDefault,
204 HostTrue
205 };
206
207 class Module
208 {
209 public:
210 const Project& project;
211 const XMLElement& node;
212 std::string xmlbuildFile;
213 std::string name;
214 std::string extension;
215 std::string entrypoint;
216 std::string baseaddress;
217 std::string path;
218 ModuleType type;
219 ImportLibrary* importLibrary;
220 bool mangledSymbols;
221 Bootstrap* bootstrap;
222 IfableData non_if_data;
223 std::vector<Invoke*> invocations;
224 std::vector<Dependency*> dependencies;
225 std::vector<CompilerFlag*> compilerFlags;
226 std::vector<LinkerFlag*> linkerFlags;
227 std::vector<StubbedComponent*> stubbedComponents;
228 PchFile* pch;
229 bool cplusplus;
230 std::string prefix;
231 HostType host;
232 std::string installBase;
233 std::string installName;
234 std::string aliasedModuleName;
235 bool useWRC;
236 bool enableWarnings;
237 bool enabled;
238
239 Module ( const Project& project,
240 const XMLElement& moduleNode,
241 const std::string& modulePath );
242 ~Module ();
243 ModuleType GetModuleType ( const std::string& location,
244 const XMLAttribute& attribute );
245 bool HasImportLibrary () const;
246 bool IsDLL () const;
247 bool GenerateInOutputTree () const;
248 std::string GetTargetName () const;
249 std::string GetDependencyPath () const;
250 std::string GetBasePath () const;
251 std::string GetPath () const;
252 std::string GetPathWithPrefix ( const std::string& prefix ) const;
253 void GetTargets ( string_list& ) const;
254 std::string GetInvocationTarget ( const int index ) const;
255 bool HasFileWithExtension ( const IfableData&, const std::string& extension ) const;
256 void InvokeModule () const;
257 void ProcessXML ();
258 void GetSourceFilenames ( string_list& list,
259 bool includeGeneratedFiles ) const;
260 private:
261 std::string GetDefaultModuleExtension () const;
262 std::string GetDefaultModuleEntrypoint () const;
263 std::string GetDefaultModuleBaseaddress () const;
264 void ProcessXMLSubElement ( const XMLElement& e,
265 const std::string& path,
266 If* pIf = NULL );
267 };
268
269
270 class Include
271 {
272 public:
273 const Project& project;
274 const Module* module;
275 const XMLElement* node;
276 const Module* baseModule;
277 std::string directory;
278 std::string basePath;
279
280 Include ( const Project& project,
281 const XMLElement* includeNode );
282 Include ( const Project& project,
283 const Module* module,
284 const XMLElement* includeNode );
285 Include ( const Project& project,
286 std::string directory,
287 std::string basePath );
288 ~Include ();
289 void ProcessXML();
290 private:
291 };
292
293
294 class Define
295 {
296 public:
297 const Project& project;
298 const Module* module;
299 const XMLElement& node;
300 std::string name;
301 std::string value;
302
303 Define ( const Project& project,
304 const XMLElement& defineNode );
305 Define ( const Project& project,
306 const Module* module,
307 const XMLElement& defineNode );
308 ~Define();
309 void ProcessXML();
310 private:
311 void Initialize();
312 };
313
314
315 class File
316 {
317 public:
318 std::string name;
319 bool first;
320 std::string switches;
321 bool isPreCompiledHeader;
322
323 File ( const std::string& _name,
324 bool _first,
325 std::string _switches,
326 bool _isPreCompiledHeader );
327
328 void ProcessXML();
329 bool IsGeneratedFile () const;
330 };
331
332
333 class Library
334 {
335 public:
336 const XMLElement& node;
337 const Module& module;
338 std::string name;
339 const Module* importedModule;
340
341 Library ( const XMLElement& _node,
342 const Module& _module,
343 const std::string& _name );
344
345 void ProcessXML();
346 };
347
348
349 class Invoke
350 {
351 public:
352 const XMLElement& node;
353 const Module& module;
354 const Module* invokeModule;
355 std::vector<InvokeFile*> input;
356 std::vector<InvokeFile*> output;
357
358 Invoke ( const XMLElement& _node,
359 const Module& _module );
360
361 void ProcessXML();
362 void GetTargets ( string_list& targets ) const;
363 std::string GetParameters () const;
364 private:
365 void ProcessXMLSubElement ( const XMLElement& e );
366 void ProcessXMLSubElementInput ( const XMLElement& e );
367 void ProcessXMLSubElementOutput ( const XMLElement& e );
368 };
369
370
371 class InvokeFile
372 {
373 public:
374 const XMLElement& node;
375 std::string name;
376 std::string switches;
377
378 InvokeFile ( const XMLElement& _node,
379 const std::string& _name );
380
381 void ProcessXML ();
382 };
383
384
385 class Dependency
386 {
387 public:
388 const XMLElement& node;
389 const Module& module;
390 const Module* dependencyModule;
391
392 Dependency ( const XMLElement& _node,
393 const Module& _module );
394
395 void ProcessXML();
396 };
397
398
399 class ImportLibrary
400 {
401 public:
402 const XMLElement& node;
403 const Module& module;
404 std::string basename;
405 std::string definition;
406
407 ImportLibrary ( const XMLElement& _node,
408 const Module& module );
409
410 void ProcessXML ();
411 };
412
413
414 class If
415 {
416 public:
417 const XMLElement& node;
418 const Project& project;
419 const Module* module;
420 const bool negated;
421 std::string property, value;
422 IfableData data;
423
424 If ( const XMLElement& node_,
425 const Project& project_,
426 const Module* module_,
427 const bool negated_ = false );
428 ~If();
429
430 void ProcessXML();
431 };
432
433
434 class CompilerFlag
435 {
436 public:
437 const Project& project;
438 const Module* module;
439 const XMLElement& node;
440 std::string flag;
441
442 CompilerFlag ( const Project& project,
443 const XMLElement& compilerFlagNode );
444 CompilerFlag ( const Project& project,
445 const Module* module,
446 const XMLElement& compilerFlagNode );
447 ~CompilerFlag ();
448 void ProcessXML();
449 private:
450 void Initialize();
451 };
452
453
454 class LinkerFlag
455 {
456 public:
457 const Project& project;
458 const Module* module;
459 const XMLElement& node;
460 std::string flag;
461
462 LinkerFlag ( const Project& project,
463 const XMLElement& linkerFlagNode );
464 LinkerFlag ( const Project& project,
465 const Module* module,
466 const XMLElement& linkerFlagNode );
467 ~LinkerFlag ();
468 void ProcessXML();
469 private:
470 void Initialize();
471 };
472
473
474 class Property
475 {
476 public:
477 const XMLElement& node;
478 const Project& project;
479 const Module* module;
480 std::string name, value;
481
482 Property ( const XMLElement& node_,
483 const Project& project_,
484 const Module* module_ );
485
486 void ProcessXML();
487 };
488
489
490 class TestSupportCode
491 {
492 public:
493 const Project& project;
494
495 TestSupportCode ( const Project& project );
496 ~TestSupportCode ();
497 void GenerateTestSupportCode ( bool verbose );
498 private:
499 bool IsTestModule ( const Module& module );
500 void GenerateTestSupportCodeForModule ( Module& module,
501 bool verbose );
502 std::string GetHooksFilename ( Module& module );
503 char* WriteStubbedSymbolToHooksFile ( char* buffer,
504 const StubbedComponent& component,
505 const StubbedSymbol& symbol );
506 char* WriteStubbedComponentToHooksFile ( char* buffer,
507 const StubbedComponent& component );
508 void WriteHooksFile ( Module& module );
509 std::string GetStubsFilename ( Module& module );
510 char* WriteStubbedSymbolToStubsFile ( char* buffer,
511 const StubbedComponent& component,
512 const StubbedSymbol& symbol,
513 int stubIndex );
514 char* WriteStubbedComponentToStubsFile ( char* buffer,
515 const StubbedComponent& component,
516 int* stubIndex );
517 void WriteStubsFile ( Module& module );
518 std::string GetStartupFilename ( Module& module );
519 bool IsUnknownCharacter ( char ch );
520 std::string GetTestDispatcherName ( std::string filename );
521 bool IsTestFile ( std::string& filename ) const;
522 void GetSourceFilenames ( string_list& list,
523 Module& module ) const;
524 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer,
525 Module& module );
526 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer,
527 Module& module );
528 void WriteStartupFile ( Module& module );
529 };
530
531
532 class WineResource
533 {
534 public:
535 const Project& project;
536 std::string bin2res;
537
538 WineResource ( const Project& project,
539 std::string bin2res );
540 ~WineResource ();
541 void UnpackResources ( bool verbose );
542 private:
543 bool IsSpecFile ( const File& file );
544 bool IsWineModule ( const Module& module );
545 bool IsResourceFile ( const File& file );
546 std::string GetResourceFilename ( const Module& module );
547 void UnpackResourcesInModule ( Module& module,
548 bool verbose );
549 };
550
551
552 class SourceFile
553 {
554 public:
555 SourceFile ( AutomaticDependency* automaticDependency,
556 const Module& module,
557 const std::string& filename,
558 SourceFile* parent,
559 bool isNonAutomaticDependency );
560 SourceFile* ParseFile ( const std::string& normalizedFilename );
561 void Parse ();
562 std::string Location () const;
563 std::vector<SourceFile*> files;
564 AutomaticDependency* automaticDependency;
565 const Module& module;
566 std::string filename;
567 std::string filenamePart;
568 std::string directoryPart;
569 std::vector<SourceFile*> parents; /* List of files, this file is included from */
570 bool isNonAutomaticDependency;
571 std::string cachedDependencies;
572 time_t lastWriteTime;
573 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
574 SourceFile* youngestFile;
575 private:
576 void GetDirectoryAndFilenameParts ();
577 void Close ();
578 void Open ();
579 void SkipWhitespace ();
580 bool ReadInclude ( std::string& filename,
581 bool& searchCurrentDirectory,
582 bool& includeNext );
583 bool IsIncludedFrom ( const std::string& normalizedFilename );
584 SourceFile* GetParentSourceFile ();
585 bool CanProcessFile ( const std::string& extension );
586 bool IsParentOf ( const SourceFile* parent,
587 const SourceFile* child );
588 std::string buf;
589 const char *p;
590 const char *end;
591 };
592
593
594 class AutomaticDependency
595 {
596 friend class SourceFileTest;
597 public:
598 const Project& project;
599
600 AutomaticDependency ( const Project& project );
601 ~AutomaticDependency ();
602 std::string GetFilename ( const std::string& filename );
603 bool LocateIncludedFile ( const std::string& directory,
604 const std::string& includedFilename,
605 std::string& resolvedFilename );
606 bool LocateIncludedFile ( SourceFile* sourceFile,
607 const Module& module,
608 const std::string& includedFilename,
609 bool searchCurrentDirectory,
610 bool includeNext,
611 std::string& resolvedFilename );
612 SourceFile* RetrieveFromCacheOrParse ( const Module& module,
613 const std::string& filename,
614 SourceFile* parentSourceFile );
615 SourceFile* RetrieveFromCache ( const std::string& filename );
616 void CheckAutomaticDependencies ( bool verbose );
617 void CheckAutomaticDependenciesForModule ( Module& module,
618 bool verbose );
619 private:
620 void GetModulesToCheck ( Module& module, std::vector<const Module*>& modules );
621 void CheckAutomaticDependencies ( const Module& module,
622 bool verbose );
623 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
624 void GetIncludeDirectories ( std::vector<Include*>& includes,
625 const Module& module,
626 Include& currentDirectory,
627 bool searchCurrentDirectory );
628 void GetModuleFiles ( const Module& module,
629 std::vector<File*>& files ) const;
630 void ParseFiles ();
631 void ParseFiles ( const Module& module );
632 void ParseFile ( const Module& module,
633 const File& file );
634 std::map<std::string, SourceFile*> sourcefile_map;
635 };
636
637
638 class Bootstrap
639 {
640 public:
641 const Project& project;
642 const Module* module;
643 const XMLElement& node;
644 std::string base;
645 std::string nameoncd;
646
647 Bootstrap ( const Project& project,
648 const Module* module,
649 const XMLElement& bootstrapNode );
650 ~Bootstrap ();
651 void ProcessXML();
652 private:
653 bool IsSupportedModuleType ( ModuleType type );
654 void Initialize();
655 };
656
657
658 class CDFile
659 {
660 public:
661 const Project& project;
662 const XMLElement& node;
663 std::string name;
664 std::string base;
665 std::string nameoncd;
666 std::string path;
667
668 CDFile ( const Project& project,
669 const XMLElement& bootstrapNode,
670 const std::string& path );
671 ~CDFile ();
672 void ProcessXML();
673 std::string GetPath () const;
674 };
675
676
677 class InstallFile
678 {
679 public:
680 const Project& project;
681 const XMLElement& node;
682 std::string name;
683 std::string base;
684 std::string newname;
685 std::string path;
686
687 InstallFile ( const Project& project,
688 const XMLElement& bootstrapNode,
689 const std::string& path );
690 ~InstallFile ();
691 void ProcessXML ();
692 std::string GetPath () const;
693 };
694
695
696 class PchFile
697 {
698 public:
699 const XMLElement& node;
700 const Module& module;
701 File file;
702
703 PchFile (
704 const XMLElement& node,
705 const Module& module,
706 const File file );
707 void ProcessXML();
708 };
709
710
711 class StubbedComponent
712 {
713 public:
714 const Module* module;
715 const XMLElement& node;
716 std::string name;
717 std::vector<StubbedSymbol*> symbols;
718
719 StubbedComponent ( const Module* module_,
720 const XMLElement& stubbedComponentNode );
721 ~StubbedComponent ();
722 void ProcessXML ();
723 void ProcessXMLSubElement ( const XMLElement& e );
724 };
725
726
727 class StubbedSymbol
728 {
729 public:
730 const XMLElement& node;
731 std::string symbol;
732 std::string newname;
733 std::string strippedName;
734
735 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
736 ~StubbedSymbol ();
737 void ProcessXML();
738 private:
739 std::string StripSymbol ( std::string symbol );
740 };
741
742
743 extern std::string
744 FixSeparator ( const std::string& s );
745
746 extern std::string
747 ReplaceExtension (
748 const std::string& filename,
749 const std::string& newExtension );
750
751 extern std::string
752 GetSubPath (
753 const std::string& location,
754 const std::string& path,
755 const std::string& att_value );
756
757 extern std::string
758 GetExtension ( const std::string& filename );
759
760 extern std::string
761 GetDirectory ( const std::string& filename );
762
763 extern std::string
764 GetFilename ( const std::string& filename );
765
766 extern std::string
767 NormalizeFilename ( const std::string& filename );
768
769 #endif /* __RBUILD_H */