fad90bc92b14a3f49a3f03302910657b8c54b444
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
1
2 #include "../../pch.h"
3 #include <assert.h>
4
5 #include "../../rbuild.h"
6 #include "mingw.h"
7 #include "modulehandler.h"
8
9 using std::string;
10 using std::vector;
11 using std::map;
12
13 map<ModuleType,MingwModuleHandler*>*
14 MingwModuleHandler::handler_map = NULL;
15 int
16 MingwModuleHandler::ref = 0;
17
18 FILE*
19 MingwModuleHandler::fMakefile = NULL;
20
21 MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype )
22 {
23 if ( !ref++ )
24 handler_map = new map<ModuleType,MingwModuleHandler*>;
25 (*handler_map)[moduletype] = this;
26 }
27
28 MingwModuleHandler::~MingwModuleHandler()
29 {
30 if ( !--ref )
31 {
32 delete handler_map;
33 handler_map = NULL;
34 }
35 }
36
37 /*static*/ void
38 MingwModuleHandler::SetMakefile ( FILE* f )
39 {
40 fMakefile = f;
41 }
42
43 /*static*/ MingwModuleHandler*
44 MingwModuleHandler::LookupHandler ( const string& location,
45 ModuleType moduletype )
46 {
47 if ( !handler_map )
48 throw Exception ( "internal tool error: no registered module handlers" );
49 MingwModuleHandler* h = (*handler_map)[moduletype];
50 if ( !h )
51 {
52 throw UnknownModuleTypeException ( location, moduletype );
53 return NULL;
54 }
55 return h;
56 }
57
58 string
59 MingwModuleHandler::GetWorkingDirectory () const
60 {
61 return ".";
62 }
63
64 string
65 MingwModuleHandler::GetExtension ( const string& filename ) const
66 {
67 size_t index = filename.find_last_of ( '.' );
68 if (index != string::npos)
69 return filename.substr ( index );
70 return "";
71 }
72
73 string
74 MingwModuleHandler::ReplaceExtension ( const string& filename,
75 const string& newExtension ) const
76 {
77 size_t index = filename.find_last_of ( '.' );
78 if (index != string::npos)
79 return filename.substr ( 0, index ) + newExtension;
80 return filename;
81 }
82
83 string
84 MingwModuleHandler::GetModuleArchiveFilename ( const Module& module ) const
85 {
86 return ReplaceExtension ( FixupTargetFilename ( module.GetPath () ).c_str (),
87 ".a" );
88 }
89
90 string
91 MingwModuleHandler::GetImportLibraryDependencies ( const Module& module ) const
92 {
93 if ( module.libraries.size () == 0 )
94 return "";
95
96 string dependencies ( "" );
97 for ( size_t i = 0; i < module.libraries.size (); i++ )
98 {
99 if ( dependencies.size () > 0 )
100 dependencies += " ";
101 const Module* importedModule = module.project.LocateModule ( module.libraries[i]->name );
102 assert ( importedModule != NULL );
103 dependencies += FixupTargetFilename ( importedModule->GetDependencyPath () ).c_str ();
104 }
105 return dependencies;
106 }
107
108 string
109 MingwModuleHandler::GetModuleDependencies ( const Module& module ) const
110 {
111 if ( module.dependencies.size () == 0 )
112 return "";
113
114 string dependencies ( "" );
115 for ( size_t i = 0; i < module.dependencies.size (); i++ )
116 {
117 if ( dependencies.size () > 0 )
118 dependencies += " ";
119 const Dependency* dependency = module.dependencies[i];
120 const Module* dependencyModule = dependency->dependencyModule;
121 dependencies += dependencyModule->GetTargets ();
122 }
123 return dependencies;
124 }
125
126 string
127 MingwModuleHandler::GetAllDependencies ( const Module& module ) const
128 {
129 string dependencies = GetImportLibraryDependencies ( module );
130 string s = GetModuleDependencies ( module );
131 if (s.length () > 0)
132 {
133 dependencies += " ";
134 dependencies += s;
135 }
136 return dependencies;
137 }
138
139 string
140 MingwModuleHandler::GetSourceFilenames ( const Module& module ) const
141 {
142 size_t i;
143
144 string sourceFilenames ( "" );
145 for ( i = 0; i < module.files.size (); i++ )
146 sourceFilenames += " " + module.files[i]->name;
147 vector<If*> ifs = module.ifs;
148 for ( i = 0; i < ifs.size(); i++ )
149 {
150 size_t j;
151 If& rIf = *ifs[i];
152 for ( j = 0; j < rIf.ifs.size(); j++ )
153 ifs.push_back ( rIf.ifs[j] );
154 for ( j = 0; j < rIf.files.size(); j++ )
155 sourceFilenames += " " + rIf.files[j]->name;
156 }
157 return sourceFilenames;
158 }
159
160 string
161 MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const
162 {
163 return FixupTargetFilename ( ReplaceExtension ( sourceFilename,
164 ".o" ) );
165 }
166
167 string
168 MingwModuleHandler::GetObjectFilenames ( const Module& module ) const
169 {
170 if ( module.files.size () == 0 )
171 return "";
172
173 string objectFilenames ( "" );
174 for ( size_t i = 0; i < module.files.size (); i++ )
175 {
176 if ( objectFilenames.size () > 0 )
177 objectFilenames += " ";
178 objectFilenames += GetObjectFilename ( module.files[i]->name );
179 }
180 return objectFilenames;
181 }
182
183 string
184 MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector<Define*>& defines ) const
185 {
186 string parameters;
187 for (size_t i = 0; i < defines.size (); i++)
188 {
189 Define& define = *defines[i];
190 if (parameters.length () > 0)
191 parameters += " ";
192 parameters += "-D";
193 parameters += define.name;
194 if (define.value.length () > 0)
195 {
196 parameters += "=";
197 parameters += define.value;
198 }
199 }
200 return parameters;
201 }
202
203 string
204 MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const
205 {
206 string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );
207 string s = GenerateGccDefineParametersFromVector ( module.defines );
208 if (s.length () > 0)
209 {
210 parameters += " ";
211 parameters += s;
212 }
213 return parameters;
214 }
215
216 string
217 MingwModuleHandler::ConcatenatePaths ( const string& path1,
218 const string& path2 ) const
219 {
220 if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )
221 return path2;
222 if ( path1[path1.length ()] == CSEP )
223 return path1 + path2;
224 else
225 return path1 + CSEP + path2;
226 }
227
228 string
229 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes ) const
230 {
231 string parameters;
232 for ( size_t i = 0; i < includes.size (); i++ )
233 {
234 Include& include = *includes[i];
235 if (parameters.length () > 0)
236 parameters += " ";
237 parameters += "-I" + include.directory;
238 }
239 return parameters;
240 }
241
242 void
243 MingwModuleHandler::GenerateGccModuleIncludeVariable ( const Module& module ) const
244 {
245 #if 0
246 string name ( module.name + "_CFLAGS" );
247 fprintf ( fMakefile,
248 "%s := %s %s\n",
249 name.c_str(),
250 GenerateGccDefineParameters(module).c_str(),
251 GenerateGccIncludeParameters(module).c_str() );
252 #endif
253 }
254
255 string
256 MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const
257 {
258 string parameters = GenerateGccIncludeParametersFromVector ( module.includes );
259 string s = GenerateGccIncludeParametersFromVector ( module.project.includes );
260 if ( s.length () > 0 )
261 {
262 parameters += " ";
263 parameters += s;
264 }
265 return parameters;
266 }
267
268 void
269 MingwModuleHandler::GenerateMacros (
270 const char* op,
271 const vector<File*>& files,
272 const vector<Include*>& includes,
273 const vector<Define*>& defines,
274 const vector<If*>& ifs,
275 const string& cflags_macro,
276 const string& nasmflags_macro,
277 const string& objs_macro) const
278 {
279 size_t i;
280
281 if ( includes.size() || defines.size() )
282 {
283 fprintf (
284 fMakefile,
285 "%s %s",
286 cflags_macro.c_str(),
287 op );
288 for ( i = 0; i < includes.size(); i++ )
289 {
290 fprintf (
291 fMakefile,
292 " -I%s",
293 includes[i]->directory.c_str() );
294 }
295 for ( i = 0; i < defines.size(); i++ )
296 {
297 Define& d = *defines[i];
298 fprintf (
299 fMakefile,
300 " -D%s",
301 d.name.c_str() );
302 if ( d.value.size() )
303 fprintf (
304 fMakefile,
305 "=%s",
306 d.value.c_str() );
307 }
308 fprintf ( fMakefile, "\n" );
309 }
310
311 if ( files.size() )
312 {
313 fprintf (
314 fMakefile,
315 "%s %s",
316 objs_macro.c_str(),
317 op );
318 for ( i = 0; i < files.size(); i++ )
319 {
320 fprintf (
321 fMakefile,
322 "%s%s",
323 ( i%10 == 9 ? "\\\n\t" : " " ),
324 GetObjectFilename(files[i]->name).c_str() );
325 }
326 fprintf ( fMakefile, "\n" );
327 }
328
329 for ( i = 0; i < ifs.size(); i++ )
330 {
331 If& rIf = *ifs[i];
332 if ( rIf.defines.size() || rIf.includes.size() || rIf.files.size() || rIf.ifs.size() )
333 {
334 fprintf (
335 fMakefile,
336 "ifeq (\"$(%s)\",\"%s\")\n",
337 rIf.property.c_str(),
338 rIf.value.c_str() );
339 GenerateMacros (
340 "+=",
341 rIf.files,
342 rIf.includes,
343 rIf.defines,
344 rIf.ifs,
345 cflags_macro,
346 nasmflags_macro,
347 objs_macro );
348 fprintf (
349 fMakefile,
350 "endif\n\n" );
351 }
352 }
353 }
354
355 void
356 MingwModuleHandler::GenerateMacros (
357 const Module& module,
358 const string& cflags_macro,
359 const string& nasmflags_macro,
360 const string& objs_macro) const
361 {
362 GenerateMacros (
363 "=",
364 module.files,
365 module.includes,
366 module.defines,
367 module.ifs,
368 cflags_macro,
369 nasmflags_macro,
370 objs_macro );
371 fprintf ( fMakefile, "\n" );
372
373 fprintf (
374 fMakefile,
375 "%s += $(PROJECT_CFLAGS)\n\n",
376 cflags_macro.c_str () );
377 }
378
379 string
380 MingwModuleHandler::GenerateGccCommand ( const Module& module,
381 const string& sourceFilename,
382 const string& cc,
383 const string& cflagsMacro ) const
384 {
385 string objectFilename = GetObjectFilename ( sourceFilename );
386 return ssprintf ( "%s -c %s -o %s %s\n",
387 cc.c_str (),
388 sourceFilename.c_str (),
389 objectFilename.c_str (),
390 cflagsMacro.c_str () );
391 }
392
393 string
394 MingwModuleHandler::GenerateGccAssemblerCommand ( const Module& module,
395 const string& sourceFilename,
396 const string& cc,
397 const string& cflagsMacro ) const
398 {
399 string objectFilename = GetObjectFilename ( sourceFilename );
400 return ssprintf ( "%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",
401 cc.c_str (),
402 sourceFilename.c_str (),
403 objectFilename.c_str (),
404 cflagsMacro.c_str () );
405 }
406
407 string
408 MingwModuleHandler::GenerateNasmCommand ( const Module& module,
409 const string& sourceFilename,
410 const string& nasmflagsMacro ) const
411 {
412 string objectFilename = GetObjectFilename ( sourceFilename );
413 return ssprintf ( "%s -f win32 %s -o %s %s\n",
414 "nasm",
415 sourceFilename.c_str (),
416 objectFilename.c_str (),
417 nasmflagsMacro.c_str () );
418 }
419
420 string
421 MingwModuleHandler::GenerateCommand ( const Module& module,
422 const string& sourceFilename,
423 const string& cc,
424 const string& cflagsMacro,
425 const string& nasmflagsMacro ) const
426 {
427 string extension = GetExtension ( sourceFilename );
428 if ( extension == ".c" || extension == ".C" )
429 return GenerateGccCommand ( module,
430 sourceFilename,
431 cc,
432 cflagsMacro );
433 else if ( extension == ".s" || extension == ".S" )
434 return GenerateGccAssemblerCommand ( module,
435 sourceFilename,
436 cc,
437 cflagsMacro );
438 else if ( extension == ".asm" || extension == ".ASM" )
439 return GenerateNasmCommand ( module,
440 sourceFilename,
441 nasmflagsMacro );
442
443 throw InvalidOperationException ( __FILE__,
444 __LINE__,
445 "Unsupported filename extension '%s' in file '%s'",
446 extension.c_str (),
447 sourceFilename.c_str () );
448 }
449
450 void
451 MingwModuleHandler::GenerateObjectFileTargets ( const Module& module,
452 const vector<File*>& files,
453 const vector<If*>& ifs,
454 const string& cc,
455 const string& cflagsMacro,
456 const string& nasmflagsMacro ) const
457 {
458 size_t i;
459
460 for ( i = 0; i < files.size (); i++ )
461 {
462 string sourceFilename = files[i]->name;
463 string objectFilename = GetObjectFilename ( sourceFilename );
464 fprintf ( fMakefile,
465 "%s: %s\n",
466 objectFilename.c_str (),
467 sourceFilename.c_str () );
468 fprintf ( fMakefile,
469 "\t%s\n",
470 GenerateCommand ( module,
471 sourceFilename,
472 cc,
473 cflagsMacro,
474 nasmflagsMacro ).c_str () );
475 }
476
477 for ( i = 0; i < ifs.size(); i++ )
478 GenerateObjectFileTargets ( module, ifs[i]->files, ifs[i]->ifs, cc, cflagsMacro, nasmflagsMacro );
479 }
480
481 void
482 MingwModuleHandler::GenerateObjectFileTargets ( const Module& module,
483 const string& cc,
484 const string& cflagsMacro,
485 const string& nasmflagsMacro ) const
486 {
487 GenerateObjectFileTargets ( module, module.files, module.ifs, cc, cflagsMacro, nasmflagsMacro );
488 fprintf ( fMakefile, "\n" );
489 }
490
491 void
492 MingwModuleHandler::GetCleanTargets ( vector<string>& out,
493 const vector<File*>& files,
494 const vector<If*>& ifs ) const
495 {
496 size_t i;
497
498 for ( i = 0; i < files.size(); i++ )
499 out.push_back ( GetObjectFilename(files[i]->name) );
500
501 for ( i = 0; i < ifs.size(); i++ )
502 GetCleanTargets ( out, ifs[i]->files, ifs[i]->ifs );
503 }
504
505 string
506 MingwModuleHandler::GenerateArchiveTarget ( const Module& module,
507 const string& ar,
508 const string& objs_macro ) const
509 {
510 string archiveFilename = GetModuleArchiveFilename ( module );
511
512 fprintf ( fMakefile,
513 "%s: %s\n",
514 archiveFilename.c_str (),
515 objs_macro.c_str ());
516
517 fprintf ( fMakefile,
518 "\t%s -rc %s %s\n\n",
519 ar.c_str (),
520 archiveFilename.c_str (),
521 objs_macro.c_str ());
522
523 return archiveFilename;
524 }
525
526 void
527 MingwModuleHandler::GenerateMacrosAndTargets (
528 const Module& module,
529 const string& cc,
530 const string& ar ) const
531 {
532 string cflagsMacro = ssprintf("%s_CFLAGS",module.name.c_str());
533 string nasmflagsMacro = ssprintf("%s_NASMFLAGS",module.name.c_str());
534 string objectsMacro = ssprintf("%s_OBJS",module.name.c_str());
535
536 GenerateMacros ( module, cflagsMacro, nasmflagsMacro, objectsMacro );
537
538 // generate phony target for module name
539 fprintf ( fMakefile, ".PHONY: %s\n",
540 module.name.c_str() );
541 fprintf ( fMakefile, "%s: %s\n\n",
542 module.name.c_str(),
543 module.GetPath().c_str() );
544
545 // future references to the macros will be to get their values
546 cflagsMacro = ssprintf("$(%s)",cflagsMacro.c_str());
547 nasmflagsMacro = ssprintf("$(%s)",nasmflagsMacro.c_str());
548 objectsMacro = ssprintf("$(%s)",objectsMacro.c_str());
549
550 string ar_target = GenerateArchiveTarget ( module, ar, objectsMacro );
551 GenerateObjectFileTargets ( module, cc, cflagsMacro, nasmflagsMacro );
552
553 vector<string> clean_files;
554 clean_files.push_back ( FixupTargetFilename(module.GetPath()) );
555 clean_files.push_back ( ar_target );
556 GetCleanTargets ( clean_files, module.files, module.ifs );
557
558 fprintf ( fMakefile, "clean::\n\t-@$(rm)" );
559 for ( size_t i = 0; i < clean_files.size(); i++ )
560 {
561 if ( 9==(i%10) )
562 fprintf ( fMakefile, " 2>NUL\n\t-@$(rm)" );
563 fprintf ( fMakefile, " %s", clean_files[i].c_str() );
564 }
565 fprintf ( fMakefile, " 2>NUL\n\n" );
566 }
567
568 void
569 MingwModuleHandler::GenerateMacrosAndTargetsHost ( const Module& module ) const
570 {
571 GenerateMacrosAndTargets ( module, "${host_gcc}", "${host_ar}" );
572 }
573
574 void
575 MingwModuleHandler::GenerateMacrosAndTargetsTarget ( const Module& module ) const
576 {
577 GenerateMacrosAndTargets ( module, "${gcc}", "${ar}" );
578 }
579
580 string
581 MingwModuleHandler::GetInvocationDependencies ( const Module& module ) const
582 {
583 string dependencies;
584 for ( size_t i = 0; i < module.invocations.size (); i++ )
585 {
586 Invoke& invoke = *module.invocations[i];
587 if (invoke.invokeModule == &module)
588 /* Protect against circular dependencies */
589 continue;
590 if ( dependencies.length () > 0 )
591 dependencies += " ";
592 dependencies += invoke.GetTargets ();
593 }
594 return dependencies;
595 }
596
597 string
598 MingwModuleHandler::GetInvocationParameters ( const Invoke& invoke ) const
599 {
600 string parameters ( "" );
601 size_t i;
602 for (i = 0; i < invoke.output.size (); i++)
603 {
604 if (parameters.length () > 0)
605 parameters += " ";
606 InvokeFile& invokeFile = *invoke.output[i];
607 if (invokeFile.switches.length () > 0)
608 {
609 parameters += invokeFile.switches;
610 parameters += " ";
611 }
612 parameters += invokeFile.name;
613 }
614
615 for (i = 0; i < invoke.input.size (); i++)
616 {
617 if (parameters.length () > 0)
618 parameters += " ";
619 InvokeFile& invokeFile = *invoke.input[i];
620 if (invokeFile.switches.length () > 0)
621 {
622 parameters += invokeFile.switches;
623 parameters += " ";
624 }
625 parameters += invokeFile.name;
626 }
627
628 return parameters;
629 }
630
631 void
632 MingwModuleHandler::GenerateInvocations ( const Module& module ) const
633 {
634 if ( module.invocations.size () == 0 )
635 return;
636
637 for ( size_t i = 0; i < module.invocations.size (); i++ )
638 {
639 const Invoke& invoke = *module.invocations[i];
640
641 if ( invoke.invokeModule->type != BuildTool )
642 throw InvalidBuildFileException ( module.node.location,
643 "Only modules of type buildtool can be invoked." );
644
645 string invokeTarget = module.GetInvocationTarget ( i );
646 fprintf ( fMakefile,
647 "%s: %s\n\n",
648 invoke.GetTargets ().c_str (),
649 invokeTarget.c_str () );
650 fprintf ( fMakefile,
651 "%s: %s\n",
652 invokeTarget.c_str (),
653 FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str () );
654 fprintf ( fMakefile,
655 "\t%s %s\n\n",
656 FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str (),
657 GetInvocationParameters ( invoke ).c_str () );
658 fprintf ( fMakefile,
659 ".PNONY: %s\n\n",
660 invokeTarget.c_str () );
661 }
662 }
663
664 string
665 MingwModuleHandler::GetPreconditionDependenciesName ( const Module& module ) const
666 {
667 return ssprintf ( "%s_precondition",
668 module.name.c_str () );
669 }
670
671 void
672 MingwModuleHandler::GeneratePreconditionDependencies ( const Module& module ) const
673 {
674 string preconditionDependenciesName = GetPreconditionDependenciesName ( module );
675 string sourceFilenames = GetSourceFilenames ( module );
676 string dependencies = GetModuleDependencies ( module );
677 string s = GetInvocationDependencies ( module );
678 if ( s.length () > 0 )
679 {
680 if ( dependencies.length () > 0 )
681 dependencies += " ";
682 dependencies += s;
683 }
684
685 fprintf ( fMakefile,
686 ".PHONY: %s\n\n",
687 preconditionDependenciesName.c_str () );
688 fprintf ( fMakefile,
689 "%s: %s\n\n",
690 preconditionDependenciesName.c_str (),
691 dependencies.c_str () );
692 const char* p = sourceFilenames.c_str();
693 const char* end = p + strlen(p);
694 while ( p < end )
695 {
696 const char* p2 = &p[512];
697 if ( p2 > end )
698 p2 = end;
699 while ( p2 > p && !isspace(*p2) )
700 --p2;
701 if ( p == p2 )
702 {
703 p2 = strpbrk ( p, " \t" );
704 if ( !p2 )
705 p2 = end;
706 }
707 fprintf ( fMakefile,
708 "%.*s: %s\n",
709 p2-p,
710 p,
711 preconditionDependenciesName.c_str ());
712 p = p2;
713 p += strspn ( p, " \t" );
714 }
715 fprintf ( fMakefile, "\n" );
716 }
717
718
719 static MingwBuildToolModuleHandler buildtool_handler;
720
721 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler()
722 : MingwModuleHandler ( BuildTool )
723 {
724 }
725
726 void
727 MingwBuildToolModuleHandler::Process ( const Module& module )
728 {
729 GeneratePreconditionDependencies ( module );
730 GenerateBuildToolModuleTarget ( module );
731 GenerateInvocations ( module );
732 }
733
734 void
735 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module& module )
736 {
737 string target ( FixupTargetFilename ( module.GetPath () ) );
738 string archiveFilename = GetModuleArchiveFilename ( module );
739
740 GenerateMacrosAndTargetsHost ( module );
741
742 fprintf ( fMakefile, "%s: %s\n",
743 target.c_str (),
744 archiveFilename.c_str () );
745 fprintf ( fMakefile,
746 "\t${host_gcc} -o %s %s\n\n",
747 target.c_str (),
748 archiveFilename.c_str () );
749 }
750
751 static MingwKernelModuleHandler kernelmodule_handler;
752
753 MingwKernelModuleHandler::MingwKernelModuleHandler ()
754 : MingwModuleHandler ( Kernel )
755 {
756 }
757
758 void
759 MingwKernelModuleHandler::Process ( const Module& module )
760 {
761 GeneratePreconditionDependencies ( module );
762 GenerateKernelModuleTarget ( module );
763 GenerateInvocations ( module );
764 }
765
766 void
767 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module )
768 {
769 static string ros_junk ( "$(ROS_TEMPORARY)" );
770 //static string ros_output ( "$(ROS_INTERMEDIATE)" );
771 string target ( FixupTargetFilename(module.GetPath()) );
772 string workingDirectory = GetWorkingDirectory ( );
773 string archiveFilename = GetModuleArchiveFilename ( module );
774 string importLibraryDependencies = GetImportLibraryDependencies ( module );
775 string base_tmp = ros_junk + module.name + ".base.tmp";
776 string junk_tmp = ros_junk + module.name + ".junk.tmp";
777 string temp_exp = ros_junk + module.name + ".temp.exp";
778 string gccOptions = ssprintf ("-Wl,-T,%s" SSEP "ntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,_NtProcessStartup -Wl,--image-base,0xC0000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
779 module.GetBasePath ().c_str () );
780
781 GenerateMacrosAndTargetsTarget ( module );
782
783 fprintf ( fMakefile, "%s: %s %s\n",
784 target.c_str (),
785 archiveFilename.c_str (),
786 importLibraryDependencies.c_str () );
787 fprintf ( fMakefile,
788 "\t${gcc} %s -Wl,--base-file,%s -o %s %s %s\n",
789 gccOptions.c_str (),
790 base_tmp.c_str (),
791 junk_tmp.c_str (),
792 archiveFilename.c_str (),
793 importLibraryDependencies.c_str () );
794 fprintf ( fMakefile,
795 "\t${rm} %s\n",
796 junk_tmp.c_str () );
797 fprintf ( fMakefile,
798 "\t${dlltool} --dllname %s --base-file %s --output-exp %s --kill-at\n",
799 target.c_str (),
800 base_tmp.c_str (),
801 temp_exp.c_str ());
802 fprintf ( fMakefile,
803 "\t${rm} %s\n",
804 base_tmp.c_str () );
805 fprintf ( fMakefile,
806 "\t${gcc} %s -Wl,%s -o %s %s %s\n",
807 gccOptions.c_str (),
808 temp_exp.c_str (),
809 target.c_str (),
810 archiveFilename.c_str (),
811 importLibraryDependencies.c_str () );
812 fprintf ( fMakefile,
813 "\t${rm} %s\n\n",
814 temp_exp.c_str () );
815 }
816
817
818 static MingwStaticLibraryModuleHandler staticlibrary_handler;
819
820 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()
821 : MingwModuleHandler ( StaticLibrary )
822 {
823 }
824
825 void
826 MingwStaticLibraryModuleHandler::Process ( const Module& module )
827 {
828 GeneratePreconditionDependencies ( module );
829 GenerateStaticLibraryModuleTarget ( module );
830 GenerateInvocations ( module );
831 }
832
833 void
834 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module& module )
835 {
836 GenerateMacrosAndTargetsTarget ( module );
837 }
838
839
840 static MingwKernelModeDLLModuleHandler kernelmodedll_handler;
841
842 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler ()
843 : MingwModuleHandler ( KernelModeDLL )
844 {
845 }
846
847 void
848 MingwKernelModeDLLModuleHandler::Process ( const Module& module )
849 {
850 GeneratePreconditionDependencies ( module );
851 GenerateKernelModeDLLModuleTarget ( module );
852 GenerateInvocations ( module );
853 }
854
855 void
856 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Module& module )
857 {
858 static string ros_junk ( "$(ROS_TEMPORARY)" );
859 string target ( FixupTargetFilename ( module.GetPath () ) );
860 string workingDirectory = GetWorkingDirectory ( );
861 string archiveFilename = GetModuleArchiveFilename ( module );
862 string importLibraryDependencies = GetImportLibraryDependencies ( module );
863
864 if (module.importLibrary != NULL)
865 {
866 fprintf ( fMakefile, "%s:\n",
867 module.GetDependencyPath ().c_str () );
868
869 fprintf ( fMakefile,
870 "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",
871 module.GetTargetName ().c_str (),
872 FixupTargetFilename ( module.GetBasePath () + SSEP + module.importLibrary->definition ).c_str (),
873 FixupTargetFilename ( module.GetDependencyPath () ).c_str () );
874 }
875
876 if (module.files.size () > 0)
877 {
878 GenerateMacrosAndTargetsTarget ( module );
879
880 fprintf ( fMakefile, "%s: %s %s\n",
881 target.c_str (),
882 archiveFilename.c_str (),
883 importLibraryDependencies.c_str () );
884
885 fprintf ( fMakefile,
886 "\t${gcc} -Wl,--subsystem,native -Wl,--entry,_DriverEntry@8 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll -o %s %s %s\n\n",
887 target.c_str (),
888 archiveFilename.c_str (),
889 importLibraryDependencies.c_str () );
890 }
891 else
892 {
893 fprintf ( fMakefile, "%s:\n",
894 target.c_str ());
895 fprintf ( fMakefile, ".PHONY: %s\n\n",
896 target.c_str ());
897 }
898 }
899
900
901 static MingwNativeDLLModuleHandler nativedll_handler;
902
903 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler ()
904 : MingwModuleHandler ( NativeDLL )
905 {
906 }
907
908 void
909 MingwNativeDLLModuleHandler::Process ( const Module& module )
910 {
911 GeneratePreconditionDependencies ( module );
912 GenerateNativeDLLModuleTarget ( module );
913 GenerateInvocations ( module );
914 }
915
916 void
917 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ( const Module& module )
918 {
919 static string ros_junk ( "$(ROS_TEMPORARY)" );
920 string target ( FixupTargetFilename ( module.GetPath () ) );
921 string workingDirectory = GetWorkingDirectory ( );
922 string archiveFilename = GetModuleArchiveFilename ( module );
923 string importLibraryDependencies = GetImportLibraryDependencies ( module );
924
925 if (module.importLibrary != NULL)
926 {
927 fprintf ( fMakefile, "%s:\n",
928 module.GetDependencyPath ().c_str () );
929
930 fprintf ( fMakefile,
931 "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",
932 module.GetTargetName ().c_str (),
933 FixupTargetFilename ( module.GetBasePath () + SSEP + module.importLibrary->definition ).c_str (),
934 FixupTargetFilename ( module.GetDependencyPath () ).c_str () );
935 }
936
937 if (module.files.size () > 0)
938 {
939 GenerateMacrosAndTargetsTarget ( module );
940
941 fprintf ( fMakefile, "%s: %s %s\n",
942 target.c_str (),
943 archiveFilename.c_str (),
944 importLibraryDependencies.c_str () );
945
946 fprintf ( fMakefile,
947 "\t${gcc} -Wl,--subsystem,native -Wl,--entry,_DllMainCRTStartup@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll -o %s %s %s\n\n",
948 target.c_str (),
949 archiveFilename.c_str (),
950 importLibraryDependencies.c_str () );
951 }
952 else
953 {
954 fprintf ( fMakefile, "%s:\n\n",
955 target.c_str ());
956 fprintf ( fMakefile, ".PHONY: %s\n\n",
957 target.c_str ());
958 }
959 }
960
961
962 static MingwWin32DLLModuleHandler win32dll_handler;
963
964 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler ()
965 : MingwModuleHandler ( Win32DLL )
966 {
967 }
968
969 void
970 MingwWin32DLLModuleHandler::Process ( const Module& module )
971 {
972 GeneratePreconditionDependencies ( module );
973 GenerateWin32DLLModuleTarget ( module );
974 GenerateInvocations ( module );
975 }
976
977 void
978 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module )
979 {
980 static string ros_junk ( "$(ROS_TEMPORARY)" );
981 string target ( FixupTargetFilename ( module.GetPath () ) );
982 string workingDirectory = GetWorkingDirectory ( );
983 string archiveFilename = GetModuleArchiveFilename ( module );
984 string importLibraryDependencies = GetImportLibraryDependencies ( module );
985
986 if (module.importLibrary != NULL)
987 {
988 fprintf ( fMakefile, "%s:\n",
989 module.GetDependencyPath ().c_str () );
990
991 fprintf ( fMakefile,
992 "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",
993 module.GetTargetName ().c_str (),
994 FixupTargetFilename ( module.GetBasePath () + SSEP + module.importLibrary->definition ).c_str (),
995 FixupTargetFilename ( module.GetDependencyPath () ).c_str () );
996 }
997
998 if (module.files.size () > 0)
999 {
1000 GenerateMacrosAndTargetsTarget ( module );
1001
1002 fprintf ( fMakefile, "%s: %s %s\n",
1003 target.c_str (),
1004 archiveFilename.c_str (),
1005 importLibraryDependencies.c_str () );
1006
1007 fprintf ( fMakefile,
1008 "\t${gcc} -Wl,--subsystem,console -Wl,--entry,_DllMain@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll -o %s %s %s\n",
1009 target.c_str (),
1010 archiveFilename.c_str (),
1011 importLibraryDependencies.c_str () );
1012 }
1013 else
1014 {
1015 fprintf ( fMakefile, "%s:\n\n",
1016 target.c_str ());
1017 fprintf ( fMakefile, ".PHONY: %s\n\n",
1018 target.c_str ());
1019 }
1020 }