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