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