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