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