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