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