more efficient detection of C++ modules, fixed bug in C++ pch support, always clean...
[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$(ECHO_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$(ECHO_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$(ECHO_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$(ECHO_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$(ECHO_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$(ECHO_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$(ECHO_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$(ECHO_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 )
1060 {
1061 const string& pch_file = module.pch->header;
1062 string gch_file = pch_file + ".gch";
1063 CLEAN_FILE(gch_file);
1064 if ( use_pch )
1065 {
1066 fprintf (
1067 fMakefile,
1068 "%s: %s\n",
1069 gch_file.c_str(),
1070 pch_file.c_str() );
1071 fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
1072 fprintf (
1073 fMakefile,
1074 "\t%s -o %s %s -g %s\n\n",
1075 ( module.cplusplus ? cppc.c_str() : cc.c_str() ),
1076 gch_file.c_str(),
1077 cflagsMacro.c_str(),
1078 pch_file.c_str() );
1079 }
1080 }
1081
1082 GenerateObjectFileTargets ( module,
1083 module.non_if_data,
1084 cc,
1085 cppc,
1086 cflagsMacro,
1087 nasmflagsMacro,
1088 windresflagsMacro,
1089 clean_files );
1090 fprintf ( fMakefile, "\n" );
1091 }
1092
1093 void
1094 MingwModuleHandler::GetCleanTargets (
1095 string_list& out,
1096 const IfableData& data ) const
1097 {
1098 size_t i;
1099
1100 const vector<File*>& files = data.files;
1101 for ( i = 0; i < files.size(); i++ )
1102 out.push_back ( PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ) );
1103
1104 const vector<If*>& ifs = data.ifs;
1105 for ( i = 0; i < ifs.size(); i++ )
1106 GetCleanTargets ( out, ifs[i]->data );
1107 }
1108
1109 string
1110 MingwModuleHandler::GenerateArchiveTarget ( const Module& module,
1111 const string& ar,
1112 const string& objs_macro ) const
1113 {
1114 string archiveFilename = GetModuleArchiveFilename ( module );
1115
1116 fprintf ( fMakefile,
1117 "%s: %s\n",
1118 archiveFilename.c_str (),
1119 objs_macro.c_str ());
1120
1121 fprintf ( fMakefile, "\t$(ECHO_AR)\n" );
1122
1123 fprintf ( fMakefile,
1124 "\t%s -rc %s %s\n\n",
1125 ar.c_str (),
1126 archiveFilename.c_str (),
1127 objs_macro.c_str ());
1128
1129 return archiveFilename;
1130 }
1131
1132 string
1133 MingwModuleHandler::GetCFlagsMacro ( const Module& module ) const
1134 {
1135 return ssprintf ( "$(%s_CFLAGS)",
1136 module.name.c_str () );
1137 }
1138
1139 string
1140 MingwModuleHandler::GetObjectsMacro ( const Module& module ) const
1141 {
1142 return ssprintf ( "$(%s_OBJS)",
1143 module.name.c_str () );
1144 }
1145
1146 string
1147 MingwModuleHandler::GetLinkingDependenciesMacro ( const Module& module ) const
1148 {
1149 return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
1150 }
1151
1152 string
1153 MingwModuleHandler::GetLibsMacro ( const Module& module ) const
1154 {
1155 return ssprintf ( "$(%s_LIBS)", module.name.c_str () );
1156 }
1157
1158 string
1159 MingwModuleHandler::GetLinkerMacro ( const Module& module ) const
1160 {
1161 return ssprintf ( "$(%s_LFLAGS)",
1162 module.name.c_str () );
1163 }
1164
1165 void
1166 MingwModuleHandler::GenerateMacrosAndTargets (
1167 const Module& module,
1168 const string& cc,
1169 const string& cppc,
1170 const string& ar,
1171 const string* cflags,
1172 const string* nasmflags,
1173 string_list& clean_files ) const
1174 {
1175 string cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
1176 string nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
1177 string windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
1178 string linkerFlagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
1179 string objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
1180 string libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
1181 string linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
1182
1183 GenerateMacros ( module,
1184 cflagsMacro,
1185 nasmflagsMacro,
1186 windresflagsMacro,
1187 linkerFlagsMacro,
1188 objectsMacro,
1189 libsMacro,
1190 linkDepsMacro );
1191
1192 if ( cflags != NULL )
1193 {
1194 fprintf ( fMakefile,
1195 "%s += %s\n\n",
1196 cflagsMacro.c_str (),
1197 cflags->c_str () );
1198 }
1199
1200 if ( nasmflags != NULL )
1201 {
1202 fprintf ( fMakefile,
1203 "%s += %s\n\n",
1204 nasmflagsMacro.c_str (),
1205 nasmflags->c_str () );
1206 }
1207
1208 // generate phony target for module name
1209 fprintf ( fMakefile, ".PHONY: %s\n",
1210 module.name.c_str () );
1211 fprintf ( fMakefile, "%s: %s\n\n",
1212 module.name.c_str (),
1213 FixupTargetFilename ( module.GetPath () ).c_str () );
1214
1215 // future references to the macros will be to get their values
1216 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
1217 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
1218 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
1219
1220 string ar_target = GenerateArchiveTarget ( module, ar, objectsMacro );
1221 GenerateObjectFileTargets ( module,
1222 cc,
1223 cppc,
1224 cflagsMacro,
1225 nasmflagsMacro,
1226 windresflagsMacro,
1227 clean_files );
1228
1229 CLEAN_FILE ( ar_target );
1230 string tgt = FixupTargetFilename(module.GetPath());
1231 if ( tgt != ar_target )
1232 {
1233 CLEAN_FILE ( tgt );
1234 }
1235 }
1236
1237 void
1238 MingwModuleHandler::GenerateMacrosAndTargetsHost (
1239 const Module& module,
1240 string_list& clean_files ) const
1241 {
1242 GenerateMacrosAndTargets (
1243 module,
1244 "${host_gcc}",
1245 "${host_gpp}",
1246 "${host_ar}",
1247 NULL,
1248 NULL,
1249 clean_files );
1250 }
1251
1252 void
1253 MingwModuleHandler::GenerateMacrosAndTargetsTarget (
1254 const Module& module,
1255 string_list& clean_files ) const
1256 {
1257 GenerateMacrosAndTargetsTarget (
1258 module,
1259 NULL,
1260 NULL,
1261 clean_files );
1262 }
1263
1264 void
1265 MingwModuleHandler::GenerateMacrosAndTargetsTarget (
1266 const Module& module,
1267 const string* cflags,
1268 const string* nasmflags,
1269 string_list& clean_files ) const
1270 {
1271 GenerateMacrosAndTargets (
1272 module,
1273 "${gcc}",
1274 "${gpp}",
1275 "${ar}",
1276 cflags,
1277 nasmflags,
1278 clean_files );
1279 }
1280
1281 string
1282 MingwModuleHandler::GetInvocationDependencies ( const Module& module ) const
1283 {
1284 string dependencies;
1285 for ( size_t i = 0; i < module.invocations.size (); i++ )
1286 {
1287 Invoke& invoke = *module.invocations[i];
1288 if (invoke.invokeModule == &module)
1289 /* Protect against circular dependencies */
1290 continue;
1291 if ( dependencies.length () > 0 )
1292 dependencies += " ";
1293 dependencies += invoke.GetTargets ();
1294 }
1295 return dependencies;
1296 }
1297
1298 void
1299 MingwModuleHandler::GenerateInvocations ( const Module& module ) const
1300 {
1301 if ( module.invocations.size () == 0 )
1302 return;
1303
1304 for ( size_t i = 0; i < module.invocations.size (); i++ )
1305 {
1306 const Invoke& invoke = *module.invocations[i];
1307
1308 if ( invoke.invokeModule->type != BuildTool )
1309 {
1310 throw InvalidBuildFileException ( module.node.location,
1311 "Only modules of type buildtool can be invoked." );
1312 }
1313
1314 string invokeTarget = module.GetInvocationTarget ( i );
1315 fprintf ( fMakefile,
1316 ".PHONY: %s\n\n",
1317 invokeTarget.c_str () );
1318 fprintf ( fMakefile,
1319 "%s: %s\n\n",
1320 invokeTarget.c_str (),
1321 invoke.GetTargets ().c_str () );
1322 fprintf ( fMakefile,
1323 "%s: %s\n",
1324 invoke.GetTargets ().c_str (),
1325 FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str () );
1326 fprintf ( fMakefile, "\t$(ECHO_INVOKE)\n" );
1327 fprintf ( fMakefile,
1328 "\t%s %s\n\n",
1329 FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str (),
1330 invoke.GetParameters ().c_str () );
1331 }
1332 }
1333
1334 string
1335 MingwModuleHandler::GetPreconditionDependenciesName ( const Module& module ) const
1336 {
1337 return ssprintf ( "%s_precondition",
1338 module.name.c_str () );
1339 }
1340
1341 string
1342 MingwModuleHandler::GetDefaultDependencies ( const Module& module ) const
1343 {
1344 /* Avoid circular dependency */
1345 if ( module.type == BuildTool || module.name == "zlib" )
1346 return "$(ROS_INTERMEDIATE)." SSEP "tools $(ROS_INTERMEDIATE)." SSEP "lib" SSEP "zlib";
1347 else
1348 return "init";
1349 }
1350
1351 void
1352 MingwModuleHandler::GeneratePreconditionDependencies ( const Module& module ) const
1353 {
1354 string preconditionDependenciesName = GetPreconditionDependenciesName ( module );
1355 string sourceFilenames = GetSourceFilenamesWithoutGeneratedFiles ( module );
1356 string dependencies = GetDefaultDependencies ( module );
1357 string s = GetModuleDependencies ( module );
1358 if ( s.length () > 0 )
1359 {
1360 if ( dependencies.length () > 0 )
1361 dependencies += " ";
1362 dependencies += s;
1363 }
1364
1365 s = GetInvocationDependencies ( module );
1366 if ( s.length () > 0 )
1367 {
1368 if ( dependencies.length () > 0 )
1369 dependencies += " ";
1370 dependencies += s;
1371 }
1372
1373 fprintf ( fMakefile,
1374 ".PHONY: %s\n\n",
1375 preconditionDependenciesName.c_str () );
1376 fprintf ( fMakefile,
1377 "%s: %s\n\n",
1378 preconditionDependenciesName.c_str (),
1379 dependencies.c_str () );
1380 const char* p = sourceFilenames.c_str();
1381 const char* end = p + strlen(p);
1382 while ( p < end )
1383 {
1384 const char* p2 = &p[512];
1385 if ( p2 > end )
1386 p2 = end;
1387 while ( p2 > p && !isspace(*p2) )
1388 --p2;
1389 if ( p == p2 )
1390 {
1391 p2 = strpbrk ( p, " \t" );
1392 if ( !p2 )
1393 p2 = end;
1394 }
1395 fprintf ( fMakefile,
1396 "%.*s: %s\n",
1397 p2-p,
1398 p,
1399 preconditionDependenciesName.c_str ());
1400 p = p2;
1401 p += strspn ( p, " \t" );
1402 }
1403 fprintf ( fMakefile, "\n" );
1404 }
1405
1406 void
1407 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded (
1408 const Module& module,
1409 string_list& clean_files ) const
1410 {
1411 if ( module.importLibrary != NULL )
1412 {
1413 string library_target = FixupTargetFilename( module.GetDependencyPath () ).c_str ();
1414 CLEAN_FILE ( library_target );
1415
1416 string definitionDependencies = GetDefinitionDependencies ( module );
1417 fprintf ( fMakefile, "%s: %s\n",
1418 library_target.c_str (),
1419 definitionDependencies.c_str () );
1420
1421 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
1422
1423 string killAt = module.mangledSymbols ? "" : "--kill-at";
1424 fprintf ( fMakefile,
1425 "\t${dlltool} --dllname %s --def %s --output-lib %s %s\n\n",
1426 module.GetTargetName ().c_str (),
1427 ( module.GetBasePath () + SSEP + module.importLibrary->definition ).c_str (),
1428 library_target.c_str (),
1429 killAt.c_str () );
1430 }
1431 }
1432
1433 string
1434 MingwModuleHandler::GetSpecObjectDependencies ( const string& filename ) const
1435 {
1436 string basename = GetBasename ( filename );
1437 return basename + ".spec.def" + " " + basename + ".stubs.c";
1438 }
1439
1440 string
1441 MingwModuleHandler::GetDefinitionDependencies ( const Module& module ) const
1442 {
1443 string dependencies;
1444 string dkNkmLibNoFixup = "dk/nkm/lib";
1445 dependencies += FixupTargetFilename ( dkNkmLibNoFixup );
1446 PassThruCacheDirectory ( dkNkmLibNoFixup + SSEP );
1447 const vector<File*>& files = module.non_if_data.files;
1448 for ( size_t i = 0; i < files.size (); i++ )
1449 {
1450 File& file = *files[i];
1451 string extension = GetExtension ( file.name );
1452 if ( extension == ".spec" || extension == ".SPEC" )
1453 {
1454 if ( dependencies.length () > 0 )
1455 dependencies += " ";
1456 dependencies += GetSpecObjectDependencies ( file.name );
1457 }
1458 }
1459 return dependencies;
1460 }
1461
1462 bool
1463 MingwModuleHandler::IsCPlusPlusModule ( const Module& module ) const
1464 {
1465 return module.cplusplus;
1466 }
1467
1468
1469 static MingwBuildToolModuleHandler buildtool_handler;
1470
1471 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler()
1472 : MingwModuleHandler ( BuildTool )
1473 {
1474 }
1475
1476 void
1477 MingwBuildToolModuleHandler::Process ( const Module& module, string_list& clean_files )
1478 {
1479 GeneratePreconditionDependencies ( module );
1480 GenerateBuildToolModuleTarget ( module, clean_files );
1481 GenerateInvocations ( module );
1482 }
1483
1484 void
1485 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module& module, string_list& clean_files )
1486 {
1487 string target ( FixupTargetFilename ( module.GetPath () ) );
1488 string objectsMacro = GetObjectsMacro ( module );
1489 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1490 string libsMacro = GetLibsMacro ( module );
1491
1492 GenerateMacrosAndTargetsHost ( module, clean_files );
1493
1494 string linker;
1495 if ( IsCPlusPlusModule ( module ) )
1496 linker = "${host_gpp}";
1497 else
1498 linker = "${host_gcc}";
1499
1500 fprintf ( fMakefile, "%s: %s %s\n",
1501 target.c_str (),
1502 objectsMacro.c_str (),
1503 linkDepsMacro.c_str () );
1504 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1505 fprintf ( fMakefile,
1506 "\t%s %s -o %s %s %s\n\n",
1507 linker.c_str (),
1508 GetLinkerMacro ( module ).c_str (),
1509 target.c_str (),
1510 objectsMacro.c_str (),
1511 libsMacro.c_str () );
1512 }
1513
1514
1515 static MingwKernelModuleHandler kernelmodule_handler;
1516
1517 MingwKernelModuleHandler::MingwKernelModuleHandler ()
1518 : MingwModuleHandler ( Kernel )
1519 {
1520 }
1521
1522 void
1523 MingwKernelModuleHandler::Process ( const Module& module, string_list& clean_files )
1524 {
1525 GeneratePreconditionDependencies ( module );
1526 GenerateKernelModuleTarget ( module, clean_files );
1527 GenerateInvocations ( module );
1528 }
1529
1530 void
1531 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module, string_list& clean_files )
1532 {
1533 static string ros_junk ( "$(ROS_TEMPORARY)" );
1534 string targetName ( module.GetTargetName () ); // i.e. "ntoskrnl.exe"
1535 string target ( FixupTargetFilename (module.GetPath ()) ); // i.e. "$(ROS_INT).\ntoskrnl\ntoskrnl.exe"
1536 string workingDirectory = GetWorkingDirectory ();
1537 string objectsMacro = GetObjectsMacro ( module );
1538 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1539 string libsMacro = GetLibsMacro ( module );
1540 string base_tmp = ros_junk + module.name + ".base.tmp";
1541 CLEAN_FILE ( base_tmp );
1542 string junk_tmp = ros_junk + module.name + ".junk.tmp";
1543 CLEAN_FILE ( junk_tmp );
1544 string temp_exp = ros_junk + module.name + ".temp.exp";
1545 CLEAN_FILE ( temp_exp );
1546 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",
1547 module.GetBasePath ().c_str (),
1548 module.entrypoint.c_str (),
1549 module.baseaddress.c_str () );
1550
1551 GenerateMacrosAndTargetsTarget ( module, clean_files );
1552
1553 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
1554
1555 fprintf ( fMakefile, "%s: %s %s\n",
1556 target.c_str (),
1557 objectsMacro.c_str (),
1558 linkDepsMacro.c_str () );
1559 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1560 fprintf ( fMakefile,
1561 "\t${gcc} %s %s -Wl,--base-file,%s -o %s %s %s\n",
1562 GetLinkerMacro ( module ).c_str (),
1563 gccOptions.c_str (),
1564 base_tmp.c_str (),
1565 junk_tmp.c_str (),
1566 objectsMacro.c_str (),
1567 linkDepsMacro.c_str () );
1568 fprintf ( fMakefile,
1569 "\t-@${rm} %s\n",
1570 junk_tmp.c_str () );
1571 string killAt = module.mangledSymbols ? "" : "--kill-at";
1572 fprintf ( fMakefile,
1573 "\t${dlltool} --dllname %s --base-file %s --def ntoskrnl/ntoskrnl.def --output-exp %s %s\n",
1574 targetName.c_str (),
1575 base_tmp.c_str (),
1576 temp_exp.c_str (),
1577 killAt.c_str () );
1578 fprintf ( fMakefile,
1579 "\t-@${rm} %s\n",
1580 base_tmp.c_str () );
1581 fprintf ( fMakefile,
1582 "\t${gcc} %s %s -Wl,%s -o %s %s %s\n",
1583 GetLinkerMacro ( module ).c_str (),
1584 gccOptions.c_str (),
1585 temp_exp.c_str (),
1586 target.c_str (),
1587 objectsMacro.c_str (),
1588 linkDepsMacro.c_str () );
1589 fprintf ( fMakefile,
1590 "\t-@${rm} %s\n",
1591 temp_exp.c_str () );
1592 fprintf ( fMakefile, "\t$(ECHO_RSYM)\n" );
1593 fprintf ( fMakefile,
1594 "\t${rsym} %s %s\n\n",
1595 target.c_str (),
1596 target.c_str () );
1597 }
1598
1599
1600 static MingwStaticLibraryModuleHandler staticlibrary_handler;
1601
1602 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()
1603 : MingwModuleHandler ( StaticLibrary )
1604 {
1605 }
1606
1607 void
1608 MingwStaticLibraryModuleHandler::Process ( const Module& module, string_list& clean_files )
1609 {
1610 GeneratePreconditionDependencies ( module );
1611 GenerateStaticLibraryModuleTarget ( module, clean_files );
1612 GenerateInvocations ( module );
1613 }
1614
1615 void
1616 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module& module, string_list& clean_files )
1617 {
1618 GenerateMacrosAndTargetsTarget ( module, clean_files );
1619 }
1620
1621
1622 static MingwObjectLibraryModuleHandler objectlibrary_handler;
1623
1624 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler ()
1625 : MingwModuleHandler ( ObjectLibrary )
1626 {
1627 }
1628
1629 void
1630 MingwObjectLibraryModuleHandler::Process ( const Module& module, string_list& clean_files )
1631 {
1632 GeneratePreconditionDependencies ( module );
1633 GenerateObjectLibraryModuleTarget ( module, clean_files );
1634 GenerateInvocations ( module );
1635 }
1636
1637 void
1638 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ( const Module& module, string_list& clean_files )
1639 {
1640 GenerateMacrosAndTargetsTarget ( module, clean_files );
1641 }
1642
1643
1644 static MingwKernelModeDLLModuleHandler kernelmodedll_handler;
1645
1646 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler ()
1647 : MingwModuleHandler ( KernelModeDLL )
1648 {
1649 }
1650
1651 void
1652 MingwKernelModeDLLModuleHandler::Process ( const Module& module, string_list& clean_files )
1653 {
1654 GeneratePreconditionDependencies ( module );
1655 GenerateKernelModeDLLModuleTarget ( module, clean_files );
1656 GenerateInvocations ( module );
1657 }
1658
1659 void
1660 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget (
1661 const Module& module,
1662 string_list& clean_files )
1663 {
1664 static string ros_junk ( "$(ROS_TEMPORARY)" );
1665 string target ( FixupTargetFilename ( module.GetPath () ) );
1666 string workingDirectory = GetWorkingDirectory ( );
1667 string objectsMacro = GetObjectsMacro ( module );
1668 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1669 string libsMacro = GetLibsMacro ( module );
1670
1671 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
1672
1673 if ( module.non_if_data.files.size () > 0 )
1674 {
1675 GenerateMacrosAndTargetsTarget ( module, clean_files );
1676
1677 fprintf ( fMakefile, "%s: %s %s\n",
1678 target.c_str (),
1679 objectsMacro.c_str (),
1680 linkDepsMacro.c_str () );
1681
1682 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1683 module.entrypoint.c_str (),
1684 module.baseaddress.c_str () );
1685 GenerateLinkerCommand ( module,
1686 "${gcc}",
1687 linkerParameters,
1688 objectsMacro,
1689 libsMacro,
1690 clean_files );
1691 }
1692 else
1693 {
1694 fprintf ( fMakefile, ".PHONY: %s\n\n",
1695 target.c_str ());
1696 fprintf ( fMakefile, "%s:\n",
1697 target.c_str ());
1698 }
1699 }
1700
1701
1702 static MingwKernelModeDriverModuleHandler kernelmodedriver_handler;
1703
1704 MingwKernelModeDriverModuleHandler::MingwKernelModeDriverModuleHandler ()
1705 : MingwModuleHandler ( KernelModeDriver )
1706 {
1707 }
1708
1709 void
1710 MingwKernelModeDriverModuleHandler::Process ( const Module& module, string_list& clean_files )
1711 {
1712 GeneratePreconditionDependencies ( module );
1713 GenerateKernelModeDriverModuleTarget ( module, clean_files );
1714 GenerateInvocations ( module );
1715 }
1716
1717
1718 void
1719 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget (
1720 const Module& module,
1721 string_list& clean_files )
1722 {
1723 static string ros_junk ( "$(ROS_TEMPORARY)" );
1724 string target ( PassThruCacheDirectory( FixupTargetFilename ( module.GetPath () ) ) );
1725 string workingDirectory = GetWorkingDirectory ();
1726 string objectsMacro = GetObjectsMacro ( module );
1727 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1728 string libsMacro = GetLibsMacro ( module );
1729
1730 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
1731
1732 if ( module.non_if_data.files.size () > 0 )
1733 {
1734 string cflags ( "-D__NTDRIVER__" );
1735 GenerateMacrosAndTargetsTarget ( module,
1736 &cflags,
1737 NULL,
1738 clean_files);
1739
1740 fprintf ( fMakefile, "%s: %s %s\n",
1741 target.c_str (),
1742 objectsMacro.c_str (),
1743 linkDepsMacro.c_str () );
1744
1745 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1746 module.entrypoint.c_str (),
1747 module.baseaddress.c_str () );
1748 GenerateLinkerCommand ( module,
1749 "${gcc}",
1750 linkerParameters,
1751 objectsMacro,
1752 libsMacro,
1753 clean_files );
1754 }
1755 else
1756 {
1757 fprintf ( fMakefile, ".PHONY: %s\n\n",
1758 target.c_str ());
1759 fprintf ( fMakefile, "%s:\n",
1760 target.c_str () );
1761 }
1762 }
1763
1764
1765 static MingwNativeDLLModuleHandler nativedll_handler;
1766
1767 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler ()
1768 : MingwModuleHandler ( NativeDLL )
1769 {
1770 }
1771
1772 void
1773 MingwNativeDLLModuleHandler::Process ( const Module& module, string_list& clean_files )
1774 {
1775 GeneratePreconditionDependencies ( module );
1776 GenerateNativeDLLModuleTarget ( module, clean_files );
1777 GenerateInvocations ( module );
1778 }
1779
1780 void
1781 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ( const Module& module, string_list& clean_files )
1782 {
1783 static string ros_junk ( "$(ROS_TEMPORARY)" );
1784 string target ( FixupTargetFilename ( module.GetPath () ) );
1785 string workingDirectory = GetWorkingDirectory ( );
1786 string objectsMacro = GetObjectsMacro ( module );
1787 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1788 string libsMacro = GetLibsMacro ( module );
1789
1790 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
1791
1792 if ( module.non_if_data.files.size () > 0 )
1793 {
1794 GenerateMacrosAndTargetsTarget ( module, clean_files );
1795
1796 fprintf ( fMakefile, "%s: %s %s\n",
1797 target.c_str (),
1798 objectsMacro.c_str (),
1799 linkDepsMacro.c_str () );
1800
1801 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll",
1802 module.entrypoint.c_str (),
1803 module.baseaddress.c_str () );
1804 GenerateLinkerCommand ( module,
1805 "${gcc}",
1806 linkerParameters,
1807 objectsMacro,
1808 libsMacro,
1809 clean_files );
1810 }
1811 else
1812 {
1813 fprintf ( fMakefile, ".PHONY: %s\n\n",
1814 target.c_str ());
1815 fprintf ( fMakefile, "%s:\n\n",
1816 target.c_str ());
1817 }
1818 }
1819
1820
1821 static MingwNativeCUIModuleHandler nativecui_handler;
1822
1823 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler ()
1824 : MingwModuleHandler ( NativeCUI )
1825 {
1826 }
1827
1828 void
1829 MingwNativeCUIModuleHandler::Process ( const Module& module, string_list& clean_files )
1830 {
1831 GeneratePreconditionDependencies ( module );
1832 GenerateNativeCUIModuleTarget ( module, clean_files );
1833 GenerateInvocations ( module );
1834 }
1835
1836 void
1837 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ( const Module& module, string_list& clean_files )
1838 {
1839 static string ros_junk ( "$(ROS_TEMPORARY)" );
1840 string target ( FixupTargetFilename ( module.GetPath () ) );
1841 string workingDirectory = GetWorkingDirectory ( );
1842 string objectsMacro = GetObjectsMacro ( module );
1843 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1844 string libsMacro = GetLibsMacro ( module );
1845
1846 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
1847
1848 if ( module.non_if_data.files.size () > 0 )
1849 {
1850 string cflags ( "-D__NTAPP__" );
1851 GenerateMacrosAndTargetsTarget ( module,
1852 &cflags,
1853 NULL,
1854 clean_files );
1855
1856 fprintf ( fMakefile, "%s: %s %s\n",
1857 target.c_str (),
1858 objectsMacro.c_str (),
1859 linkDepsMacro.c_str () );
1860
1861 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib",
1862 module.entrypoint.c_str (),
1863 module.baseaddress.c_str () );
1864 GenerateLinkerCommand ( module,
1865 "${gcc}",
1866 linkerParameters,
1867 objectsMacro,
1868 libsMacro,
1869 clean_files );
1870 }
1871 else
1872 {
1873 fprintf ( fMakefile, ".PHONY: %s\n\n",
1874 target.c_str ());
1875 fprintf ( fMakefile, "%s:\n\n",
1876 target.c_str ());
1877 }
1878 }
1879
1880
1881 static MingwWin32DLLModuleHandler win32dll_handler;
1882
1883 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler ()
1884 : MingwModuleHandler ( Win32DLL )
1885 {
1886 }
1887
1888 void
1889 MingwWin32DLLModuleHandler::Process ( const Module& module, string_list& clean_files )
1890 {
1891 GenerateExtractWineDLLResourcesTarget ( module, clean_files );
1892 GeneratePreconditionDependencies ( module );
1893 GenerateWin32DLLModuleTarget ( module, clean_files );
1894 GenerateInvocations ( module );
1895 }
1896
1897 void
1898 MingwWin32DLLModuleHandler::GenerateExtractWineDLLResourcesTarget ( const Module& module, string_list& clean_files )
1899 {
1900 fprintf ( fMakefile, ".PHONY: %s_extractresources\n\n",
1901 module.name.c_str () );
1902 fprintf ( fMakefile, "%s_extractresources: bin2res\n",
1903 module.name.c_str () );
1904 const vector<File*>& files = module.non_if_data.files;
1905 for ( size_t i = 0; i < files.size (); i++ )
1906 {
1907 File& file = *files[i];
1908 string extension = GetExtension ( file.name );
1909 if ( extension == ".rc" || extension == ".RC" )
1910 {
1911 string resource = FixupTargetFilename ( file.name );
1912 fprintf ( fMakefile, "\t$(ECHO_BIN2RES)\n" );
1913 fprintf ( fMakefile, "\t@:echo ${bin2res} -f -x %s\n",
1914 resource.c_str () );
1915 }
1916 }
1917 fprintf ( fMakefile, "\n");
1918 }
1919
1920 void
1921 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module, string_list& clean_files )
1922 {
1923 static string ros_junk ( "$(ROS_TEMPORARY)" );
1924 string target ( FixupTargetFilename ( module.GetPath () ) );
1925 string workingDirectory = GetWorkingDirectory ( );
1926 string objectsMacro = GetObjectsMacro ( module );
1927 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1928 string libsMacro = GetLibsMacro ( module );
1929
1930 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
1931
1932 if ( module.non_if_data.files.size () > 0 )
1933 {
1934 GenerateMacrosAndTargetsTarget ( module, clean_files );
1935
1936 fprintf ( fMakefile, "%s: %s %s\n",
1937 target.c_str (),
1938 objectsMacro.c_str (),
1939 linkDepsMacro.c_str () );
1940
1941 string linker;
1942 if ( IsCPlusPlusModule ( module ) )
1943 linker = "${gpp}";
1944 else
1945 linker = "${gcc}";
1946
1947 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll",
1948 module.entrypoint.c_str (),
1949 module.baseaddress.c_str () );
1950 GenerateLinkerCommand ( module,
1951 linker,
1952 linkerParameters,
1953 objectsMacro,
1954 libsMacro,
1955 clean_files );
1956 }
1957 else
1958 {
1959 fprintf ( fMakefile, ".PHONY: %s\n\n",
1960 target.c_str () );
1961 fprintf ( fMakefile, "%s:\n\n",
1962 target.c_str () );
1963 }
1964 }
1965
1966
1967 static MingwWin32CUIModuleHandler win32cui_handler;
1968
1969 MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler ()
1970 : MingwModuleHandler ( Win32CUI )
1971 {
1972 }
1973
1974 void
1975 MingwWin32CUIModuleHandler::Process ( const Module& module, string_list& clean_files )
1976 {
1977 GeneratePreconditionDependencies ( module );
1978 GenerateWin32CUIModuleTarget ( module, clean_files );
1979 GenerateInvocations ( module );
1980 }
1981
1982 void
1983 MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ( const Module& module, string_list& clean_files )
1984 {
1985 static string ros_junk ( "$(ROS_TEMPORARY)" );
1986 string target ( FixupTargetFilename ( module.GetPath () ) );
1987 string workingDirectory = GetWorkingDirectory ( );
1988 string objectsMacro = GetObjectsMacro ( module );
1989 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
1990 string libsMacro = GetLibsMacro ( module );
1991
1992 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
1993
1994 if ( module.non_if_data.files.size () > 0 )
1995 {
1996 GenerateMacrosAndTargetsTarget ( module, clean_files );
1997
1998 fprintf ( fMakefile, "%s: %s %s\n",
1999 target.c_str (),
2000 objectsMacro.c_str (),
2001 linkDepsMacro.c_str () );
2002
2003 string linker;
2004 if ( IsCPlusPlusModule ( module ) )
2005 linker = "${gpp}";
2006 else
2007 linker = "${gcc}";
2008
2009 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
2010 module.entrypoint.c_str (),
2011 module.baseaddress.c_str () );
2012 GenerateLinkerCommand ( module,
2013 linker,
2014 linkerParameters,
2015 objectsMacro,
2016 libsMacro,
2017 clean_files );
2018 }
2019 else
2020 {
2021 fprintf ( fMakefile, ".PHONY: %s\n\n",
2022 target.c_str ());
2023 fprintf ( fMakefile, "%s:\n\n",
2024 target.c_str ());
2025 }
2026 }
2027
2028
2029 static MingwWin32GUIModuleHandler win32gui_handler;
2030
2031 MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler ()
2032 : MingwModuleHandler ( Win32GUI )
2033 {
2034 }
2035
2036 void
2037 MingwWin32GUIModuleHandler::Process ( const Module& module, string_list& clean_files )
2038 {
2039 GeneratePreconditionDependencies ( module );
2040 GenerateWin32GUIModuleTarget ( module, clean_files );
2041 GenerateInvocations ( module );
2042 }
2043
2044 void
2045 MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ( const Module& module, string_list& clean_files )
2046 {
2047 static string ros_junk ( "$(ROS_TEMPORARY)" );
2048 string target ( FixupTargetFilename ( module.GetPath () ) );
2049 string workingDirectory = GetWorkingDirectory ( );
2050 string objectsMacro = GetObjectsMacro ( module );
2051 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
2052 string libsMacro = GetLibsMacro ( module );
2053
2054 GenerateImportLibraryTargetIfNeeded ( module, clean_files );
2055
2056 if ( module.non_if_data.files.size () > 0 )
2057 {
2058 GenerateMacrosAndTargetsTarget ( module, clean_files );
2059
2060 fprintf ( fMakefile, "%s: %s %s\n",
2061 target.c_str (),
2062 objectsMacro.c_str (),
2063 linkDepsMacro.c_str () );
2064
2065 string linker;
2066 if ( IsCPlusPlusModule ( module ) )
2067 linker = "${gpp}";
2068 else
2069 linker = "${gcc}";
2070
2071 string linkerParameters = ssprintf ( "-Wl,--subsystem,windows -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
2072 module.entrypoint.c_str (),
2073 module.baseaddress.c_str () );
2074 GenerateLinkerCommand ( module,
2075 linker,
2076 linkerParameters,
2077 objectsMacro,
2078 libsMacro,
2079 clean_files );
2080 }
2081 else
2082 {
2083 fprintf ( fMakefile, ".PHONY: %s\n\n",
2084 target.c_str ());
2085 fprintf ( fMakefile, "%s:\n\n",
2086 target.c_str ());
2087 }
2088 }
2089
2090
2091 static MingwBootLoaderModuleHandler bootloadermodule_handler;
2092
2093 MingwBootLoaderModuleHandler::MingwBootLoaderModuleHandler ()
2094 : MingwModuleHandler ( BootLoader )
2095 {
2096 }
2097
2098 void
2099 MingwBootLoaderModuleHandler::Process ( const Module& module, string_list& clean_files )
2100 {
2101 GeneratePreconditionDependencies ( module );
2102 GenerateBootLoaderModuleTarget ( module, clean_files );
2103 GenerateInvocations ( module );
2104 }
2105
2106 void
2107 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget (
2108 const Module& module,
2109 string_list& clean_files )
2110 {
2111 static string ros_junk ( "$(ROS_TEMPORARY)" );
2112 string targetName ( module.GetTargetName () );
2113 string target ( FixupTargetFilename ( module.GetPath () ) );
2114 string workingDirectory = GetWorkingDirectory ();
2115 string junk_tmp = ros_junk + module.name + ".junk.tmp";
2116 CLEAN_FILE ( junk_tmp );
2117 string objectsMacro = GetObjectsMacro ( module );
2118 string linkDepsMacro = GetLinkingDependenciesMacro ( module );
2119 string libsMacro = GetLibsMacro ( module );
2120
2121 GenerateMacrosAndTargetsTarget ( module, clean_files );
2122
2123 fprintf ( fMakefile, "%s: %s %s\n",
2124 target.c_str (),
2125 objectsMacro.c_str (),
2126 linkDepsMacro.c_str () );
2127
2128 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2129
2130 fprintf ( fMakefile,
2131 "\t${ld} %s -N -Ttext=0x8000 -o %s %s %s\n",
2132 GetLinkerMacro ( module ).c_str (),
2133 junk_tmp.c_str (),
2134 objectsMacro.c_str (),
2135 linkDepsMacro.c_str () );
2136 fprintf ( fMakefile,
2137 "\t${objcopy} -O binary %s %s\n",
2138 junk_tmp.c_str (),
2139 target.c_str () );
2140 fprintf ( fMakefile,
2141 "\t-@${rm} %s\n",
2142 junk_tmp.c_str () );
2143 }
2144
2145
2146 static MingwBootSectorModuleHandler bootsectormodule_handler;
2147
2148 MingwBootSectorModuleHandler::MingwBootSectorModuleHandler ()
2149 : MingwModuleHandler ( BootSector )
2150 {
2151 }
2152
2153 void
2154 MingwBootSectorModuleHandler::Process ( const Module& module, string_list& clean_files )
2155 {
2156 GeneratePreconditionDependencies ( module );
2157 GenerateBootSectorModuleTarget ( module, clean_files );
2158 GenerateInvocations ( module );
2159 }
2160
2161 void
2162 MingwBootSectorModuleHandler::GenerateBootSectorModuleTarget ( const Module& module, string_list& clean_files )
2163 {
2164 string objectsMacro = GetObjectsMacro ( module );
2165
2166 string* nasmflags = new string ( "-f bin" );
2167 GenerateMacrosAndTargetsTarget ( module,
2168 NULL,
2169 nasmflags,
2170 clean_files );
2171
2172 fprintf ( fMakefile, ".PHONY: %s\n\n",
2173 module.name.c_str ());
2174 fprintf ( fMakefile,
2175 "%s: %s\n",
2176 module.name.c_str (),
2177 objectsMacro.c_str () );
2178 }
2179
2180
2181 static MingwIsoModuleHandler isomodule_handler;
2182
2183 MingwIsoModuleHandler::MingwIsoModuleHandler ()
2184 : MingwModuleHandler ( Iso )
2185 {
2186 }
2187
2188 void
2189 MingwIsoModuleHandler::Process ( const Module& module, string_list& clean_files )
2190 {
2191 GeneratePreconditionDependencies ( module );
2192 GenerateIsoModuleTarget ( module, clean_files );
2193 GenerateInvocations ( module );
2194 }
2195
2196 void
2197 MingwIsoModuleHandler::OutputBootstrapfileCopyCommands ( const string bootcdDirectory,
2198 const Module& module ) const
2199 {
2200 for ( size_t i = 0; i < module.project.modules.size (); i++ )
2201 {
2202 const Module& m = *module.project.modules[i];
2203 if ( m.bootstrap != NULL )
2204 {
2205 string targetFilenameNoFixup = bootcdDirectory + SSEP + m.bootstrap->base + SSEP + m.bootstrap->nameoncd;
2206 string targetFilename = PassThruCacheDirectory ( FixupTargetFilename ( targetFilenameNoFixup ) );
2207 fprintf ( fMakefile,
2208 "\t${cp} %s %s\n",
2209 m.GetPath ().c_str (),
2210 targetFilename.c_str () );
2211 }
2212 }
2213 }
2214
2215 void
2216 MingwIsoModuleHandler::OutputCdfileCopyCommands ( const string bootcdDirectory,
2217 const Module& module ) const
2218 {
2219 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
2220 {
2221 const CDFile& cdfile = *module.project.cdfiles[i];
2222 string targetFilenameNoFixup = bootcdDirectory + SSEP + cdfile.base + SSEP + cdfile.nameoncd;
2223 string targetFilename = PassThruCacheDirectory ( FixupTargetFilename ( targetFilenameNoFixup ) );
2224 fprintf ( fMakefile,
2225 "\t${cp} %s %s\n",
2226 cdfile.GetPath ().c_str (),
2227 targetFilename.c_str () );
2228 }
2229 }
2230
2231 string
2232 MingwIsoModuleHandler::GetBootstrapCdDirectories ( const string bootcdDirectory,
2233 const Module& module ) const
2234 {
2235 string directories;
2236 for ( size_t i = 0; i < module.project.modules.size (); i++ )
2237 {
2238 const Module& m = *module.project.modules[i];
2239 if ( m.bootstrap != NULL )
2240 {
2241 string targetDirecctory = bootcdDirectory + SSEP + m.bootstrap->base;
2242 if ( directories.size () > 0 )
2243 directories += " ";
2244 directories += FixupTargetFilename ( targetDirecctory );
2245 }
2246 }
2247 return directories;
2248 }
2249
2250 string
2251 MingwIsoModuleHandler::GetNonModuleCdDirectories ( const string bootcdDirectory,
2252 const Module& module ) const
2253 {
2254 string directories;
2255 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
2256 {
2257 const CDFile& cdfile = *module.project.cdfiles[i];
2258 string targetDirecctory = bootcdDirectory + SSEP + cdfile.base;
2259 if ( directories.size () > 0 )
2260 directories += " ";
2261 directories += FixupTargetFilename ( targetDirecctory );
2262 }
2263 return directories;
2264 }
2265
2266 string
2267 MingwIsoModuleHandler::GetCdDirectories ( const string bootcdDirectory,
2268 const Module& module ) const
2269 {
2270 string directories = GetBootstrapCdDirectories ( bootcdDirectory,
2271 module );
2272 directories += " " + GetNonModuleCdDirectories ( bootcdDirectory,
2273 module );
2274 return directories;
2275 }
2276
2277 string
2278 MingwIsoModuleHandler::GetBootstrapCdFiles ( const string bootcdDirectory,
2279 const Module& module ) const
2280 {
2281 string cdfiles;
2282 for ( size_t i = 0; i < module.project.modules.size (); i++ )
2283 {
2284 const Module& m = *module.project.modules[i];
2285 if ( m.bootstrap != NULL )
2286 {
2287 if ( cdfiles.size () > 0 )
2288 cdfiles += " ";
2289 cdfiles += FixupTargetFilename ( m.GetPath () );
2290 }
2291 }
2292 return cdfiles;
2293 }
2294
2295 string
2296 MingwIsoModuleHandler::GetNonModuleCdFiles ( const string bootcdDirectory,
2297 const Module& module ) const
2298 {
2299 string cdfiles;
2300 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
2301 {
2302 const CDFile& cdfile = *module.project.cdfiles[i];
2303 if ( cdfiles.size () > 0 )
2304 cdfiles += " ";
2305 cdfiles += NormalizeFilename ( cdfile.GetPath () );
2306 }
2307 return cdfiles;
2308 }
2309
2310 string
2311 MingwIsoModuleHandler::GetCdFiles ( const string bootcdDirectory,
2312 const Module& module ) const
2313 {
2314 string cdfiles = GetBootstrapCdFiles ( bootcdDirectory,
2315 module );
2316 cdfiles += " " + GetNonModuleCdFiles ( bootcdDirectory,
2317 module );
2318 return cdfiles;
2319 }
2320
2321 void
2322 MingwIsoModuleHandler::GenerateIsoModuleTarget ( const Module& module, string_list& clean_files )
2323 {
2324 string bootcdDirectory = "cd";
2325 string isoboot = FixupTargetFilename ( "boot/freeldr/bootsect/isoboot.o" );
2326 string bootcdReactosNoFixup = bootcdDirectory + "/reactos";
2327 string bootcdReactos = FixupTargetFilename ( bootcdReactosNoFixup );
2328 PassThruCacheDirectory ( bootcdReactos + SSEP );
2329 string reactosInf = FixupTargetFilename ( bootcdReactosNoFixup + "/reactos.inf" );
2330 string reactosDff = NormalizeFilename ( "bootdata/packages/reactos.dff" );
2331 string cdDirectories = bootcdReactos + " " + GetCdDirectories ( bootcdDirectory,
2332 module );
2333 string cdFiles = GetCdFiles ( bootcdDirectory,
2334 module );
2335
2336 fprintf ( fMakefile, ".PHONY: %s\n\n",
2337 module.name.c_str ());
2338 fprintf ( fMakefile,
2339 "%s: all %s %s %s\n",
2340 module.name.c_str (),
2341 isoboot.c_str (),
2342 cdDirectories.c_str (),
2343 cdFiles.c_str () );
2344 fprintf ( fMakefile, "\t$(ECHO_CABMAN)\n" );
2345 fprintf ( fMakefile,
2346 "\t${cabman} -C %s -L %s -I\n",
2347 reactosDff.c_str (),
2348 bootcdReactos.c_str () );
2349 fprintf ( fMakefile,
2350 "\t${cabman} -C %s -RC %s -L %s -N\n",
2351 reactosDff.c_str (),
2352 reactosInf.c_str (),
2353 bootcdReactos.c_str () );
2354 fprintf ( fMakefile,
2355 "\t-@${rm} %s\n",
2356 reactosInf.c_str () );
2357 OutputBootstrapfileCopyCommands ( bootcdDirectory,
2358 module );
2359 OutputCdfileCopyCommands ( bootcdDirectory,
2360 module );
2361 fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
2362 fprintf ( fMakefile,
2363 "\t${cdmake} -v -m -b %s %s REACTOS ReactOS.iso\n",
2364 isoboot.c_str (),
2365 bootcdDirectory.c_str () );
2366 fprintf ( fMakefile,
2367 "\n" );
2368 }