60671e083d928587c6c0cc250ce7e34a2df4e166
[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 guid;
218 std::string extension;
219 std::string entrypoint;
220 std::string baseaddress;
221 std::string path;
222 ModuleType type;
223 ImportLibrary* importLibrary;
224 bool mangledSymbols;
225 Bootstrap* bootstrap;
226 IfableData non_if_data;
227 std::vector<Invoke*> invocations;
228 std::vector<Dependency*> dependencies;
229 std::vector<CompilerFlag*> compilerFlags;
230 std::vector<LinkerFlag*> linkerFlags;
231 std::vector<StubbedComponent*> stubbedComponents;
232 PchFile* pch;
233 bool cplusplus;
234 std::string prefix;
235 HostType host;
236 std::string installBase;
237 std::string installName;
238 std::string aliasedModuleName;
239 bool useWRC;
240 bool allowWarnings;
241 bool enabled;
242
243 Module ( const Project& project,
244 const XMLElement& moduleNode,
245 const std::string& modulePath );
246 ~Module ();
247 ModuleType GetModuleType ( const std::string& location,
248 const XMLAttribute& attribute );
249 bool HasImportLibrary () const;
250 bool IsDLL () const;
251 bool GenerateInOutputTree () const;
252 std::string GetTargetName () const; // "foo.exe"
253 std::string GetDependencyPath () const; // "path/foo.exe" or "path/libfoo.a"
254 std::string GetBasePath () const; // "path"
255 std::string GetPath () const; // "path/foo.exe"
256 std::string GetPathWithPrefix ( const std::string& prefix ) const; // "path/prefixfoo.exe"
257 void GetTargets ( string_list& ) const;
258 std::string GetInvocationTarget ( const int index ) const;
259 bool HasFileWithExtension ( const IfableData&, const std::string& extension ) const;
260 void InvokeModule () const;
261 void ProcessXML ();
262 void GetSourceFilenames ( string_list& list,
263 bool includeGeneratedFiles ) const;
264 private:
265 std::string GetDefaultModuleExtension () const;
266 std::string GetDefaultModuleEntrypoint () const;
267 std::string GetDefaultModuleBaseaddress () const;
268 void ProcessXMLSubElement ( const XMLElement& e,
269 const std::string& path,
270 If* pIf = NULL );
271 };
272
273
274 class Include
275 {
276 public:
277 const Project& project;
278 const Module* module;
279 const XMLElement* node;
280 const Module* baseModule;
281 std::string directory;
282 std::string basePath;
283
284 Include ( const Project& project,
285 const XMLElement* includeNode );
286 Include ( const Project& project,
287 const Module* module,
288 const XMLElement* includeNode );
289 Include ( const Project& project,
290 std::string directory,
291 std::string basePath );
292 ~Include ();
293 void ProcessXML();
294 private:
295 };
296
297
298 class Define
299 {
300 public:
301 const Project& project;
302 const Module* module;
303 const XMLElement& node;
304 std::string name;
305 std::string value;
306
307 Define ( const Project& project,
308 const XMLElement& defineNode );
309 Define ( const Project& project,
310 const Module* module,
311 const XMLElement& defineNode );
312 ~Define();
313 void ProcessXML();
314 private:
315 void Initialize();
316 };
317
318
319 class File
320 {
321 public:
322 std::string name;
323 bool first;
324 std::string switches;
325 bool isPreCompiledHeader;
326
327 File ( const std::string& _name,
328 bool _first,
329 std::string _switches,
330 bool _isPreCompiledHeader );
331
332 void ProcessXML();
333 bool IsGeneratedFile () const;
334 };
335
336
337 class Library
338 {
339 public:
340 const XMLElement& node;
341 const Module& module;
342 std::string name;
343 const Module* importedModule;
344
345 Library ( const XMLElement& _node,
346 const Module& _module,
347 const std::string& _name );
348
349 void ProcessXML();
350 };
351
352
353 class Invoke
354 {
355 public:
356 const XMLElement& node;
357 const Module& module;
358 const Module* invokeModule;
359 std::vector<InvokeFile*> input;
360 std::vector<InvokeFile*> output;
361
362 Invoke ( const XMLElement& _node,
363 const Module& _module );
364
365 void ProcessXML();
366 void GetTargets ( string_list& targets ) const;
367 std::string GetParameters () const;
368 private:
369 void ProcessXMLSubElement ( const XMLElement& e );
370 void ProcessXMLSubElementInput ( const XMLElement& e );
371 void ProcessXMLSubElementOutput ( const XMLElement& e );
372 };
373
374
375 class InvokeFile
376 {
377 public:
378 const XMLElement& node;
379 std::string name;
380 std::string switches;
381
382 InvokeFile ( const XMLElement& _node,
383 const std::string& _name );
384
385 void ProcessXML ();
386 };
387
388
389 class Dependency
390 {
391 public:
392 const XMLElement& node;
393 const Module& module;
394 const Module* dependencyModule;
395
396 Dependency ( const XMLElement& _node,
397 const Module& _module );
398
399 void ProcessXML();
400 };
401
402
403 class ImportLibrary
404 {
405 public:
406 const XMLElement& node;
407 const Module& module;
408 std::string basename;
409 std::string definition;
410
411 ImportLibrary ( const XMLElement& _node,
412 const Module& module );
413
414 void ProcessXML ();
415 };
416
417
418 class If
419 {
420 public:
421 const XMLElement& node;
422 const Project& project;
423 const Module* module;
424 const bool negated;
425 std::string property, value;
426 IfableData data;
427
428 If ( const XMLElement& node_,
429 const Project& project_,
430 const Module* module_,
431 const bool negated_ = false );
432 ~If();
433
434 void ProcessXML();
435 };
436
437
438 class CompilerFlag
439 {
440 public:
441 const Project& project;
442 const Module* module;
443 const XMLElement& node;
444 std::string flag;
445
446 CompilerFlag ( const Project& project,
447 const XMLElement& compilerFlagNode );
448 CompilerFlag ( const Project& project,
449 const Module* module,
450 const XMLElement& compilerFlagNode );
451 ~CompilerFlag ();
452 void ProcessXML();
453 private:
454 void Initialize();
455 };
456
457
458 class LinkerFlag
459 {
460 public:
461 const Project& project;
462 const Module* module;
463 const XMLElement& node;
464 std::string flag;
465
466 LinkerFlag ( const Project& project,
467 const XMLElement& linkerFlagNode );
468 LinkerFlag ( const Project& project,
469 const Module* module,
470 const XMLElement& linkerFlagNode );
471 ~LinkerFlag ();
472 void ProcessXML();
473 private:
474 void Initialize();
475 };
476
477
478 class Property
479 {
480 public:
481 const XMLElement& node;
482 const Project& project;
483 const Module* module;
484 std::string name, value;
485
486 Property ( const XMLElement& node_,
487 const Project& project_,
488 const Module* module_ );
489
490 void ProcessXML();
491 };
492
493
494 class TestSupportCode
495 {
496 public:
497 const Project& project;
498
499 TestSupportCode ( const Project& project );
500 ~TestSupportCode ();
501 void GenerateTestSupportCode ( bool verbose );
502 private:
503 bool IsTestModule ( const Module& module );
504 void GenerateTestSupportCodeForModule ( Module& module,
505 bool verbose );
506 std::string GetHooksFilename ( Module& module );
507 char* WriteStubbedSymbolToHooksFile ( char* buffer,
508 const StubbedComponent& component,
509 const StubbedSymbol& symbol );
510 char* WriteStubbedComponentToHooksFile ( char* buffer,
511 const StubbedComponent& component );
512 void WriteHooksFile ( Module& module );
513 std::string GetStubsFilename ( Module& module );
514 char* WriteStubbedSymbolToStubsFile ( char* buffer,
515 const StubbedComponent& component,
516 const StubbedSymbol& symbol,
517 int stubIndex );
518 char* WriteStubbedComponentToStubsFile ( char* buffer,
519 const StubbedComponent& component,
520 int* stubIndex );
521 void WriteStubsFile ( Module& module );
522 std::string GetStartupFilename ( Module& module );
523 bool IsUnknownCharacter ( char ch );
524 std::string GetTestDispatcherName ( std::string filename );
525 bool IsTestFile ( std::string& filename ) const;
526 void GetSourceFilenames ( string_list& list,
527 Module& module ) const;
528 char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer,
529 Module& module );
530 char* WriteRegisterTestsFunctionToStartupFile ( char* buffer,
531 Module& module );
532 void WriteStartupFile ( Module& module );
533 };
534
535
536 class WineResource
537 {
538 public:
539 const Project& project;
540 std::string bin2res;
541
542 WineResource ( const Project& project,
543 std::string bin2res );
544 ~WineResource ();
545 void UnpackResources ( bool verbose );
546 private:
547 bool IsSpecFile ( const File& file );
548 bool IsWineModule ( const Module& module );
549 bool IsResourceFile ( const File& file );
550 std::string GetResourceFilename ( const Module& module );
551 void UnpackResourcesInModule ( Module& module,
552 bool verbose );
553 };
554
555
556 class SourceFile
557 {
558 public:
559 SourceFile ( AutomaticDependency* automaticDependency,
560 const Module& module,
561 const std::string& filename,
562 SourceFile* parent,
563 bool isNonAutomaticDependency );
564 SourceFile* ParseFile ( const std::string& normalizedFilename );
565 void Parse ();
566 std::string Location () const;
567 std::vector<SourceFile*> files;
568 AutomaticDependency* automaticDependency;
569 const Module& module;
570 std::string filename;
571 std::string filenamePart;
572 std::string directoryPart;
573 std::vector<SourceFile*> parents; /* List of files, this file is included from */
574 bool isNonAutomaticDependency;
575 std::string cachedDependencies;
576 time_t lastWriteTime;
577 time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
578 SourceFile* youngestFile;
579 private:
580 void GetDirectoryAndFilenameParts ();
581 void Close ();
582 void Open ();
583 void SkipWhitespace ();
584 bool ReadInclude ( std::string& filename,
585 bool& searchCurrentDirectory,
586 bool& includeNext );
587 bool IsIncludedFrom ( const std::string& normalizedFilename );
588 SourceFile* GetParentSourceFile ();
589 bool CanProcessFile ( const std::string& extension );
590 bool IsParentOf ( const SourceFile* parent,
591 const SourceFile* child );
592 std::string buf;
593 const char *p;
594 const char *end;
595 };
596
597
598 class AutomaticDependency
599 {
600 friend class SourceFileTest;
601 public:
602 const Project& project;
603
604 AutomaticDependency ( const Project& project );
605 ~AutomaticDependency ();
606 std::string GetFilename ( const std::string& filename );
607 bool LocateIncludedFile ( const std::string& directory,
608 const std::string& includedFilename,
609 std::string& resolvedFilename );
610 bool LocateIncludedFile ( SourceFile* sourceFile,
611 const Module& module,
612 const std::string& includedFilename,
613 bool searchCurrentDirectory,
614 bool includeNext,
615 std::string& resolvedFilename );
616 SourceFile* RetrieveFromCacheOrParse ( const Module& module,
617 const std::string& filename,
618 SourceFile* parentSourceFile );
619 SourceFile* RetrieveFromCache ( const std::string& filename );
620 void CheckAutomaticDependencies ( bool verbose );
621 void CheckAutomaticDependenciesForModule ( Module& module,
622 bool verbose );
623 private:
624 void GetModulesToCheck ( Module& module, std::vector<const Module*>& modules );
625 void CheckAutomaticDependencies ( const Module& module,
626 bool verbose );
627 void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
628 void GetIncludeDirectories ( std::vector<Include*>& includes,
629 const Module& module,
630 Include& currentDirectory,
631 bool searchCurrentDirectory );
632 void GetModuleFiles ( const Module& module,
633 std::vector<File*>& files ) const;
634 void ParseFiles ();
635 void ParseFiles ( const Module& module );
636 void ParseFile ( const Module& module,
637 const File& file );
638 std::map<std::string, SourceFile*> sourcefile_map;
639 };
640
641
642 class Bootstrap
643 {
644 public:
645 const Project& project;
646 const Module* module;
647 const XMLElement& node;
648 std::string base;
649 std::string nameoncd;
650
651 Bootstrap ( const Project& project,
652 const Module* module,
653 const XMLElement& bootstrapNode );
654 ~Bootstrap ();
655 void ProcessXML();
656 private:
657 bool IsSupportedModuleType ( ModuleType type );
658 void Initialize();
659 };
660
661
662 class CDFile
663 {
664 public:
665 const Project& project;
666 const XMLElement& node;
667 std::string name;
668 std::string base;
669 std::string nameoncd;
670 std::string path;
671
672 CDFile ( const Project& project,
673 const XMLElement& bootstrapNode,
674 const std::string& path );
675 ~CDFile ();
676 void ProcessXML();
677 std::string GetPath () const;
678 };
679
680
681 class InstallFile
682 {
683 public:
684 const Project& project;
685 const XMLElement& node;
686 std::string name;
687 std::string base;
688 std::string newname;
689 std::string path;
690
691 InstallFile ( const Project& project,
692 const XMLElement& bootstrapNode,
693 const std::string& path );
694 ~InstallFile ();
695 void ProcessXML ();
696 std::string GetPath () const;
697 };
698
699
700 class PchFile
701 {
702 public:
703 const XMLElement& node;
704 const Module& module;
705 File file;
706
707 PchFile (
708 const XMLElement& node,
709 const Module& module,
710 const File file );
711 void ProcessXML();
712 };
713
714
715 class StubbedComponent
716 {
717 public:
718 const Module* module;
719 const XMLElement& node;
720 std::string name;
721 std::vector<StubbedSymbol*> symbols;
722
723 StubbedComponent ( const Module* module_,
724 const XMLElement& stubbedComponentNode );
725 ~StubbedComponent ();
726 void ProcessXML ();
727 void ProcessXMLSubElement ( const XMLElement& e );
728 };
729
730
731 class StubbedSymbol
732 {
733 public:
734 const XMLElement& node;
735 std::string symbol;
736 std::string newname;
737 std::string strippedName;
738
739 StubbedSymbol ( const XMLElement& stubbedSymbolNode );
740 ~StubbedSymbol ();
741 void ProcessXML();
742 private:
743 std::string StripSymbol ( std::string symbol );
744 };
745
746 extern std::string
747 Right ( const std::string& s, size_t n );
748
749 extern std::string
750 Replace ( const std::string& s, const std::string& find, const std::string& with );
751
752 extern std::string
753 FixSeparator ( const std::string& s );
754
755 extern std::string
756 DosSeparator ( const std::string& s );
757
758 extern std::string
759 ReplaceExtension (
760 const std::string& filename,
761 const std::string& newExtension );
762
763 extern std::string
764 GetSubPath (
765 const std::string& location,
766 const std::string& path,
767 const std::string& att_value );
768
769 extern std::string
770 GetExtension ( const std::string& filename );
771
772 extern std::string
773 GetDirectory ( const std::string& filename );
774
775 extern std::string
776 GetFilename ( const std::string& filename );
777
778 extern std::string
779 NormalizeFilename ( const std::string& filename );
780
781 #endif /* __RBUILD_H */