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