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