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