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