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