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