Fix case when $(TEMPORARY) is not the current directory. Fixed with the help of nanot...
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
1 /*
2 * Copyright (C) 2005 Casper S. Hornstrup
3 * 2007-2008 Hervé Poussineau
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include "../../pch.h"
20 #include <assert.h>
21
22 #include "../../rbuild.h"
23 #include "mingw.h"
24 #include "modulehandler.h"
25 #include "rule.h"
26
27 using std::set;
28 using std::string;
29 using std::vector;
30
31 #define CLEAN_FILE(f) clean_files.push_back ( (f).name.length () > 0 ? backend->GetFullName ( f ) : backend->GetFullPath ( f ) );
32
33 MingwBackend*
34 MingwModuleHandler::backend = NULL;
35 FILE*
36 MingwModuleHandler::fMakefile = NULL;
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 use_pch = false;
77 }
78
79 MingwModuleHandler::~MingwModuleHandler()
80 {
81 }
82
83 /*static*/ void
84 MingwModuleHandler::SetBackend ( MingwBackend* backend_ )
85 {
86 backend = backend_;
87 }
88
89 /*static*/ void
90 MingwModuleHandler::SetMakefile ( FILE* f )
91 {
92 fMakefile = f;
93 }
94
95 void
96 MingwModuleHandler::EnablePreCompiledHeaderSupport ()
97 {
98 use_pch = true;
99 }
100
101 /*static*/ const FileLocation*
102 MingwModuleHandler::PassThruCacheDirectory (const FileLocation* file )
103 {
104 switch ( file->directory )
105 {
106 case SourceDirectory:
107 break;
108 case IntermediateDirectory:
109 backend->AddDirectoryTarget ( file->relative_path, backend->intermediateDirectory );
110 break;
111 case OutputDirectory:
112 backend->AddDirectoryTarget ( file->relative_path, backend->outputDirectory );
113 break;
114 case InstallDirectory:
115 backend->AddDirectoryTarget ( file->relative_path, backend->installDirectory );
116 break;
117 default:
118 throw InvalidOperationException ( __FILE__,
119 __LINE__,
120 "Invalid directory %d.",
121 file->directory );
122 }
123
124 return file;
125 }
126
127 /* caller needs to delete the returned object */
128 const FileLocation*
129 MingwModuleHandler::GetTargetFilename (
130 const Module& module,
131 string_list* pclean_files )
132 {
133 FileLocation *target = new FileLocation ( *module.output );
134 if ( pclean_files )
135 {
136 string_list& clean_files = *pclean_files;
137 CLEAN_FILE ( *target );
138 }
139 return target;
140 }
141
142 /* caller needs to delete the returned object */
143 const FileLocation*
144 MingwModuleHandler::GetImportLibraryFilename (
145 const Module& module,
146 string_list* pclean_files )
147 {
148 FileLocation *target = new FileLocation ( *module.dependency );
149 if ( pclean_files )
150 {
151 string_list& clean_files = *pclean_files;
152 CLEAN_FILE ( *target );
153 }
154 return target;
155 }
156
157 /* caller needs to delete the returned object */
158 MingwModuleHandler*
159 MingwModuleHandler::InstanciateHandler (
160 const Module& module,
161 MingwBackend* backend )
162 {
163 MingwModuleHandler* handler;
164 switch ( module.type )
165 {
166 case BuildTool:
167 handler = new MingwBuildToolModuleHandler ( module );
168 break;
169 case StaticLibrary:
170 handler = new MingwStaticLibraryModuleHandler ( module );
171 break;
172 case ObjectLibrary:
173 handler = new MingwObjectLibraryModuleHandler ( module );
174 break;
175 case Kernel:
176 handler = new MingwKernelModuleHandler ( module );
177 break;
178 case NativeCUI:
179 handler = new MingwNativeCUIModuleHandler ( module );
180 break;
181 case Win32CUI:
182 handler = new MingwWin32CUIModuleHandler ( module );
183 break;
184 case Win32SCR:
185 case Win32GUI:
186 handler = new MingwWin32GUIModuleHandler ( module );
187 break;
188 case KernelModeDLL:
189 handler = new MingwKernelModeDLLModuleHandler ( module );
190 break;
191 case NativeDLL:
192 handler = new MingwNativeDLLModuleHandler ( module );
193 break;
194 case Win32DLL:
195 handler = new MingwWin32DLLModuleHandler ( module );
196 break;
197 case Win32OCX:
198 handler = new MingwWin32OCXModuleHandler ( module );
199 break;
200 case KernelModeDriver:
201 handler = new MingwKernelModeDriverModuleHandler ( module );
202 break;
203 case BootLoader:
204 handler = new MingwBootLoaderModuleHandler ( module );
205 break;
206 case BootSector:
207 handler = new MingwBootSectorModuleHandler ( module );
208 break;
209 case BootProgram:
210 handler = new MingwBootProgramModuleHandler ( module );
211 break;
212 case Iso:
213 handler = new MingwIsoModuleHandler ( module );
214 break;
215 case LiveIso:
216 handler = new MingwLiveIsoModuleHandler ( module );
217 break;
218 case IsoRegTest:
219 handler = new MingwIsoModuleHandler ( module );
220 break;
221 case LiveIsoRegTest:
222 handler = new MingwLiveIsoModuleHandler ( module );
223 break;
224 case Test:
225 handler = new MingwTestModuleHandler ( module );
226 break;
227 case RpcServer:
228 handler = new MingwRpcServerModuleHandler ( module );
229 break;
230 case RpcClient:
231 handler = new MingwRpcClientModuleHandler ( module );
232 break;
233 case RpcProxy:
234 handler = new MingwRpcProxyModuleHandler ( module );
235 break;
236 case Alias:
237 handler = new MingwAliasModuleHandler ( module );
238 break;
239 case IdlHeader:
240 handler = new MingwIdlHeaderModuleHandler ( module );
241 break;
242 case EmbeddedTypeLib:
243 handler = new MingwEmbeddedTypeLibModuleHandler ( module );
244 break;
245 case ElfExecutable:
246 handler = new MingwElfExecutableModuleHandler ( module );
247 break;
248 default:
249 throw UnknownModuleTypeException (
250 module.node.location,
251 module.type );
252 break;
253 }
254 return handler;
255 }
256
257 string
258 MingwModuleHandler::GetWorkingDirectory () const
259 {
260 return ".";
261 }
262
263 string
264 MingwModuleHandler::GetBasename ( const string& filename ) const
265 {
266 size_t index = filename.find_last_of ( '.' );
267 if ( index != string::npos )
268 return filename.substr ( 0, index );
269 return "";
270 }
271
272 /* caller needs to delete the returned object */
273 const FileLocation*
274 MingwModuleHandler::GetActualSourceFilename (
275 const FileLocation* file ) const
276 {
277 string filename = file->name;
278
279 string extension = GetExtension ( *file );
280 if ( extension == ".spec" || extension == ".SPEC" )
281 {
282 const FileLocation *objectFile = GetObjectFilename ( file, module, NULL );
283 FileLocation *sourceFile = new FileLocation (
284 objectFile->directory,
285 objectFile->relative_path,
286 ReplaceExtension ( objectFile->name, ".c" ) );
287 delete objectFile;
288 return sourceFile;
289 }
290 else if ( ( extension == ".idl" || extension == ".IDL" ) &&
291 ( module.type == RpcServer || module.type == RpcClient || module.type == RpcProxy ) )
292 {
293 const FileLocation *objectFile = GetObjectFilename ( file, module, NULL );
294 FileLocation *sourceFile = new FileLocation (
295 objectFile->directory,
296 objectFile->relative_path,
297 ReplaceExtension ( objectFile->name, ".c" ) );
298 delete objectFile;
299 return sourceFile;
300 }
301 else if ( extension == ".mc" || extension == ".MC" )
302 {
303 const FileLocation *objectFile = GetObjectFilename ( file, module, NULL );
304 FileLocation *sourceFile = new FileLocation (
305 objectFile->directory,
306 objectFile->relative_path,
307 ReplaceExtension ( objectFile->name, ".rc" ) );
308 delete objectFile;
309 return sourceFile;
310 }
311 else
312 return new FileLocation ( *file );
313 }
314
315 string
316 MingwModuleHandler::GetExtraDependencies (
317 const FileLocation *file ) const
318 {
319 string extension = GetExtension ( *file );
320 if ( extension == ".idl" || extension == ".IDL" )
321 {
322 const FileLocation *header;
323 switch ( module.type )
324 {
325 case RpcServer: header = GetRpcServerHeaderFilename ( file ); break;
326 case RpcClient: header = GetRpcClientHeaderFilename ( file ); break;
327 case RpcProxy: header = GetRpcProxyHeaderFilename ( file ); break;
328 case IdlHeader: header = GetIdlHeaderFilename ( file ); break;
329 default: header = NULL; break;
330 }
331 if ( !header )
332 return "";
333
334 string dependencies = backend->GetFullName ( *header );
335 delete header;
336 return dependencies;
337 }
338 else
339 return "";
340 }
341
342 string
343 MingwModuleHandler::GetCompilationUnitDependencies (
344 const CompilationUnit& compilationUnit ) const
345 {
346 if ( compilationUnit.GetFiles ().size () <= 1 )
347 return "";
348 vector<string> sourceFiles;
349 for ( size_t i = 0; i < compilationUnit.GetFiles ().size (); i++ )
350 {
351 const File& file = *compilationUnit.GetFiles ()[i];
352 sourceFiles.push_back ( backend->GetFullName ( file.file ) );
353 }
354 return v2s ( sourceFiles, 10 );
355 }
356
357 /* caller needs to delete the returned object */
358 const FileLocation*
359 MingwModuleHandler::GetModuleArchiveFilename () const
360 {
361 if ( module.type == StaticLibrary )
362 return GetTargetFilename ( module, NULL );
363 return new FileLocation ( IntermediateDirectory,
364 module.output->relative_path,
365 ReplaceExtension ( module.name, ".temp.a" ) );
366 }
367
368 bool
369 MingwModuleHandler::IsGeneratedFile ( const File& file ) const
370 {
371 string extension = GetExtension ( file.file );
372 return ( extension == ".spec" || extension == ".SPEC" );
373 }
374
375 /*static*/ bool
376 MingwModuleHandler::ReferenceObjects (
377 const Module& module )
378 {
379 if ( module.type == ObjectLibrary )
380 return true;
381 if ( module.type == RpcServer )
382 return true;
383 if ( module.type == RpcClient )
384 return true;
385 if ( module.type == RpcProxy )
386 return true;
387 if ( module.type == IdlHeader )
388 return true;
389 return false;
390 }
391
392 void
393 MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
394 const FileLocation& destination )
395 {
396 fprintf ( fMakefile,
397 "\t$(ECHO_CP)\n" );
398 fprintf ( fMakefile,
399 "\t${cp} %s %s 1>$(NUL)\n",
400 backend->GetFullName ( source ).c_str (),
401 backend->GetFullName ( *PassThruCacheDirectory ( &destination ) ).c_str () );
402 }
403
404 string
405 MingwModuleHandler::GetImportLibraryDependency (
406 const Module& importedModule )
407 {
408 string dep;
409 if ( ReferenceObjects ( importedModule ) )
410 {
411 const vector<CompilationUnit*>& compilationUnits = importedModule.non_if_data.compilationUnits;
412 size_t i;
413
414 dep = GetTargetMacro ( importedModule );
415 for ( i = 0; i < compilationUnits.size (); i++ )
416 {
417 CompilationUnit& compilationUnit = *compilationUnits[i];
418 const FileLocation& compilationName = compilationUnit.GetFilename ();
419 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, importedModule, NULL );
420 if ( GetExtension ( *objectFilename ) == ".h" )
421 dep += ssprintf ( " $(%s_HEADERS)", importedModule.name.c_str () );
422 else if ( GetExtension ( *objectFilename ) == ".rc" )
423 dep += ssprintf ( " $(%s_MCHEADERS)", importedModule.name.c_str () );
424 }
425 }
426 else
427 {
428 const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL );
429 dep = backend->GetFullName ( *library_target );
430 delete library_target;
431 }
432 return dep;
433 }
434
435 void
436 MingwModuleHandler::GetTargets ( const Module& dependencyModule,
437 string_list& targets )
438 {
439 if ( dependencyModule.invocations.size () > 0 )
440 {
441 for ( size_t i = 0; i < dependencyModule.invocations.size (); i++ )
442 {
443 Invoke& invoke = *dependencyModule.invocations[i];
444 invoke.GetTargets ( targets );
445 }
446 }
447 else
448 targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
449 }
450
451 void
452 MingwModuleHandler::GetModuleDependencies (
453 string_list& dependencies )
454 {
455 size_t iend = module.dependencies.size ();
456
457 if ( iend == 0 )
458 return;
459
460 for ( size_t i = 0; i < iend; i++ )
461 {
462 const Dependency& dependency = *module.dependencies[i];
463 const Module& dependencyModule = *dependency.dependencyModule;
464 GetTargets ( dependencyModule,
465 dependencies );
466 }
467 vector<FileLocation> v;
468 GetDefinitionDependencies ( v );
469
470 for ( size_t i = 0; i < v.size (); i++ )
471 {
472 const FileLocation& file = v[i];
473 dependencies.push_back ( backend->GetFullName ( file ) );
474 }
475 }
476
477 void
478 MingwModuleHandler::GetSourceFilenames ( vector<FileLocation>& list,
479 bool includeGeneratedFiles ) const
480 {
481 size_t i;
482
483 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
484 for ( i = 0; i < compilationUnits.size (); i++ )
485 {
486 if ( includeGeneratedFiles || !compilationUnits[i]->IsGeneratedFile () )
487 {
488 const FileLocation& compilationName = compilationUnits[i]->GetFilename ();
489 const FileLocation* sourceFileLocation = GetActualSourceFilename ( &compilationName );
490 list.push_back ( *sourceFileLocation );
491 delete sourceFileLocation;
492 }
493 }
494 // intentionally make a copy so that we can append more work in
495 // the middle of processing without having to go recursive
496 vector<If*> v = module.non_if_data.ifs;
497 for ( i = 0; i < v.size (); i++ )
498 {
499 size_t j;
500 If& rIf = *v[i];
501 // check for sub-ifs to add to list
502 const vector<If*>& ifs = rIf.data.ifs;
503 for ( j = 0; j < ifs.size (); j++ )
504 v.push_back ( ifs[j] );
505 const vector<CompilationUnit*>& compilationUnits = rIf.data.compilationUnits;
506 for ( j = 0; j < compilationUnits.size (); j++ )
507 {
508 CompilationUnit& compilationUnit = *compilationUnits[j];
509 if ( includeGeneratedFiles || !compilationUnit.IsGeneratedFile () )
510 {
511 const FileLocation& compilationName = compilationUnit.GetFilename ();
512 const FileLocation* sourceFileLocation = GetActualSourceFilename ( &compilationName );
513 list.push_back ( *sourceFileLocation );
514 delete sourceFileLocation;
515 }
516 }
517 }
518 }
519
520 void
521 MingwModuleHandler::GetSourceFilenamesWithoutGeneratedFiles (
522 vector<FileLocation>& list ) const
523 {
524 GetSourceFilenames ( list, false );
525 }
526
527 /* caller needs to delete the returned object */
528 const FileLocation*
529 MingwModuleHandler::GetObjectFilename (
530 const FileLocation* sourceFile,
531 const Module& module,
532 string_list* pclean_files ) const
533 {
534 DirectoryLocation destination_directory;
535 string newExtension;
536 string extension = GetExtension ( *sourceFile );
537
538 if ( module.type == BootSector )
539 return new FileLocation ( *module.output );
540 else if ( extension == ".rc" || extension == ".RC" )
541 newExtension = "_" + module.name + ".coff";
542 else if ( extension == ".mc" || extension == ".MC" )
543 newExtension = ".rc";
544 else if ( extension == ".spec" || extension == ".SPEC" )
545 newExtension = ".stubs.o";
546 else if ( extension == ".idl" || extension == ".IDL" )
547 {
548 if ( module.type == RpcServer )
549 newExtension = "_s.o";
550 else if ( module.type == RpcClient )
551 newExtension = "_c.o";
552 else if ( module.type == RpcProxy )
553 newExtension = "_p.o";
554 else
555 newExtension = ".h";
556 }
557 else
558 newExtension = "_" + module.name + ".o";
559
560 if ( module.type == BootSector )
561 destination_directory = OutputDirectory;
562 else
563 destination_directory = IntermediateDirectory;
564
565 const FileLocation *obj_file = new FileLocation(
566 destination_directory,
567 sourceFile->relative_path,
568 ReplaceExtension ( sourceFile->name, newExtension ) );
569
570 if ( pclean_files )
571 {
572 string_list& clean_files = *pclean_files;
573 CLEAN_FILE ( *obj_file );
574 }
575 return obj_file;
576 }
577
578 string
579 MingwModuleHandler::GetModuleCleanTarget ( const Module& module ) const
580 {
581 return module.name + "_clean";
582 }
583
584 void
585 MingwModuleHandler::GetReferencedObjectLibraryModuleCleanTargets ( vector<string>& moduleNames ) const
586 {
587 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
588 {
589 Library& library = *module.non_if_data.libraries[i];
590 if ( library.importedModule->type == ObjectLibrary )
591 moduleNames.push_back ( GetModuleCleanTarget ( *library.importedModule ) );
592 }
593 }
594
595 void
596 MingwModuleHandler::GenerateCleanTarget () const
597 {
598 if ( module.type == Alias )
599 return;
600
601 fprintf ( fMakefile,
602 ".PHONY: %s_clean\n",
603 module.name.c_str() );
604 vector<string> referencedModuleNames;
605 GetReferencedObjectLibraryModuleCleanTargets ( referencedModuleNames );
606 fprintf ( fMakefile,
607 "%s: %s\n\t-@${rm}",
608 GetModuleCleanTarget ( module ).c_str(),
609 v2s ( referencedModuleNames, 10 ).c_str () );
610 for ( size_t i = 0; i < clean_files.size(); i++ )
611 {
612 if ( ( i + 1 ) % 10 == 9 )
613 fprintf ( fMakefile, " 2>$(NUL)\n\t-@${rm}" );
614 fprintf ( fMakefile, " %s", clean_files[i].c_str() );
615 }
616 fprintf ( fMakefile, " 2>$(NUL)\n" );
617
618 if ( module.name != "zlib" ) /* Avoid make warning */
619 {
620 DirectoryLocation root;
621 if ( backend->configuration.GenerateProxyMakefilesInSourceTree )
622 root = SourceDirectory;
623 else
624 root = OutputDirectory;
625 FileLocation proxyMakefile ( root,
626 module.output->relative_path,
627 "GNUmakefile" );
628 fprintf ( fMakefile, "\t-@${rm} %s 2>$(NUL)\n",
629 backend->GetFullName ( proxyMakefile ).c_str () );
630 }
631
632 fprintf ( fMakefile, "clean: %s_clean\n\n", module.name.c_str() );
633 }
634
635 void
636 MingwModuleHandler::GenerateInstallTarget () const
637 {
638 if ( !module.install )
639 return;
640 fprintf ( fMakefile, ".PHONY: %s_install\n", module.name.c_str() );
641 fprintf ( fMakefile,
642 "%s_install: %s\n",
643 module.name.c_str (),
644 backend->GetFullName ( *module.install ).c_str () );
645 }
646
647 void
648 MingwModuleHandler::GenerateDependsTarget () const
649 {
650 fprintf ( fMakefile,
651 ".PHONY: %s_depends\n",
652 module.name.c_str() );
653 fprintf ( fMakefile,
654 "%s_depends: $(RBUILD_TARGET)\n",
655 module.name.c_str () );
656 fprintf ( fMakefile,
657 "\t$(ECHO_RBUILD)\n" );
658 fprintf ( fMakefile,
659 "\t$(Q)$(RBUILD_TARGET) $(RBUILD_FLAGS) -dm%s mingw\n",
660 module.name.c_str () );
661 }
662
663 string
664 MingwModuleHandler::GetObjectFilenames ()
665 {
666 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
667 if ( compilationUnits.size () == 0 )
668 return "";
669
670 string objectFilenames ( "" );
671 for ( size_t i = 0; i < compilationUnits.size (); i++ )
672 {
673 if ( objectFilenames.size () > 0 )
674 objectFilenames += " ";
675 const FileLocation& compilationName = compilationUnits[i]->GetFilename ();
676 const FileLocation *object_file = GetObjectFilename ( &compilationName, module, NULL );
677 objectFilenames += backend->GetFullName ( *object_file );
678 delete object_file;
679 }
680 return objectFilenames;
681 }
682
683 /* static */ string
684 MingwModuleHandler::GenerateGccDefineParametersFromVector (
685 const vector<Define*>& defines,
686 set<string>& used_defs)
687 {
688 string parameters;
689
690 for ( size_t i = 0; i < defines.size (); i++ )
691 {
692 Define& define = *defines[i];
693 if (used_defs.find(define.name) != used_defs.end())
694 continue;
695 if (parameters.length () > 0)
696 parameters += " ";
697 if (define.name.find('(') != string::npos)
698 parameters += "$(QT)";
699 parameters += "-D";
700 parameters += define.name;
701 if (define.value.length () > 0)
702 {
703 parameters += "=";
704 parameters += define.value;
705 }
706 if (define.name.find('(') != string::npos)
707 parameters += "$(QT)";
708 used_defs.insert(used_defs.begin(),define.name);
709 }
710 return parameters;
711 }
712
713 string
714 MingwModuleHandler::GenerateGccDefineParameters () const
715 {
716 set<string> used_defs;
717 string parameters = GenerateGccDefineParametersFromVector ( module.project.non_if_data.defines, used_defs );
718 string s = GenerateGccDefineParametersFromVector ( module.non_if_data.defines, used_defs );
719 if ( s.length () > 0 )
720 {
721 parameters += " ";
722 parameters += s;
723 }
724 return parameters;
725 }
726
727 string
728 MingwModuleHandler::ConcatenatePaths (
729 const string& path1,
730 const string& path2 ) const
731 {
732 if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )
733 return path2;
734 if ( path1[path1.length ()] == cSep )
735 return path1 + path2;
736 else
737 return path1 + cSep + path2;
738 }
739
740 /* static */ string
741 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes )
742 {
743 string parameters, path_prefix;
744 for ( size_t i = 0; i < includes.size (); i++ )
745 {
746 Include& include = *includes[i];
747 if ( parameters.length () > 0 )
748 parameters += " ";
749 parameters += "-I" + backend->GetFullPath ( *include.directory );;
750 }
751 return parameters;
752 }
753
754 string
755 MingwModuleHandler::GenerateGccIncludeParameters () const
756 {
757 string parameters = GenerateGccIncludeParametersFromVector ( module.non_if_data.includes );
758 string s = GenerateGccIncludeParametersFromVector ( module.project.non_if_data.includes );
759 if ( s.length () > 0 )
760 {
761 parameters += " ";
762 parameters += s;
763 }
764 return parameters;
765 }
766
767 string
768 MingwModuleHandler::GenerateCompilerParametersFromVector ( const vector<CompilerFlag*>& compilerFlags, const CompilerType type ) const
769 {
770 string parameters;
771 for ( size_t i = 0; i < compilerFlags.size (); i++ )
772 {
773 CompilerFlag& compilerFlag = *compilerFlags[i];
774 if ( compilerFlag.compiler == type )
775 {
776 if ( parameters.length () > 0 )
777 parameters += " ";
778 parameters += compilerFlag.flag;
779 }
780 }
781 return parameters;
782 }
783
784 string
785 MingwModuleHandler::GenerateLinkerParametersFromVector ( const vector<LinkerFlag*>& linkerFlags ) const
786 {
787 string parameters;
788 for ( size_t i = 0; i < linkerFlags.size (); i++ )
789 {
790 LinkerFlag& linkerFlag = *linkerFlags[i];
791 if ( parameters.length () > 0 )
792 parameters += " ";
793 parameters += linkerFlag.flag;
794 }
795 return parameters;
796 }
797
798 string
799 MingwModuleHandler::GenerateImportLibraryDependenciesFromVector (
800 const vector<Library*>& libraries )
801 {
802 string dependencies ( "" );
803 int wrap_count = 0;
804 for ( size_t i = 0; i < libraries.size (); i++ )
805 {
806 if ( wrap_count++ == 5 )
807 dependencies += " \\\n\t\t", wrap_count = 0;
808 else if ( dependencies.size () > 0 )
809 dependencies += " ";
810 dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule );
811 }
812 return dependencies;
813 }
814
815 string
816 MingwModuleHandler::GenerateLinkerParameters () const
817 {
818 return GenerateLinkerParametersFromVector ( module.linkerFlags );
819 }
820
821 void
822 MingwModuleHandler::GenerateMacro (
823 const char* assignmentOperation,
824 const string& macro,
825 const IfableData& data,
826 set<const Define *> *used_defs,
827 bool generatingCompilerMacro )
828 {
829 size_t i;
830 bool generateAssignment;
831
832 if ( generatingCompilerMacro )
833 generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0 || data.compilerFlags.size () > 0;
834 else
835 generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0;
836 if ( generateAssignment )
837 {
838 fprintf ( fMakefile,
839 "%s %s",
840 macro.c_str(),
841 assignmentOperation );
842 }
843
844 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
845 if ( pchFilename )
846 {
847 fprintf ( fMakefile,
848 " -I%s",
849 backend->GetFullPath ( *pchFilename ).c_str () );
850 delete pchFilename;
851 }
852
853 if ( generatingCompilerMacro )
854 {
855 string compilerParameters = GenerateCompilerParametersFromVector ( data.compilerFlags , CompilerTypeDontCare );
856 if ( compilerParameters.size () > 0 )
857 {
858 fprintf (
859 fMakefile,
860 " %s",
861 compilerParameters.c_str () );
862 }
863 }
864 for ( i = 0; i < data.includes.size(); i++ )
865 {
866 const Include& include = *data.includes[i];
867 const FileLocation* includeDirectory = include.directory;
868 fprintf (
869 fMakefile,
870 " -I%s",
871 backend->GetFullPath ( *includeDirectory ).c_str() );
872 }
873 for ( i = 0; i < data.defines.size(); i++ )
874 {
875 const Define& define = *data.defines[i];
876 if ( used_defs )
877 {
878 set<const Define *>::const_iterator last_define;
879 for (last_define = used_defs->begin ();
880 last_define != used_defs->end ();
881 last_define++)
882 {
883 if ( (*last_define)->name != define.name )
884 continue;
885 if ( !define.overridable )
886 {
887 throw InvalidOperationException ( (*last_define)->node->location.c_str (),
888 0,
889 "Invalid override of define '%s', already defined at %s",
890 define.name.c_str (),
891 define.node->location.c_str () );
892 }
893 if ( backend->configuration.Verbose )
894 printf("%s: Overriding '%s' already defined at %s\n",
895 (*last_define)->node->location.c_str (), define.name.c_str (),
896 define.node->location.c_str () );
897 break;
898 }
899 if ( last_define != used_defs->end () )
900 continue;
901 }
902 fprintf (
903 fMakefile,
904 " -D%s",
905 define.name.c_str() );
906 if (define.value.length () > 0)
907 fprintf (
908 fMakefile,
909 "=%s",
910 define.value.c_str() );
911 if ( used_defs )
912 used_defs->insert( used_defs->begin (), &define );
913 }
914 if ( generateAssignment )
915 {
916 fprintf ( fMakefile, "\n" );
917 }
918 }
919
920 void
921 MingwModuleHandler::GenerateMacros (
922 const char* assignmentOperation,
923 const IfableData& data,
924 const vector<LinkerFlag*>* linkerFlags,
925 set<const Define *>& used_defs )
926 {
927 size_t i;
928
929 GenerateMacro ( assignmentOperation,
930 cflagsMacro,
931 data,
932 &used_defs,
933 true );
934 GenerateMacro ( assignmentOperation,
935 windresflagsMacro,
936 data,
937 NULL,
938 false );
939
940 if ( linkerFlags != NULL )
941 {
942 string linkerParameters = GenerateLinkerParametersFromVector ( *linkerFlags );
943 if ( linkerParameters.size () > 0 )
944 {
945 fprintf (
946 fMakefile,
947 "%s %s %s\n",
948 linkerflagsMacro.c_str (),
949 assignmentOperation,
950 linkerParameters.c_str() );
951 }
952 }
953
954 if ( data.libraries.size () > 0 )
955 {
956 string deps = GenerateImportLibraryDependenciesFromVector ( data.libraries );
957 if ( deps.size () > 0 )
958 {
959 fprintf (
960 fMakefile,
961 "%s %s %s\n",
962 libsMacro.c_str(),
963 assignmentOperation,
964 deps.c_str() );
965 }
966 }
967
968 const vector<If*>& ifs = data.ifs;
969 for ( i = 0; i < ifs.size(); i++ )
970 {
971 If& rIf = *ifs[i];
972 if ( rIf.data.defines.size()
973 || rIf.data.includes.size()
974 || rIf.data.libraries.size()
975 || rIf.data.compilationUnits.size()
976 || rIf.data.compilerFlags.size()
977 || rIf.data.ifs.size() )
978 {
979 fprintf (
980 fMakefile,
981 "%s (\"$(%s)\",\"%s\")\n",
982 rIf.negated ? "ifneq" : "ifeq",
983 rIf.property.c_str(),
984 rIf.value.c_str() );
985 GenerateMacros (
986 "+=",
987 rIf.data,
988 NULL,
989 used_defs );
990 fprintf (
991 fMakefile,
992 "endif\n\n" );
993 }
994 }
995 }
996
997 void
998 MingwModuleHandler::CleanupCompilationUnitVector ( vector<CompilationUnit*>& compilationUnits )
999 {
1000 for ( size_t i = 0; i < compilationUnits.size (); i++ )
1001 delete compilationUnits[i];
1002 }
1003
1004 void
1005 MingwModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUnit*>& compilationUnits )
1006 {
1007 }
1008
1009 void
1010 MingwModuleHandler::GenerateSourceMacros (
1011 const char* assignmentOperation,
1012 const IfableData& data )
1013 {
1014 size_t i;
1015
1016 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1017 vector<const FileLocation *> headers;
1018 if ( compilationUnits.size () > 0 )
1019 {
1020 fprintf (
1021 fMakefile,
1022 "%s %s",
1023 sourcesMacro.c_str (),
1024 assignmentOperation );
1025 for ( i = 0; i < compilationUnits.size(); i++ )
1026 {
1027 CompilationUnit& compilationUnit = *compilationUnits[i];
1028 const FileLocation& compilationName = compilationUnit.GetFilename ();
1029 fprintf (
1030 fMakefile,
1031 "%s%s",
1032 ( i%10 == 9 ? " \\\n\t" : " " ),
1033 backend->GetFullName ( compilationName ).c_str () );
1034 }
1035 fprintf ( fMakefile, "\n" );
1036 }
1037
1038 const vector<If*>& ifs = data.ifs;
1039 for ( i = 0; i < ifs.size(); i++ )
1040 {
1041 If& rIf = *ifs[i];
1042 if ( rIf.data.defines.size()
1043 || rIf.data.includes.size()
1044 || rIf.data.libraries.size()
1045 || rIf.data.compilationUnits.size()
1046 || rIf.data.compilerFlags.size()
1047 || rIf.data.ifs.size() )
1048 {
1049 fprintf (
1050 fMakefile,
1051 "%s (\"$(%s)\",\"%s\")\n",
1052 rIf.negated ? "ifneq" : "ifeq",
1053 rIf.property.c_str(),
1054 rIf.value.c_str() );
1055 GenerateSourceMacros (
1056 "+=",
1057 rIf.data );
1058 fprintf (
1059 fMakefile,
1060 "endif\n\n" );
1061 }
1062 }
1063
1064 vector<CompilationUnit*> sourceCompilationUnits;
1065 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1066 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1067 {
1068 const FileLocation& compilationName = sourceCompilationUnits[i]->GetFilename ();
1069 fprintf (
1070 fMakefile,
1071 "%s += %s\n",
1072 sourcesMacro.c_str(),
1073 backend->GetFullName ( compilationName ).c_str () );
1074 }
1075 CleanupCompilationUnitVector ( sourceCompilationUnits );
1076 }
1077
1078 void
1079 MingwModuleHandler::GenerateObjectMacros (
1080 const char* assignmentOperation,
1081 const IfableData& data )
1082 {
1083 size_t i;
1084
1085 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1086 vector<const FileLocation *> headers;
1087 vector<const FileLocation *> mcheaders;
1088 vector<const FileLocation *> mcresources;
1089 if ( compilationUnits.size () > 0 )
1090 {
1091 for ( i = 0; i < compilationUnits.size (); i++ )
1092 {
1093 CompilationUnit& compilationUnit = *compilationUnits[i];
1094 if ( compilationUnit.IsFirstFile () )
1095 {
1096 const FileLocation& compilationName = compilationUnit.GetFilename ();
1097 const FileLocation *object_file = GetObjectFilename ( &compilationName, module, NULL );
1098 fprintf ( fMakefile,
1099 "%s := %s $(%s)\n",
1100 objectsMacro.c_str(),
1101 backend->GetFullName ( *object_file ).c_str (),
1102 objectsMacro.c_str() );
1103 delete object_file;
1104 }
1105 }
1106 fprintf (
1107 fMakefile,
1108 "%s %s",
1109 objectsMacro.c_str (),
1110 assignmentOperation );
1111 for ( i = 0; i < compilationUnits.size(); i++ )
1112 {
1113 CompilationUnit& compilationUnit = *compilationUnits[i];
1114 if ( !compilationUnit.IsFirstFile () )
1115 {
1116 const FileLocation& compilationName = compilationUnit.GetFilename ();
1117 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module, NULL );
1118 if ( GetExtension ( *objectFilename ) == ".h" )
1119 headers.push_back ( objectFilename );
1120 else if ( GetExtension ( *objectFilename ) == ".rc" )
1121 {
1122 const FileLocation *headerFilename = GetMcHeaderFilename ( &compilationUnit.GetFilename () );
1123 mcheaders.push_back ( headerFilename );
1124 mcresources.push_back ( objectFilename );
1125 }
1126 else
1127 {
1128 fprintf (
1129 fMakefile,
1130 "%s%s",
1131 ( i%10 == 9 ? " \\\n\t" : " " ),
1132 backend->GetFullName ( *objectFilename ).c_str () );
1133 delete objectFilename;
1134 }
1135 }
1136 }
1137 fprintf ( fMakefile, "\n" );
1138 }
1139 if ( headers.size () > 0 )
1140 {
1141 fprintf (
1142 fMakefile,
1143 "%s_HEADERS %s",
1144 module.name.c_str (),
1145 assignmentOperation );
1146 for ( i = 0; i < headers.size (); i++ )
1147 {
1148 fprintf (
1149 fMakefile,
1150 "%s%s",
1151 ( i%10 == 9 ? " \\\n\t" : " " ),
1152 backend->GetFullName ( *headers[i] ).c_str () );
1153 delete headers[i];
1154 }
1155 fprintf ( fMakefile, "\n" );
1156 }
1157
1158 if ( mcheaders.size () > 0 )
1159 {
1160 fprintf (
1161 fMakefile,
1162 "%s_MCHEADERS %s",
1163 module.name.c_str (),
1164 assignmentOperation );
1165 for ( i = 0; i < mcheaders.size (); i++ )
1166 {
1167 fprintf (
1168 fMakefile,
1169 "%s%s",
1170 ( i%10 == 9 ? " \\\n\t" : " " ),
1171 backend->GetFullName ( *mcheaders[i] ).c_str () );
1172 delete mcheaders[i];
1173 }
1174 fprintf ( fMakefile, "\n" );
1175 }
1176
1177 if ( mcresources.size () > 0 )
1178 {
1179 fprintf (
1180 fMakefile,
1181 "%s_RESOURCES %s",
1182 module.name.c_str (),
1183 assignmentOperation );
1184 for ( i = 0; i < mcresources.size (); i++ )
1185 {
1186 fprintf (
1187 fMakefile,
1188 "%s%s",
1189 ( i%10 == 9 ? " \\\n\t" : " " ),
1190 backend->GetFullName ( *mcresources[i] ).c_str () );
1191 delete mcresources[i];
1192 }
1193 fprintf ( fMakefile, "\n" );
1194 }
1195
1196 const vector<If*>& ifs = data.ifs;
1197 for ( i = 0; i < ifs.size(); i++ )
1198 {
1199 If& rIf = *ifs[i];
1200 if ( rIf.data.defines.size()
1201 || rIf.data.includes.size()
1202 || rIf.data.libraries.size()
1203 || rIf.data.compilationUnits.size()
1204 || rIf.data.compilerFlags.size()
1205 || rIf.data.ifs.size() )
1206 {
1207 fprintf (
1208 fMakefile,
1209 "%s (\"$(%s)\",\"%s\")\n",
1210 rIf.negated ? "ifneq" : "ifeq",
1211 rIf.property.c_str(),
1212 rIf.value.c_str() );
1213 GenerateObjectMacros (
1214 "+=",
1215 rIf.data );
1216 fprintf (
1217 fMakefile,
1218 "endif\n\n" );
1219 }
1220 }
1221
1222 vector<CompilationUnit*> sourceCompilationUnits;
1223 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1224 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1225 {
1226 const FileLocation& compilationName = sourceCompilationUnits[i]->GetFilename ();
1227 const FileLocation *object_file = GetObjectFilename ( &compilationName, module, NULL );
1228 fprintf (
1229 fMakefile,
1230 "%s += %s\n",
1231 objectsMacro.c_str(),
1232 backend->GetFullName ( *object_file ).c_str () );
1233 delete object_file;
1234 }
1235 CleanupCompilationUnitVector ( sourceCompilationUnits );
1236 }
1237
1238 /* caller needs to delete the returned object */
1239 const FileLocation*
1240 MingwModuleHandler::GetPrecompiledHeaderFilename () const
1241 {
1242 if ( !module.pch || !use_pch )
1243 return NULL;
1244 return new FileLocation ( IntermediateDirectory,
1245 module.pch->file.relative_path,
1246 ReplaceExtension ( module.pch->file.name, "_" + module.name + ".gch" ) );
1247 }
1248
1249 Rule gasRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source) $(module_rbuild) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1250 "\t$(ECHO_GAS)\n"
1251 "\t${gcc} -x assembler-with-cpp -c $< -o $@ -D__ASM__ $($(module_name)_CFLAGS)\n",
1252 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
1253 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1254 Rule bootRule ( "$(module_output): $(source) $(module_rbuild) | $(OUTPUT)$(SEP)$(source_dir)\n"
1255 "\t$(ECHO_NASM)\n"
1256 "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
1257 "$(OUTPUT)$(SEP)$(source_dir)$(SEP)", NULL );
1258 Rule nasmRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source) $(module_rbuild) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1259 "\t$(ECHO_NASM)\n"
1260 "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
1261 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
1262 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1263 Rule windresRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff: $(source) $(module_rbuild) $(WRC_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir) $(TEMPORARY)\n"
1264 "\t$(ECHO_WRC)\n"
1265 "\t${gcc} -xc -E -DRC_INVOKED ${$(module_name)_RCFLAGS} $(source) > $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp\n"
1266 "\t$(Q)$(WRC_TARGET) ${$(module_name)_RCFLAGS} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp\n"
1267 "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp 2>$(NUL)\n"
1268 "\t${windres} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp -o $@\n"
1269 "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp 2>$(NUL)\n",
1270 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff",
1271 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1272 Rule wmcRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc $(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h: $(WMC_TARGET) $(source)\n"
1273 "\t$(ECHO_WMC)\n"
1274 "\t$(Q)$(WMC_TARGET) -i -H $(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h -o $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc $(source)\n",
1275 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc", "$(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h", NULL );
1276 Rule winebuildRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def: $(source) $(module_rbuild) $(WINEBUILD_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1277 "\t$(ECHO_WINEBLD)\n"
1278 "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).spec.def --def -E $(source_path)$(SEP)$(source_name_noext).spec\n"
1279 "$(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).stubs.c: $(source_path)$(SEP)$(source_name_noext).spec $(WINEBUILD_TARGET)\n"
1280 "\t$(ECHO_WINEBLD)\n"
1281 "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).stubs.c --pedll $(source_path)$(SEP)$(source_name_noext).spec\n",
1282 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def",
1283 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.c",
1284 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1285 Rule widlHeaderRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h: $(source) $(module_rbuild) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1286 "\t$(ECHO_WIDL)\n"
1287 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h $(source)\n",
1288 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h",
1289 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1290 Rule widlServerRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h: $(source) $(module_rbuild) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1291 "\t$(ECHO_WIDL)\n"
1292 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h -s -S $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c $(source)\n",
1293 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h",
1294 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c",
1295 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1296 Rule widlClientRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h: $(source) $(module_rbuild) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1297 "\t$(ECHO_WIDL)\n"
1298 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h -c -C $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c $(source)\n",
1299 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h",
1300 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c",
1301 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1302 Rule widlProxyRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h: $(source) $(module_rbuild) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1303 "\t$(ECHO_WIDL)\n"
1304 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h -p -P $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c $(source)\n",
1305 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h",
1306 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c",
1307 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1308 Rule widlTlbRule ( "$(OUTPUT)$(SEP)$(source_dir)$(SEP)$(module_name).tlb: $(source) $(module_rbuild) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1309 "\t$(ECHO_WIDL)\n"
1310 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -t -T $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).tlb $(source)\n",
1311 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1312
1313 void
1314 MingwModuleHandler::GenerateGccCommand (
1315 const FileLocation* sourceFile,
1316 const string& extraDependencies,
1317 const string& cc,
1318 const string& cflagsMacro )
1319 {
1320 const FileLocation *generatedSourceFileName = GetActualSourceFilename ( sourceFile );
1321 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1322 string dependencies = backend->GetFullName ( *generatedSourceFileName );
1323
1324 if ( extraDependencies != "" )
1325 dependencies += " " + extraDependencies;
1326 if ( pchFilename )
1327 dependencies += " " + backend->GetFullName ( *pchFilename );
1328
1329 /* WIDL generated headers may be used */
1330 vector<FileLocation> rpcDependencies;
1331 GetRpcHeaderDependencies ( rpcDependencies );
1332 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1333 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1334
1335 const FileLocation *objectFilename = GetObjectFilename (
1336 sourceFile, module, &clean_files );
1337 fprintf ( fMakefile,
1338 "%s: %s | %s\n",
1339 backend->GetFullName ( *objectFilename ).c_str (),
1340 dependencies.c_str (),
1341 backend->GetFullPath ( *objectFilename ).c_str () );
1342 fprintf ( fMakefile, "\t$(ECHO_CC)\n" );
1343 fprintf ( fMakefile,
1344 "\t%s -c $< -o $@ %s\n",
1345 cc.c_str (),
1346 cflagsMacro.c_str () );
1347
1348 delete objectFilename;
1349 delete generatedSourceFileName;
1350 if ( pchFilename )
1351 delete pchFilename;
1352 }
1353
1354 string
1355 MingwModuleHandler::GetPropertyValue ( const Module& module, const std::string& name )
1356 {
1357 for ( size_t i = 0; i < module.project.non_if_data.properties.size (); i++ )
1358 {
1359 const Property& property = *module.project.non_if_data.properties[i];
1360 if ( property.name == name )
1361 return property.value;
1362 }
1363 return string ( "" );
1364 }
1365
1366 /* caller needs to delete the returned object */
1367 const FileLocation*
1368 MingwModuleHandler::GetRpcServerHeaderFilename ( const FileLocation *base ) const
1369 {
1370 string newname = GetBasename ( base->name ) + "_s.h";
1371 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1372 }
1373
1374 /* caller needs to delete the returned object */
1375 const FileLocation*
1376 MingwModuleHandler::GetRpcClientHeaderFilename ( const FileLocation *base ) const
1377 {
1378 string newname = GetBasename ( base->name ) + "_c.h";
1379 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1380 }
1381
1382 /* caller needs to delete the returned object */
1383 const FileLocation*
1384 MingwModuleHandler::GetRpcProxyHeaderFilename ( const FileLocation *base ) const
1385 {
1386 string newname = GetBasename ( base->name ) + "_p.h";
1387 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1388 }
1389
1390 /* caller needs to delete the returned object */
1391 const FileLocation*
1392 MingwModuleHandler::GetIdlHeaderFilename ( const FileLocation *base ) const
1393 {
1394 string newname = GetBasename ( base->name ) + ".h";
1395 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1396 }
1397
1398 /* caller needs to delete the returned object */
1399 const FileLocation*
1400 MingwModuleHandler::GetMcHeaderFilename ( const FileLocation *base ) const
1401 {
1402 string newname = GetBasename ( base->name ) + ".h";
1403 return new FileLocation ( IntermediateDirectory, "include/reactos" , newname );
1404 }
1405
1406 void
1407 MingwModuleHandler::GenerateCommands (
1408 const CompilationUnit& compilationUnit,
1409 const string& extraDependencies,
1410 const string& cc,
1411 const string& cppc,
1412 const string& cflagsMacro,
1413 const string& nasmflagsMacro,
1414 const string& windresflagsMacro,
1415 const string& widlflagsMacro )
1416 {
1417 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1418 string extension = GetExtension ( sourceFile );
1419 std::transform ( extension.begin (), extension.end (), extension.begin (), tolower );
1420
1421 struct
1422 {
1423 HostType host;
1424 ModuleType type;
1425 string extension;
1426 Rule* rule;
1427 } rules[] = {
1428 { HostDontCare, TypeDontCare, ".s", &gasRule },
1429 { HostDontCare, BootSector, ".asm", &bootRule },
1430 { HostDontCare, TypeDontCare, ".asm", &nasmRule },
1431 { HostDontCare, TypeDontCare, ".rc", &windresRule },
1432 { HostDontCare, TypeDontCare, ".mc", &wmcRule },
1433 { HostDontCare, TypeDontCare, ".spec", &winebuildRule },
1434 { HostDontCare, RpcServer, ".idl", &widlServerRule },
1435 { HostDontCare, RpcClient, ".idl", &widlClientRule },
1436 { HostDontCare, RpcProxy, ".idl", &widlProxyRule },
1437 { HostDontCare, EmbeddedTypeLib, ".idl", &widlTlbRule },
1438 { HostDontCare, TypeDontCare, ".idl", &widlHeaderRule },
1439 };
1440 size_t i;
1441 Rule *customRule = NULL;
1442
1443 for ( i = 0; i < sizeof ( rules ) / sizeof ( rules[0] ); i++ )
1444 {
1445 if ( rules[i].host != HostDontCare && rules[i].host != module.host )
1446 continue;
1447 if ( rules[i].type != TypeDontCare && rules[i].type != module.type )
1448 continue;
1449 if ( rules[i].extension != extension )
1450 continue;
1451 customRule = rules[i].rule;
1452 break;
1453 }
1454
1455 if ( customRule )
1456 customRule->Execute ( fMakefile, backend, module, &sourceFile, clean_files );
1457
1458 string flags = cflagsMacro;
1459 flags += " ";
1460 if ( extension == ".c" )
1461 {
1462 flags += GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags , CompilerTypeCC );
1463 GenerateGccCommand ( &sourceFile,
1464 GetCompilationUnitDependencies ( compilationUnit ) + extraDependencies,
1465 cc,
1466 flags );
1467 }
1468 else if ( extension == ".cc" ||
1469 extension == ".cpp" ||
1470 extension == ".cxx" )
1471 {
1472 flags += GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags , CompilerTypeCPP );
1473 GenerateGccCommand ( &sourceFile,
1474 GetCompilationUnitDependencies ( compilationUnit ) + extraDependencies,
1475 cppc,
1476 flags );
1477 }
1478 else if ( extension == ".spec" )
1479 {
1480 GenerateGccCommand ( &sourceFile,
1481 extraDependencies,
1482 cc,
1483 cflagsMacro );
1484 }
1485 else if ( extension == ".idl" &&
1486 (module.type == RpcServer) || (module.type == RpcClient) || (module.type == RpcProxy) )
1487 {
1488 GenerateGccCommand ( &sourceFile,
1489 GetExtraDependencies ( &sourceFile ),
1490 cc,
1491 cflagsMacro );
1492 }
1493 else if ( !customRule )
1494 {
1495 throw InvalidOperationException ( __FILE__,
1496 __LINE__,
1497 "Unsupported filename extension '%s' in file '%s'",
1498 extension.c_str (),
1499 backend->GetFullName ( sourceFile ).c_str () );
1500 }
1501 }
1502
1503 void
1504 MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget )
1505 {
1506 fprintf ( fMakefile,
1507 "ifeq ($(ROS_BUILDMAP),full)\n" );
1508
1509 FileLocation mapFilename ( OutputDirectory,
1510 module.output->relative_path,
1511 GetBasename ( module.output->name ) + ".map" );
1512 CLEAN_FILE ( mapFilename );
1513
1514 fprintf ( fMakefile,
1515 "\t$(ECHO_OBJDUMP)\n" );
1516 fprintf ( fMakefile,
1517 "\t$(Q)${objdump} -d -S %s > %s\n",
1518 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1519 backend->GetFullName ( mapFilename ).c_str () );
1520
1521 fprintf ( fMakefile,
1522 "else\n" );
1523 fprintf ( fMakefile,
1524 "ifeq ($(ROS_BUILDMAP),yes)\n" );
1525
1526 fprintf ( fMakefile,
1527 "\t$(ECHO_NM)\n" );
1528 fprintf ( fMakefile,
1529 "\t$(Q)${nm} --numeric-sort %s > %s\n",
1530 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1531 backend->GetFullName ( mapFilename ).c_str () );
1532
1533 fprintf ( fMakefile,
1534 "endif\n" );
1535
1536 fprintf ( fMakefile,
1537 "endif\n" );
1538 }
1539
1540 void
1541 MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
1542 {
1543 fprintf ( fMakefile,
1544 "ifeq ($(ROS_BUILDNOSTRIP),yes)\n" );
1545
1546 FileLocation nostripFilename ( OutputDirectory,
1547 module.output->relative_path,
1548 GetBasename ( module.output->name ) + ".nostrip" + GetExtension ( *module.output ) );
1549 CLEAN_FILE ( nostripFilename );
1550
1551 OutputCopyCommand ( *module.output, nostripFilename );
1552
1553 fprintf ( fMakefile,
1554 "endif\n" );
1555 }
1556
1557 void
1558 MergeStringVector ( const Backend* backend,
1559 const vector<FileLocation>& input,
1560 vector<string>& output )
1561 {
1562 int wrap_at = 25;
1563 string s;
1564 int wrap_count = -1;
1565 for ( size_t i = 0; i < input.size (); i++ )
1566 {
1567 if ( wrap_count++ == wrap_at )
1568 {
1569 output.push_back ( s );
1570 s = "";
1571 wrap_count = 0;
1572 }
1573 else if ( s.size () > 0)
1574 s += " ";
1575 s += backend->GetFullName ( input[i] );
1576 }
1577 if ( s.length () > 0 )
1578 output.push_back ( s );
1579 }
1580
1581 void
1582 MingwModuleHandler::GetObjectsVector ( const IfableData& data,
1583 vector<FileLocation>& objectFiles ) const
1584 {
1585 for ( size_t i = 0; i < data.compilationUnits.size (); i++ )
1586 {
1587 CompilationUnit& compilationUnit = *data.compilationUnits[i];
1588 const FileLocation& compilationName = compilationUnit.GetFilename ();
1589 const FileLocation *object_file = GetObjectFilename ( &compilationName, module, NULL );
1590 objectFiles.push_back ( *object_file );
1591 delete object_file;
1592 }
1593 }
1594
1595 void
1596 MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
1597 {
1598 if ( backend->configuration.CleanAsYouGo )
1599 {
1600 vector<FileLocation> objectFiles;
1601 GetObjectsVector ( module.non_if_data,
1602 objectFiles );
1603 vector<string> lines;
1604 MergeStringVector ( backend,
1605 objectFiles,
1606 lines );
1607 for ( size_t i = 0; i < lines.size (); i++ )
1608 {
1609 fprintf ( fMakefile,
1610 "\t-@${rm} %s 2>$(NUL)\n",
1611 lines[i].c_str () );
1612 }
1613 }
1614 }
1615
1616 void
1617 MingwModuleHandler::GenerateRunRsymCode () const
1618 {
1619 fprintf ( fMakefile,
1620 "\t$(ECHO_RSYM)\n" );
1621 fprintf ( fMakefile,
1622 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
1623 }
1624
1625 void
1626 MingwModuleHandler::GenerateRunStripCode () const
1627 {
1628 fprintf ( fMakefile,
1629 "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
1630 fprintf ( fMakefile,
1631 "\t$(ECHO_STRIP)\n" );
1632 fprintf ( fMakefile,
1633 "\t${strip} -s -x -X $@\n\n" );
1634 fprintf ( fMakefile,
1635 "endif\n" );
1636 }
1637
1638 void
1639 MingwModuleHandler::GenerateLinkerCommand (
1640 const string& dependencies,
1641 const string& linker,
1642 const string& linkerParameters,
1643 const string& objectsMacro,
1644 const string& libsMacro,
1645 const string& pefixupParameters )
1646 {
1647 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1648 const FileLocation *definitionFilename = GetDefinitionFilename ();
1649
1650 string target_macro ( GetTargetMacro ( module ) );
1651 string target_folder ( backend->GetFullPath ( *target_file ) );
1652
1653 string linkerScriptArgument;
1654 if ( module.linkerScript != NULL )
1655 linkerScriptArgument = ssprintf ( "-Wl,-T,%s", backend->GetFullName ( module.linkerScript->file ).c_str () );
1656 else
1657 linkerScriptArgument = "";
1658
1659 fprintf ( fMakefile,
1660 "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
1661 target_macro.c_str (),
1662 backend->GetFullName ( *definitionFilename ).c_str (),
1663 dependencies.c_str (),
1664 target_folder.c_str () );
1665 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1666 string targetName ( module.output->name );
1667
1668 if ( !module.IsDLL () )
1669 {
1670 fprintf ( fMakefile,
1671 "\t%s %s %s -o %s %s %s %s\n",
1672 linker.c_str (),
1673 linkerParameters.c_str (),
1674 linkerScriptArgument.c_str (),
1675 target_macro.c_str (),
1676 objectsMacro.c_str (),
1677 libsMacro.c_str (),
1678 GetLinkerMacro ().c_str () );
1679 }
1680 else if ( module.HasImportLibrary () )
1681 {
1682 FileLocation temp_exp ( TemporaryDirectory,
1683 "",
1684 module.name + ".temp.exp" );
1685 CLEAN_FILE ( temp_exp );
1686
1687 fprintf ( fMakefile,
1688 "\t${dlltool} --dllname %s --def %s --output-exp %s %s %s\n",
1689 targetName.c_str (),
1690 backend->GetFullName ( *definitionFilename ).c_str (),
1691 backend->GetFullName ( temp_exp ).c_str (),
1692 module.mangledSymbols ? "" : "--kill-at",
1693 module.underscoreSymbols ? "--add-underscore" : "" );
1694
1695 fprintf ( fMakefile,
1696 "\t%s %s %s %s -o %s %s %s %s\n",
1697 linker.c_str (),
1698 linkerParameters.c_str (),
1699 linkerScriptArgument.c_str (),
1700 backend->GetFullName ( temp_exp ).c_str (),
1701 target_macro.c_str (),
1702 objectsMacro.c_str (),
1703 libsMacro.c_str (),
1704 GetLinkerMacro ().c_str () );
1705
1706 fprintf ( fMakefile,
1707 "\t$(Q)$(PEFIXUP_TARGET) %s -exports %s\n",
1708 target_macro.c_str (),
1709 pefixupParameters.c_str() );
1710
1711 fprintf ( fMakefile,
1712 "\t-@${rm} %s 2>$(NUL)\n",
1713 backend->GetFullName ( temp_exp ).c_str () );
1714 }
1715 else
1716 {
1717 /* XXX: need to workaround binutils bug, which exports
1718 * all functions in a dll if no .def file or an empty
1719 * one has been provided... */
1720 /* See bug 1244 */
1721 //printf ( "%s will have all its functions exported\n",
1722 // module.target->name.c_str () );
1723 fprintf ( fMakefile,
1724 "\t%s %s %s -o %s %s %s %s\n",
1725 linker.c_str (),
1726 linkerParameters.c_str (),
1727 linkerScriptArgument.c_str (),
1728 target_macro.c_str (),
1729 objectsMacro.c_str (),
1730 libsMacro.c_str (),
1731 GetLinkerMacro ().c_str () );
1732 }
1733
1734 GenerateBuildMapCode ();
1735 GenerateBuildNonSymbolStrippedCode ();
1736 GenerateRunRsymCode ();
1737 GenerateRunStripCode ();
1738 GenerateCleanObjectsAsYouGoCode ();
1739
1740 delete definitionFilename;
1741 delete target_file;
1742 }
1743
1744 void
1745 MingwModuleHandler::GeneratePhonyTarget() const
1746 {
1747 string targetMacro ( GetTargetMacro ( module ) );
1748 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1749
1750 fprintf ( fMakefile,
1751 ".PHONY: %s\n\n",
1752 targetMacro.c_str ());
1753 fprintf ( fMakefile, "%s: | %s\n",
1754 targetMacro.c_str (),
1755 backend->GetFullPath ( *target_file ).c_str () );
1756
1757 delete target_file;
1758 }
1759
1760 void
1761 MingwModuleHandler::GenerateObjectFileTargets (
1762 const IfableData& data,
1763 const string& cc,
1764 const string& cppc,
1765 const string& cflagsMacro,
1766 const string& nasmflagsMacro,
1767 const string& windresflagsMacro,
1768 const string& widlflagsMacro )
1769 {
1770 size_t i;
1771 string moduleDependencies;
1772
1773 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1774 for ( i = 0; i < compilationUnits.size (); i++ )
1775 {
1776 CompilationUnit& compilationUnit = *compilationUnits[i];
1777 const FileLocation& compilationName = compilationUnit.GetFilename ();
1778 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module, NULL );
1779 if ( GetExtension ( *objectFilename ) == ".h" )
1780 moduleDependencies += ssprintf ( " $(%s_HEADERS)", module.name.c_str () );
1781 else if ( GetExtension ( *objectFilename ) == ".rc" )
1782 moduleDependencies += ssprintf ( " $(%s_RESOURCES)", module.name.c_str () );
1783 delete objectFilename;
1784 }
1785
1786 for ( i = 0; i < compilationUnits.size (); i++ )
1787 {
1788 GenerateCommands ( *compilationUnits[i],
1789 moduleDependencies,
1790 cc,
1791 cppc,
1792 cflagsMacro,
1793 nasmflagsMacro,
1794 windresflagsMacro,
1795 widlflagsMacro );
1796 fprintf ( fMakefile,
1797 "\n" );
1798 }
1799
1800 const vector<If*>& ifs = data.ifs;
1801 for ( i = 0; i < ifs.size(); i++ )
1802 {
1803 GenerateObjectFileTargets ( ifs[i]->data,
1804 cc,
1805 cppc,
1806 cflagsMacro,
1807 nasmflagsMacro,
1808 windresflagsMacro,
1809 widlflagsMacro );
1810 }
1811
1812 vector<CompilationUnit*> sourceCompilationUnits;
1813 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1814 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1815 {
1816 GenerateCommands ( *sourceCompilationUnits[i],
1817 moduleDependencies,
1818 cc,
1819 cppc,
1820 cflagsMacro,
1821 nasmflagsMacro,
1822 windresflagsMacro,
1823 widlflagsMacro );
1824 }
1825 CleanupCompilationUnitVector ( sourceCompilationUnits );
1826 }
1827
1828 void
1829 MingwModuleHandler::GenerateObjectFileTargets (
1830 const string& cc,
1831 const string& cppc,
1832 const string& cflagsMacro,
1833 const string& nasmflagsMacro,
1834 const string& windresflagsMacro,
1835 const string& widlflagsMacro )
1836 {
1837 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1838
1839 if ( pchFilename )
1840 {
1841 const FileLocation& baseHeaderFile = module.pch->file;
1842 CLEAN_FILE ( *pchFilename );
1843 string dependencies = backend->GetFullName ( baseHeaderFile );
1844 string flags = cflagsMacro;
1845 CompilerType type = module.cplusplus ? CompilerTypeCPP : CompilerTypeCC;
1846 flags += " ";
1847 flags += GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags , type );
1848 /* WIDL generated headers may be used */
1849 vector<FileLocation> rpcDependencies;
1850 GetRpcHeaderDependencies ( rpcDependencies );
1851 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1852 fprintf ( fMakefile,
1853 "%s: %s | %s\n",
1854 backend->GetFullName ( *pchFilename ).c_str(),
1855 dependencies.c_str(),
1856 backend->GetFullPath ( *pchFilename ).c_str() );
1857 fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
1858 fprintf ( fMakefile,
1859 "\t%s -o %s %s -g %s\n\n",
1860 module.cplusplus ? cppc.c_str() : cc.c_str(),
1861 backend->GetFullName ( *pchFilename ).c_str(),
1862 flags.c_str(),
1863 backend->GetFullName ( baseHeaderFile ).c_str() );
1864 delete pchFilename;
1865 }
1866
1867 GenerateObjectFileTargets ( module.non_if_data,
1868 cc,
1869 cppc,
1870 cflagsMacro,
1871 nasmflagsMacro,
1872 windresflagsMacro,
1873 widlflagsMacro );
1874 fprintf ( fMakefile, "\n" );
1875 }
1876
1877 /* caller needs to delete the returned object */
1878 const FileLocation*
1879 MingwModuleHandler::GenerateArchiveTarget ( const string& ar,
1880 const string& objs_macro ) const
1881 {
1882 const FileLocation *archiveFilename = GetModuleArchiveFilename ();
1883
1884 fprintf ( fMakefile,
1885 "%s: %s | %s\n",
1886 backend->GetFullName ( *archiveFilename ).c_str (),
1887 objs_macro.c_str (),
1888 backend->GetFullPath ( *archiveFilename ).c_str() );
1889
1890 if ( module.type == StaticLibrary && module.importLibrary )
1891 {
1892 const FileLocation *definitionFilename = GetDefinitionFilename ();
1893
1894 fprintf ( fMakefile,
1895 "\t${dlltool} --dllname %s --def %s --output-lib $@ %s %s\n",
1896 module.importLibrary->dllname.c_str (),
1897 backend->GetFullName ( *definitionFilename ).c_str (),
1898 module.mangledSymbols ? "" : "--kill-at",
1899 module.underscoreSymbols ? "--add-underscore" : "" );
1900
1901 delete definitionFilename;
1902 }
1903
1904 fprintf ( fMakefile, "\t$(ECHO_AR)\n" );
1905
1906 fprintf ( fMakefile,
1907 "\t%s -rc $@ %s\n",
1908 ar.c_str (),
1909 objs_macro.c_str ());
1910
1911 GenerateCleanObjectsAsYouGoCode ();
1912
1913 fprintf ( fMakefile, "\n" );
1914
1915 return archiveFilename;
1916 }
1917
1918 string
1919 MingwModuleHandler::GetCFlagsMacro () const
1920 {
1921 return ssprintf ( "$(%s_CFLAGS)",
1922 module.name.c_str () );
1923 }
1924
1925 /*static*/ string
1926 MingwModuleHandler::GetObjectsMacro ( const Module& module )
1927 {
1928 return ssprintf ( "$(%s_OBJS)",
1929 module.name.c_str () );
1930 }
1931
1932 string
1933 MingwModuleHandler::GetLinkingDependenciesMacro () const
1934 {
1935 return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
1936 }
1937
1938 string
1939 MingwModuleHandler::GetLibsMacro () const
1940 {
1941 return ssprintf ( "$(%s_LIBS)", module.name.c_str () );
1942 }
1943
1944 string
1945 MingwModuleHandler::GetLinkerMacro () const
1946 {
1947 return ssprintf ( "$(%s_LFLAGS)",
1948 module.name.c_str () );
1949 }
1950
1951 string
1952 MingwModuleHandler::GetModuleTargets ( const Module& module )
1953 {
1954 if ( ReferenceObjects ( module ) )
1955 return GetObjectsMacro ( module );
1956 else
1957 {
1958 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1959 string target = backend->GetFullName ( *target_file ).c_str ();
1960 delete target_file;
1961 return target;
1962 }
1963 }
1964
1965 void
1966 MingwModuleHandler::GenerateSourceMacro ()
1967 {
1968 sourcesMacro = ssprintf ( "%s_SOURCES", module.name.c_str ());
1969
1970 GenerateSourceMacros (
1971 "=",
1972 module.non_if_data );
1973
1974 // future references to the macro will be to get its values
1975 sourcesMacro = ssprintf ("$(%s)", sourcesMacro.c_str ());
1976 }
1977
1978 void
1979 MingwModuleHandler::GenerateObjectMacro ()
1980 {
1981 objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
1982
1983 GenerateObjectMacros (
1984 "=",
1985 module.non_if_data );
1986
1987 // future references to the macro will be to get its values
1988 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
1989 }
1990
1991 void
1992 MingwModuleHandler::GenerateTargetMacro ()
1993 {
1994 fprintf ( fMakefile,
1995 "%s := %s\n",
1996 GetTargetMacro ( module, false ).c_str (),
1997 GetModuleTargets ( module ).c_str () );
1998 }
1999
2000 void
2001 MingwModuleHandler::GetRpcHeaderDependencies (
2002 vector<FileLocation>& dependencies ) const
2003 {
2004 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
2005 {
2006 Library& library = *module.non_if_data.libraries[i];
2007 if ( library.importedModule->type == RpcServer ||
2008 library.importedModule->type == RpcClient ||
2009 library.importedModule->type == RpcProxy ||
2010 library.importedModule->type == IdlHeader )
2011 {
2012 for ( size_t j = 0; j < library.importedModule->non_if_data.compilationUnits.size (); j++ )
2013 {
2014 CompilationUnit& compilationUnit = *library.importedModule->non_if_data.compilationUnits[j];
2015 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2016 string extension = GetExtension ( sourceFile );
2017 if ( extension == ".idl" || extension == ".IDL" )
2018 {
2019 string basename = GetBasename ( sourceFile.name );
2020 if ( library.importedModule->type == RpcServer )
2021 {
2022 const FileLocation *header = GetRpcServerHeaderFilename ( &sourceFile );
2023 dependencies.push_back ( *header );
2024 delete header;
2025 }
2026 if ( library.importedModule->type == RpcClient )
2027 {
2028 const FileLocation *header = GetRpcClientHeaderFilename ( &sourceFile );
2029 dependencies.push_back ( *header );
2030 delete header;
2031 }
2032 if ( library.importedModule->type == RpcProxy )
2033 {
2034 const FileLocation *header = GetRpcProxyHeaderFilename ( &sourceFile );
2035 dependencies.push_back ( *header );
2036 delete header;
2037 }
2038 if ( library.importedModule->type == IdlHeader )
2039 {
2040 const FileLocation *header = GetIdlHeaderFilename ( &sourceFile );
2041 dependencies.push_back ( *header );
2042 delete header;
2043 }
2044 }
2045 }
2046 }
2047 }
2048 }
2049
2050 void
2051 MingwModuleHandler::GenerateOtherMacros ()
2052 {
2053 set<const Define *> used_defs;
2054
2055 cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
2056 nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
2057 windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
2058 widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());
2059 linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
2060 libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
2061 linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
2062
2063 GenerateMacros (
2064 "=",
2065 module.non_if_data,
2066 &module.linkerFlags,
2067 used_defs );
2068
2069 GenerateMacros (
2070 "+=",
2071 module.project.non_if_data,
2072 NULL,
2073 used_defs );
2074
2075 vector<FileLocation> s;
2076 if ( module.importLibrary )
2077 {
2078 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2079 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2080 {
2081 CompilationUnit& compilationUnit = *compilationUnits[i];
2082 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2083 string extension = GetExtension ( sourceFile );
2084 if ( extension == ".spec" || extension == ".SPEC" )
2085 GetSpecObjectDependencies ( s, &sourceFile );
2086 }
2087 }
2088 if ( s.size () > 0 )
2089 {
2090 fprintf (
2091 fMakefile,
2092 "%s +=",
2093 linkDepsMacro.c_str() );
2094 for ( size_t i = 0; i < s.size(); i++ )
2095 fprintf ( fMakefile,
2096 " %s",
2097 backend->GetFullName ( s[i] ).c_str () );
2098 fprintf ( fMakefile, "\n" );
2099 }
2100
2101 string globalCflags = "-g";
2102 if ( backend->usePipe )
2103 globalCflags += " -pipe";
2104 if ( !module.allowWarnings )
2105 globalCflags += " -Werror";
2106 if ( module.host == HostTrue )
2107 {
2108 if ( module.cplusplus )
2109 globalCflags += " $(HOST_CPPFLAGS)";
2110 else
2111 globalCflags += " $(HOST_CFLAGS)";
2112 }
2113 else
2114 {
2115 if ( module.cplusplus )
2116 {
2117 // HACK: use host headers when building C++
2118 globalCflags += " $(HOST_CPPFLAGS)";
2119 }
2120 else
2121 globalCflags += " -nostdinc";
2122 }
2123
2124 // Always force disabling of sibling calls optimisation for GCC
2125 // (TODO: Move to version-specific once this bug is fixed in GCC)
2126 globalCflags += " -fno-optimize-sibling-calls";
2127
2128 fprintf (
2129 fMakefile,
2130 "%s += $(PROJECT_CFLAGS) %s\n",
2131 cflagsMacro.c_str (),
2132 globalCflags.c_str () );
2133
2134 fprintf (
2135 fMakefile,
2136 "%s += $(PROJECT_RCFLAGS)\n",
2137 windresflagsMacro.c_str () );
2138
2139 fprintf (
2140 fMakefile,
2141 "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
2142 widlflagsMacro.c_str (),
2143 module.output->relative_path.c_str () );
2144
2145 fprintf (
2146 fMakefile,
2147 "%s_LFLAGS += $(PROJECT_LFLAGS) -g\n",
2148 module.name.c_str () );
2149
2150 fprintf (
2151 fMakefile,
2152 "%s += $(%s)\n",
2153 linkDepsMacro.c_str (),
2154 libsMacro.c_str () );
2155
2156 string cflags = TypeSpecificCFlags();
2157 if ( cflags.size() > 0 )
2158 {
2159 fprintf ( fMakefile,
2160 "%s += %s\n\n",
2161 cflagsMacro.c_str (),
2162 cflags.c_str () );
2163 }
2164
2165 string nasmflags = TypeSpecificNasmFlags();
2166 if ( nasmflags.size () > 0 )
2167 {
2168 fprintf ( fMakefile,
2169 "%s += %s\n\n",
2170 nasmflagsMacro.c_str (),
2171 nasmflags.c_str () );
2172 }
2173
2174 string linkerflags = TypeSpecificLinkerFlags();
2175 if ( linkerflags.size() > 0 )
2176 {
2177 fprintf ( fMakefile,
2178 "%s += %s\n\n",
2179 linkerflagsMacro.c_str (),
2180 linkerflags.c_str () );
2181 }
2182
2183 if ( module.type == StaticLibrary && module.isStartupLib )
2184 {
2185 fprintf ( fMakefile,
2186 "%s += -Wno-main\n\n",
2187 cflagsMacro.c_str () );
2188 }
2189
2190 fprintf ( fMakefile, "\n\n" );
2191
2192 // future references to the macros will be to get their values
2193 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
2194 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
2195 widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
2196 }
2197
2198 void
2199 MingwModuleHandler::GenerateRules ()
2200 {
2201 string cc = ( module.host == HostTrue ? "${host_gcc}" : "${gcc}" );
2202 string cppc = ( module.host == HostTrue ? "${host_gpp}" : "${gpp}" );
2203 string ar = ( module.host == HostTrue ? "${host_ar}" : "${ar}" );
2204
2205 string targetMacro = GetTargetMacro ( module );
2206 //CLEAN_FILE ( targetMacro );
2207 CLEAN_FILE ( FileLocation ( SourceDirectory, "", targetMacro ) );
2208
2209 // generate phony target for module name
2210 fprintf ( fMakefile, ".PHONY: %s\n",
2211 module.name.c_str () );
2212 string dependencies = GetTargetMacro ( module );
2213 if ( module.type == Test )
2214 dependencies += " $(REGTESTS_RUN_TARGET)";
2215 fprintf ( fMakefile, "%s: %s\n\n",
2216 module.name.c_str (),
2217 dependencies.c_str () );
2218 if ( module.type == Test )
2219 {
2220 fprintf ( fMakefile,
2221 "\t@%s\n",
2222 targetMacro.c_str ());
2223 }
2224
2225 if ( !ReferenceObjects ( module ) )
2226 {
2227 const FileLocation* ar_target = GenerateArchiveTarget ( ar, objectsMacro );
2228 CLEAN_FILE ( *ar_target );
2229 delete ar_target;
2230 }
2231
2232 GenerateObjectFileTargets ( cc,
2233 cppc,
2234 cflagsMacro,
2235 nasmflagsMacro,
2236 windresflagsMacro,
2237 widlflagsMacro );
2238 }
2239
2240 void
2241 MingwModuleHandler::GetInvocationDependencies (
2242 const Module& module,
2243 string_list& dependencies )
2244 {
2245 for ( size_t i = 0; i < module.invocations.size (); i++ )
2246 {
2247 Invoke& invoke = *module.invocations[i];
2248 if ( invoke.invokeModule == &module )
2249 /* Protect against circular dependencies */
2250 continue;
2251 invoke.GetTargets ( dependencies );
2252 }
2253 }
2254
2255 void
2256 MingwModuleHandler::GenerateInvocations () const
2257 {
2258 if ( module.invocations.size () == 0 )
2259 return;
2260
2261 size_t iend = module.invocations.size ();
2262 for ( size_t i = 0; i < iend; i++ )
2263 {
2264 const Invoke& invoke = *module.invocations[i];
2265
2266 if ( invoke.invokeModule->type != BuildTool )
2267 {
2268 throw XMLInvalidBuildFileException (
2269 module.node.location,
2270 "Only modules of type buildtool can be invoked." );
2271 }
2272
2273 string invokeTarget = module.GetInvocationTarget ( i );
2274 string_list invoke_targets;
2275 assert ( invoke_targets.size() );
2276 invoke.GetTargets ( invoke_targets );
2277 fprintf ( fMakefile,
2278 ".PHONY: %s\n\n",
2279 invokeTarget.c_str () );
2280 fprintf ( fMakefile,
2281 "%s:",
2282 invokeTarget.c_str () );
2283 size_t j, jend = invoke_targets.size();
2284 for ( j = 0; j < jend; j++ )
2285 {
2286 fprintf ( fMakefile,
2287 " %s",
2288 invoke_targets[i].c_str () );
2289 }
2290 fprintf ( fMakefile, "\n\n%s", invoke_targets[0].c_str () );
2291 for ( j = 1; j < jend; j++ )
2292 fprintf ( fMakefile,
2293 " %s",
2294 invoke_targets[i].c_str () );
2295 fprintf ( fMakefile,
2296 ": %s\n",
2297 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str () );
2298 fprintf ( fMakefile, "\t$(ECHO_INVOKE)\n" );
2299 fprintf ( fMakefile,
2300 "\t%s %s\n\n",
2301 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str (),
2302 invoke.GetParameters ().c_str () );
2303 }
2304 }
2305
2306 string
2307 MingwModuleHandler::GetPreconditionDependenciesName () const
2308 {
2309 return module.name + "_precondition";
2310 }
2311
2312 void
2313 MingwModuleHandler::GetDefaultDependencies (
2314 string_list& dependencies ) const
2315 {
2316 /* Avoid circular dependency */
2317 if ( module.type != BuildTool
2318 && module.name != "zlib"
2319 && module.name != "hostzlib" )
2320
2321 dependencies.push_back ( "$(INIT)" );
2322
2323 if ( module.type != BuildTool
2324 && module.name != "psdk" )
2325
2326 dependencies.push_back ( "$(PSDK_TARGET) $(psdk_HEADERS)" );
2327
2328 /* Check if any dependent library relays on the generated headers */
2329 for ( size_t i = 0; i < module.project.modules.size (); i++ )
2330 {
2331 const Module& m = *module.project.modules[i];
2332 for ( size_t j = 0; j < m.non_if_data.compilationUnits.size (); j++ )
2333 {
2334 CompilationUnit& compilationUnit = *m.non_if_data.compilationUnits[j];
2335 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2336 string extension = GetExtension ( sourceFile );
2337 if (extension == ".mc" || extension == ".MC" )
2338 {
2339 string dependency = ssprintf ( " $(%s_MCHEADERS)", m.name.c_str () );
2340 dependencies.push_back ( dependency );
2341 }
2342 }
2343 }
2344 }
2345
2346 void
2347 MingwModuleHandler::GeneratePreconditionDependencies ()
2348 {
2349 string preconditionDependenciesName = GetPreconditionDependenciesName ();
2350 vector<FileLocation> sourceFilenames;
2351 GetSourceFilenamesWithoutGeneratedFiles ( sourceFilenames );
2352 string_list dependencies;
2353 GetDefaultDependencies ( dependencies );
2354 GetModuleDependencies ( dependencies );
2355
2356 GetInvocationDependencies ( module, dependencies );
2357
2358 if ( dependencies.size() )
2359 {
2360 fprintf ( fMakefile,
2361 "%s =",
2362 preconditionDependenciesName.c_str () );
2363 for ( size_t i = 0; i < dependencies.size(); i++ )
2364 fprintf ( fMakefile,
2365 " %s",
2366 dependencies[i].c_str () );
2367 fprintf ( fMakefile, "\n\n" );
2368 }
2369
2370 for ( size_t i = 0; i < sourceFilenames.size(); i++ )
2371 {
2372 fprintf ( fMakefile,
2373 "%s: ${%s}\n",
2374 backend->GetFullName ( sourceFilenames[i] ).c_str (),
2375 preconditionDependenciesName.c_str ());
2376 }
2377 fprintf ( fMakefile, "\n" );
2378 }
2379
2380 bool
2381 MingwModuleHandler::IsWineModule () const
2382 {
2383 if ( module.importLibrary == NULL)
2384 return false;
2385
2386 size_t index = module.importLibrary->source->name.rfind ( ".spec.def" );
2387 return ( index != string::npos );
2388 }
2389
2390 /* caller needs to delete the returned object */
2391 const FileLocation*
2392 MingwModuleHandler::GetDefinitionFilename () const
2393 {
2394 if ( module.importLibrary != NULL )
2395 {
2396 DirectoryLocation directory;
2397 if ( IsWineModule () )
2398 directory = IntermediateDirectory;
2399 else
2400 directory = SourceDirectory;
2401
2402 return new FileLocation ( directory,
2403 module.importLibrary->source->relative_path,
2404 module.importLibrary->source->name );
2405 }
2406 else
2407 return new FileLocation ( SourceDirectory, "tools" + sSep + "rbuild", "empty.def" );
2408 }
2409
2410 void
2411 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
2412 {
2413 if ( module.importLibrary != NULL )
2414 {
2415 const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
2416 const FileLocation *defFilename = GetDefinitionFilename ();
2417
2418 vector<FileLocation> deps;
2419 GetDefinitionDependencies ( deps );
2420
2421 fprintf ( fMakefile, "# IMPORT LIBRARY RULE:\n" );
2422
2423 fprintf ( fMakefile, "%s: %s",
2424 backend->GetFullName ( *library_target ).c_str (),
2425 backend->GetFullName ( *defFilename ).c_str () );
2426
2427 size_t i, iend = deps.size();
2428 for ( i = 0; i < iend; i++ )
2429 fprintf ( fMakefile, " %s",
2430 backend->GetFullName ( deps[i] ).c_str () );
2431
2432 fprintf ( fMakefile, " | %s\n",
2433 backend->GetFullPath ( *library_target ).c_str () );
2434
2435 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
2436
2437 fprintf ( fMakefile,
2438 "\t${dlltool} --dllname %s --def %s --output-lib %s %s %s\n\n",
2439 module.output->name.c_str (),
2440 backend->GetFullName ( *defFilename ).c_str (),
2441 backend->GetFullName ( *library_target ).c_str (),
2442 module.mangledSymbols ? "" : "--kill-at",
2443 module.underscoreSymbols ? "--add-underscore" : "" );
2444
2445 delete defFilename;
2446 delete library_target;
2447 }
2448 }
2449
2450 void
2451 MingwModuleHandler::GetSpecObjectDependencies (
2452 vector<FileLocation>& dependencies,
2453 const FileLocation *file ) const
2454 {
2455 string basename = GetBasename ( file->name );
2456
2457 FileLocation defDependency ( IntermediateDirectory,
2458 file->relative_path,
2459 basename + ".spec.def" );
2460 dependencies.push_back ( defDependency );
2461
2462 FileLocation stubsDependency ( IntermediateDirectory,
2463 file->relative_path,
2464 basename + ".stubs.c" );
2465 dependencies.push_back ( stubsDependency );
2466 }
2467
2468 void
2469 MingwModuleHandler::GetMcObjectDependencies (
2470 vector<FileLocation>& dependencies,
2471 const FileLocation *file ) const
2472 {
2473 string basename = GetBasename ( file->name );
2474
2475 FileLocation defDependency ( IntermediateDirectory,
2476 "include/reactos",
2477 basename + ".h" );
2478 dependencies.push_back ( defDependency );
2479
2480 FileLocation stubsDependency ( IntermediateDirectory,
2481 file->relative_path,
2482 basename + ".rc" );
2483 dependencies.push_back ( stubsDependency );
2484 }
2485
2486 void
2487 MingwModuleHandler::GetWidlObjectDependencies (
2488 vector<FileLocation>& dependencies,
2489 const FileLocation *file ) const
2490 {
2491 string basename = GetBasename ( file->name );
2492 const FileLocation *generatedHeaderFilename = GetRpcServerHeaderFilename ( file );
2493
2494 FileLocation serverSourceDependency ( IntermediateDirectory,
2495 file->relative_path,
2496 basename + "_s.c" );
2497 dependencies.push_back ( serverSourceDependency );
2498 dependencies.push_back ( *generatedHeaderFilename );
2499
2500 delete generatedHeaderFilename;
2501 }
2502
2503 void
2504 MingwModuleHandler::GetDefinitionDependencies (
2505 vector<FileLocation>& dependencies ) const
2506 {
2507 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2508 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2509 {
2510 const CompilationUnit& compilationUnit = *compilationUnits[i];
2511 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2512 string extension = GetExtension ( sourceFile );
2513 if ( extension == ".spec" || extension == ".SPEC" )
2514 GetSpecObjectDependencies ( dependencies, &sourceFile );
2515 if ( extension == ".idl" || extension == ".IDL" )
2516 {
2517 if ( ( module.type == RpcServer ) || ( module.type == RpcClient ) || ( module.type == RpcProxy ) )
2518 GetWidlObjectDependencies ( dependencies, &sourceFile );
2519 }
2520 }
2521 }
2522
2523 enum DebugSupportType
2524 {
2525 DebugKernelMode,
2526 DebugUserMode
2527 };
2528
2529 static void
2530 MingwAddDebugSupportLibraries ( Module& module, DebugSupportType type )
2531 {
2532 Library* pLibrary;
2533
2534 switch(type)
2535 {
2536 case DebugKernelMode:
2537 pLibrary = new Library ( module, "debugsup_ntoskrnl" );
2538 break;
2539
2540 case DebugUserMode:
2541 pLibrary = new Library ( module, "debugsup_ntdll" );
2542 break;
2543
2544 default:
2545 assert(0);
2546 }
2547
2548 module.non_if_data.libraries.push_back(pLibrary);
2549 }
2550
2551 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler ( const Module& module_ )
2552 : MingwModuleHandler ( module_ )
2553 {
2554 }
2555
2556 void
2557 MingwBuildToolModuleHandler::Process ()
2558 {
2559 GenerateBuildToolModuleTarget ();
2560 }
2561
2562 void
2563 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
2564 {
2565 string targetMacro ( GetTargetMacro (module) );
2566 string objectsMacro = GetObjectsMacro ( module );
2567 string linkDepsMacro = GetLinkingDependenciesMacro ();
2568 string libsMacro = GetLibsMacro ();
2569
2570 GenerateRules ();
2571
2572 string linker;
2573 if ( module.cplusplus )
2574 linker = "${host_gpp}";
2575 else
2576 linker = "${host_gcc}";
2577
2578 const FileLocation *target_file = GetTargetFilename ( module, NULL );
2579 fprintf ( fMakefile, "%s: %s %s | %s\n",
2580 targetMacro.c_str (),
2581 objectsMacro.c_str (),
2582 linkDepsMacro.c_str (),
2583 backend->GetFullPath ( *target_file ).c_str () );
2584 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2585 fprintf ( fMakefile,
2586 "\t%s %s -o $@ %s %s\n\n",
2587 linker.c_str (),
2588 GetLinkerMacro ().c_str (),
2589 objectsMacro.c_str (),
2590 libsMacro.c_str () );
2591
2592 delete target_file;
2593 }
2594
2595
2596 MingwKernelModuleHandler::MingwKernelModuleHandler (
2597 const Module& module_ )
2598
2599 : MingwModuleHandler ( module_ )
2600 {
2601 }
2602
2603 void
2604 MingwKernelModuleHandler::Process ()
2605 {
2606 GenerateKernelModuleTarget ();
2607 }
2608
2609 void
2610 MingwKernelModuleHandler::GenerateKernelModuleTarget ()
2611 {
2612 string targetMacro ( GetTargetMacro ( module ) );
2613 string workingDirectory = GetWorkingDirectory ( );
2614 string objectsMacro = GetObjectsMacro ( module );
2615 string linkDepsMacro = GetLinkingDependenciesMacro ();
2616 string libsMacro = GetLibsMacro ();
2617
2618 GenerateImportLibraryTargetIfNeeded ();
2619
2620 if ( module.non_if_data.compilationUnits.size () > 0 )
2621 {
2622 GenerateRules ();
2623
2624 string dependencies = linkDepsMacro + " " + objectsMacro;
2625
2626 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s",
2627 module.GetEntryPoint(true).c_str (),
2628 module.baseaddress.c_str () );
2629 GenerateLinkerCommand ( dependencies,
2630 "${gcc}",
2631 linkerParameters + " $(NTOSKRNL_SHARED)",
2632 objectsMacro,
2633 libsMacro,
2634 "-sections" );
2635 }
2636 else
2637 {
2638 GeneratePhonyTarget();
2639 }
2640 }
2641
2642
2643 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler (
2644 const Module& module_ )
2645
2646 : MingwModuleHandler ( module_ )
2647 {
2648 }
2649
2650 void
2651 MingwStaticLibraryModuleHandler::Process ()
2652 {
2653 GenerateStaticLibraryModuleTarget ();
2654 }
2655
2656 void
2657 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ()
2658 {
2659 GenerateRules ();
2660 }
2661
2662
2663 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler (
2664 const Module& module_ )
2665
2666 : MingwModuleHandler ( module_ )
2667 {
2668 }
2669
2670 void
2671 MingwObjectLibraryModuleHandler::Process ()
2672 {
2673 GenerateObjectLibraryModuleTarget ();
2674 }
2675
2676 void
2677 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ()
2678 {
2679 GenerateRules ();
2680 }
2681
2682
2683 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
2684 const Module& module_ )
2685
2686 : MingwModuleHandler ( module_ )
2687 {
2688 }
2689
2690 MingwEmbeddedTypeLibModuleHandler::MingwEmbeddedTypeLibModuleHandler (
2691 const Module& module_ )
2692
2693 : MingwModuleHandler ( module_ )
2694 {
2695 }
2696
2697 void
2698 MingwEmbeddedTypeLibModuleHandler::Process ()
2699 {
2700 GenerateRules ();
2701 }
2702
2703
2704 void
2705 MingwKernelModeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2706 {
2707 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2708 }
2709
2710 void
2711 MingwKernelModeDLLModuleHandler::Process ()
2712 {
2713 GenerateKernelModeDLLModuleTarget ();
2714 }
2715
2716 void
2717 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
2718 {
2719 string targetMacro ( GetTargetMacro ( module ) );
2720 string workingDirectory = GetWorkingDirectory ( );
2721 string objectsMacro = GetObjectsMacro ( module );
2722 string linkDepsMacro = GetLinkingDependenciesMacro ();
2723 string libsMacro = GetLibsMacro ();
2724
2725 GenerateImportLibraryTargetIfNeeded ();
2726
2727 if ( module.non_if_data.compilationUnits.size () > 0 )
2728 {
2729 GenerateRules ();
2730
2731 string dependencies = linkDepsMacro + " " + objectsMacro;
2732
2733 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
2734 module.GetEntryPoint(true).c_str (),
2735 module.baseaddress.c_str () );
2736 GenerateLinkerCommand ( dependencies,
2737 "${gcc}",
2738 linkerParameters,
2739 objectsMacro,
2740 libsMacro,
2741 "-sections" );
2742 }
2743 else
2744 {
2745 GeneratePhonyTarget();
2746 }
2747 }
2748
2749
2750 MingwKernelModeDriverModuleHandler::MingwKernelModeDriverModuleHandler (
2751 const Module& module_ )
2752
2753 : MingwModuleHandler ( module_ )
2754 {
2755 }
2756
2757 void
2758 MingwKernelModeDriverModuleHandler::AddImplicitLibraries ( Module& module )
2759 {
2760 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2761 }
2762
2763 void
2764 MingwKernelModeDriverModuleHandler::Process ()
2765 {
2766 GenerateKernelModeDriverModuleTarget ();
2767 }
2768
2769
2770 void
2771 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ()
2772 {
2773 string targetMacro ( GetTargetMacro (module) );
2774 string workingDirectory = GetWorkingDirectory ();
2775 string objectsMacro = GetObjectsMacro ( module );
2776 string linkDepsMacro = GetLinkingDependenciesMacro ();
2777 string libsMacro = GetLibsMacro ();
2778
2779 GenerateImportLibraryTargetIfNeeded ();
2780
2781 if ( module.non_if_data.compilationUnits.size () > 0 )
2782 {
2783 GenerateRules ();
2784
2785 string dependencies = linkDepsMacro + " " + objectsMacro;
2786
2787 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
2788 module.GetEntryPoint(true).c_str (),
2789 module.baseaddress.c_str () );
2790 GenerateLinkerCommand ( dependencies,
2791 "${gcc}",
2792 linkerParameters,
2793 objectsMacro,
2794 libsMacro,
2795 "-sections" );
2796 }
2797 else
2798 {
2799 GeneratePhonyTarget();
2800 }
2801 }
2802
2803
2804 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler (
2805 const Module& module_ )
2806
2807 : MingwModuleHandler ( module_ )
2808 {
2809 }
2810
2811 void
2812 MingwNativeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2813 {
2814 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2815 }
2816
2817 void
2818 MingwNativeDLLModuleHandler::Process ()
2819 {
2820 GenerateNativeDLLModuleTarget ();
2821 }
2822
2823 void
2824 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
2825 {
2826 string targetMacro ( GetTargetMacro (module) );
2827 string workingDirectory = GetWorkingDirectory ( );
2828 string objectsMacro = GetObjectsMacro ( module );
2829 string linkDepsMacro = GetLinkingDependenciesMacro ();
2830 string libsMacro = GetLibsMacro ();
2831
2832 GenerateImportLibraryTargetIfNeeded ();
2833
2834 if ( module.non_if_data.compilationUnits.size () > 0 )
2835 {
2836 GenerateRules ();
2837
2838 string dependencies = linkDepsMacro + " " + objectsMacro;
2839
2840 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -shared",
2841 module.GetEntryPoint(true).c_str (),
2842 module.baseaddress.c_str () );
2843 GenerateLinkerCommand ( dependencies,
2844 "${gcc}",
2845 linkerParameters,
2846 objectsMacro,
2847 libsMacro,
2848 "" );
2849 }
2850 else
2851 {
2852 GeneratePhonyTarget();
2853 }
2854 }
2855
2856
2857 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler (
2858 const Module& module_ )
2859
2860 : MingwModuleHandler ( module_ )
2861 {
2862 }
2863
2864 void
2865 MingwNativeCUIModuleHandler::AddImplicitLibraries ( Module& module )
2866 {
2867 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2868 }
2869
2870 void
2871 MingwNativeCUIModuleHandler::Process ()
2872 {
2873 GenerateNativeCUIModuleTarget ();
2874 }
2875
2876 void
2877 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
2878 {
2879 string targetMacro ( GetTargetMacro (module) );
2880 string workingDirectory = GetWorkingDirectory ( );
2881 string objectsMacro = GetObjectsMacro ( module );
2882 string linkDepsMacro = GetLinkingDependenciesMacro ();
2883 string libsMacro = GetLibsMacro ();
2884
2885 GenerateImportLibraryTargetIfNeeded ();
2886
2887 if ( module.non_if_data.compilationUnits.size () > 0 )
2888 {
2889 GenerateRules ();
2890
2891 string dependencies = linkDepsMacro + " " + objectsMacro;
2892
2893 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib",
2894 module.GetEntryPoint(true).c_str (),
2895 module.baseaddress.c_str () );
2896 GenerateLinkerCommand ( dependencies,
2897 "${gcc}",
2898 linkerParameters,
2899 objectsMacro,
2900 libsMacro,
2901 "" );
2902 }
2903 else
2904 {
2905 GeneratePhonyTarget();
2906 }
2907 }
2908
2909
2910 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler (
2911 const Module& module_ )
2912
2913 : MingwModuleHandler ( module_ )
2914 {
2915 }
2916
2917 MingwWin32OCXModuleHandler::MingwWin32OCXModuleHandler (
2918 const Module& module_ )
2919
2920 : MingwModuleHandler ( module_ )
2921 {
2922 }
2923
2924 static bool
2925 LinksToCrt( Module &module )
2926 {
2927 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
2928 {
2929 Library& library = *module.non_if_data.libraries[i];
2930 if ( library.name == "libcntpr" || library.name == "crt" )
2931 return true;
2932 }
2933 return false;
2934 }
2935
2936 static void
2937 MingwAddImplicitLibraries( Module &module )
2938 {
2939 Library* pLibrary;
2940 bool links_to_crt;
2941
2942 if ( module.type != Win32DLL
2943 && module.type != Win32OCX
2944 && module.type != Win32CUI
2945 && module.type != Win32GUI
2946 && module.type != Win32SCR )
2947 {
2948 // no implicit libraries
2949 return;
2950 }
2951
2952 links_to_crt = LinksToCrt ( module );
2953
2954 if ( !module.isDefaultEntryPoint )
2955 {
2956 if ( module.GetEntryPoint(false) == "0" )
2957 {
2958 if ( !links_to_crt )
2959 {
2960 pLibrary = new Library ( module, "mingw_common" );
2961 module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin() , pLibrary );
2962
2963 pLibrary = new Library ( module, "msvcrt" );
2964 module.non_if_data.libraries.push_back ( pLibrary );
2965 links_to_crt = true;
2966 }
2967 }
2968 return;
2969 }
2970
2971 if ( module.IsDLL () )
2972 {
2973 //pLibrary = new Library ( module, "__mingw_dllmain" );
2974 //module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
2975 }
2976 else
2977 {
2978 pLibrary = new Library ( module, module.isUnicode ? "mingw_wmain" : "mingw_main" );
2979 module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
2980 }
2981
2982 pLibrary = new Library ( module, "mingw_common" );
2983 module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin() + 1, pLibrary );
2984
2985 if ( !links_to_crt )
2986 {
2987 // always link in msvcrt to get the basic routines
2988 pLibrary = new Library ( module, "msvcrt" );
2989 module.non_if_data.libraries.push_back ( pLibrary );
2990 }
2991 }
2992
2993 void
2994 MingwWin32DLLModuleHandler::AddImplicitLibraries ( Module& module )
2995 {
2996 MingwAddImplicitLibraries ( module );
2997 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2998 }
2999
3000 void
3001 MingwWin32DLLModuleHandler::Process ()
3002 {
3003 GenerateWin32DLLModuleTarget ();
3004 }
3005
3006 void
3007 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
3008 {
3009 string targetMacro ( GetTargetMacro (module) );
3010 string workingDirectory = GetWorkingDirectory ( );
3011 string objectsMacro = GetObjectsMacro ( module );
3012 string linkDepsMacro = GetLinkingDependenciesMacro ();
3013 string libsMacro = GetLibsMacro ();
3014
3015 GenerateImportLibraryTargetIfNeeded ();
3016
3017 if ( module.non_if_data.compilationUnits.size () > 0 )
3018 {
3019 GenerateRules ();
3020
3021 string dependencies = linkDepsMacro + " " + objectsMacro;
3022
3023 string linker;
3024 if ( module.cplusplus )
3025 linker = "${gpp}";
3026 else
3027 linker = "${gcc}";
3028
3029 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -shared",
3030 module.GetEntryPoint(true).c_str (),
3031 module.baseaddress.c_str () );
3032 GenerateLinkerCommand ( dependencies,
3033 linker,
3034 linkerParameters,
3035 objectsMacro,
3036 libsMacro,
3037 "" );
3038 }
3039 else
3040 {
3041 GeneratePhonyTarget();
3042 }
3043 }
3044
3045
3046 void
3047 MingwWin32OCXModuleHandler::AddImplicitLibraries ( Module& module )
3048 {
3049 MingwAddImplicitLibraries ( module );
3050 MingwAddDebugSupportLibraries ( module, DebugUserMode );
3051 }
3052
3053 void
3054 MingwWin32OCXModuleHandler::Process ()
3055 {
3056 GenerateWin32OCXModuleTarget ();
3057 }
3058
3059 void
3060 MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget ()
3061 {
3062 string targetMacro ( GetTargetMacro (module) );
3063 string workingDirectory = GetWorkingDirectory ( );
3064 string objectsMacro = GetObjectsMacro ( module );
3065 string linkDepsMacro = GetLinkingDependenciesMacro ();
3066 string libsMacro = GetLibsMacro ();
3067
3068 GenerateImportLibraryTargetIfNeeded ();
3069
3070 if ( module.non_if_data.compilationUnits.size () > 0 )
3071 {
3072 GenerateRules ();
3073
3074 string dependencies = linkDepsMacro + " " + objectsMacro;
3075
3076 string linker;
3077 if ( module.cplusplus )
3078 linker = "${gpp}";
3079 else
3080 linker = "${gcc}";
3081
3082 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -shared",
3083 module.GetEntryPoint(true).c_str (),
3084 module.baseaddress.c_str () );
3085 GenerateLinkerCommand ( dependencies,
3086 linker,
3087 linkerParameters,
3088 objectsMacro,
3089 libsMacro,
3090 "" );
3091 }
3092 else
3093 {
3094 GeneratePhonyTarget();
3095 }
3096 }
3097
3098
3099 MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler (
3100 const Module& module_ )
3101
3102 : MingwModuleHandler ( module_ )
3103 {
3104 }
3105
3106 void
3107 MingwWin32CUIModuleHandler::AddImplicitLibraries ( Module& module )
3108 {
3109 MingwAddImplicitLibraries ( module );
3110 MingwAddDebugSupportLibraries ( module, DebugUserMode );
3111 }
3112
3113 void
3114 MingwWin32CUIModuleHandler::Process ()
3115 {
3116 GenerateWin32CUIModuleTarget ();
3117 }
3118
3119 void
3120 MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ()
3121 {
3122 string targetMacro ( GetTargetMacro (module) );
3123 string workingDirectory = GetWorkingDirectory ( );
3124 string objectsMacro = GetObjectsMacro ( module );
3125 string linkDepsMacro = GetLinkingDependenciesMacro ();
3126 string libsMacro = GetLibsMacro ();
3127
3128 GenerateImportLibraryTargetIfNeeded ();
3129
3130 if ( module.non_if_data.compilationUnits.size () > 0 )
3131 {
3132 GenerateRules ();
3133
3134 string dependencies = linkDepsMacro + " " + objectsMacro;
3135
3136 string linker;
3137 if ( module.cplusplus )
3138 linker = "${gpp}";
3139 else
3140 linker = "${gcc}";
3141
3142 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
3143 module.GetEntryPoint(true).c_str (),
3144 module.baseaddress.c_str () );
3145 GenerateLinkerCommand ( dependencies,
3146 linker,
3147 linkerParameters,
3148 objectsMacro,
3149 libsMacro,
3150 "" );
3151 }
3152 else
3153 {
3154 GeneratePhonyTarget();
3155 }
3156 }
3157
3158
3159 MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler (
3160 const Module& module_ )
3161
3162 : MingwModuleHandler ( module_ )
3163 {
3164 }
3165
3166 void
3167 MingwWin32GUIModuleHandler::AddImplicitLibraries ( Module& module )
3168 {
3169 MingwAddImplicitLibraries ( module );
3170 MingwAddDebugSupportLibraries ( module, DebugUserMode );
3171 }
3172
3173 void
3174 MingwWin32GUIModuleHandler::Process ()
3175 {
3176 GenerateWin32GUIModuleTarget ();
3177 }
3178
3179 void
3180 MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ()
3181 {
3182 string targetMacro ( GetTargetMacro (module) );
3183 string workingDirectory = GetWorkingDirectory ( );
3184 string objectsMacro = GetObjectsMacro ( module );
3185 string linkDepsMacro = GetLinkingDependenciesMacro ();
3186 string libsMacro = GetLibsMacro ();
3187
3188 GenerateImportLibraryTargetIfNeeded ();
3189
3190 if ( module.non_if_data.compilationUnits.size () > 0 )
3191 {
3192 GenerateRules ();
3193
3194 string dependencies = linkDepsMacro + " " + objectsMacro;
3195
3196 string linker;
3197 if ( module.cplusplus )
3198 linker = "${gpp}";
3199 else
3200 linker = "${gcc}";
3201
3202 string linkerParameters = ssprintf ( "-Wl,--subsystem,windows -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
3203 module.GetEntryPoint(true).c_str (),
3204 module.baseaddress.c_str () );
3205 GenerateLinkerCommand ( dependencies,
3206 linker,
3207 linkerParameters,
3208 objectsMacro,
3209 libsMacro,
3210 "" );
3211 }
3212 else
3213 {
3214 GeneratePhonyTarget();
3215 }
3216 }
3217
3218
3219 MingwBootLoaderModuleHandler::MingwBootLoaderModuleHandler (
3220 const Module& module_ )
3221
3222 : MingwModuleHandler ( module_ )
3223 {
3224 }
3225
3226 void
3227 MingwBootLoaderModuleHandler::Process ()
3228 {
3229 GenerateBootLoaderModuleTarget ();
3230 }
3231
3232 void
3233 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
3234 {
3235 string targetName ( module.output->name );
3236 string targetMacro ( GetTargetMacro (module) );
3237 string workingDirectory = GetWorkingDirectory ();
3238 FileLocation junk_tmp ( TemporaryDirectory,
3239 "",
3240 module.name + ".junk.tmp" );
3241 CLEAN_FILE ( junk_tmp );
3242 string objectsMacro = GetObjectsMacro ( module );
3243 string linkDepsMacro = GetLinkingDependenciesMacro ();
3244 string libsMacro = GetLibsMacro ();
3245
3246 GenerateRules ();
3247
3248 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3249 fprintf ( fMakefile, "%s: %s %s | %s\n",
3250 targetMacro.c_str (),
3251 objectsMacro.c_str (),
3252 linkDepsMacro.c_str (),
3253 backend->GetFullPath ( *target_file ).c_str () );
3254
3255 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
3256
3257 if (Environment::GetArch() == "arm")
3258 {
3259 fprintf ( fMakefile,
3260 "\t${gcc} -Wl,--subsystem,native -Wl,--section-start,startup=0x8000 -o %s %s %s %s\n",
3261 backend->GetFullName ( junk_tmp ).c_str (),
3262 objectsMacro.c_str (),
3263 linkDepsMacro.c_str (),
3264 GetLinkerMacro ().c_str ());
3265 }
3266 else
3267 {
3268 fprintf ( fMakefile,
3269 "\t${gcc} -Wl,--subsystem,native -Wl,-Ttext,0x8000 -o %s %s %s %s\n",
3270 backend->GetFullName ( junk_tmp ).c_str (),
3271 objectsMacro.c_str (),
3272 linkDepsMacro.c_str (),
3273 GetLinkerMacro ().c_str ());
3274 }
3275 fprintf ( fMakefile,
3276 "\t${objcopy} -O binary %s $@\n",
3277 backend->GetFullName ( junk_tmp ).c_str () );
3278 GenerateBuildMapCode ( &junk_tmp );
3279 fprintf ( fMakefile,
3280 "\t-@${rm} %s 2>$(NUL)\n",
3281 backend->GetFullName ( junk_tmp ).c_str () );
3282
3283 delete target_file;
3284 }
3285
3286
3287 MingwBootSectorModuleHandler::MingwBootSectorModuleHandler (
3288 const Module& module_ )
3289
3290 : MingwModuleHandler ( module_ )
3291 {
3292 }
3293
3294 void
3295 MingwBootSectorModuleHandler::Process ()
3296 {
3297 GenerateBootSectorModuleTarget ();
3298 }
3299
3300 void
3301 MingwBootSectorModuleHandler::GenerateBootSectorModuleTarget ()
3302 {
3303 string objectsMacro = GetObjectsMacro ( module );
3304
3305 GenerateRules ();
3306
3307 fprintf ( fMakefile, ".PHONY: %s\n\n",
3308 module.name.c_str ());
3309 fprintf ( fMakefile,
3310 "%s: %s\n",
3311 module.name.c_str (),
3312 objectsMacro.c_str () );
3313 }
3314
3315
3316 MingwBootProgramModuleHandler::MingwBootProgramModuleHandler (
3317 const Module& module_ )
3318 : MingwModuleHandler ( module_ )
3319 {
3320 }
3321
3322 void
3323 MingwBootProgramModuleHandler::Process ()
3324 {
3325 GenerateBootProgramModuleTarget ();
3326 }
3327
3328 void
3329 MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
3330 {
3331 string targetName ( module.output->name );
3332 string targetMacro ( GetTargetMacro (module) );
3333 string workingDirectory = GetWorkingDirectory ();
3334 FileLocation junk_tmp ( TemporaryDirectory,
3335 "",
3336 module.name + ".junk.tmp" );
3337 FileLocation junk_elf ( TemporaryDirectory,
3338 "",
3339 module.name + ".junk.elf" );
3340 FileLocation junk_cpy ( TemporaryDirectory,
3341 "",
3342 module.name + ".junk.elf" );
3343 CLEAN_FILE ( junk_tmp );
3344 CLEAN_FILE ( junk_elf );
3345 CLEAN_FILE ( junk_cpy );
3346 string objectsMacro = GetObjectsMacro ( module );
3347 string linkDepsMacro = GetLinkingDependenciesMacro ();
3348 string libsMacro = GetLibsMacro ();
3349 const Module *payload = module.project.LocateModule ( module.payload );
3350
3351 GenerateRules ();
3352
3353 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3354 fprintf ( fMakefile, "%s: %s %s %s | %s\n",
3355 targetMacro.c_str (),
3356 objectsMacro.c_str (),
3357 linkDepsMacro.c_str (),
3358 payload->name.c_str (),
3359 backend->GetFullPath ( *target_file ).c_str () );
3360
3361 fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
3362
3363 fprintf ( fMakefile, "\t$(%s_PREPARE) $(OUTPUT)$(SEP)%s %s\n",
3364 module.buildtype.c_str (),
3365 NormalizeFilename( backend->GetFullName ( *payload->output ) ).c_str (),
3366 backend->GetFullName ( junk_cpy ).c_str () );
3367
3368 fprintf ( fMakefile, "\t${objcopy} $(%s_FLATFORMAT) %s %s\n",
3369 module.buildtype.c_str (),
3370 backend->GetFullName ( junk_cpy ).c_str (),
3371 backend->GetFullName ( junk_tmp ).c_str () );
3372
3373 fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -g -o %s\n",
3374 module.buildtype.c_str (),
3375 linkDepsMacro.c_str (),
3376 backend->GetFullName ( junk_tmp ).c_str (),
3377 backend->GetFullName ( junk_elf ).c_str () );
3378
3379 fprintf ( fMakefile, "\t${objcopy} $(%s_COPYFORMAT) %s $(INTERMEDIATE)$(SEP)%s\n",
3380 module.buildtype.c_str (),
3381 backend->GetFullName ( junk_elf ).c_str (),
3382 backend->GetFullName ( *module.output ) .c_str () );
3383
3384 fprintf ( fMakefile,
3385 "\t-@${rm} %s %s %s 2>$(NUL)\n",
3386 backend->GetFullName ( junk_tmp ).c_str (),
3387 backend->GetFullName ( junk_elf ).c_str (),
3388 backend->GetFullName ( junk_cpy ).c_str () );
3389
3390 delete target_file;
3391 }
3392
3393
3394 MingwIsoModuleHandler::MingwIsoModuleHandler (
3395 const Module& module_ )
3396
3397 : MingwModuleHandler ( module_ )
3398 {
3399 }
3400
3401 void
3402 MingwIsoModuleHandler::Process ()
3403 {
3404 GenerateIsoModuleTarget ();
3405 }
3406
3407 void
3408 MingwIsoModuleHandler::OutputBootstrapfileCopyCommands (
3409 const string& bootcdDirectory )
3410 {
3411 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3412 {
3413 const Module& m = *module.project.modules[i];
3414 if ( !m.enabled )
3415 continue;
3416 if ( m.bootstrap != NULL )
3417 {
3418 FileLocation targetFile ( OutputDirectory,
3419 m.bootstrap->base.length () > 0
3420 ? bootcdDirectory + sSep + m.bootstrap->base
3421 : bootcdDirectory,
3422 m.bootstrap->nameoncd );
3423 OutputCopyCommand ( *m.output, targetFile );
3424 }
3425 }
3426 }
3427
3428 void
3429 MingwIsoModuleHandler::OutputCdfileCopyCommands (
3430 const string& bootcdDirectory )
3431 {
3432 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3433 {
3434 const CDFile& cdfile = *module.project.cdfiles[i];
3435 FileLocation targetFile ( OutputDirectory,
3436 cdfile.target->relative_path.length () > 0
3437 ? bootcdDirectory + sSep + cdfile.target->relative_path
3438 : bootcdDirectory,
3439 cdfile.target->name );
3440 OutputCopyCommand ( *cdfile.source, targetFile );
3441 }
3442 }
3443
3444 void
3445 MingwIsoModuleHandler::GetBootstrapCdDirectories ( vector<FileLocation>& out,
3446 const string& bootcdDirectory )
3447 {
3448 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3449 {
3450 const Module& m = *module.project.modules[i];
3451 if ( !m.enabled )
3452 continue;
3453 if ( m.bootstrap != NULL )
3454 {
3455 FileLocation targetDirectory ( OutputDirectory,
3456 m.bootstrap->base.length () > 0
3457 ? bootcdDirectory + sSep + m.bootstrap->base
3458 : bootcdDirectory,
3459 "" );
3460 out.push_back ( targetDirectory );
3461 }
3462 }
3463 }
3464
3465 void
3466 MingwIsoModuleHandler::GetNonModuleCdDirectories ( vector<FileLocation>& out,
3467 const string& bootcdDirectory )
3468 {
3469 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3470 {
3471 const CDFile& cdfile = *module.project.cdfiles[i];
3472 FileLocation targetDirectory ( OutputDirectory,
3473 cdfile.target->relative_path.length () > 0
3474 ? bootcdDirectory + sSep + cdfile.target->relative_path
3475 : bootcdDirectory,
3476 "" );
3477 out.push_back( targetDirectory );
3478 }
3479 }
3480
3481 void
3482 MingwIsoModuleHandler::GetCdDirectories ( vector<FileLocation>& out,
3483 const string& bootcdDirectory )
3484 {
3485 GetBootstrapCdDirectories ( out, bootcdDirectory );
3486 GetNonModuleCdDirectories ( out, bootcdDirectory );
3487 }
3488
3489 void
3490 MingwIsoModuleHandler::GetBootstrapCdFiles (
3491 vector<FileLocation>& out ) const
3492 {
3493 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3494 {
3495 const Module& m = *module.project.modules[i];
3496 if ( !m.enabled )
3497 continue;
3498 if ( m.bootstrap != NULL )
3499 {
3500 out.push_back ( *m.output );
3501 }
3502 }
3503 }
3504
3505 void
3506 MingwIsoModuleHandler::GetNonModuleCdFiles (
3507 vector<FileLocation>& out ) const
3508 {
3509 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3510 {
3511 const CDFile& cdfile = *module.project.cdfiles[i];
3512 out.push_back ( *cdfile.source );
3513 }
3514 }
3515
3516 void
3517 MingwIsoModuleHandler::GetCdFiles (
3518 vector<FileLocation>& out ) const
3519 {
3520 GetBootstrapCdFiles ( out );
3521 GetNonModuleCdFiles ( out );
3522 }
3523
3524 void
3525 MingwIsoModuleHandler::GenerateIsoModuleTarget ()
3526 {
3527 string bootcdDirectory = "cd";
3528 FileLocation bootcd ( OutputDirectory,
3529 bootcdDirectory,
3530 "" );
3531 FileLocation bootcdReactos ( OutputDirectory,
3532 bootcdDirectory + sSep + Environment::GetCdOutputPath (),
3533 "" );
3534 vector<FileLocation> vSourceFiles, vCdFiles;
3535 vector<FileLocation> vCdDirectories;
3536
3537 // unattend.inf
3538 FileLocation srcunattend ( SourceDirectory,
3539 "boot" + sSep + "bootdata" + sSep + "bootcdregtest",
3540 "unattend.inf" );
3541 FileLocation tarunattend ( bootcdReactos.directory,
3542 bootcdReactos.relative_path,
3543 "unattend.inf" );
3544 if (module.type == IsoRegTest)
3545 vSourceFiles.push_back ( srcunattend );
3546
3547 // bootsector
3548 const Module* bootModule;
3549 bootModule = module.project.LocateModule ( module.type == IsoRegTest
3550 ? "isobtrt"
3551 : "isoboot" );
3552 const FileLocation *isoboot = bootModule->output;
3553 vSourceFiles.push_back ( *isoboot );
3554
3555 // prepare reactos.dff and reactos.inf
3556 FileLocation reactosDff ( SourceDirectory,
3557 "boot" + sSep + "bootdata" + sSep + "packages",
3558 "reactos.dff" );
3559 FileLocation reactosInf ( bootcdReactos.directory,
3560 bootcdReactos.relative_path,
3561 "reactos.inf" );
3562 FileLocation vgafontsCab( bootcdReactos.directory,
3563 bootcdReactos.relative_path,
3564 "vgafonts.cab");
3565 FileLocation vgafontsDir( SourceDirectory,
3566 "media" + sSep + "vgafonts",
3567 "" );
3568
3569 vSourceFiles.push_back ( reactosDff );
3570
3571 string IsoName;
3572
3573 if (module.type == IsoRegTest)
3574 IsoName = "ReactOS-RegTest.iso";
3575 else
3576 IsoName = "ReactOS.iso";
3577
3578
3579 string sourceFiles = v2s ( backend, vSourceFiles, 5 );
3580
3581 // fill cdrom
3582 GetCdDirectories ( vCdDirectories, bootcdDirectory );
3583 GetCdFiles ( vCdFiles );
3584 string cdDirectories = "";//v2s ( vCdDirectories, 5 );
3585 string cdFiles = v2s ( backend, vCdFiles, 5 );
3586
3587 fprintf ( fMakefile, ".PHONY: %s\n\n",
3588 module.name.c_str ());
3589 fprintf ( fMakefile,
3590 "%s: all %s %s %s $(CABMAN_TARGET) $(CDMAKE_TARGET) %s\n",
3591 module.name.c_str (),
3592 backend->GetFullName ( *isoboot ).c_str (),
3593 sourceFiles.c_str (),
3594 cdFiles.c_str (),
3595 cdDirectories.c_str () );
3596 fprintf ( fMakefile, "\t$(ECHO_CABMAN)\n" );
3597 fprintf ( fMakefile,
3598 "\t$(Q)$(CABMAN_TARGET) -M raw -S %s %s\\*.bin\n", // Escape the asterisk for Make
3599 backend->GetFullName ( vgafontsCab ).c_str (),
3600 backend->GetFullName ( vgafontsDir ).c_str ());
3601 fprintf ( fMakefile,
3602 "\t$(Q)$(CABMAN_TARGET) -C %s -L %s -I -P $(OUTPUT)\n",
3603 backend->GetFullName ( reactosDff ).c_str (),
3604 backend->GetFullPath ( bootcdReactos ).c_str () );
3605 fprintf ( fMakefile,
3606 "\t$(Q)$(CABMAN_TARGET) -C %s -RC %s -L %s -N -P $(OUTPUT)\n",
3607 backend->GetFullName ( reactosDff ).c_str (),
3608 backend->GetFullName ( reactosInf ).c_str (),
3609 backend->GetFullPath ( bootcdReactos ).c_str ());
3610 fprintf ( fMakefile,
3611 "\t-@${rm} %s 2>$(NUL)\n",
3612 backend->GetFullName ( reactosInf ).c_str () );
3613 OutputBootstrapfileCopyCommands ( bootcdDirectory );
3614 OutputCdfileCopyCommands ( bootcdDirectory );
3615
3616 if (module.type == IsoRegTest)
3617 OutputCopyCommand ( srcunattend, tarunattend );
3618
3619 fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
3620 fprintf ( fMakefile,
3621 "\t$(Q)$(CDMAKE_TARGET) -v -j -m -b %s %s REACTOS %s\n",
3622 backend->GetFullName ( *isoboot ).c_str (),
3623 backend->GetFullPath ( bootcd ).c_str (),
3624 IsoName.c_str() );
3625 fprintf ( fMakefile,
3626 "\n" );
3627 }
3628
3629
3630 MingwLiveIsoModuleHandler::MingwLiveIsoModuleHandler (
3631 const Module& module_ )
3632
3633 : MingwModuleHandler ( module_ )
3634 {
3635 }
3636
3637 void
3638 MingwLiveIsoModuleHandler::Process ()
3639 {
3640 GenerateLiveIsoModuleTarget ();
3641 }
3642
3643 void
3644 MingwLiveIsoModuleHandler::CreateDirectory ( const string& directory )
3645 {
3646 FileLocation dir ( OutputDirectory,
3647 directory,
3648 "" );
3649 MingwModuleHandler::PassThruCacheDirectory ( &dir );
3650 }
3651
3652 void
3653 MingwLiveIsoModuleHandler::OutputModuleCopyCommands ( string& livecdDirectory,
3654 string& reactosDirectory )
3655 {
3656 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3657 {
3658 const Module& m = *module.project.modules[i];
3659 if ( !m.enabled )
3660 continue;
3661 if ( m.install )
3662 {
3663 const Module& aliasedModule = backend->GetAliasedModuleOrModule ( m );
3664 FileLocation destination ( OutputDirectory,
3665 m.install->relative_path.length () > 0
3666 ? livecdDirectory + sSep + reactosDirectory + sSep + m.install->relative_path
3667 : livecdDirectory + sSep + reactosDirectory,
3668 m.install->name );
3669 OutputCopyCommand ( *aliasedModule.output,
3670 destination);
3671 }
3672 }
3673 }
3674
3675 void
3676 MingwLiveIsoModuleHandler::OutputNonModuleCopyCommands ( string& livecdDirectory,
3677 string& reactosDirectory )
3678 {
3679 for ( size_t i = 0; i < module.project.installfiles.size (); i++ )
3680 {
3681 const InstallFile& installfile = *module.project.installfiles[i];
3682 FileLocation target ( OutputDirectory,
3683 installfile.target->relative_path.length () > 0
3684 ? livecdDirectory + sSep + reactosDirectory + sSep + installfile.target->relative_path
3685 : livecdDirectory + sSep + reactosDirectory,
3686 installfile.target->name );
3687 OutputCopyCommand ( *installfile.source, target );
3688 }
3689 }
3690
3691 void
3692 MingwLiveIsoModuleHandler::OutputProfilesDirectoryCommands ( string& livecdDirectory )
3693 {
3694 CreateDirectory ( livecdDirectory + sSep + "Profiles" );
3695 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "All Users") ;
3696 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "All Users" + sSep + "Desktop" );
3697 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" );
3698 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" + sSep + "Desktop" );
3699 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" + sSep + "My Documents" );
3700
3701 FileLocation livecdIni ( SourceDirectory,
3702 "boot" + sSep + "bootdata",
3703 "livecd.ini" );
3704 FileLocation destination ( OutputDirectory,
3705 livecdDirectory,
3706 "freeldr.ini" );
3707 OutputCopyCommand ( livecdIni,
3708 destination );
3709 }
3710
3711 void
3712 MingwLiveIsoModuleHandler::OutputLoaderCommands ( string& livecdDirectory )
3713 {
3714 FileLocation freeldr ( OutputDirectory,
3715 "boot" + sSep + "freeldr" + sSep + "freeldr",
3716 "freeldr.sys" );
3717 FileLocation destination ( OutputDirectory,
3718 livecdDirectory + sSep + "loader",
3719 "setupldr.sys" );
3720 OutputCopyCommand ( freeldr,
3721 destination );
3722 }
3723
3724 void
3725 MingwLiveIsoModuleHandler::OutputRegistryCommands ( string& livecdDirectory )
3726 {
3727 FileLocation reactosSystem32ConfigDirectory ( OutputDirectory,
3728 livecdDirectory + sSep + "reactos" + sSep + "system32" + sSep + "config",
3729 "" );
3730 fprintf ( fMakefile,
3731 "\t$(ECHO_MKHIVE)\n" );
3732 fprintf ( fMakefile,
3733 "\t$(MKHIVE_TARGET) boot%cbootdata %s boot%cbootdata%clivecd.inf boot%cbootdata%chiveinst.inf\n",
3734 cSep, backend->GetFullPath ( reactosSystem32ConfigDirectory ).c_str (),
3735 cSep, cSep, cSep, cSep );
3736 }
3737
3738 void
3739 MingwLiveIsoModuleHandler::GenerateLiveIsoModuleTarget ()
3740 {
3741 string livecdDirectory = module.name;
3742 FileLocation livecd ( OutputDirectory, livecdDirectory, "" );
3743
3744 string IsoName;
3745
3746 const Module* bootModule;
3747 bootModule = module.project.LocateModule ( module.name == "livecdregtest"
3748 ? "isobtrt"
3749 : "isoboot" );
3750 const FileLocation *isoboot = bootModule->output;
3751 if (module.name == "livecdregtest")
3752 IsoName = "ReactOS-LiveCD-RegTest.iso";
3753 else
3754 IsoName = "ReactOS-LiveCD.iso";
3755
3756 string reactosDirectory = "reactos";
3757 string livecdReactosNoFixup = livecdDirectory + sSep + reactosDirectory;
3758 FileLocation livecdReactos ( OutputDirectory,
3759 livecdReactosNoFixup,
3760 "" );
3761 CLEAN_FILE ( livecdReactos );
3762
3763 fprintf ( fMakefile, ".PHONY: %s\n\n",
3764 module.name.c_str ());
3765 fprintf ( fMakefile,
3766 "%s: all %s %s $(MKHIVE_TARGET) $(CDMAKE_TARGET)\n",
3767 module.name.c_str (),
3768 backend->GetFullName ( *isoboot) .c_str (),
3769 backend->GetFullPath ( livecdReactos ).c_str () );
3770 OutputModuleCopyCommands ( livecdDirectory,
3771 reactosDirectory );
3772 OutputNonModuleCopyCommands ( livecdDirectory,
3773 reactosDirectory );
3774 OutputProfilesDirectoryCommands ( livecdDirectory );
3775 OutputLoaderCommands ( livecdDirectory );
3776 OutputRegistryCommands ( livecdDirectory );
3777 fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
3778 fprintf ( fMakefile,
3779 "\t$(Q)$(CDMAKE_TARGET) -v -m -j -b %s %s REACTOS %s\n",
3780 backend->GetFullName( *isoboot ).c_str (),
3781 backend->GetFullPath ( livecd ).c_str (),
3782 IsoName.c_str() );
3783 fprintf ( fMakefile,
3784 "\n" );
3785 }
3786
3787
3788 MingwTestModuleHandler::MingwTestModuleHandler (
3789 const Module& module_ )
3790
3791 : MingwModuleHandler ( module_ )
3792 {
3793 }
3794
3795 void
3796 MingwTestModuleHandler::Process ()
3797 {
3798 GenerateTestModuleTarget ();
3799 }
3800
3801 /* caller needs to delete the returned object */
3802 void
3803 MingwTestModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUnit*>& compilationUnits )
3804 {
3805 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_hooks.c", false, "", false ) ) );
3806 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_stubs.S", false, "", false ) ) );
3807 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_startup.c", false, "", false ) ) );
3808 }
3809
3810 void
3811 MingwTestModuleHandler::GenerateTestModuleTarget ()
3812 {
3813 string targetMacro ( GetTargetMacro ( module ) );
3814 string workingDirectory = GetWorkingDirectory ( );
3815 string objectsMacro = GetObjectsMacro ( module );
3816 string linkDepsMacro = GetLinkingDependenciesMacro ();
3817 string libsMacro = GetLibsMacro ();
3818
3819 GenerateImportLibraryTargetIfNeeded ();
3820
3821 if ( module.non_if_data.compilationUnits.size () > 0 )
3822 {
3823 GenerateRules ();
3824
3825 string dependencies = linkDepsMacro + " " + objectsMacro;
3826
3827 string linker;
3828 if ( module.cplusplus )
3829 linker = "${gpp}";
3830 else
3831 linker = "${gcc}";
3832
3833 string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",
3834 module.GetEntryPoint(true).c_str (),
3835 module.baseaddress.c_str () );
3836 GenerateLinkerCommand ( dependencies,
3837 linker,
3838 linkerParameters,
3839 objectsMacro,
3840 libsMacro,
3841 "" );
3842 }
3843 else
3844 {
3845 GeneratePhonyTarget();
3846 }
3847 }
3848
3849
3850 MingwRpcServerModuleHandler::MingwRpcServerModuleHandler (
3851 const Module& module_ )
3852
3853 : MingwModuleHandler ( module_ )
3854 {
3855 }
3856
3857 void
3858 MingwRpcServerModuleHandler::Process ()
3859 {
3860 GenerateRules ();
3861 }
3862
3863
3864 MingwRpcClientModuleHandler::MingwRpcClientModuleHandler (
3865 const Module& module_ )
3866
3867 : MingwModuleHandler ( module_ )
3868 {
3869 }
3870
3871 void
3872 MingwRpcClientModuleHandler::Process ()
3873 {
3874 GenerateRules ();
3875 }
3876
3877
3878 MingwRpcProxyModuleHandler::MingwRpcProxyModuleHandler (
3879 const Module& module_ )
3880
3881 : MingwModuleHandler ( module_ )
3882 {
3883 }
3884
3885 void
3886 MingwRpcProxyModuleHandler::Process ()
3887 {
3888 GenerateRules ();
3889 }
3890
3891
3892 MingwAliasModuleHandler::MingwAliasModuleHandler (
3893 const Module& module_ )
3894
3895 : MingwModuleHandler ( module_ )
3896 {
3897 }
3898
3899 void
3900 MingwAliasModuleHandler::Process ()
3901 {
3902 }
3903
3904 MingwIdlHeaderModuleHandler::MingwIdlHeaderModuleHandler (
3905 const Module& module_ )
3906
3907 : MingwModuleHandler ( module_ )
3908 {
3909 }
3910
3911 void
3912 MingwIdlHeaderModuleHandler::Process ()
3913 {
3914 GenerateRules ();
3915 }
3916
3917 MingwElfExecutableModuleHandler::MingwElfExecutableModuleHandler (
3918 const Module& module_ )
3919
3920 : MingwModuleHandler ( module_ )
3921 {
3922 }
3923
3924 void
3925 MingwElfExecutableModuleHandler::Process ()
3926 {
3927 string targetName ( module.output->name );
3928 string targetMacro ( GetTargetMacro (module) );
3929 string workingDirectory = GetWorkingDirectory ();
3930 string objectsMacro = GetObjectsMacro ( module );
3931 string linkDepsMacro = GetLinkingDependenciesMacro ();
3932 string libsMacro = GetLibsMacro ();
3933
3934 GenerateRules ();
3935
3936 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3937 fprintf ( fMakefile, "%s: %s %s | %s\n",
3938 targetMacro.c_str (),
3939 objectsMacro.c_str (),
3940 linkDepsMacro.c_str (),
3941 backend->GetFullPath ( *target_file ).c_str () );
3942
3943 fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
3944
3945 fprintf ( fMakefile, "\t${gcc} $(%s_LINKFORMAT) %s %s -g -o %s\n",
3946 module.buildtype.c_str(),
3947 objectsMacro.c_str(),
3948 libsMacro.c_str(),
3949 targetMacro.c_str () );
3950
3951 delete target_file;
3952 }