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