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