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