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