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