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