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