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