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