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