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