Build snmpapi and network applications
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
1 #include "../../pch.h"
2 #include <assert.h>
3
4 #include "../../rbuild.h"
5 #include "mingw.h"
6 #include "modulehandler.h"
7
8 using std::string;
9 using std::vector;
10 using std::map;
11 using std::set;
12
13 typedef set<string> set_string;
14
15 map<ModuleType,MingwModuleHandler*>*
16 MingwModuleHandler::handler_map = NULL;
17 set_string
18 MingwModuleHandler::directory_set;
19 int
20 MingwModuleHandler::ref = 0;
21
22 FILE*
23 MingwModuleHandler::fMakefile = NULL;
24
25 string
26 ReplaceExtension ( const string& filename,
27 const string& newExtension )
28 {
29 size_t index = filename.find_last_of ( '/' );
30 if (index == string::npos) index = 0;
31 string tmp = filename.substr( index, filename.size() - index );
32 size_t ext_index = tmp.find_last_of( '.' );
33 if (ext_index != string::npos)
34 return filename.substr ( 0, index + ext_index ) + newExtension;
35 return filename + newExtension;
36 }
37
38
39 MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype )
40 {
41 if ( !ref++ )
42 handler_map = new map<ModuleType,MingwModuleHandler*>;
43 (*handler_map)[moduletype] = this;
44 }
45
46 MingwModuleHandler::~MingwModuleHandler()
47 {
48 if ( !--ref )
49 {
50 delete handler_map;
51 handler_map = NULL;
52 }
53 }
54
55 const string &
56 MingwModuleHandler::PassThruCacheDirectory( const string &file ) const
57 {
58 directory_set.insert( ReplaceExtension( GetDirectory( file ), "" ) );
59 return file;
60 }
61
62 void
63 MingwModuleHandler::SetMakefile ( FILE* f )
64 {
65 fMakefile = f;
66 }
67
68 MingwModuleHandler*
69 MingwModuleHandler::LookupHandler ( const string& location,
70 ModuleType moduletype )
71 {
72 if ( !handler_map )
73 throw Exception ( "internal tool error: no registered module handlers" );
74 MingwModuleHandler* h = (*handler_map)[moduletype];
75 if ( !h )
76 {
77 throw UnknownModuleTypeException ( location, moduletype );
78 return NULL;
79 }
80 return h;
81 }
82
83 string
84 MingwModuleHandler::GetWorkingDirectory () const
85 {
86 return ".";
87 }
88
89 string
90 MingwModuleHandler::GetDirectory ( const string& filename )
91 {
92 size_t index = filename.find_last_of ( CSEP );
93 if (index == string::npos)
94 return ".";
95 else
96 return filename.substr ( 0, index );
97 }
98
99 string
100 MingwModuleHandler::GetBasename ( const string& filename ) const
101 {
102 size_t index = filename.find_last_of ( '.' );
103 if (index != string::npos)
104 return filename.substr ( 0, index );
105 return "";
106 }
107
108 string
109 MingwModuleHandler::GetActualSourceFilename ( const string& filename ) const
110 {
111 string extension = GetExtension ( filename );
112 if ( extension == ".spec" || extension == "SPEC" )
113 {
114 string basename = GetBasename( filename );
115 return basename + ".stubs.c";
116 }
117 else
118 return filename;
119 }
120
121 string
122 MingwModuleHandler::GetModuleArchiveFilename ( const Module& module ) const
123 {
124 return ReplaceExtension ( FixupTargetFilename ( module.GetPath () ),
125 ".a" );
126 }
127
128 bool
129 MingwModuleHandler::IsGeneratedFile ( const File& file ) const
130 {
131 string extension = GetExtension ( file.name );
132 if ( extension == ".spec" || extension == "SPEC" )
133 return true;
134 else
135 return false;
136 }
137
138 string
139 MingwModuleHandler::GetImportLibraryDependency ( const Module& importedModule ) const
140 {
141 if ( importedModule.type == ObjectLibrary )
142 return GetObjectsMacro ( importedModule );
143 else
144 return PassThruCacheDirectory ( FixupTargetFilename ( importedModule.GetDependencyPath () ) );
145 }
146
147 string
148 MingwModuleHandler::GetImportLibraryDependencies ( const Module& module ) const
149 {
150 string dependencies ( "" );
151 for ( size_t i = 0; i < module.libraries.size (); i++ )
152 {
153 if ( dependencies.size () > 0 )
154 dependencies += " ";
155 const Module* importedModule = module.project.LocateModule ( module.libraries[i]->name );
156 assert ( importedModule != NULL );
157 dependencies += GetImportLibraryDependency ( *importedModule );
158 }
159 return dependencies;
160 }
161
162 string
163 MingwModuleHandler::GetModuleDependencies ( const Module& module ) const
164 {
165 if ( module.dependencies.size () == 0 )
166 return "";
167
168 string dependencies ( "" );
169 for ( size_t i = 0; i < module.dependencies.size (); i++ )
170 {
171 if ( dependencies.size () > 0 )
172 dependencies += " ";
173 const Dependency* dependency = module.dependencies[i];
174 const Module* dependencyModule = dependency->dependencyModule;
175 dependencies += dependencyModule->GetTargets ();
176 }
177 string definitionDependencies = GetDefinitionDependencies ( module );
178 if ( dependencies.length () > 0 && definitionDependencies.length () > 0 )
179 dependencies += " " + definitionDependencies;
180 else if ( definitionDependencies.length () > 0 )
181 dependencies = definitionDependencies;
182 return dependencies;
183 }
184
185 string
186 MingwModuleHandler::GetAllDependencies ( const Module& module ) const
187 {
188 string dependencies = GetImportLibraryDependencies ( module );
189 string s = GetModuleDependencies ( module );
190 if (s.length () > 0)
191 {
192 dependencies += " ";
193 dependencies += s;
194 }
195 return dependencies;
196 }
197
198 string
199 MingwModuleHandler::GetSourceFilenames ( const Module& module,
200 bool includeGeneratedFiles ) const
201 {
202 size_t i;
203
204 string sourceFilenames ( "" );
205 for ( i = 0; i < module.files.size (); i++ )
206 {
207 if ( includeGeneratedFiles || !IsGeneratedFile ( *module.files[i] ) )
208 sourceFilenames += " " + GetActualSourceFilename ( module.files[i]->name );
209 }
210 vector<If*> ifs = module.ifs;
211 for ( i = 0; i < ifs.size(); i++ )
212 {
213 size_t j;
214 If& rIf = *ifs[i];
215 for ( j = 0; j < rIf.ifs.size(); j++ )
216 ifs.push_back ( rIf.ifs[j] );
217 for ( j = 0; j < rIf.files.size(); j++ )
218 {
219 if ( includeGeneratedFiles || !IsGeneratedFile ( *rIf.files[j] ) )
220 sourceFilenames += " " + GetActualSourceFilename ( rIf.files[j]->name );
221 }
222 }
223 return sourceFilenames;
224 }
225
226 string
227 MingwModuleHandler::GetSourceFilenames ( const Module& module ) const
228 {
229 return GetSourceFilenames ( module,
230 true );
231 }
232
233 string
234 MingwModuleHandler::GetSourceFilenamesWithoutGeneratedFiles ( const Module& module ) const
235 {
236 return GetSourceFilenames ( module,
237 false );
238 }
239
240 string
241 MingwModuleHandler::GetObjectFilename ( const string& sourceFilename )
242 {
243 string newExtension;
244 string extension = GetExtension ( sourceFilename );
245 if ( extension == ".rc" || extension == ".RC" )
246 newExtension = ".coff";
247 else if ( extension == ".spec" || extension == ".SPEC" )
248 newExtension = ".stubs.o";
249 else
250 newExtension = ".o";
251 return FixupTargetFilename (
252 ReplaceExtension ( sourceFilename, newExtension ) );
253 }
254
255 string
256 MingwModuleHandler::GetObjectFilenames ( const Module& module ) const
257 {
258 if ( module.files.size () == 0 )
259 return "";
260
261 string objectFilenames ( "" );
262 for ( size_t i = 0; i < module.files.size (); i++ )
263 {
264 if ( objectFilenames.size () > 0 )
265 objectFilenames += " ";
266 objectFilenames += PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( module.files[i]->name ) );
267 }
268 return objectFilenames;
269 }
270
271 void
272 MingwModuleHandler::GenerateDirectoryTargets() const
273 {
274 set_string::iterator i;
275 fprintf( fMakefile, "ifneq ($(ROS_INTERMEDIATE),)\ndirectories::" );
276
277 for ( i = directory_set.begin();
278 i != directory_set.end();
279 i++ )
280 {
281 fprintf ( fMakefile, " %s", i->c_str() );
282 }
283
284 fprintf( fMakefile, "\n\n" );
285
286 for ( i = directory_set.begin();
287 i != directory_set.end();
288 i++ )
289 {
290 fprintf ( fMakefile, "%s ", i->c_str() );
291 }
292
293 fprintf ( fMakefile,
294 "::\n\t${mkdir} $@\n\n"
295 "else\n"
296 "directories::\n\n"
297 "endif\n\n" );
298
299 directory_set.clear();
300 }
301
302 string
303 MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector<Define*>& defines ) const
304 {
305 string parameters;
306 for ( size_t i = 0; i < defines.size (); i++ )
307 {
308 Define& define = *defines[i];
309 if (parameters.length () > 0)
310 parameters += " ";
311 parameters += "-D";
312 parameters += define.name;
313 if (define.value.length () > 0)
314 {
315 parameters += "=";
316 parameters += define.value;
317 }
318 }
319 return parameters;
320 }
321
322 string
323 MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const
324 {
325 string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );
326 string s = GenerateGccDefineParametersFromVector ( module.defines );
327 if ( s.length () > 0 )
328 {
329 parameters += " ";
330 parameters += s;
331 }
332 return parameters;
333 }
334
335 string
336 MingwModuleHandler::ConcatenatePaths ( const string& path1,
337 const string& path2 ) const
338 {
339 if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )
340 return path2;
341 if ( path1[path1.length ()] == CSEP )
342 return path1 + path2;
343 else
344 return path1 + CSEP + path2;
345 }
346
347 string
348 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes ) const
349 {
350 string parameters;
351 for ( size_t i = 0; i < includes.size (); i++ )
352 {
353 Include& include = *includes[i];
354 if (parameters.length () > 0)
355 parameters += " ";
356 parameters += "-I" + include.directory;
357 }
358 return parameters;
359 }
360
361 string
362 MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const
363 {
364 string parameters = GenerateGccIncludeParametersFromVector ( module.includes );
365 string s = GenerateGccIncludeParametersFromVector ( module.project.includes );
366 if ( s.length () > 0 )
367 {
368 parameters += " ";
369 parameters += s;
370 }
371 return parameters;
372 }
373
374
375 string
376 MingwModuleHandler::GenerateCompilerParametersFromVector ( const vector<CompilerFlag*>& compilerFlags ) const
377 {
378 string parameters;
379 for ( size_t i = 0; i < compilerFlags.size (); i++ )
380 {
381 CompilerFlag& compilerFlag = *compilerFlags[i];
382 if ( parameters.length () > 0 )
383 parameters += " ";
384 parameters += compilerFlag.flag;
385 }
386 return parameters;
387 }
388
389 string
390 MingwModuleHandler::GenerateLinkerParametersFromVector ( const vector<LinkerFlag*>& linkerFlags ) const
391 {
392 string parameters;
393 for ( size_t i = 0; i < linkerFlags.size (); i++ )
394 {
395 LinkerFlag& linkerFlag = *linkerFlags[i];
396 if ( parameters.length () > 0 )
397 parameters += " ";
398 parameters += linkerFlag.flag;
399 }
400 return parameters;
401 }
402
403 string
404 MingwModuleHandler::GenerateLinkerParameters ( const Module& module ) const
405 {
406 return GenerateLinkerParametersFromVector ( module.linkerFlags );
407 }
408
409 void
410 MingwModuleHandler::GenerateMacro ( const char* assignmentOperation,
411 const string& macro,
412 const vector<Include*>& includes,
413 const vector<Define*>& defines,
414 const vector<CompilerFlag*>* compilerFlags ) const
415 {
416 size_t i;
417
418 fprintf (
419 fMakefile,
420 "%s %s",
421 macro.c_str(),
422 assignmentOperation );
423
424 if ( compilerFlags != NULL )
425 {
426 string compilerParameters = GenerateCompilerParametersFromVector ( *compilerFlags );
427 if ( compilerParameters.size () > 0 )
428 {
429 fprintf (
430 fMakefile,
431 " %s",
432 compilerParameters.c_str () );
433 }
434 }
435
436 for ( i = 0; i < includes.size(); i++ )
437 {
438 fprintf (
439 fMakefile,
440 " -I%s",
441 includes[i]->directory.c_str() );
442 }
443 for ( i = 0; i < defines.size(); i++ )
444 {
445 Define& d = *defines[i];
446 fprintf (
447 fMakefile,
448 " -D%s",
449 d.name.c_str() );
450 if ( d.value.size() )
451 fprintf (
452 fMakefile,
453 "=%s",
454 d.value.c_str() );
455 }
456 fprintf ( fMakefile, "\n" );
457 }
458
459 void
460 MingwModuleHandler::GenerateMacros (
461 const char* assignmentOperation,
462 const vector<File*>& files,
463 const vector<Include*>& includes,
464 const vector<Define*>& defines,
465 const vector<CompilerFlag*>* compilerFlags,
466 const vector<LinkerFlag*>* linkerFlags,
467 const vector<If*>& ifs,
468 const string& cflags_macro,
469 const string& nasmflags_macro,
470 const string& windresflags_macro,
471 const string& linkerflags_macro,
472 const string& objs_macro) const
473 {
474 size_t i;
475
476 if ( includes.size() || defines.size() )
477 {
478 GenerateMacro ( assignmentOperation,
479 cflags_macro,
480 includes,
481 defines,
482 compilerFlags );
483 GenerateMacro ( assignmentOperation,
484 windresflags_macro,
485 includes,
486 defines,
487 compilerFlags );
488 }
489
490 if ( linkerFlags != NULL )
491 {
492 string linkerParameters = GenerateLinkerParametersFromVector ( *linkerFlags );
493 if ( linkerParameters.size () > 0 )
494 {
495 fprintf (
496 fMakefile,
497 "%s %s %s\n",
498 linkerflags_macro.c_str (),
499 assignmentOperation,
500 linkerParameters.c_str() );
501 }
502 }
503
504 if ( files.size() )
505 {
506 for ( i = 0; i < files.size(); i++ )
507 {
508 if ( files[i]->first )
509 {
510 fprintf ( fMakefile,
511 "%s := %s $(%s)\n",
512 objs_macro.c_str(),
513 PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ).c_str (),
514 objs_macro.c_str() );
515 }
516 }
517 fprintf (
518 fMakefile,
519 "%s %s",
520 objs_macro.c_str(),
521 assignmentOperation );
522 for ( i = 0; i < files.size(); i++ )
523 {
524 string extension = GetExtension ( files[i]->name );
525 if ( extension != ".spec"
526 && extension != ".SPEC"
527 && !files[i]->first )
528 {
529 fprintf (
530 fMakefile,
531 "%s%s",
532 ( i%10 == 9 ? "\\\n\t" : " " ),
533 PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ).c_str () );
534 }
535 }
536 fprintf ( fMakefile, "\n" );
537 }
538
539 for ( i = 0; i < ifs.size(); i++ )
540 {
541 If& rIf = *ifs[i];
542 if ( rIf.defines.size() || rIf.includes.size() || rIf.files.size() || rIf.ifs.size() )
543 {
544 fprintf (
545 fMakefile,
546 "ifeq (\"$(%s)\",\"%s\")\n",
547 rIf.property.c_str(),
548 rIf.value.c_str() );
549 GenerateMacros (
550 "+=",
551 rIf.files,
552 rIf.includes,
553 rIf.defines,
554 NULL,
555 NULL,
556 rIf.ifs,
557 cflags_macro,
558 nasmflags_macro,
559 windresflags_macro,
560 linkerflags_macro,
561 objs_macro );
562 fprintf (
563 fMakefile,
564 "endif\n\n" );
565 }
566 }
567 }
568
569 void
570 MingwModuleHandler::GenerateMacros (
571 const Module& module,
572 const string& cflags_macro,
573 const string& nasmflags_macro,
574 const string& windresflags_macro,
575 const string& linkerflags_macro,
576 const string& objs_macro) const
577 {
578 GenerateMacros (
579 "=",
580 module.files,
581 module.includes,
582 module.defines,
583 &module.compilerFlags,
584 &module.linkerFlags,
585 module.ifs,
586 cflags_macro,
587 nasmflags_macro,
588 windresflags_macro,
589 linkerflags_macro,
590 objs_macro );
591 fprintf ( fMakefile, "\n" );
592
593 fprintf (
594 fMakefile,
595 "%s += $(PROJECT_CFLAGS)\n\n",
596 cflags_macro.c_str () );
597
598 fprintf (
599 fMakefile,
600 "%s += $(PROJECT_RCFLAGS)\n\n",
601 windresflags_macro.c_str () );
602
603 fprintf (
604 fMakefile,
605 "%s_LFLAGS += $(PROJECT_LFLAGS)\n\n",
606 module.name.c_str () );
607 }
608
609 void
610 MingwModuleHandler::GenerateGccCommand ( const Module& module,
611 const string& sourceFilename,
612 const string& cc,
613 const string& cflagsMacro ) const
614 {
615 string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
616 fprintf ( fMakefile,
617 "%s: %s\n",
618 objectFilename.c_str (),
619 sourceFilename.c_str () );
620 fprintf ( fMakefile,
621 "\t%s -c %s -o %s %s\n",
622 cc.c_str (),
623 sourceFilename.c_str (),
624 objectFilename.c_str (),
625 cflagsMacro.c_str () );
626 }
627
628 void
629 MingwModuleHandler::GenerateGccAssemblerCommand ( const Module& module,
630 const string& sourceFilename,
631 const string& cc,
632 const string& cflagsMacro ) const
633 {
634 string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
635 fprintf ( fMakefile,
636 "%s: %s\n",
637 objectFilename.c_str (),
638 sourceFilename.c_str () );
639 fprintf ( fMakefile,
640 "\t%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",
641 cc.c_str (),
642 sourceFilename.c_str (),
643 objectFilename.c_str (),
644 cflagsMacro.c_str () );
645 }
646
647 void
648 MingwModuleHandler::GenerateNasmCommand ( const Module& module,
649 const string& sourceFilename,
650 const string& nasmflagsMacro ) const
651 {
652 string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
653 fprintf ( fMakefile,
654 "%s: %s\n",
655 objectFilename.c_str (),
656 sourceFilename.c_str () );
657 fprintf ( fMakefile,
658 "\t%s -f win32 %s -o %s %s\n",
659 "nasm",
660 sourceFilename.c_str (),
661 objectFilename.c_str (),
662 nasmflagsMacro.c_str () );
663 }
664
665 void
666 MingwModuleHandler::GenerateWindresCommand ( const Module& module,
667 const string& sourceFilename,
668 const string& windresflagsMacro ) const
669 {
670 string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
671 fprintf ( fMakefile,
672 "%s: %s\n",
673 objectFilename.c_str (),
674 sourceFilename.c_str () );
675 fprintf ( fMakefile,
676 "\t%s %s -o %s ${%s}\n",
677 "${windres}",
678 sourceFilename.c_str (),
679 objectFilename.c_str (),
680 windresflagsMacro.c_str () );
681 }
682
683 void
684 MingwModuleHandler::GenerateWinebuildCommands ( const Module& module,
685 const string& sourceFilename ) const
686 {
687 string basename = GetBasename ( sourceFilename );
688 fprintf ( fMakefile,
689 "%s.spec.def: %s\n",
690 basename.c_str (),
691 sourceFilename.c_str () );
692 fprintf ( fMakefile,
693 "\t%s --def=%s -o %s.spec.def\n",
694 "${winebuild}",
695 sourceFilename.c_str (),
696 basename.c_str () );
697
698 fprintf ( fMakefile,
699 "%s.stubs.c: %s\n",
700 basename.c_str (),
701 sourceFilename.c_str () );
702 fprintf ( fMakefile,
703 "\t%s --pedll=%s -o %s.stubs.c\n",
704 "${winebuild}",
705 sourceFilename.c_str (),
706 basename.c_str () );
707 }
708
709 void
710 MingwModuleHandler::GenerateCommands ( const Module& module,
711 const string& sourceFilename,
712 const string& cc,
713 const string& cppc,
714 const string& cflagsMacro,
715 const string& nasmflagsMacro,
716 const string& windresflagsMacro ) const
717 {
718 string extension = GetExtension ( sourceFilename );
719 if ( extension == ".c" || extension == ".C" )
720 {
721 GenerateGccCommand ( module,
722 sourceFilename,
723 cc,
724 cflagsMacro );
725 return;
726 }
727 else if ( extension == ".cc" || extension == ".CC" ||
728 extension == ".cpp" || extension == ".CPP" ||
729 extension == ".cxx" || extension == ".CXX" )
730 {
731 GenerateGccCommand ( module,
732 sourceFilename,
733 cppc,
734 cflagsMacro );
735 return;
736 }
737 else if ( extension == ".s" || extension == ".S" )
738 {
739 GenerateGccAssemblerCommand ( module,
740 sourceFilename,
741 cc,
742 cflagsMacro );
743 return;
744 }
745 else if ( extension == ".asm" || extension == ".ASM" )
746 {
747 GenerateNasmCommand ( module,
748 sourceFilename,
749 nasmflagsMacro );
750 return;
751 }
752 else if ( extension == ".rc" || extension == ".RC" )
753 {
754 GenerateWindresCommand ( module,
755 sourceFilename,
756 windresflagsMacro );
757 return;
758 }
759 else if ( extension == ".spec" || extension == ".SPEC" )
760 {
761 GenerateWinebuildCommands ( module,
762 sourceFilename );
763 GenerateGccCommand ( module,
764 GetActualSourceFilename ( sourceFilename ),
765 cc,
766 cflagsMacro );
767 return;
768 }
769
770 throw InvalidOperationException ( __FILE__,
771 __LINE__,
772 "Unsupported filename extension '%s' in file '%s'",
773 extension.c_str (),
774 sourceFilename.c_str () );
775 }
776
777 void
778 MingwModuleHandler::GenerateLinkerCommand ( const Module& module,
779 const string& linker,
780 const string& linkerParameters,
781 const string& objectFilenames ) const
782 {
783 string targetName ( module.GetTargetName () );
784 string target ( FixupTargetFilename ( module.GetPath () ) );
785 string importLibraryDependencies = GetImportLibraryDependencies ( module );
786 if ( module.importLibrary != NULL )
787 {
788 static string ros_junk ( "$(ROS_TEMPORARY)" );
789 string base_tmp = ros_junk + module.name + ".base.tmp";
790 string junk_tmp = ros_junk + module.name + ".junk.tmp";
791 string temp_exp = ros_junk + module.name + ".temp.exp";
792
793 fprintf ( fMakefile,
794 "\t%s %s -Wl,--base-file,%s -o %s %s %s %s\n",
795 linker.c_str (),
796 linkerParameters.c_str (),
797 base_tmp.c_str (),
798 junk_tmp.c_str (),
799 objectFilenames.c_str (),
800 importLibraryDependencies.c_str (),
801 GetLinkerMacro ( module ).c_str () );
802
803 fprintf ( fMakefile,
804 "\t${rm} %s\n",
805 junk_tmp.c_str () );
806
807 string killAt = module.mangledSymbols ? "" : "--kill-at";
808 fprintf ( fMakefile,
809 "\t${dlltool} --dllname %s --base-file %s --def %s --output-exp %s %s\n",
810 targetName.c_str (),
811 base_tmp.c_str (),
812 ( module.GetBasePath () + SSEP + module.importLibrary->definition ).c_str (),
813 temp_exp.c_str (),
814 killAt.c_str () );
815
816 fprintf ( fMakefile,
817 "\t${rm} %s\n",
818 base_tmp.c_str () );
819
820 fprintf ( fMakefile,
821 "\t%s %s %s -o %s %s %s %s\n\n",
822 linker.c_str (),
823 linkerParameters.c_str (),
824 temp_exp.c_str (),
825 target.c_str (),
826 objectFilenames.c_str (),
827 importLibraryDependencies.c_str (),
828 GetLinkerMacro ( module ).c_str () );
829
830 fprintf ( fMakefile,
831 "\t${rm} %s\n\n",
832 temp_exp.c_str () );
833 }
834 else
835 {
836 fprintf ( fMakefile,
837 "\t%s %s -o %s %s %s %s\n\n",
838 linker.c_str (),
839 linkerParameters.c_str (),
840 target.c_str (),
841 objectFilenames.c_str (),
842 importLibraryDependencies.c_str (),
843 GetLinkerMacro ( module ).c_str () );
844 }
845 }
846
847 void
848 MingwModuleHandler::GenerateObjectFileTargets ( const Module& module,
849 const vector<File*>& files,
850 const vector<If*>& ifs,
851 const string& cc,
852 const string& cppc,
853 const string& cflagsMacro,
854 const string& nasmflagsMacro,
855 const string& windresflagsMacro ) const
856 {
857 size_t i;
858
859 for ( i = 0; i < files.size (); i++ )
860 {
861 string sourceFilename = files[i]->name;
862 GenerateCommands ( module,
863 sourceFilename,
864 cc,
865 cppc,
866 cflagsMacro,
867 nasmflagsMacro,
868 windresflagsMacro );
869 fprintf ( fMakefile,
870 "\n" );
871 }
872
873 for ( i = 0; i < ifs.size(); i++ )
874 {
875 GenerateObjectFileTargets ( module,
876 ifs[i]->files,
877 ifs[i]->ifs,
878 cc,
879 cppc,
880 cflagsMacro,
881 nasmflagsMacro,
882 windresflagsMacro );
883 }
884 }
885
886 void
887 MingwModuleHandler::GenerateObjectFileTargets ( const Module& module,
888 const string& cc,
889 const string& cppc,
890 const string& cflagsMacro,
891 const string& nasmflagsMacro,
892 const string& windresflagsMacro ) const
893 {
894 GenerateObjectFileTargets ( module,
895 module.files,
896 module.ifs,
897 cc,
898 cppc,
899 cflagsMacro,
900 nasmflagsMacro,
901 windresflagsMacro );
902 fprintf ( fMakefile, "\n" );
903 }
904
905 void
906 MingwModuleHandler::GetCleanTargets ( vector<string>& out,
907 const vector<File*>& files,
908 const vector<If*>& ifs ) const
909 {
910 size_t i;
911
912 for ( i = 0; i < files.size(); i++ )
913 out.push_back ( PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ) );
914
915 for ( i = 0; i < ifs.size(); i++ )
916 GetCleanTargets ( out, ifs[i]->files, ifs[i]->ifs );
917 }
918
919 string
920 MingwModuleHandler::GenerateArchiveTarget ( const Module& module,
921 const string& ar,
922 const string& objs_macro ) const
923 {
924 string archiveFilename = GetModuleArchiveFilename ( module );
925
926 fprintf ( fMakefile,
927 "%s: %s\n",
928 archiveFilename.c_str (),
929 objs_macro.c_str ());
930
931 fprintf ( fMakefile,
932 "\t%s -rc %s %s\n\n",
933 ar.c_str (),
934 archiveFilename.c_str (),
935 objs_macro.c_str ());
936
937 return archiveFilename;
938 }
939
940 string
941 MingwModuleHandler::GetCFlagsMacro ( const Module& module ) const
942 {
943 return ssprintf ( "$(%s_CFLAGS)",
944 module.name.c_str () );
945 }
946
947 string
948 MingwModuleHandler::GetObjectsMacro ( const Module& module ) const
949 {
950 return ssprintf ( "$(%s_OBJS)",
951 module.name.c_str () );
952 }
953
954 string
955 MingwModuleHandler::GetLinkerMacro ( const Module& module ) const
956 {
957 return ssprintf ( "$(%s_LFLAGS)",
958 module.name.c_str () );
959 }
960
961 void
962 MingwModuleHandler::GenerateMacrosAndTargets (
963 const Module& module,
964 const string& cc,
965 const string& cppc,
966 const string& ar,
967 const string* cflags,
968 const string* nasmflags ) const
969 {
970 string cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
971 string nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
972 string windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
973 string linkerFlagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
974 string objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
975
976 GenerateMacros ( module,
977 cflagsMacro,
978 nasmflagsMacro,
979 windresflagsMacro,
980 linkerFlagsMacro,
981 objectsMacro );
982
983 if ( cflags != NULL )
984 {
985 fprintf ( fMakefile,
986 "%s += %s\n\n",
987 cflagsMacro.c_str (),
988 cflags->c_str () );
989 }
990
991 if ( nasmflags != NULL )
992 {
993 fprintf ( fMakefile,
994 "%s += %s\n\n",
995 nasmflagsMacro.c_str (),
996 nasmflags->c_str () );
997 }
998
999 // generate phony target for module name
1000 fprintf ( fMakefile, ".PHONY: %s\n",
1001 module.name.c_str () );
1002 fprintf ( fMakefile, "%s: %s\n\n",
1003 module.name.c_str (),
1004 FixupTargetFilename ( module.GetPath () ).c_str () );
1005
1006 // future references to the macros will be to get their values
1007 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
1008 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
1009 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
1010
1011 string ar_target = GenerateArchiveTarget ( module, ar, objectsMacro );
1012 GenerateObjectFileTargets ( module,
1013 cc,
1014 cppc,
1015 cflagsMacro,
1016 nasmflagsMacro,
1017 windresflagsMacro );
1018
1019 vector<string> clean_files;
1020 clean_files.push_back ( FixupTargetFilename(module.GetPath()) );
1021 clean_files.push_back ( ar_target );
1022 GetCleanTargets ( clean_files, module.files, module.ifs );
1023
1024 fprintf ( fMakefile, "clean::\n\t-@$(rm)" );
1025 for ( size_t i = 0; i < clean_files.size(); i++ )
1026 {
1027 if ( 9==(i%10) )
1028 fprintf ( fMakefile, " 2>$(NUL)\n\t-@$(rm)" );
1029 fprintf ( fMakefile, " %s", clean_files[i].c_str() );
1030 }
1031 fprintf ( fMakefile, " 2>$(NUL)\n\n" );
1032 }
1033
1034 void
1035 MingwModuleHandler::GenerateMacrosAndTargetsHost ( const Module& module ) const
1036 {
1037 GenerateMacrosAndTargets ( module,
1038 "${host_gcc}",
1039 "${host_gpp}",
1040 "${host_ar}",
1041 NULL,
1042 NULL );
1043 }
1044
1045 void
1046 MingwModuleHandler::GenerateMacrosAndTargetsTarget ( const Module& module ) const
1047 {
1048 GenerateMacrosAndTargetsTarget ( module,
1049 NULL,
1050 NULL );
1051 }
1052
1053 void
1054 MingwModuleHandler::GenerateMacrosAndTargetsTarget ( const Module& module,
1055 const string* cflags,
1056 const string* nasmflags ) const
1057 {
1058 GenerateMacrosAndTargets ( module,
1059 "${gcc}",
1060 "${gpp}",
1061 "${ar}",
1062 cflags,
1063 nasmflags );
1064 }
1065
1066 string
1067 MingwModuleHandler::GetInvocationDependencies ( const Module& module ) const
1068 {
1069 string dependencies;
1070 for ( size_t i = 0; i < module.invocations.size (); i++ )
1071 {
1072 Invoke& invoke = *module.invocations[i];
1073 if (invoke.invokeModule == &module)
1074 /* Protect against circular dependencies */
1075 continue;
1076 if ( dependencies.length () > 0 )
1077 dependencies += " ";
1078 dependencies += invoke.GetTargets ();
1079 }
1080 return dependencies;
1081 }
1082
1083 string
1084 MingwModuleHandler::GetInvocationParameters ( const Invoke& invoke ) const
1085 {
1086 string parameters ( "" );
1087 size_t i;
1088 for (i = 0; i < invoke.output.size (); i++)
1089 {
1090 if (parameters.length () > 0)
1091 parameters += " ";
1092 InvokeFile& invokeFile = *invoke.output[i];
1093 if (invokeFile.switches.length () > 0)
1094 {
1095 parameters += invokeFile.switches;
1096 parameters += " ";
1097 }
1098 parameters += invokeFile.name;
1099 }
1100
1101 for (i = 0; i < invoke.input.size (); i++)
1102 {
1103 if (parameters.length () > 0)
1104 parameters += " ";
1105 InvokeFile& invokeFile = *invoke.input[i];
1106 if (invokeFile.switches.length () > 0)
1107 {
1108 parameters += invokeFile.switches;
1109 parameters += " ";
1110 }
1111 parameters += invokeFile.name ;
1112 }
1113
1114 return parameters;
1115 }
1116
1117 void
1118 MingwModuleHandler::GenerateInvocations ( const Module& module ) const
1119 {
1120 if ( module.invocations.size () == 0 )
1121 return;
1122
1123 for ( size_t i = 0; i < module.invocations.size (); i++ )
1124 {
1125 const Invoke& invoke = *module.invocations[i];
1126
1127 if ( invoke.invokeModule->type != BuildTool )
1128 {
1129 throw InvalidBuildFileException ( module.node.location,
1130 "Only modules of type buildtool can be invoked." );
1131 }
1132
1133 string invokeTarget = module.GetInvocationTarget ( i );
1134 fprintf ( fMakefile,
1135 ".PHONY: %s\n\n",
1136 invokeTarget.c_str () );
1137 fprintf ( fMakefile,
1138 "%s: %s\n\n",
1139 invokeTarget.c_str (),
1140 invoke.GetTargets ().c_str () );
1141 fprintf ( fMakefile,
1142 "%s: %s\n",
1143 invoke.GetTargets ().c_str (),
1144 FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str () );
1145 fprintf ( fMakefile,
1146 "\t%s %s\n\n",
1147 FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str (),
1148 GetInvocationParameters ( invoke ).c_str () );
1149 }
1150 }
1151
1152 string
1153 MingwModuleHandler::GetPreconditionDependenciesName ( const Module& module ) const
1154 {
1155 return ssprintf ( "%s_precondition",
1156 module.name.c_str () );
1157 }
1158
1159 void
1160 MingwModuleHandler::GeneratePreconditionDependencies ( const Module& module ) const
1161 {
1162 string preconditionDependenciesName = GetPreconditionDependenciesName ( module );
1163 string sourceFilenames = GetSourceFilenamesWithoutGeneratedFiles ( module );
1164 string dependencies = GetModuleDependencies ( module );
1165 string s = GetInvocationDependencies ( module );
1166 if ( s.length () > 0 )
1167 {
1168 if ( dependencies.length () > 0 )
1169 dependencies += " ";
1170 dependencies += s;
1171 }
1172
1173 fprintf ( fMakefile,
1174 ".PHONY: %s\n\n",
1175 preconditionDependenciesName.c_str () );
1176 fprintf ( fMakefile,
1177 "%s: %s\n\n",
1178 preconditionDependenciesName.c_str (),
1179 dependencies.c_str () );
1180 const char* p = sourceFilenames.c_str();
1181 const char* end = p + strlen(p);
1182 while ( p < end )
1183 {
1184 const char* p2 = &p[512];
1185 if ( p2 > end )
1186 p2 = end;
1187 while ( p2 > p && !isspace(*p2) )
1188 --p2;
1189 if ( p == p2 )
1190 {
1191 p2 = strpbrk ( p, " \t" );
1192 if ( !p2 )
1193 p2 = end;
1194 }
1195 fprintf ( fMakefile,
1196 "%.*s: %s\n",
1197 p2-p,
1198 p,
1199 preconditionDependenciesName.c_str ());
1200 p = p2;
1201 p += strspn ( p, " \t" );
1202 }
1203 fprintf ( fMakefile, "\n" );
1204 }
1205
1206 void
1207 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ( const Module& module ) const
1208 {
1209 if ( module.importLibrary != NULL )
1210 {
1211 string definitionDependencies = GetDefinitionDependencies ( module );
1212 fprintf ( fMakefile, "%s: %s\n",
1213 FixupTargetFilename( module.GetDependencyPath () ).c_str (),
1214 definitionDependencies.c_str () );
1215
1216 string killAt = module.mangledSymbols ? "" : "--kill-at";
1217 fprintf ( fMakefile,
1218 "\t${dlltool} --dllname %s --def %s --output-lib %s %s\n\n",
1219 module.GetTargetName ().c_str (),
1220 ( module.GetBasePath () + SSEP + module.importLibrary->definition ).c_str (),
1221 FixupTargetFilename ( module.GetDependencyPath () ).c_str (),
1222 killAt.c_str () );
1223 }
1224 }
1225
1226 string
1227 MingwModuleHandler::GetSpecObjectDependencies ( const string& filename ) const
1228 {
1229 string basename = GetBasename ( filename );
1230 return basename + ".spec.def" + " " + basename + ".stubs.c";
1231 }
1232
1233 string
1234 MingwModuleHandler::GetDefinitionDependencies ( const Module& module ) const
1235 {
1236 string dependencies;
1237 for ( size_t i = 0; i < module.files.size (); i++ )
1238 {
1239 File& file = *module.files[i];
1240 string extension = GetExtension ( file.name );
1241 if ( extension == ".spec" || extension == ".SPEC" )
1242 {
1243 if ( dependencies.length () > 0 )
1244 dependencies += " ";
1245 dependencies += GetSpecObjectDependencies ( file.name );
1246 }
1247 }
1248 return dependencies;
1249 }
1250
1251 string
1252 MingwModuleHandler::GetLinkingDependencies ( const Module& module ) const
1253 {
1254 string dependencies = GetImportLibraryDependencies ( module );
1255 string s = GetDefinitionDependencies ( module );
1256 if ( s.length () > 0 )
1257 {
1258 dependencies += " ";
1259 dependencies += s;
1260 }
1261 return dependencies;
1262 }
1263
1264 bool
1265 MingwModuleHandler::IsCPlusPlusModule ( const Module& module ) const
1266 {
1267 if ( module.HasFileWithExtensions ( ".cxx", ".CXX" ) )
1268 return true;
1269 if ( module.HasFileWithExtensions ( ".cpp", ".CPP" ) )
1270 return true;
1271 return false;
1272 }
1273
1274
1275 static MingwBuildToolModuleHandler buildtool_handler;
1276
1277 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler()
1278 : MingwModuleHandler ( BuildTool )
1279 {
1280 }
1281
1282 void
1283 MingwBuildToolModuleHandler::Process ( const Module& module )
1284 {
1285 GeneratePreconditionDependencies ( module );
1286 GenerateBuildToolModuleTarget ( module );
1287 GenerateInvocations ( module );
1288 }
1289
1290 void
1291 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module& module )
1292 {
1293 string target ( FixupTargetFilename ( module.GetPath () ) );
1294 string archiveFilename = GetModuleArchiveFilename ( module );
1295 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1296
1297 GenerateMacrosAndTargetsHost ( module );
1298
1299 string linker;
1300 if ( IsCPlusPlusModule ( module ) )
1301 linker = "${host_gpp}";
1302 else
1303 linker = "${host_gcc}";
1304
1305 fprintf ( fMakefile, "%s: %s %s\n",
1306 target.c_str (),
1307 archiveFilename.c_str (),
1308 importLibraryDependencies.c_str () );
1309 fprintf ( fMakefile,
1310 "\t%s %s -o %s %s %s\n\n",
1311 linker.c_str (),
1312 GetLinkerMacro ( module ).c_str (),
1313 target.c_str (),
1314 archiveFilename.c_str (),
1315 importLibraryDependencies.c_str () );
1316 }
1317
1318
1319 static MingwKernelModuleHandler kernelmodule_handler;
1320
1321 MingwKernelModuleHandler::MingwKernelModuleHandler ()
1322 : MingwModuleHandler ( Kernel )
1323 {
1324 }
1325
1326 void
1327 MingwKernelModuleHandler::Process ( const Module& module )
1328 {
1329 GeneratePreconditionDependencies ( module );
1330 GenerateKernelModuleTarget ( module );
1331 GenerateInvocations ( module );
1332 }
1333
1334 void
1335 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module )
1336 {
1337 static string ros_junk ( "$(ROS_TEMPORARY)" );
1338 string targetName ( module.GetTargetName () );
1339 string target ( FixupTargetFilename (module.GetPath ()) );
1340 string workingDirectory = GetWorkingDirectory ();
1341 string objectsMacro = GetObjectsMacro ( module );
1342 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1343 string base_tmp = ros_junk + module.name + ".base.tmp";
1344 string junk_tmp = ros_junk + module.name + ".junk.tmp";
1345 string temp_exp = ros_junk + module.name + ".temp.exp";
1346 string gccOptions = ssprintf ("-Wl,-T,%s" SSEP "ntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0xC0000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1347 module.GetBasePath ().c_str (),
1348 module.entrypoint.c_str () );
1349
1350 GenerateMacrosAndTargetsTarget ( module );
1351
1352 GenerateImportLibraryTargetIfNeeded ( module );
1353
1354 fprintf ( fMakefile, "%s: %s %s\n",
1355 target.c_str (),
1356 objectsMacro.c_str (),
1357 importLibraryDependencies.c_str () );
1358 fprintf ( fMakefile,
1359 "\t${gcc} %s %s -Wl,--base-file,%s -o %s %s %s\n",
1360 GetLinkerMacro ( module ).c_str (),
1361 gccOptions.c_str (),
1362 base_tmp.c_str (),
1363 junk_tmp.c_str (),
1364 objectsMacro.c_str (),
1365 importLibraryDependencies.c_str () );
1366 fprintf ( fMakefile,
1367 "\t${rm} %s\n",
1368 junk_tmp.c_str () );
1369 string killAt = module.mangledSymbols ? "" : "--kill-at";
1370 fprintf ( fMakefile,
1371 "\t${dlltool} --dllname %s --base-file %s --def ntoskrnl/ntoskrnl.def --output-exp %s %s\n",
1372 targetName.c_str (),
1373 base_tmp.c_str (),
1374 temp_exp.c_str (),
1375 killAt.c_str () );
1376 fprintf ( fMakefile,
1377 "\t${rm} %s\n",
1378 base_tmp.c_str () );
1379 fprintf ( fMakefile,
1380 "\t${gcc} %s %s -Wl,%s -o %s %s %s\n",
1381 GetLinkerMacro ( module ).c_str (),
1382 gccOptions.c_str (),
1383 temp_exp.c_str (),
1384 target.c_str (),
1385 objectsMacro.c_str (),
1386 importLibraryDependencies.c_str () );
1387 fprintf ( fMakefile,
1388 "\t${rm} %s\n\n",
1389 temp_exp.c_str () );
1390 }
1391
1392
1393 static MingwStaticLibraryModuleHandler staticlibrary_handler;
1394
1395 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()
1396 : MingwModuleHandler ( StaticLibrary )
1397 {
1398 }
1399
1400 void
1401 MingwStaticLibraryModuleHandler::Process ( const Module& module )
1402 {
1403 GeneratePreconditionDependencies ( module );
1404 GenerateStaticLibraryModuleTarget ( module );
1405 GenerateInvocations ( module );
1406 }
1407
1408 void
1409 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module& module )
1410 {
1411 GenerateMacrosAndTargetsTarget ( module );
1412 }
1413
1414
1415 static MingwObjectLibraryModuleHandler objectlibrary_handler;
1416
1417 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler ()
1418 : MingwModuleHandler ( ObjectLibrary )
1419 {
1420 }
1421
1422 void
1423 MingwObjectLibraryModuleHandler::Process ( const Module& module )
1424 {
1425 GeneratePreconditionDependencies ( module );
1426 GenerateObjectLibraryModuleTarget ( module );
1427 GenerateInvocations ( module );
1428 }
1429
1430 void
1431 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ( const Module& module )
1432 {
1433 GenerateMacrosAndTargetsTarget ( module );
1434 }
1435
1436
1437 static MingwKernelModeDLLModuleHandler kernelmodedll_handler;
1438
1439 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler ()
1440 : MingwModuleHandler ( KernelModeDLL )
1441 {
1442 }
1443
1444 void
1445 MingwKernelModeDLLModuleHandler::Process ( const Module& module )
1446 {
1447 GeneratePreconditionDependencies ( module );
1448 GenerateKernelModeDLLModuleTarget ( module );
1449 GenerateInvocations ( module );
1450 }
1451
1452 void
1453 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Module& module )
1454 {
1455 static string ros_junk ( "$(ROS_TEMPORARY)" );
1456 string target ( FixupTargetFilename ( module.GetPath () ) );
1457 string workingDirectory = GetWorkingDirectory ( );
1458 string archiveFilename = GetModuleArchiveFilename ( module );
1459 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1460
1461 GenerateImportLibraryTargetIfNeeded ( module );
1462
1463 if ( module.files.size () > 0 )
1464 {
1465 GenerateMacrosAndTargetsTarget ( module );
1466
1467 fprintf ( fMakefile, "%s: %s %s\n",
1468 target.c_str (),
1469 archiveFilename.c_str (),
1470 importLibraryDependencies.c_str () );
1471
1472 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1473 module.entrypoint.c_str () );
1474 GenerateLinkerCommand ( module,
1475 "${gcc}",
1476 linkerParameters,
1477 archiveFilename );
1478 }
1479 else
1480 {
1481 fprintf ( fMakefile, ".PHONY: %s\n\n",
1482 target.c_str ());
1483 fprintf ( fMakefile, "%s:\n",
1484 target.c_str ());
1485 }
1486 }
1487
1488
1489 static MingwKernelModeDriverModuleHandler kernelmodedriver_handler;
1490
1491 MingwKernelModeDriverModuleHandler::MingwKernelModeDriverModuleHandler ()
1492 : MingwModuleHandler ( KernelModeDriver )
1493 {
1494 }
1495
1496 void
1497 MingwKernelModeDriverModuleHandler::Process ( const Module& module )
1498 {
1499 GeneratePreconditionDependencies ( module );
1500 GenerateKernelModeDriverModuleTarget ( module );
1501 GenerateInvocations ( module );
1502 }
1503
1504
1505 void
1506 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ( const Module& module )
1507 {
1508 static string ros_junk ( "$(ROS_TEMPORARY)" );
1509 string target ( PassThruCacheDirectory( FixupTargetFilename ( module.GetPath () ) ) );
1510 string workingDirectory = GetWorkingDirectory ( );
1511 string archiveFilename = GetModuleArchiveFilename ( module );
1512 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1513
1514 GenerateImportLibraryTargetIfNeeded ( module );
1515
1516 if ( module.files.size () > 0 )
1517 {
1518 string* cflags = new string ( "-D__NTDRIVER__" );
1519 GenerateMacrosAndTargetsTarget ( module,
1520 cflags,
1521 NULL );
1522 delete cflags;
1523
1524 fprintf ( fMakefile, "%s: %s %s\n",
1525 target.c_str (),
1526 archiveFilename.c_str (),
1527 importLibraryDependencies.c_str () );
1528
1529 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1530 module.entrypoint.c_str () );
1531 GenerateLinkerCommand ( module,
1532 "${gcc}",
1533 linkerParameters,
1534 archiveFilename );
1535 }
1536 else
1537 {
1538 fprintf ( fMakefile, ".PHONY: %s\n\n",
1539 target.c_str ());
1540 fprintf ( fMakefile, "%s:\n",
1541 target.c_str () );
1542 }
1543 }
1544
1545
1546 static MingwNativeDLLModuleHandler nativedll_handler;
1547
1548 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler ()
1549 : MingwModuleHandler ( NativeDLL )
1550 {
1551 }
1552
1553 void
1554 MingwNativeDLLModuleHandler::Process ( const Module& module )
1555 {
1556 GeneratePreconditionDependencies ( module );
1557 GenerateNativeDLLModuleTarget ( module );
1558 GenerateInvocations ( module );
1559 }
1560
1561 void
1562 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ( const Module& module )
1563 {
1564 static string ros_junk ( "$(ROS_TEMPORARY)" );
1565 string target ( FixupTargetFilename ( module.GetPath () ) );
1566 string workingDirectory = GetWorkingDirectory ( );
1567 string objectFilenames = GetObjectFilenames ( module );
1568 string archiveFilename = GetModuleArchiveFilename ( module );
1569 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1570
1571 GenerateImportLibraryTargetIfNeeded ( module );
1572
1573 if ( module.files.size () > 0 )
1574 {
1575 GenerateMacrosAndTargetsTarget ( module );
1576
1577 fprintf ( fMakefile, "%s: %s %s\n",
1578 target.c_str (),
1579 archiveFilename.c_str (),
1580 importLibraryDependencies.c_str () );
1581
1582 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll",
1583 module.entrypoint.c_str () );
1584 GenerateLinkerCommand ( module,
1585 "${gcc}",
1586 linkerParameters,
1587 objectFilenames );
1588 }
1589 else
1590 {
1591 fprintf ( fMakefile, ".PHONY: %s\n\n",
1592 target.c_str ());
1593 fprintf ( fMakefile, "%s:\n\n",
1594 target.c_str ());
1595 }
1596 }
1597
1598
1599 static MingwNativeCUIModuleHandler nativecui_handler;
1600
1601 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler ()
1602 : MingwModuleHandler ( NativeCUI )
1603 {
1604 }
1605
1606 void
1607 MingwNativeCUIModuleHandler::Process ( const Module& module )
1608 {
1609 GeneratePreconditionDependencies ( module );
1610 GenerateNativeCUIModuleTarget ( module );
1611 GenerateInvocations ( module );
1612 }
1613
1614 void
1615 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ( const Module& module )
1616 {
1617 static string ros_junk ( "$(ROS_TEMPORARY)" );
1618 string target ( FixupTargetFilename ( module.GetPath () ) );
1619 string workingDirectory = GetWorkingDirectory ( );
1620 string objectFilenames = GetObjectFilenames ( module );
1621 string archiveFilename = GetModuleArchiveFilename ( module );
1622 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1623
1624 GenerateImportLibraryTargetIfNeeded ( module );
1625
1626 if ( module.files.size () > 0 )
1627 {
1628 string* cflags = new string ( "-D__NTAPP__" );
1629 GenerateMacrosAndTargetsTarget ( module,
1630 cflags,
1631 NULL );
1632 delete cflags;
1633
1634 fprintf ( fMakefile, "%s: %s %s\n",
1635 target.c_str (),
1636 archiveFilename.c_str (),
1637 importLibraryDependencies.c_str () );
1638
1639 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib",
1640 module.entrypoint.c_str () );
1641 GenerateLinkerCommand ( module,
1642 "${gcc}",
1643 linkerParameters,
1644 objectFilenames );
1645 }
1646 else
1647 {
1648 fprintf ( fMakefile, ".PHONY: %s\n\n",
1649 target.c_str ());
1650 fprintf ( fMakefile, "%s:\n\n",
1651 target.c_str ());
1652 }
1653 }
1654
1655
1656 static MingwWin32DLLModuleHandler win32dll_handler;
1657
1658 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler ()
1659 : MingwModuleHandler ( Win32DLL )
1660 {
1661 }
1662
1663 void
1664 MingwWin32DLLModuleHandler::Process ( const Module& module )
1665 {
1666 GenerateExtractWineDLLResourcesTarget ( module );
1667 GeneratePreconditionDependencies ( module );
1668 GenerateWin32DLLModuleTarget ( module );
1669 GenerateInvocations ( module );
1670 }
1671
1672 void
1673 MingwWin32DLLModuleHandler::GenerateExtractWineDLLResourcesTarget ( const Module& module )
1674 {
1675 fprintf ( fMakefile, ".PHONY: %s_extractresources\n\n",
1676 module.name.c_str () );
1677 fprintf ( fMakefile, "%s_extractresources: bin2res\n",
1678 module.name.c_str () );
1679 for ( size_t i = 0; i < module.files.size (); i++ )
1680 {
1681 File& file = *module.files[i];
1682 string extension = GetExtension ( file.name );
1683 if ( extension == ".rc" || extension == ".RC" )
1684 {
1685 string resource = FixupTargetFilename ( file.name );
1686 fprintf ( fMakefile, "\t@echo ${bin2res} -f -x %s\n",
1687 resource.c_str () );
1688 }
1689 }
1690 fprintf ( fMakefile, "\n");
1691 }
1692
1693 void
1694 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module )
1695 {
1696 static string ros_junk ( "$(ROS_TEMPORARY)" );
1697 string target ( FixupTargetFilename ( module.GetPath () ) );
1698 string workingDirectory = GetWorkingDirectory ( );
1699 string objectFilenames = GetObjectFilenames ( module );
1700 string linkingDependencies = GetLinkingDependencies ( module );
1701
1702 GenerateImportLibraryTargetIfNeeded ( module );
1703 if ( module.files.size () > 0 )
1704 {
1705 GenerateMacrosAndTargetsTarget ( module );
1706
1707 fprintf ( fMakefile, "%s: %s %s\n",
1708 target.c_str (),
1709 objectFilenames.c_str (),
1710 linkingDependencies.c_str () );
1711
1712 string linker;
1713 if ( IsCPlusPlusModule ( module ) )
1714 linker = "${gpp}";
1715 else
1716 linker = "${gcc}";
1717
1718 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll",
1719 module.entrypoint.c_str () );
1720 GenerateLinkerCommand ( module,
1721 linker,
1722 linkerParameters,
1723 objectFilenames );
1724 }
1725 else
1726 {
1727 fprintf ( fMakefile, ".PHONY: %s\n\n",
1728 target.c_str () );
1729 fprintf ( fMakefile, "%s:\n\n",
1730 target.c_str () );
1731 }
1732 }
1733
1734
1735 static MingwWin32CUIModuleHandler win32cui_handler;
1736
1737 MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler ()
1738 : MingwModuleHandler ( Win32CUI )
1739 {
1740 }
1741
1742 void
1743 MingwWin32CUIModuleHandler::Process ( const Module& module )
1744 {
1745 GeneratePreconditionDependencies ( module );
1746 GenerateWin32CUIModuleTarget ( module );
1747 GenerateInvocations ( module );
1748 }
1749
1750 void
1751 MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ( const Module& module )
1752 {
1753 static string ros_junk ( "$(ROS_TEMPORARY)" );
1754 string target ( FixupTargetFilename ( module.GetPath () ) );
1755 string workingDirectory = GetWorkingDirectory ( );
1756 string objectFilenames = GetObjectFilenames ( module );
1757 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1758
1759 GenerateImportLibraryTargetIfNeeded ( module );
1760
1761 if ( module.files.size () > 0 )
1762 {
1763 GenerateMacrosAndTargetsTarget ( module );
1764
1765 fprintf ( fMakefile, "%s: %s %s\n",
1766 target.c_str (),
1767 objectFilenames.c_str (),
1768 importLibraryDependencies.c_str () );
1769
1770 string linker;
1771 if ( IsCPlusPlusModule ( module ) )
1772 linker = "${gpp}";
1773 else
1774 linker = "${gcc}";
1775
1776 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,0x00400000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
1777 module.entrypoint.c_str () );
1778 GenerateLinkerCommand ( module,
1779 linker,
1780 linkerParameters,
1781 objectFilenames );
1782 }
1783 else
1784 {
1785 fprintf ( fMakefile, ".PHONY: %s\n\n",
1786 target.c_str ());
1787 fprintf ( fMakefile, "%s:\n\n",
1788 target.c_str ());
1789 }
1790 }
1791
1792
1793 static MingwWin32GUIModuleHandler win32gui_handler;
1794
1795 MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler ()
1796 : MingwModuleHandler ( Win32GUI )
1797 {
1798 }
1799
1800 void
1801 MingwWin32GUIModuleHandler::Process ( const Module& module )
1802 {
1803 GeneratePreconditionDependencies ( module );
1804 GenerateWin32GUIModuleTarget ( module );
1805 GenerateInvocations ( module );
1806 }
1807
1808 void
1809 MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ( const Module& module )
1810 {
1811 static string ros_junk ( "$(ROS_TEMPORARY)" );
1812 string target ( FixupTargetFilename ( module.GetPath () ) );
1813 string workingDirectory = GetWorkingDirectory ( );
1814 string objectFilenames = GetObjectFilenames ( module );
1815 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1816
1817 GenerateImportLibraryTargetIfNeeded ( module );
1818
1819 if ( module.files.size () > 0 )
1820 {
1821 GenerateMacrosAndTargetsTarget ( module );
1822
1823 fprintf ( fMakefile, "%s: %s %s\n",
1824 target.c_str (),
1825 objectFilenames.c_str (),
1826 importLibraryDependencies.c_str () );
1827
1828 string linker;
1829 if ( IsCPlusPlusModule ( module ) )
1830 linker = "${gpp}";
1831 else
1832 linker = "${gcc}";
1833
1834 string linkerParameters = ssprintf ( "-Wl,--subsystem,windows -Wl,--entry,%s -Wl,--image-base,0x00400000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
1835 module.entrypoint.c_str () );
1836 GenerateLinkerCommand ( module,
1837 linker,
1838 linkerParameters,
1839 objectFilenames );
1840 }
1841 else
1842 {
1843 fprintf ( fMakefile, ".PHONY: %s\n\n",
1844 target.c_str ());
1845 fprintf ( fMakefile, "%s:\n\n",
1846 target.c_str ());
1847 }
1848 }
1849
1850
1851 static MingwBootLoaderModuleHandler bootloadermodule_handler;
1852
1853 MingwBootLoaderModuleHandler::MingwBootLoaderModuleHandler ()
1854 : MingwModuleHandler ( BootLoader )
1855 {
1856 }
1857
1858 void
1859 MingwBootLoaderModuleHandler::Process ( const Module& module )
1860 {
1861 GeneratePreconditionDependencies ( module );
1862 GenerateBootLoaderModuleTarget ( module );
1863 GenerateInvocations ( module );
1864 }
1865
1866 void
1867 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ( const Module& module )
1868 {
1869 static string ros_junk ( "$(ROS_TEMPORARY)" );
1870 string targetName ( module.GetTargetName () );
1871 string target ( FixupTargetFilename (module.GetPath ()) );
1872 string workingDirectory = GetWorkingDirectory ();
1873 string junk_tmp = ros_junk + module.name + ".junk.tmp";
1874 string objectsMacro = GetObjectsMacro ( module );
1875 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1876
1877 GenerateMacrosAndTargetsTarget ( module );
1878
1879 fprintf ( fMakefile, "%s: %s %s\n",
1880 target.c_str (),
1881 objectsMacro.c_str (),
1882 importLibraryDependencies.c_str () );
1883
1884 fprintf ( fMakefile,
1885 "\t${ld} %s -N -Ttext=0x8000 -o %s %s %s\n",
1886 GetLinkerMacro ( module ).c_str (),
1887 junk_tmp.c_str (),
1888 objectsMacro.c_str (),
1889 importLibraryDependencies.c_str () );
1890 fprintf ( fMakefile,
1891 "\t${objcopy} -O binary %s %s\n",
1892 junk_tmp.c_str (),
1893 target.c_str () );
1894 fprintf ( fMakefile,
1895 "\t${rm} %s\n",
1896 junk_tmp.c_str () );
1897 }
1898
1899
1900 static MingwBootSectorModuleHandler bootsectormodule_handler;
1901
1902 MingwBootSectorModuleHandler::MingwBootSectorModuleHandler ()
1903 : MingwModuleHandler ( BootSector )
1904 {
1905 }
1906
1907 void
1908 MingwBootSectorModuleHandler::Process ( const Module& module )
1909 {
1910 GeneratePreconditionDependencies ( module );
1911 GenerateBootSectorModuleTarget ( module );
1912 GenerateInvocations ( module );
1913 }
1914
1915 void
1916 MingwBootSectorModuleHandler::GenerateBootSectorModuleTarget ( const Module& module )
1917 {
1918 string objectsMacro = GetObjectsMacro ( module );
1919
1920 string* nasmflags = new string ( "-f bin" );
1921 GenerateMacrosAndTargetsTarget ( module,
1922 NULL,
1923 nasmflags);
1924
1925 fprintf ( fMakefile, ".PHONY: %s\n\n",
1926 module.name.c_str ());
1927 fprintf ( fMakefile,
1928 "%s: %s\n",
1929 module.name.c_str (),
1930 objectsMacro.c_str () );
1931 }
1932
1933
1934 static MingwIsoModuleHandler isomodule_handler;
1935
1936 MingwIsoModuleHandler::MingwIsoModuleHandler ()
1937 : MingwModuleHandler ( Iso )
1938 {
1939 }
1940
1941 void
1942 MingwIsoModuleHandler::Process ( const Module& module )
1943 {
1944 GeneratePreconditionDependencies ( module );
1945 GenerateIsoModuleTarget ( module );
1946 GenerateInvocations ( module );
1947 }
1948
1949 void
1950 MingwIsoModuleHandler::GenerateIsoModuleTarget ( const Module& module )
1951 {
1952 string isoboot = "$(ROS_INTERMEDIATE)" + FixupTargetFilename ( "boot/freeldr/bootsect/isoboot.o" );
1953
1954 fprintf ( fMakefile, ".PHONY: %s\n\n",
1955 module.name.c_str ());
1956 fprintf ( fMakefile,
1957 "%s: all %s\n",
1958 module.name.c_str (),
1959 isoboot.c_str () );
1960 fprintf ( fMakefile,
1961 "\t${cabman} /C %s /L $(ROS_INTERMEDIATE)%s /I\n",
1962 FixupTargetFilename ( "bootdata/packages/reactos.dff" ).c_str (),
1963 FixupTargetFilename ( "bootcd/reactos" ).c_str () );
1964 fprintf ( fMakefile,
1965 "\t${cabman} /C %s /RC $(ROS_INTERMEDIATE)%s /L $(BOOTCD_DIR)reactos /N\n",
1966 FixupTargetFilename ( "bootdata/packages/reactos.dff" ).c_str (),
1967 FixupTargetFilename ( "bootcd/reactos/reactos.inf" ).c_str () );
1968 fprintf ( fMakefile,
1969 "\t- ${rm} $(ROS_INTERMEDIATE)%s\n",
1970 FixupTargetFilename ( "bootcd/reactos/reactos.inf" ).c_str () );
1971 fprintf ( fMakefile,
1972 "\t${cdmake} -v -m -b %s $(ROS_INTERMEDIATE)bootcd REACTOS ReactOS.iso\n",
1973 isoboot.c_str () );
1974 fprintf ( fMakefile,
1975 "\n" );
1976 }