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