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