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