Replace File by CompilationUnit
[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 };
357
358
359 class Library
360 {
361 public:
362 const XMLElement& node;
363 const Module& module;
364 std::string name;
365 const Module* importedModule;
366
367 Library ( const XMLElement& _node,
368 const Module& _module,
369 const std::string& _name );
370
371 void ProcessXML();
372 };
373
374
375 class Invoke
376 {
377 public:
378 const XMLElement& node;
379 const Module& module;
380 const Module* invokeModule;
381 std::vector<InvokeFile*> input;
382 std::vector<InvokeFile*> output;
383
384 Invoke ( const XMLElement& _node,
385 const Module& _module );
386
387 void ProcessXML();
388 void GetTargets ( string_list& targets ) const;
389 std::string GetParameters () const;
390 private:
391 void ProcessXMLSubElement ( const XMLElement& e );
392 void ProcessXMLSubElementInput ( const XMLElement& e );
393 void ProcessXMLSubElementOutput ( const XMLElement& e );
394 };
395
396
397 class InvokeFile
398 {
399 public:
400 const XMLElement& node;
401 std::string name;
402 std::string switches;
403
404 InvokeFile ( const XMLElement& _node,
405 const std::string& _name );
406
407 void ProcessXML ();
408 };
409
410
411 class Dependency
412 {
413 public:
414 const XMLElement& node;
415 const Module& module;
416 const Module* dependencyModule;
417
418 Dependency ( const XMLElement& _node,
419 const Module& _module );
420
421 void ProcessXML();
422 };
423
424
425 class ImportLibrary
426 {
427 public:
428 const XMLElement& node;
429 const Module& module;
430 std::string basename;
431 std::string definition;
432
433 ImportLibrary ( const XMLElement& _node,
434 const Module& module );
435
436 void ProcessXML ();
437 };
438
439
440 class If
441 {
442 public:
443 const XMLElement& node;
444 const Project& project;
445 const Module* module;
446 const bool negated;
447 std::string property, value;
448 IfableData data;
449
450 If ( const XMLElement& node_,
451 const Project& project_,
452 const Module* module_,
453 const bool negated_ = false );
454 ~If();
455
456 void ProcessXML();
457 };
458
459
460 class CompilerFlag
461 {
462 public:
463 const Project& project;
464 const Module* module;
465 const XMLElement& node;
466 std::string flag;
467
468 CompilerFlag ( const Project& project,
469 const XMLElement& compilerFlagNode );
470 CompilerFlag ( const Project& project,
471 const Module* module,
472 const XMLElement& compilerFlagNode );
473 ~CompilerFlag ();
474 void ProcessXML();
475 private:
476 void Initialize();
477 };
478
479
480 class LinkerFlag
481 {
482 public:
483 const Project& project;
484 const Module* module;
485 const XMLElement& node;
486 std::string flag;
487
488 LinkerFlag ( const Project& project,
489 const XMLElement& linkerFlagNode );
490 LinkerFlag ( const Project& project,
491 const Module* module,
492 const XMLElement& linkerFlagNode );
493 ~LinkerFlag ();
494 void ProcessXML();
495 private:
496 void Initialize();
497 };
498
499
500 class LinkerScript
501 {
502 public:
503 const Project& project;
504 const Module* module;
505 const XMLElement& node;
506 const Module* baseModule;
507 std::string directory;
508 std::string basePath;
509
510 LinkerScript ( const Project& project,
511 const Module* module,
512 const XMLElement& node );
513 ~LinkerScript ();
514 void ProcessXML();
515 };
516
517
518 class Property
519 {
520 public:
521 const XMLElement& node;
522 const Project& project;
523 const Module* module;
524 std::string name, value;
525
526 Property ( const XMLElement& node_,
527 const Project& project_,
528 const Module* module_ );
529
530 void ProcessXML();
531 };
532
533
534 class TestSupportCode
535 {
536 public:
537 const Project& project;
538
539 TestSupportCode ( const Project& project );
540 ~TestSupportCode ();
541 void GenerateTestSupportCode ( bool verbose );
542 private:
543 bool IsTestModule ( const Module& module );
544 void GenerateTestSupportCodeForModule ( Module& module,
545 bool verbose );
546 std::string GetHooksFilename ( Module& module );
547 char* WriteStubbedSymbolToHooksFile ( char* buffer,
548 const StubbedComponent& component,
549 const StubbedSymbol& symbol );
550 char* WriteStubbedComponentToHooksFile ( char* buffer,
551 const StubbedComponent& component );
552 void WriteHooksFile ( Module& module );
553 std::string GetStubsFilename ( Module& module );
554 char* WriteStubbedSymbolToStubsFile ( char* buffer,
555 const StubbedComponent& component,
556 const StubbedSymbol& symbol,
557 int stubIndex );
558 char* WriteStubbedComponentToStubsFile ( char* buffer,
559 const StubbedComponent& component,
560 int* stubIndex );
561 void WriteStubsFile ( Module& module );
562 std::string GetStartupFilename ( Module& module );
563 bool IsUnknownCharacter ( char ch );
564 std::string GetTestDispatcherName ( std::string filename );
565 bool IsTestFile ( std::string& filename ) const;
566 void GetSourceFilenames ( string_list& list,
567 Module& module ) const;
568 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer,
569 Module& module );
570 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer,
571 Module& module );
572 void WriteStartupFile ( Module& module );
573 };
574
575
576 class WineResource
577 {
578 public:
579 const Project& project;
580 std::string bin2res;
581
582 WineResource ( const Project& project,
583 std::string bin2res );
584 ~WineResource ();
585 void UnpackResources ( bool verbose );
586 private:
587 bool IsSpecFile ( const File& file );
588 bool IsWineModule ( const Module& module );
589 bool IsResourceFile ( const File& file );
590 std::string GetResourceFilename ( const Module& module );
591 void UnpackResourcesInModule ( Module& module,
592 bool verbose );
593 };
594
595
596 class SourceFile
597 {
598 public:
599 SourceFile ( AutomaticDependency* automaticDependency,
600 const Module& module,
601 const std::string& filename,
602 SourceFile* parent,
603 bool isNonAutomaticDependency );
604 SourceFile* ParseFile ( const std::string& normalizedFilename );
605 void Parse ();
606 std::string Location () const;
607 std::vector<SourceFile*> files;
608 AutomaticDependency* automaticDependency;
609 const Module& module;
610 std::string filename;
611 std::string filenamePart;
612 std::string directoryPart;
613 std::vector<SourceFile*> parents; /* List of files, this file is included from */
614 bool isNonAutomaticDependency;
615 std::string cachedDependencies;
616 time_t lastWriteTime;
617 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
618 SourceFile* youngestFile;
619 private:
620 void GetDirectoryAndFilenameParts ();
621 void Close ();
622 void Open ();
623 void SkipWhitespace ();
624 bool ReadInclude ( std::string& filename,
625 bool& searchCurrentDirectory,
626 bool& includeNext );
627 bool IsIncludedFrom ( const std::string& normalizedFilename );
628 SourceFile* GetParentSourceFile ();
629 bool CanProcessFile ( const std::string& extension );
630 bool IsParentOf ( const SourceFile* parent,
631 const SourceFile* child );
632 std::string buf;
633 const char *p;
634 const char *end;
635 };
636
637
638 class AutomaticDependency
639 {
640 friend class SourceFileTest;
641 public:
642 const Project& project;
643
644 AutomaticDependency ( const Project& project );
645 ~AutomaticDependency ();
646 std::string GetFilename ( const std::string& filename );
647 bool LocateIncludedFile ( const std::string& directory,
648 const std::string& includedFilename,
649 std::string& resolvedFilename );
650 bool LocateIncludedFile ( SourceFile* sourceFile,
651 const Module& module,
652 const std::string& includedFilename,
653 bool searchCurrentDirectory,
654 bool includeNext,
655 std::string& resolvedFilename );
656 SourceFile* RetrieveFromCacheOrParse ( const Module& module,
657 const std::string& filename,
658 SourceFile* parentSourceFile );
659 SourceFile* RetrieveFromCache ( const std::string& filename );
660 void CheckAutomaticDependencies ( bool verbose );
661 void CheckAutomaticDependenciesForModule ( Module& module,
662 bool verbose );
663 private:
664 void GetModulesToCheck ( Module& module, std::vector<const Module*>& modules );
665 void CheckAutomaticDependencies ( const Module& module,
666 bool verbose );
667 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
668 void GetIncludeDirectories ( std::vector<Include*>& includes,
669 const Module& module,
670 Include& currentDirectory,
671 bool searchCurrentDirectory );
672 void GetModuleFiles ( const Module& module,
673 std::vector<File*>& files ) const;
674 void ParseFiles ();
675 void ParseFiles ( const Module& module );
676 void ParseFile ( const Module& module,
677 const File& file );
678 std::map<std::string, SourceFile*> sourcefile_map;
679 };
680
681
682 class Bootstrap
683 {
684 public:
685 const Project& project;
686 const Module* module;
687 const XMLElement& node;
688 std::string base;
689 std::string nameoncd;
690
691 Bootstrap ( const Project& project,
692 const Module* module,
693 const XMLElement& bootstrapNode );
694 ~Bootstrap ();
695 void ProcessXML();
696 private:
697 bool IsSupportedModuleType ( ModuleType type );
698 void Initialize();
699 };
700
701
702 class CDFile
703 {
704 public:
705 const Project& project;
706 const XMLElement& node;
707 std::string name;
708 std::string base;
709 std::string nameoncd;
710 std::string path;
711
712 CDFile ( const Project& project,
713 const XMLElement& bootstrapNode,
714 const std::string& path );
715 ~CDFile ();
716 void ProcessXML();
717 std::string GetPath () const;
718 };
719
720
721 class InstallFile
722 {
723 public:
724 const Project& project;
725 const XMLElement& node;
726 std::string name;
727 std::string base;
728 std::string newname;
729 std::string path;
730
731 InstallFile ( const Project& project,
732 const XMLElement& bootstrapNode,
733 const std::string& path );
734 ~InstallFile ();
735 void ProcessXML ();
736 std::string GetPath () const;
737 };
738
739
740 class PchFile
741 {
742 public:
743 const XMLElement& node;
744 const Module& module;
745 File file;
746
747 PchFile (
748 const XMLElement& node,
749 const Module& module,
750 const File file );
751 void ProcessXML();
752 };
753
754
755 class StubbedComponent
756 {
757 public:
758 const Module* module;
759 const XMLElement& node;
760 std::string name;
761 std::vector<StubbedSymbol*> symbols;
762
763 StubbedComponent ( const Module* module_,
764 const XMLElement& stubbedComponentNode );
765 ~StubbedComponent ();
766 void ProcessXML ();
767 void ProcessXMLSubElement ( const XMLElement& e );
768 };
769
770
771 class StubbedSymbol
772 {
773 public:
774 const XMLElement& node;
775 std::string symbol;
776 std::string newname;
777 std::string strippedName;
778
779 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
780 ~StubbedSymbol ();
781 void ProcessXML();
782 private:
783 std::string StripSymbol ( std::string symbol );
784 };
785
786
787 class CompilationUnit
788 {
789 public:
790 const Project* project;
791 const Module* module;
792 const XMLElement* node;
793 std::vector<File*> files;
794
795 CompilationUnit ( File* file );
796 CompilationUnit ( const Project* project,
797 const Module* module,
798 const XMLElement* node );
799 ~CompilationUnit ();
800 void ProcessXML();
801 bool IsGeneratedFile () const;
802 bool HasFileWithExtension ( const std::string& extension ) const;
803 bool IsFirstFile () const;
804 std::string GetFilename () const;
805 std::string GetSwitches () const;
806 };
807
808
809 extern void
810 InitializeEnvironment ();
811
812 extern std::string
813 Right ( const std::string& s, size_t n );
814
815 extern std::string
816 Replace ( const std::string& s, const std::string& find, const std::string& with );
817
818 extern std::string
819 FixSeparator ( const std::string& s );
820
821 extern std::string
822 FixSeparatorForSystemCommand ( const std::string& s );
823
824 extern std::string
825 DosSeparator ( const std::string& s );
826
827 extern std::string
828 ReplaceExtension (
829 const std::string& filename,
830 const std::string& newExtension );
831
832 extern std::string
833 GetSubPath (
834 const std::string& location,
835 const std::string& path,
836 const std::string& att_value );
837
838 extern std::string
839 GetExtension ( const std::string& filename );
840
841 extern std::string
842 GetDirectory ( const std::string& filename );
843
844 extern std::string
845 GetFilename ( const std::string& filename );
846
847 extern std::string
848 NormalizeFilename ( const std::string& filename );
849
850 #endif /* __RBUILD_H */