a9dc3a14bc799782e7b80b87cadac16be82d01e7
[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,0xC0000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1344 module.GetBasePath ().c_str (),
1345 module.entrypoint.c_str () );
1346
1347 GenerateMacrosAndTargetsTarget ( module );
1348
1349 GenerateImportLibraryTargetIfNeeded ( module );
1350
1351 fprintf ( fMakefile, "%s: %s %s\n",
1352 target.c_str (),
1353 objectsMacro.c_str (),
1354 importLibraryDependencies.c_str () );
1355 fprintf ( fMakefile,
1356 "\t${gcc} %s %s -Wl,--base-file,%s -o %s %s %s\n",
1357 GetLinkerMacro ( module ).c_str (),
1358 gccOptions.c_str (),
1359 base_tmp.c_str (),
1360 junk_tmp.c_str (),
1361 objectsMacro.c_str (),
1362 importLibraryDependencies.c_str () );
1363 fprintf ( fMakefile,
1364 "\t${rm} %s\n",
1365 junk_tmp.c_str () );
1366 string killAt = module.mangledSymbols ? "" : "--kill-at";
1367 fprintf ( fMakefile,
1368 "\t${dlltool} --dllname %s --base-file %s --def ntoskrnl/ntoskrnl.def --output-exp %s %s\n",
1369 targetName.c_str (),
1370 base_tmp.c_str (),
1371 temp_exp.c_str (),
1372 killAt.c_str () );
1373 fprintf ( fMakefile,
1374 "\t${rm} %s\n",
1375 base_tmp.c_str () );
1376 fprintf ( fMakefile,
1377 "\t${gcc} %s %s -Wl,%s -o %s %s %s\n",
1378 GetLinkerMacro ( module ).c_str (),
1379 gccOptions.c_str (),
1380 temp_exp.c_str (),
1381 target.c_str (),
1382 objectsMacro.c_str (),
1383 importLibraryDependencies.c_str () );
1384 fprintf ( fMakefile,
1385 "\t${rm} %s\n\n",
1386 temp_exp.c_str () );
1387 }
1388
1389
1390 static MingwStaticLibraryModuleHandler staticlibrary_handler;
1391
1392 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()
1393 : MingwModuleHandler ( StaticLibrary )
1394 {
1395 }
1396
1397 void
1398 MingwStaticLibraryModuleHandler::Process ( const Module& module )
1399 {
1400 GeneratePreconditionDependencies ( module );
1401 GenerateStaticLibraryModuleTarget ( module );
1402 GenerateInvocations ( module );
1403 }
1404
1405 void
1406 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module& module )
1407 {
1408 GenerateMacrosAndTargetsTarget ( module );
1409 }
1410
1411
1412 static MingwObjectLibraryModuleHandler objectlibrary_handler;
1413
1414 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler ()
1415 : MingwModuleHandler ( ObjectLibrary )
1416 {
1417 }
1418
1419 void
1420 MingwObjectLibraryModuleHandler::Process ( const Module& module )
1421 {
1422 GeneratePreconditionDependencies ( module );
1423 GenerateObjectLibraryModuleTarget ( module );
1424 GenerateInvocations ( module );
1425 }
1426
1427 void
1428 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ( const Module& module )
1429 {
1430 GenerateMacrosAndTargetsTarget ( module );
1431 }
1432
1433
1434 static MingwKernelModeDLLModuleHandler kernelmodedll_handler;
1435
1436 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler ()
1437 : MingwModuleHandler ( KernelModeDLL )
1438 {
1439 }
1440
1441 void
1442 MingwKernelModeDLLModuleHandler::Process ( const Module& module )
1443 {
1444 GeneratePreconditionDependencies ( module );
1445 GenerateKernelModeDLLModuleTarget ( module );
1446 GenerateInvocations ( module );
1447 }
1448
1449 void
1450 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Module& module )
1451 {
1452 static string ros_junk ( "$(ROS_TEMPORARY)" );
1453 string target ( FixupTargetFilename ( module.GetPath () ) );
1454 string workingDirectory = GetWorkingDirectory ( );
1455 string archiveFilename = GetModuleArchiveFilename ( module );
1456 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1457
1458 GenerateImportLibraryTargetIfNeeded ( module );
1459
1460 if ( module.files.size () > 0 )
1461 {
1462 GenerateMacrosAndTargetsTarget ( module );
1463
1464 fprintf ( fMakefile, "%s: %s %s\n",
1465 target.c_str (),
1466 archiveFilename.c_str (),
1467 importLibraryDependencies.c_str () );
1468
1469 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1470 module.entrypoint.c_str () );
1471 GenerateLinkerCommand ( module,
1472 "${gcc}",
1473 linkerParameters,
1474 archiveFilename );
1475 }
1476 else
1477 {
1478 fprintf ( fMakefile, ".PHONY: %s\n\n",
1479 target.c_str ());
1480 fprintf ( fMakefile, "%s:\n",
1481 target.c_str ());
1482 }
1483 }
1484
1485
1486 static MingwKernelModeDriverModuleHandler kernelmodedriver_handler;
1487
1488 MingwKernelModeDriverModuleHandler::MingwKernelModeDriverModuleHandler ()
1489 : MingwModuleHandler ( KernelModeDriver )
1490 {
1491 }
1492
1493 void
1494 MingwKernelModeDriverModuleHandler::Process ( const Module& module )
1495 {
1496 GeneratePreconditionDependencies ( module );
1497 GenerateKernelModeDriverModuleTarget ( module );
1498 GenerateInvocations ( module );
1499 }
1500
1501
1502 void
1503 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ( const Module& module )
1504 {
1505 static string ros_junk ( "$(ROS_TEMPORARY)" );
1506 string target ( PassThruCacheDirectory( FixupTargetFilename ( module.GetPath () ) ) );
1507 string workingDirectory = GetWorkingDirectory ( );
1508 string archiveFilename = GetModuleArchiveFilename ( module );
1509 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1510
1511 GenerateImportLibraryTargetIfNeeded ( module );
1512
1513 if ( module.files.size () > 0 )
1514 {
1515 string* cflags = new string ( "-D__NTDRIVER__" );
1516 GenerateMacrosAndTargetsTarget ( module,
1517 cflags,
1518 NULL );
1519 delete cflags;
1520
1521 fprintf ( fMakefile, "%s: %s %s\n",
1522 target.c_str (),
1523 archiveFilename.c_str (),
1524 importLibraryDependencies.c_str () );
1525
1526 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
1527 module.entrypoint.c_str () );
1528 GenerateLinkerCommand ( module,
1529 "${gcc}",
1530 linkerParameters,
1531 archiveFilename );
1532 }
1533 else
1534 {
1535 fprintf ( fMakefile, ".PHONY: %s\n\n",
1536 target.c_str ());
1537 fprintf ( fMakefile, "%s:\n",
1538 target.c_str () );
1539 }
1540 }
1541
1542
1543 static MingwNativeDLLModuleHandler nativedll_handler;
1544
1545 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler ()
1546 : MingwModuleHandler ( NativeDLL )
1547 {
1548 }
1549
1550 void
1551 MingwNativeDLLModuleHandler::Process ( const Module& module )
1552 {
1553 GeneratePreconditionDependencies ( module );
1554 GenerateNativeDLLModuleTarget ( module );
1555 GenerateInvocations ( module );
1556 }
1557
1558 void
1559 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ( const Module& module )
1560 {
1561 static string ros_junk ( "$(ROS_TEMPORARY)" );
1562 string target ( FixupTargetFilename ( module.GetPath () ) );
1563 string workingDirectory = GetWorkingDirectory ( );
1564 string objectFilenames = GetObjectFilenames ( module );
1565 string archiveFilename = GetModuleArchiveFilename ( module );
1566 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1567
1568 GenerateImportLibraryTargetIfNeeded ( module );
1569
1570 if ( module.files.size () > 0 )
1571 {
1572 GenerateMacrosAndTargetsTarget ( module );
1573
1574 fprintf ( fMakefile, "%s: %s %s\n",
1575 target.c_str (),
1576 archiveFilename.c_str (),
1577 importLibraryDependencies.c_str () );
1578
1579 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll",
1580 module.entrypoint.c_str () );
1581 GenerateLinkerCommand ( module,
1582 "${gcc}",
1583 linkerParameters,
1584 objectFilenames );
1585 }
1586 else
1587 {
1588 fprintf ( fMakefile, ".PHONY: %s\n\n",
1589 target.c_str ());
1590 fprintf ( fMakefile, "%s:\n\n",
1591 target.c_str ());
1592 }
1593 }
1594
1595
1596 static MingwNativeCUIModuleHandler nativecui_handler;
1597
1598 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler ()
1599 : MingwModuleHandler ( NativeCUI )
1600 {
1601 }
1602
1603 void
1604 MingwNativeCUIModuleHandler::Process ( const Module& module )
1605 {
1606 GeneratePreconditionDependencies ( module );
1607 GenerateNativeCUIModuleTarget ( module );
1608 GenerateInvocations ( module );
1609 }
1610
1611 void
1612 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ( const Module& module )
1613 {
1614 static string ros_junk ( "$(ROS_TEMPORARY)" );
1615 string target ( FixupTargetFilename ( module.GetPath () ) );
1616 string workingDirectory = GetWorkingDirectory ( );
1617 string objectFilenames = GetObjectFilenames ( module );
1618 string archiveFilename = GetModuleArchiveFilename ( module );
1619 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1620
1621 GenerateImportLibraryTargetIfNeeded ( module );
1622
1623 if ( module.files.size () > 0 )
1624 {
1625 string* cflags = new string ( "-D__NTAPP__" );
1626 GenerateMacrosAndTargetsTarget ( module,
1627 cflags,
1628 NULL );
1629 delete cflags;
1630
1631 fprintf ( fMakefile, "%s: %s %s\n",
1632 target.c_str (),
1633 archiveFilename.c_str (),
1634 importLibraryDependencies.c_str () );
1635
1636 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib",
1637 module.entrypoint.c_str () );
1638 GenerateLinkerCommand ( module,
1639 "${gcc}",
1640 linkerParameters,
1641 objectFilenames );
1642 }
1643 else
1644 {
1645 fprintf ( fMakefile, ".PHONY: %s\n\n",
1646 target.c_str ());
1647 fprintf ( fMakefile, "%s:\n\n",
1648 target.c_str ());
1649 }
1650 }
1651
1652
1653 static MingwWin32DLLModuleHandler win32dll_handler;
1654
1655 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler ()
1656 : MingwModuleHandler ( Win32DLL )
1657 {
1658 }
1659
1660 void
1661 MingwWin32DLLModuleHandler::Process ( const Module& module )
1662 {
1663 GenerateExtractWineDLLResourcesTarget ( module );
1664 GeneratePreconditionDependencies ( module );
1665 GenerateWin32DLLModuleTarget ( module );
1666 GenerateInvocations ( module );
1667 }
1668
1669 void
1670 MingwWin32DLLModuleHandler::GenerateExtractWineDLLResourcesTarget ( const Module& module )
1671 {
1672 fprintf ( fMakefile, ".PHONY: %s_extractresources\n\n",
1673 module.name.c_str () );
1674 fprintf ( fMakefile, "%s_extractresources: bin2res\n",
1675 module.name.c_str () );
1676 for ( size_t i = 0; i < module.files.size (); i++ )
1677 {
1678 File& file = *module.files[i];
1679 string extension = GetExtension ( file.name );
1680 if ( extension == ".rc" || extension == ".RC" )
1681 {
1682 string resource = FixupTargetFilename ( file.name );
1683 fprintf ( fMakefile, "\t@echo ${bin2res} -f -x %s\n",
1684 resource.c_str () );
1685 }
1686 }
1687 fprintf ( fMakefile, "\n");
1688 }
1689
1690 void
1691 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module )
1692 {
1693 static string ros_junk ( "$(ROS_TEMPORARY)" );
1694 string target ( FixupTargetFilename ( module.GetPath () ) );
1695 string workingDirectory = GetWorkingDirectory ( );
1696 string objectFilenames = GetObjectFilenames ( module );
1697 string linkingDependencies = GetLinkingDependencies ( module );
1698
1699 GenerateImportLibraryTargetIfNeeded ( module );
1700 if ( module.files.size () > 0 )
1701 {
1702 GenerateMacrosAndTargetsTarget ( module );
1703
1704 fprintf ( fMakefile, "%s: %s %s\n",
1705 target.c_str (),
1706 objectFilenames.c_str (),
1707 linkingDependencies.c_str () );
1708
1709 string linker;
1710 if ( IsCPlusPlusModule ( module ) )
1711 linker = "${gpp}";
1712 else
1713 linker = "${gcc}";
1714
1715 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll",
1716 module.entrypoint.c_str () );
1717 GenerateLinkerCommand ( module,
1718 linker,
1719 linkerParameters,
1720 objectFilenames );
1721 }
1722 else
1723 {
1724 fprintf ( fMakefile, ".PHONY: %s\n\n",
1725 target.c_str () );
1726 fprintf ( fMakefile, "%s:\n\n",
1727 target.c_str () );
1728 }
1729 }
1730
1731
1732 static MingwWin32CUIModuleHandler win32cui_handler;
1733
1734 MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler ()
1735 : MingwModuleHandler ( Win32CUI )
1736 {
1737 }
1738
1739 void
1740 MingwWin32CUIModuleHandler::Process ( const Module& module )
1741 {
1742 GeneratePreconditionDependencies ( module );
1743 GenerateWin32CUIModuleTarget ( module );
1744 GenerateInvocations ( module );
1745 }
1746
1747 void
1748 MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ( const Module& module )
1749 {
1750 static string ros_junk ( "$(ROS_TEMPORARY)" );
1751 string target ( FixupTargetFilename ( module.GetPath () ) );
1752 string workingDirectory = GetWorkingDirectory ( );
1753 string objectFilenames = GetObjectFilenames ( module );
1754 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1755
1756 GenerateImportLibraryTargetIfNeeded ( module );
1757
1758 if ( module.files.size () > 0 )
1759 {
1760 GenerateMacrosAndTargetsTarget ( module );
1761
1762 fprintf ( fMakefile, "%s: %s %s\n",
1763 target.c_str (),
1764 objectFilenames.c_str (),
1765 importLibraryDependencies.c_str () );
1766
1767 string linker;
1768 if ( IsCPlusPlusModule ( module ) )
1769 linker = "${gpp}";
1770 else
1771 linker = "${gcc}";
1772
1773 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,0x00400000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
1774 module.entrypoint.c_str () );
1775 GenerateLinkerCommand ( module,
1776 linker,
1777 linkerParameters,
1778 objectFilenames );
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 MingwWin32GUIModuleHandler win32gui_handler;
1791
1792 MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler ()
1793 : MingwModuleHandler ( Win32GUI )
1794 {
1795 }
1796
1797 void
1798 MingwWin32GUIModuleHandler::Process ( const Module& module )
1799 {
1800 GeneratePreconditionDependencies ( module );
1801 GenerateWin32GUIModuleTarget ( module );
1802 GenerateInvocations ( module );
1803 }
1804
1805 void
1806 MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ( const Module& module )
1807 {
1808 static string ros_junk ( "$(ROS_TEMPORARY)" );
1809 string target ( FixupTargetFilename ( module.GetPath () ) );
1810 string workingDirectory = GetWorkingDirectory ( );
1811 string objectFilenames = GetObjectFilenames ( module );
1812 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1813
1814 GenerateImportLibraryTargetIfNeeded ( module );
1815
1816 if ( module.files.size () > 0 )
1817 {
1818 GenerateMacrosAndTargetsTarget ( module );
1819
1820 fprintf ( fMakefile, "%s: %s %s\n",
1821 target.c_str (),
1822 objectFilenames.c_str (),
1823 importLibraryDependencies.c_str () );
1824
1825 string linker;
1826 if ( IsCPlusPlusModule ( module ) )
1827 linker = "${gpp}";
1828 else
1829 linker = "${gcc}";
1830
1831 string linkerParameters = ssprintf ( "-Wl,--subsystem,windows -Wl,--entry,%s -Wl,--image-base,0x00400000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
1832 module.entrypoint.c_str () );
1833 GenerateLinkerCommand ( module,
1834 linker,
1835 linkerParameters,
1836 objectFilenames );
1837 }
1838 else
1839 {
1840 fprintf ( fMakefile, ".PHONY: %s\n\n",
1841 target.c_str ());
1842 fprintf ( fMakefile, "%s:\n\n",
1843 target.c_str ());
1844 }
1845 }
1846
1847
1848 static MingwBootLoaderModuleHandler bootloadermodule_handler;
1849
1850 MingwBootLoaderModuleHandler::MingwBootLoaderModuleHandler ()
1851 : MingwModuleHandler ( BootLoader )
1852 {
1853 }
1854
1855 void
1856 MingwBootLoaderModuleHandler::Process ( const Module& module )
1857 {
1858 GeneratePreconditionDependencies ( module );
1859 GenerateBootLoaderModuleTarget ( module );
1860 GenerateInvocations ( module );
1861 }
1862
1863 void
1864 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ( const Module& module )
1865 {
1866 static string ros_junk ( "$(ROS_TEMPORARY)" );
1867 string targetName ( module.GetTargetName () );
1868 string target ( FixupTargetFilename (module.GetPath ()) );
1869 string workingDirectory = GetWorkingDirectory ();
1870 string junk_tmp = ros_junk + module.name + ".junk.tmp";
1871 string objectsMacro = GetObjectsMacro ( module );
1872 string importLibraryDependencies = GetImportLibraryDependencies ( module );
1873
1874 GenerateMacrosAndTargetsTarget ( module );
1875
1876 fprintf ( fMakefile, "%s: %s %s\n",
1877 target.c_str (),
1878 objectsMacro.c_str (),
1879 importLibraryDependencies.c_str () );
1880
1881 fprintf ( fMakefile,
1882 "\t${ld} %s -N -Ttext=0x8000 -o %s %s %s\n",
1883 GetLinkerMacro ( module ).c_str (),
1884 junk_tmp.c_str (),
1885 objectsMacro.c_str (),
1886 importLibraryDependencies.c_str () );
1887 fprintf ( fMakefile,
1888 "\t${objcopy} -O binary %s %s\n",
1889 junk_tmp.c_str (),
1890 target.c_str () );
1891 fprintf ( fMakefile,
1892 "\t${rm} %s\n",
1893 junk_tmp.c_str () );
1894 }
1895
1896
1897 static MingwBootSectorModuleHandler bootsectormodule_handler;
1898
1899 MingwBootSectorModuleHandler::MingwBootSectorModuleHandler ()
1900 : MingwModuleHandler ( BootSector )
1901 {
1902 }
1903
1904 void
1905 MingwBootSectorModuleHandler::Process ( const Module& module )
1906 {
1907 GeneratePreconditionDependencies ( module );
1908 GenerateBootSectorModuleTarget ( module );
1909 GenerateInvocations ( module );
1910 }
1911
1912 void
1913 MingwBootSectorModuleHandler::GenerateBootSectorModuleTarget ( const Module& module )
1914 {
1915 string objectsMacro = GetObjectsMacro ( module );
1916
1917 string* nasmflags = new string ( "-f bin" );
1918 GenerateMacrosAndTargetsTarget ( module,
1919 NULL,
1920 nasmflags);
1921
1922 fprintf ( fMakefile, ".PHONY: %s\n\n",
1923 module.name.c_str ());
1924 fprintf ( fMakefile,
1925 "%s: %s\n",
1926 module.name.c_str (),
1927 objectsMacro.c_str () );
1928 }
1929
1930
1931 static MingwIsoModuleHandler isomodule_handler;
1932
1933 MingwIsoModuleHandler::MingwIsoModuleHandler ()
1934 : MingwModuleHandler ( Iso )
1935 {
1936 }
1937
1938 void
1939 MingwIsoModuleHandler::Process ( const Module& module )
1940 {
1941 GeneratePreconditionDependencies ( module );
1942 GenerateIsoModuleTarget ( module );
1943 GenerateInvocations ( module );
1944 }
1945
1946 void
1947 MingwIsoModuleHandler::GenerateIsoModuleTarget ( const Module& module )
1948 {
1949 string bootcdDirectory = "cd";
1950 string isoboot = FixupTargetFilename ( "boot/freeldr/bootsect/isoboot.o" );
1951 string bootcdReactosNoFixup = bootcdDirectory + "/reactos";
1952 string bootcdReactos = FixupTargetFilename ( bootcdReactosNoFixup );
1953 PassThruCacheDirectory ( bootcdReactos + SSEP );
1954 string reactosInf = FixupTargetFilename ( bootcdReactosNoFixup + "/reactos.inf" );
1955 string reactosDff = NormalizeFilename ( "bootdata/packages/reactos.dff" );
1956
1957 fprintf ( fMakefile, ".PHONY: %s\n\n",
1958 module.name.c_str ());
1959 fprintf ( fMakefile,
1960 "%s: all %s %s\n",
1961 module.name.c_str (),
1962 isoboot.c_str (),
1963 bootcdReactos.c_str () );
1964 fprintf ( fMakefile,
1965 "\t${cabman} /C %s /L %s /I\n",
1966 reactosDff.c_str (),
1967 bootcdReactos.c_str () );
1968 fprintf ( fMakefile,
1969 "\t${cabman} /C %s /RC %s /L %s /N\n",
1970 reactosDff.c_str (),
1971 reactosInf.c_str (),
1972 bootcdReactos.c_str () );
1973 fprintf ( fMakefile,
1974 "\t- ${rm} %s\n",
1975 reactosInf.c_str () );
1976 fprintf ( fMakefile,
1977 "\t${cdmake} -v -m -b %s %s REACTOS ReactOS.iso\n",
1978 isoboot.c_str (),
1979 bootcdDirectory.c_str () );
1980 fprintf ( fMakefile,
1981 "\n" );
1982 }