Link C++ programs against target libraries, not host ones
[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 const FileLocation temp_obj ( TemporaryDirectory, "", module.name + ".temp.ld" );
1584 string linker = "${ld}";
1585 string objectsMacro = GetObjectsMacro ( module );
1586 string libsMacro = GetLibsMacro ();
1587
1588 string target_macro ( GetTargetMacro ( module ) );
1589 string target_folder ( backend->GetFullPath ( *target_file ) );
1590
1591 string linkerScriptArgument;
1592 if ( module.linkerScript != NULL )
1593 linkerScriptArgument = ssprintf ( " -T=%s", backend->GetFullName ( *module.linkerScript->file ).c_str () );
1594 else
1595 linkerScriptArgument = "";
1596
1597 fprintf ( fMakefile,
1598 "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
1599 target_macro.c_str (),
1600 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1601 dependencies.c_str (),
1602 target_folder.c_str () );
1603 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1604 string targetName ( module.output->name );
1605
1606 fprintf ( fMakefile, "\t@echo $(subst $(SEP),/,%s) > %s\n",
1607 objectsMacro.c_str (),
1608 backend->GetFullName ( temp_obj ).c_str () );
1609 CLEAN_FILE ( temp_obj );
1610
1611 if ( !module.IsDLL () )
1612 {
1613 fprintf ( fMakefile,
1614 "\t%s %s%s @%s %s%s %s -o %s\n",
1615 linker.c_str (),
1616 linkerParameters.c_str (),
1617 linkerScriptArgument.c_str (),
1618 backend->GetFullName ( temp_obj ).c_str (),
1619 module.cplusplus ? "$(PROJECT_LPPFLAGS) " : "",
1620 libsMacro.c_str (),
1621 GetLinkerMacro ().c_str (),
1622 target_macro.c_str () );
1623 }
1624 else if ( module.HasImportLibrary () )
1625 {
1626 FileLocation temp_exp ( TemporaryDirectory,
1627 "",
1628 module.name + ".temp.exp" );
1629 CLEAN_FILE ( temp_exp );
1630
1631 fprintf ( fMakefile,
1632 "\t${dlltool} --dllname %s --def %s --output-exp %s%s%s\n",
1633 targetName.c_str (),
1634 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1635 backend->GetFullName ( temp_exp ).c_str (),
1636 module.mangledSymbols ? "" : " --kill-at",
1637 module.underscoreSymbols ? " --add-underscore" : "" );
1638
1639 fprintf ( fMakefile,
1640 "\t%s %s%s %s @%s %s%s %s -o %s\n",
1641 linker.c_str (),
1642 linkerParameters.c_str (),
1643 linkerScriptArgument.c_str (),
1644 backend->GetFullName ( temp_exp ).c_str (),
1645 backend->GetFullName ( temp_obj ).c_str (),
1646 module.cplusplus ? "$(PROJECT_LPPFLAGS) " : "",
1647 libsMacro.c_str (),
1648 GetLinkerMacro ().c_str (),
1649 target_macro.c_str () );
1650
1651 fprintf ( fMakefile,
1652 "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n",
1653 target_macro.c_str (),
1654 pefixupParameters.c_str() );
1655
1656 fprintf ( fMakefile,
1657 "\t-@${rm} %s 2>$(NUL)\n",
1658 backend->GetFullName ( temp_exp ).c_str () );
1659 }
1660 else
1661 {
1662 /* XXX: need to workaround binutils bug, which exports
1663 * all functions in a dll if no .def file or an empty
1664 * one has been provided... */
1665 /* See bug 1244 */
1666 //printf ( "%s will have all its functions exported\n",
1667 // module.target->name.c_str () );
1668 fprintf ( fMakefile,
1669 "\t%s %s%s @%s %s%s %s -o %s\n",
1670 linker.c_str (),
1671 linkerParameters.c_str (),
1672 linkerScriptArgument.c_str (),
1673 backend->GetFullName ( temp_obj ).c_str (),
1674 module.cplusplus ? "$(PROJECT_LPPFLAGS) " : "",
1675 libsMacro.c_str (),
1676 GetLinkerMacro ().c_str (),
1677 target_macro.c_str () );
1678 }
1679
1680 GenerateBuildMapCode ();
1681 GenerateBuildNonSymbolStrippedCode ();
1682 GenerateRunRsymCode ();
1683 GenerateRunStripCode ();
1684 GenerateCleanObjectsAsYouGoCode ();
1685
1686 if ( definitionFilename )
1687 delete definitionFilename;
1688 delete target_file;
1689 }
1690
1691 void
1692 MingwModuleHandler::GeneratePhonyTarget() const
1693 {
1694 string targetMacro ( GetTargetMacro ( module ) );
1695 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1696
1697 fprintf ( fMakefile,
1698 ".PHONY: %s\n\n",
1699 targetMacro.c_str ());
1700 fprintf ( fMakefile, "%s: | %s\n",
1701 targetMacro.c_str (),
1702 backend->GetFullPath ( *target_file ).c_str () );
1703
1704 delete target_file;
1705 }
1706
1707 void
1708 MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
1709 {
1710 size_t i;
1711 string moduleDependencies;
1712
1713 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1714 for ( i = 0; i < compilationUnits.size (); i++ )
1715 {
1716 CompilationUnit& compilationUnit = *compilationUnits[i];
1717 const FileLocation& compilationName = compilationUnit.GetFilename ();
1718 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module );
1719 if ( GetExtension ( *objectFilename ) == ".h" )
1720 moduleDependencies += ssprintf ( " $(%s_HEADERS)", module.name.c_str () );
1721 else if ( GetExtension ( *objectFilename ) == ".rc" )
1722 moduleDependencies += ssprintf ( " $(%s_RESOURCES)", module.name.c_str () );
1723 delete objectFilename;
1724 }
1725
1726 for ( i = 0; i < compilationUnits.size (); i++ )
1727 {
1728 GenerateCommands ( *compilationUnits[i],
1729 moduleDependencies );
1730 fprintf ( fMakefile,
1731 "\n" );
1732 }
1733
1734 const vector<If*>& ifs = data.ifs;
1735 for ( i = 0; i < ifs.size(); i++ )
1736 {
1737 GenerateObjectFileTargets ( ifs[i]->data );
1738 }
1739
1740 vector<CompilationUnit*> sourceCompilationUnits;
1741 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1742 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1743 {
1744 GenerateCommands ( *sourceCompilationUnits[i],
1745 moduleDependencies );
1746 }
1747 CleanupCompilationUnitVector ( sourceCompilationUnits );
1748 }
1749
1750 void
1751 MingwModuleHandler::GenerateObjectFileTargets ()
1752 {
1753 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1754
1755 if ( pchFilename )
1756 {
1757 string cc = ( module.host == HostTrue ? "${host_gcc}" : "${gcc}" );
1758 string cppc = ( module.host == HostTrue ? "${host_gpp}" : "${gpp}" );
1759
1760 const FileLocation& baseHeaderFile = *module.pch->file;
1761 CLEAN_FILE ( *pchFilename );
1762 string dependencies = backend->GetFullName ( baseHeaderFile );
1763 /* WIDL generated headers may be used */
1764 vector<FileLocation> rpcDependencies;
1765 GetRpcHeaderDependencies ( rpcDependencies );
1766 if ( rpcDependencies.size () > 0 )
1767 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1768 fprintf ( fMakefile,
1769 "%s: %s | %s\n",
1770 backend->GetFullName ( *pchFilename ).c_str(),
1771 dependencies.c_str(),
1772 backend->GetFullPath ( *pchFilename ).c_str() );
1773 fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
1774 fprintf ( fMakefile,
1775 "\t%s -o %s %s -g %s\n\n",
1776 module.cplusplus ? cppc.c_str() : cc.c_str(),
1777 backend->GetFullName ( *pchFilename ).c_str(),
1778 cflagsMacro.c_str(),
1779 backend->GetFullName ( baseHeaderFile ).c_str() );
1780 delete pchFilename;
1781 }
1782
1783 GenerateObjectFileTargets ( module.non_if_data );
1784 fprintf ( fMakefile, "\n" );
1785 }
1786
1787 /* caller needs to delete the returned object */
1788 const FileLocation*
1789 MingwModuleHandler::GenerateArchiveTarget ()
1790 {
1791 const FileLocation *archiveFilename = GetModuleArchiveFilename ();
1792 const FileLocation *definitionFilename = GetDefinitionFilename ();
1793
1794 arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1795
1796 if ( IsStaticLibrary ( module ) && definitionFilename )
1797 {
1798 fprintf ( fMakefile,
1799 "\t${dlltool} --dllname %s --def %s --output-lib $@%s%s\n",
1800 module.importLibrary->dllname.c_str (),
1801 backend->GetFullName ( *definitionFilename ).c_str (),
1802 module.mangledSymbols ? "" : " --kill-at",
1803 module.underscoreSymbols ? " --add-underscore" : "" );
1804 }
1805
1806 if ( definitionFilename )
1807 delete definitionFilename;
1808
1809 if(module.type == HostStaticLibrary)
1810 arHostRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1811 else
1812 arRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1813
1814 GenerateCleanObjectsAsYouGoCode ();
1815
1816 fprintf ( fMakefile, "\n" );
1817
1818 return archiveFilename;
1819 }
1820
1821 string
1822 MingwModuleHandler::GetCFlagsMacro () const
1823 {
1824 return ssprintf ( "$(%s_CFLAGS)",
1825 module.name.c_str () );
1826 }
1827
1828 /*static*/ string
1829 MingwModuleHandler::GetObjectsMacro ( const Module& module )
1830 {
1831 return ssprintf ( "$(%s_OBJS)",
1832 module.name.c_str () );
1833 }
1834
1835 string
1836 MingwModuleHandler::GetLinkingDependenciesMacro () const
1837 {
1838 return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
1839 }
1840
1841 string
1842 MingwModuleHandler::GetLibsMacro () const
1843 {
1844 return ssprintf ( "$(%s_LIBS)", module.name.c_str () );
1845 }
1846
1847 string
1848 MingwModuleHandler::GetLinkerMacro () const
1849 {
1850 return ssprintf ( "$(%s_LFLAGS)",
1851 module.name.c_str () );
1852 }
1853
1854 string
1855 MingwModuleHandler::GetModuleTargets ( const Module& module )
1856 {
1857 if ( ReferenceObjects ( module ) )
1858 return GetObjectsMacro ( module );
1859 else
1860 {
1861 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1862 string target = backend->GetFullName ( *target_file ).c_str ();
1863 delete target_file;
1864 return target;
1865 }
1866 }
1867
1868 void
1869 MingwModuleHandler::GenerateSourceMacro ()
1870 {
1871 sourcesMacro = ssprintf ( "%s_SOURCES", module.name.c_str ());
1872
1873 GenerateSourceMacros (
1874 "=",
1875 module.non_if_data );
1876
1877 // future references to the macro will be to get its values
1878 sourcesMacro = ssprintf ("$(%s)", sourcesMacro.c_str ());
1879 }
1880
1881 void
1882 MingwModuleHandler::GenerateObjectMacro ()
1883 {
1884 objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
1885
1886 GenerateObjectMacros (
1887 "=",
1888 module.non_if_data );
1889
1890 // future references to the macro will be to get its values
1891 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
1892 }
1893
1894 void
1895 MingwModuleHandler::GenerateTargetMacro ()
1896 {
1897 fprintf ( fMakefile,
1898 "%s := %s\n",
1899 GetTargetMacro ( module, false ).c_str (),
1900 GetModuleTargets ( module ).c_str () );
1901 }
1902
1903 void
1904 MingwModuleHandler::GetRpcHeaderDependencies (
1905 vector<FileLocation>& dependencies ) const
1906 {
1907 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
1908 {
1909 Library& library = *module.non_if_data.libraries[i];
1910 if ( library.importedModule->type == RpcServer ||
1911 library.importedModule->type == RpcClient ||
1912 library.importedModule->type == RpcProxy ||
1913 library.importedModule->type == IdlHeader )
1914 {
1915 for ( size_t j = 0; j < library.importedModule->non_if_data.compilationUnits.size (); j++ )
1916 {
1917 CompilationUnit& compilationUnit = *library.importedModule->non_if_data.compilationUnits[j];
1918 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1919 string extension = GetExtension ( sourceFile );
1920 if ( extension == ".idl" || extension == ".IDL" )
1921 {
1922 string basename = GetBasename ( sourceFile.name );
1923 if ( library.importedModule->type == RpcServer )
1924 {
1925 const FileLocation *header = GetRpcServerHeaderFilename ( &sourceFile );
1926 dependencies.push_back ( *header );
1927 delete header;
1928 }
1929 if ( library.importedModule->type == RpcClient )
1930 {
1931 const FileLocation *header = GetRpcClientHeaderFilename ( &sourceFile );
1932 dependencies.push_back ( *header );
1933 delete header;
1934 }
1935 if ( library.importedModule->type == RpcProxy )
1936 {
1937 const FileLocation *header = GetRpcProxyHeaderFilename ( &sourceFile );
1938 dependencies.push_back ( *header );
1939 delete header;
1940 }
1941 if ( library.importedModule->type == IdlHeader )
1942 {
1943 const FileLocation *header = GetIdlHeaderFilename ( &sourceFile );
1944 dependencies.push_back ( *header );
1945 delete header;
1946 }
1947 }
1948 }
1949 }
1950 }
1951 }
1952
1953 void
1954 MingwModuleHandler::GenerateOtherMacros ()
1955 {
1956 set<const Define *> used_defs;
1957
1958 cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
1959 nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
1960 windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
1961 widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());
1962 linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
1963 libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
1964 linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
1965
1966 GenerateMacros (
1967 "=",
1968 module.non_if_data,
1969 &module.linkerFlags,
1970 used_defs );
1971
1972 if ( module.host == HostFalse )
1973 {
1974 GenerateMacros (
1975 "+=",
1976 module.project.non_if_data,
1977 NULL,
1978 used_defs );
1979 }
1980
1981 vector<FileLocation> s;
1982 if ( module.importLibrary )
1983 {
1984 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
1985 for ( size_t i = 0; i < compilationUnits.size (); i++ )
1986 {
1987 CompilationUnit& compilationUnit = *compilationUnits[i];
1988 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1989 string extension = GetExtension ( sourceFile );
1990 if ( extension == ".spec" || extension == ".SPEC" )
1991 GetSpecObjectDependencies ( s, &sourceFile );
1992 }
1993 }
1994 if ( s.size () > 0 )
1995 {
1996 fprintf (
1997 fMakefile,
1998 "%s +=",
1999 linkDepsMacro.c_str() );
2000 for ( size_t i = 0; i < s.size(); i++ )
2001 fprintf ( fMakefile,
2002 " %s",
2003 backend->GetFullName ( s[i] ).c_str () );
2004 fprintf ( fMakefile, "\n" );
2005 }
2006
2007 string globalCflags = "";
2008 if ( module.host == HostFalse )
2009 globalCflags += " $(PROJECT_CFLAGS)";
2010 else
2011 globalCflags += " -Wall -Wpointer-arith -D__REACTOS__";
2012 globalCflags += " -g";
2013 if ( backend->usePipe )
2014 globalCflags += " -pipe";
2015 if ( !module.allowWarnings )
2016 globalCflags += " -Werror";
2017 if ( module.host == HostTrue )
2018 {
2019 if ( module.cplusplus )
2020 globalCflags += " $(HOST_CPPFLAGS)";
2021 else
2022 globalCflags += " -Wno-strict-aliasing $(HOST_CFLAGS)";
2023 }
2024 else
2025 {
2026 if ( module.cplusplus )
2027 {
2028 // HACK: use host headers when building C++
2029 globalCflags += " $(HOST_CPPFLAGS)";
2030 }
2031 else
2032 globalCflags += " -nostdinc";
2033 }
2034
2035 // Always force disabling of sibling calls optimisation for GCC
2036 // (TODO: Move to version-specific once this bug is fixed in GCC)
2037 globalCflags += " -fno-optimize-sibling-calls";
2038
2039 fprintf (
2040 fMakefile,
2041 "%s +=%s\n",
2042 cflagsMacro.c_str (),
2043 globalCflags.c_str () );
2044
2045 if ( module.host == HostFalse )
2046 {
2047 fprintf (
2048 fMakefile,
2049 "%s += $(PROJECT_RCFLAGS)\n",
2050 windresflagsMacro.c_str () );
2051
2052 fprintf (
2053 fMakefile,
2054 "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
2055 widlflagsMacro.c_str (),
2056 module.output->relative_path.c_str () );
2057
2058 fprintf (
2059 fMakefile,
2060 "%s_LFLAGS += $(PROJECT_LFLAGS) -g\n",
2061 module.name.c_str () );
2062 }
2063 else
2064 {
2065 fprintf (
2066 fMakefile,
2067 "%s_LFLAGS += $(HOST_LFLAGS)\n",
2068 module.name.c_str () );
2069 }
2070
2071 fprintf (
2072 fMakefile,
2073 "%s += $(%s)\n",
2074 linkDepsMacro.c_str (),
2075 libsMacro.c_str () );
2076
2077 string cflags = TypeSpecificCFlags();
2078 if ( cflags.size() > 0 )
2079 {
2080 fprintf ( fMakefile,
2081 "%s += %s\n\n",
2082 cflagsMacro.c_str (),
2083 cflags.c_str () );
2084 }
2085
2086 string nasmflags = TypeSpecificNasmFlags();
2087 if ( nasmflags.size () > 0 )
2088 {
2089 fprintf ( fMakefile,
2090 "%s += %s\n\n",
2091 nasmflagsMacro.c_str (),
2092 nasmflags.c_str () );
2093 }
2094
2095 string linkerflags = TypeSpecificLinkerFlags();
2096 if ( linkerflags.size() > 0 )
2097 {
2098 fprintf ( fMakefile,
2099 "%s += %s\n\n",
2100 linkerflagsMacro.c_str (),
2101 linkerflags.c_str () );
2102 }
2103
2104 if ( IsStaticLibrary ( module ) && module.isStartupLib )
2105 {
2106 fprintf ( fMakefile,
2107 "%s += -Wno-main\n\n",
2108 cflagsMacro.c_str () );
2109 }
2110
2111 fprintf ( fMakefile, "\n\n" );
2112
2113 // future references to the macros will be to get their values
2114 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
2115 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
2116 widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
2117 }
2118
2119 void
2120 MingwModuleHandler::GenerateRules ()
2121 {
2122 string targetMacro = GetTargetMacro ( module );
2123 //CLEAN_FILE ( targetMacro );
2124 CLEAN_FILE ( FileLocation ( SourceDirectory, "", targetMacro ) );
2125
2126 // generate phony target for module name
2127 fprintf ( fMakefile, ".PHONY: %s\n",
2128 module.name.c_str () );
2129 string dependencies = GetTargetMacro ( module );
2130 if ( module.type == Test )
2131 dependencies += " $(REGTESTS_RUN_TARGET)";
2132 fprintf ( fMakefile, "%s: %s\n\n",
2133 module.name.c_str (),
2134 dependencies.c_str () );
2135 if ( module.type == Test )
2136 {
2137 fprintf ( fMakefile,
2138 "\t@%s\n",
2139 targetMacro.c_str ());
2140 }
2141
2142 if ( !ReferenceObjects ( module ) )
2143 {
2144 const FileLocation* ar_target = GenerateArchiveTarget ();
2145 delete ar_target;
2146 }
2147
2148 GenerateObjectFileTargets ();
2149 }
2150
2151 void
2152 MingwModuleHandler::GetInvocationDependencies (
2153 const Module& module,
2154 string_list& dependencies )
2155 {
2156 for ( size_t i = 0; i < module.invocations.size (); i++ )
2157 {
2158 Invoke& invoke = *module.invocations[i];
2159 if ( invoke.invokeModule == &module )
2160 /* Protect against circular dependencies */
2161 continue;
2162 invoke.GetTargets ( dependencies );
2163 }
2164 }
2165
2166 void
2167 MingwModuleHandler::GenerateInvocations () const
2168 {
2169 if ( module.invocations.size () == 0 )
2170 return;
2171
2172 size_t iend = module.invocations.size ();
2173 for ( size_t i = 0; i < iend; i++ )
2174 {
2175 const Invoke& invoke = *module.invocations[i];
2176
2177 if ( invoke.invokeModule->type != BuildTool )
2178 {
2179 throw XMLInvalidBuildFileException (
2180 module.node.location,
2181 "Only modules of type buildtool can be invoked." );
2182 }
2183
2184 string invokeTarget = module.GetInvocationTarget ( i );
2185 string_list invoke_targets;
2186 assert ( invoke_targets.size() );
2187 invoke.GetTargets ( invoke_targets );
2188 fprintf ( fMakefile,
2189 ".PHONY: %s\n\n",
2190 invokeTarget.c_str () );
2191 fprintf ( fMakefile,
2192 "%s:",
2193 invokeTarget.c_str () );
2194 size_t j, jend = invoke_targets.size();
2195 for ( j = 0; j < jend; j++ )
2196 {
2197 fprintf ( fMakefile,
2198 " %s",
2199 invoke_targets[i].c_str () );
2200 }
2201 fprintf ( fMakefile, "\n\n%s", invoke_targets[0].c_str () );
2202 for ( j = 1; j < jend; j++ )
2203 fprintf ( fMakefile,
2204 " %s",
2205 invoke_targets[i].c_str () );
2206 fprintf ( fMakefile,
2207 ": %s\n",
2208 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str () );
2209 fprintf ( fMakefile, "\t$(ECHO_INVOKE)\n" );
2210 fprintf ( fMakefile,
2211 "\t%s %s\n\n",
2212 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str (),
2213 invoke.GetParameters ().c_str () );
2214 }
2215 }
2216
2217 string
2218 MingwModuleHandler::GetPreconditionDependenciesName () const
2219 {
2220 return module.name + "_precondition";
2221 }
2222
2223 void
2224 MingwModuleHandler::GetDefaultDependencies (
2225 string_list& dependencies ) const
2226 {
2227 /* Avoid circular dependency */
2228 if ( module.host == HostTrue )
2229 return;
2230
2231 if (module.name != "psdk" &&
2232 module.name != "dxsdk")
2233 {
2234 dependencies.push_back ( "$(PSDK_TARGET) $(psdk_HEADERS)" );
2235 dependencies.push_back ( "$(DXSDK_TARGET) $(dxsdk_HEADERS)" );
2236 }
2237
2238 if (module.name != "errcodes" &&
2239 module.name != "bugcodes" &&
2240 module.name != "ntstatus")
2241 {
2242 dependencies.push_back ( "$(ERRCODES_TARGET) $(ERRCODES_MCHEADERS)" );
2243 dependencies.push_back ( "$(BUGCODES_TARGET) $(BUGCODES_MCHEADERS)" );
2244 dependencies.push_back ( "$(NTSTATUS_TARGET) $(NTSTATUS_MCHEADERS)" );
2245 }
2246
2247 ///* Check if any dependent library relies on the generated headers */
2248 //for ( size_t i = 0; i < module.project.modules.size (); i++ )
2249 //{
2250 // const Module& m = *module.project.modules[i];
2251 // for ( size_t j = 0; j < m.non_if_data.compilationUnits.size (); j++ )
2252 // {
2253 // CompilationUnit& compilationUnit = *m.non_if_data.compilationUnits[j];
2254 // const FileLocation& sourceFile = compilationUnit.GetFilename ();
2255 // string extension = GetExtension ( sourceFile );
2256 // if (extension == ".mc" || extension == ".MC" )
2257 // {
2258 // string dependency = ssprintf ( "$(%s_MCHEADERS)", m.name.c_str () );
2259 // dependencies.push_back ( dependency );
2260 // }
2261 // }
2262 //}
2263 }
2264
2265 void
2266 MingwModuleHandler::GeneratePreconditionDependencies ()
2267 {
2268 string preconditionDependenciesName = GetPreconditionDependenciesName ();
2269 string_list dependencies;
2270 GetDefaultDependencies ( dependencies );
2271 GetModuleDependencies ( dependencies );
2272
2273 GetInvocationDependencies ( module, dependencies );
2274
2275 if ( dependencies.size() )
2276 {
2277 fprintf ( fMakefile,
2278 "%s =",
2279 preconditionDependenciesName.c_str () );
2280 for ( size_t i = 0; i < dependencies.size(); i++ )
2281 fprintf ( fMakefile,
2282 " %s",
2283 dependencies[i].c_str () );
2284 fprintf ( fMakefile, "\n\n" );
2285 }
2286
2287 fprintf ( fMakefile, "\n" );
2288 }
2289
2290 bool
2291 MingwModuleHandler::IsWineModule () const
2292 {
2293 if ( module.importLibrary == NULL)
2294 return false;
2295
2296 size_t index = module.importLibrary->source->name.rfind ( ".spec.def" );
2297 return ( index != string::npos );
2298 }
2299
2300 /* caller needs to delete the returned object */
2301 const FileLocation*
2302 MingwModuleHandler::GetDefinitionFilename () const
2303 {
2304 if ( module.importLibrary == NULL )
2305 return NULL;
2306
2307 DirectoryLocation directory;
2308 if ( IsWineModule () )
2309 directory = IntermediateDirectory;
2310 else
2311 directory = SourceDirectory;
2312
2313 return new FileLocation ( directory,
2314 module.importLibrary->source->relative_path,
2315 module.importLibrary->source->name );
2316 }
2317
2318 void
2319 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
2320 {
2321 if ( module.importLibrary != NULL )
2322 {
2323 const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
2324 const FileLocation *defFilename = GetDefinitionFilename ();
2325 string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
2326
2327 vector<FileLocation> deps;
2328 GetDefinitionDependencies ( deps );
2329
2330 fprintf ( fMakefile, "# IMPORT LIBRARY RULE:\n" );
2331
2332 fprintf ( fMakefile, "%s:",
2333 backend->GetFullName ( *library_target ).c_str () );
2334
2335 if ( defFilename )
2336 {
2337 fprintf ( fMakefile, " %s",
2338 backend->GetFullName ( *defFilename ).c_str () );
2339 }
2340
2341 size_t i, iend = deps.size();
2342 for ( i = 0; i < iend; i++ )
2343 fprintf ( fMakefile, " %s",
2344 backend->GetFullName ( deps[i] ).c_str () );
2345
2346 fprintf ( fMakefile, " | %s\n",
2347 backend->GetFullPath ( *library_target ).c_str () );
2348
2349 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
2350
2351 fprintf ( fMakefile,
2352 "\t${dlltool} --dllname %s --def %s --output-lib %s%s%s\n\n",
2353 module.output->name.c_str (),
2354 defFilename ? backend->GetFullName ( *defFilename ).c_str ()
2355 : empty.c_str (),
2356 backend->GetFullName ( *library_target ).c_str (),
2357 module.mangledSymbols ? "" : " --kill-at",
2358 module.underscoreSymbols ? " --add-underscore" : "" );
2359
2360 if ( defFilename )
2361 delete defFilename;
2362 delete library_target;
2363 }
2364 }
2365
2366 void
2367 MingwModuleHandler::GetSpecObjectDependencies (
2368 vector<FileLocation>& dependencies,
2369 const FileLocation *file ) const
2370 {
2371 string basename = GetBasename ( file->name );
2372
2373 FileLocation defDependency ( IntermediateDirectory,
2374 file->relative_path,
2375 basename + ".spec.def" );
2376 dependencies.push_back ( defDependency );
2377
2378 FileLocation stubsDependency ( IntermediateDirectory,
2379 file->relative_path,
2380 basename + ".stubs.c" );
2381 dependencies.push_back ( stubsDependency );
2382 }
2383
2384 void
2385 MingwModuleHandler::GetMcObjectDependencies (
2386 vector<FileLocation>& dependencies,
2387 const FileLocation *file ) const
2388 {
2389 string basename = GetBasename ( file->name );
2390
2391 FileLocation defDependency ( IntermediateDirectory,
2392 "include/reactos",
2393 basename + ".h" );
2394 dependencies.push_back ( defDependency );
2395
2396 FileLocation stubsDependency ( IntermediateDirectory,
2397 file->relative_path,
2398 basename + ".rc" );
2399 dependencies.push_back ( stubsDependency );
2400 }
2401
2402 void
2403 MingwModuleHandler::GetWidlObjectDependencies (
2404 vector<FileLocation>& dependencies,
2405 const FileLocation *file ) const
2406 {
2407 string basename = GetBasename ( file->name );
2408 const FileLocation *generatedHeaderFilename = GetRpcServerHeaderFilename ( file );
2409
2410 FileLocation serverSourceDependency ( IntermediateDirectory,
2411 file->relative_path,
2412 basename + "_s.c" );
2413 dependencies.push_back ( serverSourceDependency );
2414 dependencies.push_back ( *generatedHeaderFilename );
2415
2416 delete generatedHeaderFilename;
2417 }
2418
2419 void
2420 MingwModuleHandler::GetDefinitionDependencies (
2421 vector<FileLocation>& dependencies ) const
2422 {
2423 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2424 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2425 {
2426 const CompilationUnit& compilationUnit = *compilationUnits[i];
2427 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2428 string extension = GetExtension ( sourceFile );
2429 if ( extension == ".spec" || extension == ".SPEC" )
2430 GetSpecObjectDependencies ( dependencies, &sourceFile );
2431 if ( extension == ".idl" || extension == ".IDL" )
2432 {
2433 if ( ( module.type == RpcServer ) || ( module.type == RpcClient ) || ( module.type == RpcProxy ) )
2434 GetWidlObjectDependencies ( dependencies, &sourceFile );
2435 }
2436 }
2437 }
2438
2439 enum DebugSupportType
2440 {
2441 DebugKernelMode,
2442 DebugUserMode
2443 };
2444
2445 static void
2446 MingwAddDebugSupportLibraries ( Module& module, DebugSupportType type )
2447 {
2448 Library* pLibrary;
2449
2450 switch(type)
2451 {
2452 case DebugKernelMode:
2453 pLibrary = new Library ( module, "debugsup_ntoskrnl" );
2454 break;
2455
2456 case DebugUserMode:
2457 pLibrary = new Library ( module, "debugsup_ntdll" );
2458 break;
2459
2460 default:
2461 assert(0);
2462 }
2463
2464 module.non_if_data.libraries.push_back(pLibrary);
2465 }
2466
2467 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler ( const Module& module_ )
2468 : MingwModuleHandler ( module_ )
2469 {
2470 }
2471
2472 void
2473 MingwBuildToolModuleHandler::Process ()
2474 {
2475 GenerateBuildToolModuleTarget ();
2476 }
2477
2478 void
2479 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
2480 {
2481 string targetMacro ( GetTargetMacro (module) );
2482 string objectsMacro = GetObjectsMacro ( module );
2483 string linkDepsMacro = GetLinkingDependenciesMacro ();
2484 string libsMacro = GetLibsMacro ();
2485
2486 GenerateRules ();
2487
2488 string linker;
2489 if ( module.cplusplus )
2490 linker = "${host_gpp}";
2491 else
2492 linker = "${host_gcc}";
2493
2494 const FileLocation *target_file = GetTargetFilename ( module, NULL );
2495 fprintf ( fMakefile, "%s: %s %s | %s\n",
2496 targetMacro.c_str (),
2497 objectsMacro.c_str (),
2498 linkDepsMacro.c_str (),
2499 backend->GetFullPath ( *target_file ).c_str () );
2500 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2501 fprintf ( fMakefile,
2502 "\t%s %s -o $@ %s %s\n\n",
2503 linker.c_str (),
2504 GetLinkerMacro ().c_str (),
2505 objectsMacro.c_str (),
2506 libsMacro.c_str () );
2507
2508 delete target_file;
2509 }
2510
2511
2512 MingwKernelModuleHandler::MingwKernelModuleHandler (
2513 const Module& module_ )
2514
2515 : MingwModuleHandler ( module_ )
2516 {
2517 }
2518
2519 void
2520 MingwKernelModuleHandler::Process ()
2521 {
2522 GenerateKernelModuleTarget ();
2523 }
2524
2525 void
2526 MingwKernelModuleHandler::GenerateKernelModuleTarget ()
2527 {
2528 string targetMacro ( GetTargetMacro ( module ) );
2529 string workingDirectory = GetWorkingDirectory ( );
2530 string linkDepsMacro = GetLinkingDependenciesMacro ();
2531
2532 GenerateImportLibraryTargetIfNeeded ();
2533
2534 if ( module.non_if_data.compilationUnits.size () > 0 )
2535 {
2536 GenerateRules ();
2537
2538 string dependencies = linkDepsMacro + " " + objectsMacro;
2539
2540 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s",
2541 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2542 module.baseaddress.c_str () );
2543
2544 GenerateLinkerCommand ( dependencies,
2545 linkerParameters + " $(NTOSKRNL_SHARED)",
2546 " -sections" );
2547 }
2548 else
2549 {
2550 GeneratePhonyTarget();
2551 }
2552 }
2553
2554
2555 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler (
2556 const Module& module_ )
2557
2558 : MingwModuleHandler ( module_ )
2559 {
2560 }
2561
2562 void
2563 MingwStaticLibraryModuleHandler::Process ()
2564 {
2565 GenerateStaticLibraryModuleTarget ();
2566 }
2567
2568 void
2569 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ()
2570 {
2571 GenerateRules ();
2572 }
2573
2574
2575 MingwHostStaticLibraryModuleHandler::MingwHostStaticLibraryModuleHandler (
2576 const Module& module_ )
2577
2578 : MingwModuleHandler ( module_ )
2579 {
2580 }
2581
2582 void
2583 MingwHostStaticLibraryModuleHandler::Process ()
2584 {
2585 GenerateHostStaticLibraryModuleTarget ();
2586 }
2587
2588 void
2589 MingwHostStaticLibraryModuleHandler::GenerateHostStaticLibraryModuleTarget ()
2590 {
2591 GenerateRules ();
2592 }
2593
2594
2595 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler (
2596 const Module& module_ )
2597
2598 : MingwModuleHandler ( module_ )
2599 {
2600 }
2601
2602 void
2603 MingwObjectLibraryModuleHandler::Process ()
2604 {
2605 GenerateObjectLibraryModuleTarget ();
2606 }
2607
2608 void
2609 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ()
2610 {
2611 GenerateRules ();
2612 }
2613
2614
2615 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
2616 const Module& module_ )
2617
2618 : MingwModuleHandler ( module_ )
2619 {
2620 }
2621
2622 MingwEmbeddedTypeLibModuleHandler::MingwEmbeddedTypeLibModuleHandler (
2623 const Module& module_ )
2624
2625 : MingwModuleHandler ( module_ )
2626 {
2627 }
2628
2629 void
2630 MingwEmbeddedTypeLibModuleHandler::Process ()
2631 {
2632 GenerateRules ();
2633 }
2634
2635
2636 void
2637 MingwKernelModeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2638 {
2639 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2640 }
2641
2642 void
2643 MingwKernelModeDLLModuleHandler::Process ()
2644 {
2645 GenerateKernelModeDLLModuleTarget ();
2646 }
2647
2648 void
2649 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
2650 {
2651 string targetMacro ( GetTargetMacro ( module ) );
2652 string workingDirectory = GetWorkingDirectory ( );
2653 string linkDepsMacro = GetLinkingDependenciesMacro ();
2654
2655 GenerateImportLibraryTargetIfNeeded ();
2656
2657 if ( module.non_if_data.compilationUnits.size () > 0 )
2658 {
2659 GenerateRules ();
2660
2661 string dependencies = linkDepsMacro + " " + objectsMacro;
2662
2663 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2664 module.GetEntryPoint(true).c_str (),
2665 module.baseaddress.c_str () );
2666 GenerateLinkerCommand ( dependencies,
2667 linkerParameters,
2668 " -sections" );
2669 }
2670 else
2671 {
2672 GeneratePhonyTarget();
2673 }
2674 }
2675
2676
2677 MingwKernelModeDriverModuleHandler::MingwKernelModeDriverModuleHandler (
2678 const Module& module_ )
2679
2680 : MingwModuleHandler ( module_ )
2681 {
2682 }
2683
2684 void
2685 MingwKernelModeDriverModuleHandler::AddImplicitLibraries ( Module& module )
2686 {
2687 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2688 }
2689
2690 void
2691 MingwKernelModeDriverModuleHandler::Process ()
2692 {
2693 GenerateKernelModeDriverModuleTarget ();
2694 }
2695
2696
2697 void
2698 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ()
2699 {
2700 string targetMacro ( GetTargetMacro (module) );
2701 string workingDirectory = GetWorkingDirectory ();
2702 string linkDepsMacro = GetLinkingDependenciesMacro ();
2703
2704 GenerateImportLibraryTargetIfNeeded ();
2705
2706 if ( module.non_if_data.compilationUnits.size () > 0 )
2707 {
2708 GenerateRules ();
2709
2710 string dependencies = linkDepsMacro + " " + objectsMacro;
2711
2712 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2713 module.GetEntryPoint(true).c_str (),
2714 module.baseaddress.c_str () );
2715 GenerateLinkerCommand ( dependencies,
2716 linkerParameters,
2717 " -sections" );
2718 }
2719 else
2720 {
2721 GeneratePhonyTarget();
2722 }
2723 }
2724
2725
2726 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler (
2727 const Module& module_ )
2728
2729 : MingwModuleHandler ( module_ )
2730 {
2731 }
2732
2733 void
2734 MingwNativeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2735 {
2736 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2737 }
2738
2739 void
2740 MingwNativeDLLModuleHandler::Process ()
2741 {
2742 GenerateNativeDLLModuleTarget ();
2743 }
2744
2745 void
2746 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
2747 {
2748 string targetMacro ( GetTargetMacro (module) );
2749 string workingDirectory = GetWorkingDirectory ( );
2750 string linkDepsMacro = GetLinkingDependenciesMacro ();
2751
2752 GenerateImportLibraryTargetIfNeeded ();
2753
2754 if ( module.non_if_data.compilationUnits.size () > 0 )
2755 {
2756 GenerateRules ();
2757
2758 string dependencies = linkDepsMacro + " " + objectsMacro;
2759
2760 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2761 module.GetEntryPoint(true).c_str (),
2762 module.baseaddress.c_str () );
2763 GenerateLinkerCommand ( dependencies,
2764 linkerParameters,
2765 "" );
2766 }
2767 else
2768 {
2769 GeneratePhonyTarget();
2770 }
2771 }
2772
2773
2774 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler (
2775 const Module& module_ )
2776
2777 : MingwModuleHandler ( module_ )
2778 {
2779 }
2780
2781 void
2782 MingwNativeCUIModuleHandler::AddImplicitLibraries ( Module& module )
2783 {
2784 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2785 }
2786
2787 void
2788 MingwNativeCUIModuleHandler::Process ()
2789 {
2790 GenerateNativeCUIModuleTarget ();
2791 }
2792
2793 void
2794 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
2795 {
2796 string targetMacro ( GetTargetMacro (module) );
2797 string workingDirectory = GetWorkingDirectory ( );
2798 string linkDepsMacro = GetLinkingDependenciesMacro ();
2799
2800 GenerateImportLibraryTargetIfNeeded ();
2801
2802 if ( module.non_if_data.compilationUnits.size () > 0 )
2803 {
2804 GenerateRules ();
2805
2806 string dependencies = linkDepsMacro + " " + objectsMacro;
2807
2808 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
2809 module.GetEntryPoint(true).c_str (),
2810 module.baseaddress.c_str () );
2811 GenerateLinkerCommand ( dependencies,
2812 linkerParameters,
2813 "" );
2814 }
2815 else
2816 {
2817 GeneratePhonyTarget();
2818 }
2819 }
2820
2821
2822 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler (
2823 const Module& module_ )
2824
2825 : MingwModuleHandler ( module_ )
2826 {
2827 }
2828
2829 MingwWin32OCXModuleHandler::MingwWin32OCXModuleHandler (
2830 const Module& module_ )
2831
2832 : MingwModuleHandler ( module_ )
2833 {
2834 }
2835
2836 static bool
2837 LinksToCrt( Module &module )
2838 {
2839 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
2840 {
2841 Library& library = *module.non_if_data.libraries[i];
2842 if ( library.name == "libcntpr" || library.name == "crt" )
2843 return true;
2844 }
2845 return false;
2846 }
2847
2848 static void
2849 MingwAddImplicitLibraries( Module &module )
2850 {
2851 Library* pLibrary;
2852 bool links_to_crt;
2853
2854 if ( module.type != Win32DLL
2855 && module.type != Win32OCX
2856 && module.type != Win32CUI
2857 && module.type != Win32GUI
2858 && module.type != Win32SCR)
2859 {
2860 // no implicit libraries
2861 return;
2862 }
2863
2864 links_to_crt = LinksToCrt ( module );
2865
2866 if ( !module.isDefaultEntryPoint )
2867 {
2868 if ( module.GetEntryPoint(false) == "0" )
2869 {
2870 if ( !links_to_crt )
2871 {
2872 pLibrary = new Library ( module, "mingw_common" );
2873 module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin() , pLibrary );
2874
2875 pLibrary = new Library ( module, "msvcrt" );
2876 module.non_if_data.libraries.push_back ( pLibrary );
2877 links_to_crt = true;
2878 }
2879 }
2880 return;
2881 }
2882
2883 if ( module.IsDLL () )
2884 {
2885 //pLibrary = new Library ( module, "__mingw_dllmain" );
2886 //module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
2887 }
2888 else
2889 {
2890 pLibrary = new Library ( module, module.isUnicode ? "mingw_wmain" : "mingw_main" );
2891 module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
2892 }
2893
2894 pLibrary = new Library ( module, "mingw_common" );
2895 module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin() + 1, pLibrary );
2896
2897 if ( !links_to_crt )
2898 {
2899 // always link in msvcrt to get the basic routines
2900 pLibrary = new Library ( module, "msvcrt" );
2901 module.non_if_data.libraries.push_back ( pLibrary );
2902 }
2903 }
2904
2905 void
2906 MingwWin32DLLModuleHandler::AddImplicitLibraries ( Module& module )
2907 {
2908 MingwAddImplicitLibraries ( module );
2909 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2910 }
2911
2912 void
2913 MingwWin32DLLModuleHandler::Process ()
2914 {
2915 GenerateWin32DLLModuleTarget ();
2916 }
2917
2918 void
2919 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
2920 {
2921 string targetMacro ( GetTargetMacro (module) );
2922 string workingDirectory = GetWorkingDirectory ( );
2923 string linkDepsMacro = GetLinkingDependenciesMacro ();
2924
2925 GenerateImportLibraryTargetIfNeeded ();
2926
2927 if ( module.non_if_data.compilationUnits.size () > 0 )
2928 {
2929 GenerateRules ();
2930
2931 string dependencies = linkDepsMacro + " " + objectsMacro;
2932
2933 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2934 module.GetEntryPoint(true).c_str (),
2935 module.baseaddress.c_str () );
2936 GenerateLinkerCommand ( dependencies,
2937 linkerParameters,
2938 "" );
2939 }
2940 else
2941 {
2942 GeneratePhonyTarget();
2943 }
2944 }
2945
2946
2947 void
2948 MingwWin32OCXModuleHandler::AddImplicitLibraries ( Module& module )
2949 {
2950 MingwAddImplicitLibraries ( module );
2951 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2952 }
2953
2954 void
2955 MingwWin32OCXModuleHandler::Process ()
2956 {
2957 GenerateWin32OCXModuleTarget ();
2958 }
2959
2960 void
2961 MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget ()
2962 {
2963 string targetMacro ( GetTargetMacro (module) );
2964 string workingDirectory = GetWorkingDirectory ( );
2965 string linkDepsMacro = GetLinkingDependenciesMacro ();
2966
2967 GenerateImportLibraryTargetIfNeeded ();
2968
2969 if ( module.non_if_data.compilationUnits.size () > 0 )
2970 {
2971 GenerateRules ();
2972
2973 string dependencies = linkDepsMacro + " " + objectsMacro;
2974
2975 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2976 module.GetEntryPoint(true).c_str (),
2977 module.baseaddress.c_str () );
2978 GenerateLinkerCommand ( dependencies,
2979 linkerParameters,
2980 "" );
2981 }
2982 else
2983 {
2984 GeneratePhonyTarget();
2985 }
2986 }
2987
2988
2989 MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler (
2990 const Module& module_ )
2991
2992 : MingwModuleHandler ( module_ )
2993 {
2994 }
2995
2996 void
2997 MingwWin32CUIModuleHandler::AddImplicitLibraries ( Module& module )
2998 {
2999 MingwAddImplicitLibraries ( module );
3000 MingwAddDebugSupportLibraries ( module, DebugUserMode );
3001 }
3002
3003 void
3004 MingwWin32CUIModuleHandler::Process ()
3005 {
3006 GenerateWin32CUIModuleTarget ();
3007 }
3008
3009 void
3010 MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ()
3011 {
3012 string targetMacro ( GetTargetMacro (module) );
3013 string workingDirectory = GetWorkingDirectory ( );
3014 string linkDepsMacro = GetLinkingDependenciesMacro ();
3015
3016 GenerateImportLibraryTargetIfNeeded ();
3017
3018 if ( module.non_if_data.compilationUnits.size () > 0 )
3019 {
3020 GenerateRules ();
3021
3022 string dependencies = linkDepsMacro + " " + objectsMacro;
3023
3024 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
3025 module.GetEntryPoint(true).c_str (),
3026 module.baseaddress.c_str () );
3027 GenerateLinkerCommand ( dependencies,
3028 linkerParameters,
3029 "" );
3030 }
3031 else
3032 {
3033 GeneratePhonyTarget();
3034 }
3035 }
3036
3037
3038 MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler (
3039 const Module& module_ )
3040
3041 : MingwModuleHandler ( module_ )
3042 {
3043 }
3044
3045 void
3046 MingwWin32GUIModuleHandler::AddImplicitLibraries ( Module& module )
3047 {
3048 MingwAddImplicitLibraries ( module );
3049 MingwAddDebugSupportLibraries ( module, DebugUserMode );
3050 }
3051
3052 void
3053 MingwWin32GUIModuleHandler::Process ()
3054 {
3055 GenerateWin32GUIModuleTarget ();
3056 }
3057
3058 void
3059 MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ()
3060 {
3061 string targetMacro ( GetTargetMacro (module) );
3062 string workingDirectory = GetWorkingDirectory ( );
3063 string linkDepsMacro = GetLinkingDependenciesMacro ();
3064
3065 GenerateImportLibraryTargetIfNeeded ();
3066
3067 if ( module.non_if_data.compilationUnits.size () > 0 )
3068 {
3069 GenerateRules ();
3070
3071 string dependencies = linkDepsMacro + " " + objectsMacro;
3072
3073 string linkerParameters = ssprintf ( "-subsystem=windows -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
3074 module.GetEntryPoint(true).c_str (),
3075 module.baseaddress.c_str () );
3076 GenerateLinkerCommand ( dependencies,
3077 linkerParameters,
3078 "" );
3079 }
3080 else
3081 {
3082 GeneratePhonyTarget();
3083 }
3084 }
3085
3086
3087 MingwBootLoaderModuleHandler::MingwBootLoaderModuleHandler (
3088 const Module& module_ )
3089
3090 : MingwModuleHandler ( module_ )
3091 {
3092 }
3093
3094 void
3095 MingwBootLoaderModuleHandler::Process ()
3096 {
3097 GenerateBootLoaderModuleTarget ();
3098 }
3099
3100 void
3101 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
3102 {
3103 string targetName ( module.output->name );
3104 string targetMacro ( GetTargetMacro (module) );
3105 string workingDirectory = GetWorkingDirectory ();
3106 FileLocation junk_tmp ( TemporaryDirectory,
3107 "",
3108 module.name + ".junk.tmp" );
3109 CLEAN_FILE ( junk_tmp );
3110 string objectsMacro = GetObjectsMacro ( module );
3111 string linkDepsMacro = GetLinkingDependenciesMacro ();
3112 string libsMacro = GetLibsMacro ();
3113
3114 GenerateRules ();
3115
3116 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3117 fprintf ( fMakefile, "%s: %s %s | %s\n",
3118 targetMacro.c_str (),
3119 objectsMacro.c_str (),
3120 linkDepsMacro.c_str (),
3121 backend->GetFullPath ( *target_file ).c_str () );
3122
3123 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
3124
3125 if (Environment::GetArch() == "arm")
3126 {
3127 fprintf ( fMakefile,
3128 "\t${gcc} -Wl,--subsystem,native -Wl,--section-start,startup=0x8000 -o %s %s %s %s\n",
3129 backend->GetFullName ( junk_tmp ).c_str (),
3130 objectsMacro.c_str (),
3131 linkDepsMacro.c_str (),
3132 GetLinkerMacro ().c_str ());
3133 }
3134 else
3135 {
3136 fprintf ( fMakefile,
3137 "\t${gcc} -Wl,--subsystem,native -Wl,-Ttext,0x8000 -o %s %s %s %s\n",
3138 backend->GetFullName ( junk_tmp ).c_str (),
3139 objectsMacro.c_str (),
3140 linkDepsMacro.c_str (),
3141 GetLinkerMacro ().c_str ());
3142 }
3143 fprintf ( fMakefile,
3144 "\t${objcopy} -O binary %s $@\n",
3145 backend->GetFullName ( junk_tmp ).c_str () );
3146 GenerateBuildMapCode ( &junk_tmp );
3147 fprintf ( fMakefile,
3148 "\t-@${rm} %s 2>$(NUL)\n",
3149 backend->GetFullName ( junk_tmp ).c_str () );
3150
3151 delete target_file;
3152 }
3153
3154
3155 MingwBootSectorModuleHandler::MingwBootSectorModuleHandler (
3156 const Module& module_ )
3157
3158 : MingwModuleHandler ( module_ )
3159 {
3160 }
3161
3162 void
3163 MingwBootSectorModuleHandler::Process ()
3164 {
3165 GenerateBootSectorModuleTarget ();
3166 }
3167
3168 void
3169 MingwBootSectorModuleHandler::GenerateBootSectorModuleTarget ()
3170 {
3171 string objectsMacro = GetObjectsMacro ( module );
3172
3173 GenerateRules ();
3174
3175 fprintf ( fMakefile, ".PHONY: %s\n\n",
3176 module.name.c_str ());
3177 fprintf ( fMakefile,
3178 "%s: %s\n",
3179 module.name.c_str (),
3180 objectsMacro.c_str () );
3181 }
3182
3183
3184 MingwBootProgramModuleHandler::MingwBootProgramModuleHandler (
3185 const Module& module_ )
3186 : MingwModuleHandler ( module_ )
3187 {
3188 }
3189
3190 void
3191 MingwBootProgramModuleHandler::Process ()
3192 {
3193 GenerateBootProgramModuleTarget ();
3194 }
3195
3196 void
3197 MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
3198 {
3199 string targetName ( module.output->name );
3200 string targetMacro ( GetTargetMacro (module) );
3201 string workingDirectory = GetWorkingDirectory ();
3202 FileLocation junk_tmp ( TemporaryDirectory,
3203 "",
3204 module.name + ".junk.tmp" );
3205 FileLocation junk_elf ( TemporaryDirectory,
3206 "",
3207 module.name + ".junk.elf" );
3208 FileLocation junk_cpy ( TemporaryDirectory,
3209 "",
3210 module.name + ".junk.elf" );
3211 CLEAN_FILE ( junk_tmp );
3212 CLEAN_FILE ( junk_elf );
3213 CLEAN_FILE ( junk_cpy );
3214 string objectsMacro = GetObjectsMacro ( module );
3215 string linkDepsMacro = GetLinkingDependenciesMacro ();
3216 string libsMacro = GetLibsMacro ();
3217 const Module *payload = module.project.LocateModule ( module.payload );
3218
3219 GenerateRules ();
3220
3221 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3222 fprintf ( fMakefile, "%s: %s %s %s | %s\n",
3223 targetMacro.c_str (),
3224 objectsMacro.c_str (),
3225 linkDepsMacro.c_str (),
3226 payload->name.c_str (),
3227 backend->GetFullPath ( *target_file ).c_str () );
3228
3229 fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
3230
3231 fprintf ( fMakefile, "\t$(%s_PREPARE) $(OUTPUT)$(SEP)%s %s\n",
3232 module.buildtype.c_str (),
3233 NormalizeFilename( backend->GetFullName ( *payload->output ) ).c_str (),
3234 backend->GetFullName ( junk_cpy ).c_str () );
3235
3236 fprintf ( fMakefile, "\t${objcopy} $(%s_FLATFORMAT) %s %s\n",
3237 module.buildtype.c_str (),
3238 backend->GetFullName ( junk_cpy ).c_str (),
3239 backend->GetFullName ( junk_tmp ).c_str () );
3240
3241 fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -g -o %s\n",
3242 module.buildtype.c_str (),
3243 linkDepsMacro.c_str (),
3244 backend->GetFullName ( junk_tmp ).c_str (),
3245 backend->GetFullName ( junk_elf ).c_str () );
3246
3247 fprintf ( fMakefile, "\t${objcopy} $(%s_COPYFORMAT) %s $(INTERMEDIATE)$(SEP)%s\n",
3248 module.buildtype.c_str (),
3249 backend->GetFullName ( junk_elf ).c_str (),
3250 backend->GetFullName ( *module.output ) .c_str () );
3251
3252 fprintf ( fMakefile,
3253 "\t-@${rm} %s %s %s 2>$(NUL)\n",
3254 backend->GetFullName ( junk_tmp ).c_str (),
3255 backend->GetFullName ( junk_elf ).c_str (),
3256 backend->GetFullName ( junk_cpy ).c_str () );
3257
3258 delete target_file;
3259 }
3260
3261
3262 MingwIsoModuleHandler::MingwIsoModuleHandler (
3263 const Module& module_ )
3264
3265 : MingwModuleHandler ( module_ )
3266 {
3267 }
3268
3269 void
3270 MingwIsoModuleHandler::Process ()
3271 {
3272 GenerateIsoModuleTarget ();
3273 }
3274
3275 void
3276 MingwIsoModuleHandler::OutputBootstrapfileCopyCommands (
3277 const string& bootcdDirectory )
3278 {
3279 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3280 {
3281 const Module& m = *module.project.modules[i];
3282 if ( !m.enabled )
3283 continue;
3284 if ( m.bootstrap != NULL )
3285 {
3286 FileLocation targetFile ( OutputDirectory,
3287 m.bootstrap->base.length () > 0
3288 ? bootcdDirectory + sSep + m.bootstrap->base
3289 : bootcdDirectory,
3290 m.bootstrap->nameoncd );
3291 OutputCopyCommand ( *m.output, targetFile );
3292 }
3293 }
3294 }
3295
3296 void
3297 MingwIsoModuleHandler::OutputCdfileCopyCommands (
3298 const string& bootcdDirectory )
3299 {
3300 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3301 {
3302 const CDFile& cdfile = *module.project.cdfiles[i];
3303 FileLocation targetFile ( OutputDirectory,
3304 cdfile.target->relative_path.length () > 0
3305 ? bootcdDirectory + sSep + cdfile.target->relative_path
3306 : bootcdDirectory,
3307 cdfile.target->name );
3308 OutputCopyCommand ( *cdfile.source, targetFile );
3309 }
3310 }
3311
3312 void
3313 MingwIsoModuleHandler::GetBootstrapCdDirectories ( vector<FileLocation>& out,
3314 const string& bootcdDirectory )
3315 {
3316 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3317 {
3318 const Module& m = *module.project.modules[i];
3319 if ( !m.enabled )
3320 continue;
3321 if ( m.bootstrap != NULL )
3322 {
3323 FileLocation targetDirectory ( OutputDirectory,
3324 m.bootstrap->base.length () > 0
3325 ? bootcdDirectory + sSep + m.bootstrap->base
3326 : bootcdDirectory,
3327 "" );
3328 out.push_back ( targetDirectory );
3329 }
3330 }
3331 }
3332
3333 void
3334 MingwIsoModuleHandler::GetNonModuleCdDirectories ( vector<FileLocation>& out,
3335 const string& bootcdDirectory )
3336 {
3337 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3338 {
3339 const CDFile& cdfile = *module.project.cdfiles[i];
3340 FileLocation targetDirectory ( OutputDirectory,
3341 cdfile.target->relative_path.length () > 0
3342 ? bootcdDirectory + sSep + cdfile.target->relative_path
3343 : bootcdDirectory,
3344 "" );
3345 out.push_back( targetDirectory );
3346 }
3347 }
3348
3349 void
3350 MingwIsoModuleHandler::GetCdDirectories ( vector<FileLocation>& out,
3351 const string& bootcdDirectory )
3352 {
3353 GetBootstrapCdDirectories ( out, bootcdDirectory );
3354 GetNonModuleCdDirectories ( out, bootcdDirectory );
3355 }
3356
3357 void
3358 MingwIsoModuleHandler::GetBootstrapCdFiles (
3359 vector<FileLocation>& out ) const
3360 {
3361 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3362 {
3363 const Module& m = *module.project.modules[i];
3364 if ( !m.enabled )
3365 continue;
3366 if ( m.bootstrap != NULL )
3367 {
3368 out.push_back ( *m.output );
3369 }
3370 }
3371 }
3372
3373 void
3374 MingwIsoModuleHandler::GetNonModuleCdFiles (
3375 vector<FileLocation>& out ) const
3376 {
3377 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3378 {
3379 const CDFile& cdfile = *module.project.cdfiles[i];
3380 out.push_back ( *cdfile.source );
3381 }
3382 }
3383
3384 void
3385 MingwIsoModuleHandler::GetCdFiles (
3386 vector<FileLocation>& out ) const
3387 {
3388 GetBootstrapCdFiles ( out );
3389 GetNonModuleCdFiles ( out );
3390 }
3391
3392 void
3393 MingwIsoModuleHandler::GenerateIsoModuleTarget ()
3394 {
3395 string bootcdDirectory = "cd";
3396 FileLocation bootcd ( OutputDirectory,
3397 bootcdDirectory,
3398 "" );
3399 FileLocation bootcdReactos ( OutputDirectory,
3400 bootcdDirectory + sSep + Environment::GetCdOutputPath (),
3401 "" );
3402 vector<FileLocation> vSourceFiles, vCdFiles;
3403 vector<FileLocation> vCdDirectories;
3404
3405 // unattend.inf
3406 FileLocation srcunattend ( SourceDirectory,
3407 "boot" + sSep + "bootdata" + sSep + "bootcdregtest",
3408 "unattend.inf" );
3409 FileLocation tarunattend ( bootcdReactos.directory,
3410 bootcdReactos.relative_path,
3411 "unattend.inf" );
3412 if (module.type == IsoRegTest)
3413 vSourceFiles.push_back ( srcunattend );
3414
3415 // bootsector
3416 const Module* bootModule = module.bootSector->bootSectorModule;
3417
3418 if (!bootModule)
3419 {
3420 throw InvalidOperationException ( module.node.location.c_str(),
3421 0,
3422 "Invalid bootsector. module '%s' requires <bootsector>",
3423 module.name.c_str ());
3424 }
3425
3426 const FileLocation *isoboot = bootModule->output;
3427 vSourceFiles.push_back ( *isoboot );
3428
3429 // prepare reactos.dff and reactos.inf
3430 FileLocation reactosDff ( SourceDirectory,
3431 "boot" + sSep + "bootdata" + sSep + "packages",
3432 "reactos.dff" );
3433 FileLocation reactosInf ( bootcdReactos.directory,
3434 bootcdReactos.relative_path,
3435 "reactos.inf" );
3436
3437 vSourceFiles.push_back ( reactosDff );
3438
3439 /*
3440 We use only the name and not full FileLocation(ouput) because Iso/LiveIso are an exception to the general rule.
3441 Iso/LiveIso outputs are generated in code base root
3442 */
3443 string IsoName = module.output->name;
3444
3445 string sourceFiles = v2s ( backend, vSourceFiles, 5 );
3446
3447 // fill cdrom
3448 GetCdDirectories ( vCdDirectories, bootcdDirectory );
3449 GetCdFiles ( vCdFiles );
3450 string cdDirectories = "";//v2s ( vCdDirectories, 5 );
3451 string cdFiles = v2s ( backend, vCdFiles, 5 );
3452
3453 fprintf ( fMakefile, ".PHONY: %s\n\n",
3454 module.name.c_str ());
3455 fprintf ( fMakefile,
3456 "%s: all %s %s %s $(CABMAN_TARGET) $(CDMAKE_TARGET) %s\n",
3457 module.name.c_str (),
3458 backend->GetFullName ( *isoboot ).c_str (),
3459 sourceFiles.c_str (),
3460 cdFiles.c_str (),
3461 cdDirectories.c_str () );
3462 fprintf ( fMakefile,
3463 "\t$(Q)$(CABMAN_TARGET) -C %s -L %s -I -P $(OUTPUT)\n",
3464 backend->GetFullName ( reactosDff ).c_str (),
3465 backend->GetFullPath ( bootcdReactos ).c_str () );
3466 fprintf ( fMakefile,
3467 "\t$(Q)$(CABMAN_TARGET) -C %s -RC %s -L %s -N -P $(OUTPUT)\n",
3468 backend->GetFullName ( reactosDff ).c_str (),
3469 backend->GetFullName ( reactosInf ).c_str (),
3470 backend->GetFullPath ( bootcdReactos ).c_str ());
3471 fprintf ( fMakefile,
3472 "\t-@${rm} %s 2>$(NUL)\n",
3473 backend->GetFullName ( reactosInf ).c_str () );
3474 OutputBootstrapfileCopyCommands ( bootcdDirectory );
3475 OutputCdfileCopyCommands ( bootcdDirectory );
3476
3477 if (module.type == IsoRegTest)
3478 OutputCopyCommand ( srcunattend, tarunattend );
3479
3480 fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
3481 fprintf ( fMakefile,
3482 "\t$(Q)$(CDMAKE_TARGET) -v -j -m -b %s %s REACTOS %s\n",
3483 backend->GetFullName ( *isoboot ).c_str (),
3484 backend->GetFullPath ( bootcd ).c_str (),
3485 IsoName.c_str() );
3486 fprintf ( fMakefile,
3487 "\n" );
3488 }
3489
3490
3491 MingwLiveIsoModuleHandler::MingwLiveIsoModuleHandler (
3492 const Module& module_ )
3493
3494 : MingwModuleHandler ( module_ )
3495 {
3496 }
3497
3498 void
3499 MingwLiveIsoModuleHandler::Process ()
3500 {
3501 GenerateLiveIsoModuleTarget ();
3502 }
3503
3504 void
3505 MingwLiveIsoModuleHandler::CreateDirectory ( const string& directory )
3506 {
3507 FileLocation dir ( OutputDirectory,
3508 directory,
3509 "" );
3510 MingwModuleHandler::PassThruCacheDirectory ( &dir );
3511 }
3512
3513 void
3514 MingwLiveIsoModuleHandler::OutputModuleCopyCommands ( string& livecdDirectory,
3515 string& reactosDirectory )
3516 {
3517 for ( size_t i = 0; i < module.project.modules.size (); i++ )
3518 {
3519 const Module& m = *module.project.modules[i];
3520 if ( !m.enabled )
3521 continue;
3522 if ( m.install )
3523 {
3524 const Module& aliasedModule = backend->GetAliasedModuleOrModule ( m );
3525 FileLocation destination ( OutputDirectory,
3526 m.install->relative_path.length () > 0
3527 ? livecdDirectory + sSep + reactosDirectory + sSep + m.install->relative_path
3528 : livecdDirectory + sSep + reactosDirectory,
3529 m.install->name );
3530 OutputCopyCommand ( *aliasedModule.output,
3531 destination);
3532 }
3533 }
3534 }
3535
3536 void
3537 MingwLiveIsoModuleHandler::OutputNonModuleCopyCommands ( string& livecdDirectory,
3538 string& reactosDirectory )
3539 {
3540 for ( size_t i = 0; i < module.project.installfiles.size (); i++ )
3541 {
3542 const InstallFile& installfile = *module.project.installfiles[i];
3543 FileLocation target ( OutputDirectory,
3544 installfile.target->relative_path.length () > 0
3545 ? livecdDirectory + sSep + reactosDirectory + sSep + installfile.target->relative_path
3546 : livecdDirectory + sSep + reactosDirectory,
3547 installfile.target->name );
3548 OutputCopyCommand ( *installfile.source, target );
3549 }
3550 }
3551
3552 void
3553 MingwLiveIsoModuleHandler::OutputProfilesDirectoryCommands ( string& livecdDirectory )
3554 {
3555 CreateDirectory ( livecdDirectory + sSep + "Profiles" );
3556 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "All Users") ;
3557 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "All Users" + sSep + "Desktop" );
3558 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" );
3559 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" + sSep + "Desktop" );
3560 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" + sSep + "My Documents" );
3561
3562 FileLocation livecdIni ( SourceDirectory,
3563 "boot" + sSep + "bootdata",
3564 "livecd.ini" );
3565 FileLocation destination ( OutputDirectory,
3566 livecdDirectory,
3567 "freeldr.ini" );
3568 OutputCopyCommand ( livecdIni,
3569 destination );
3570 }
3571
3572 void
3573 MingwLiveIsoModuleHandler::OutputLoaderCommands ( string& livecdDirectory )
3574 {
3575 FileLocation freeldr ( OutputDirectory,
3576 "boot" + sSep + "freeldr" + sSep + "freeldr",
3577 "freeldr.sys" );
3578 FileLocation destination ( OutputDirectory,
3579 livecdDirectory + sSep + "loader",
3580 "setupldr.sys" );
3581 OutputCopyCommand ( freeldr,
3582 destination );
3583 }
3584
3585 void
3586 MingwLiveIsoModuleHandler::OutputRegistryCommands ( string& livecdDirectory )
3587 {
3588 FileLocation reactosSystem32ConfigDirectory ( OutputDirectory,
3589 livecdDirectory + sSep + "reactos" + sSep + "system32" + sSep + "config",
3590 "" );
3591 fprintf ( fMakefile,
3592 "\t$(ECHO_MKHIVE)\n" );
3593 fprintf ( fMakefile,
3594 "\t$(MKHIVE_TARGET) boot%cbootdata %s boot%cbootdata%clivecd.inf boot%cbootdata%chiveinst.inf\n",
3595 cSep, backend->GetFullPath ( reactosSystem32ConfigDirectory ).c_str (),
3596 cSep, cSep, cSep, cSep );
3597 }
3598
3599 void
3600 MingwLiveIsoModuleHandler::GenerateLiveIsoModuleTarget ()
3601 {
3602 string livecdDirectory = module.name;
3603 FileLocation livecd ( OutputDirectory, livecdDirectory, "" );
3604
3605 string IsoName;
3606
3607 // bootsector
3608 const Module* bootModule = module.bootSector->bootSectorModule;
3609
3610 if (!bootModule)
3611 {
3612 throw InvalidOperationException ( module.node.location.c_str(),
3613 0,
3614 "Invalid bootsector. module '%s' requires <bootsector>",
3615 module.name.c_str ());
3616 }
3617
3618 const FileLocation *isoboot = bootModule->output;
3619
3620 /*
3621 We use only the name and not full FileLocation(ouput) because Iso/LiveIso are an exception to the general rule.
3622 Iso/LiveIso outputs are generated in code base root
3623 */
3624 IsoName = module.output->name;
3625
3626 string reactosDirectory = "reactos";
3627 string livecdReactosNoFixup = livecdDirectory + sSep + reactosDirectory;
3628 FileLocation livecdReactos ( OutputDirectory,
3629 livecdReactosNoFixup,
3630 "" );
3631 CLEAN_FILE ( livecdReactos );
3632
3633 fprintf ( fMakefile, ".PHONY: %s\n\n",
3634 module.name.c_str ());
3635 fprintf ( fMakefile,
3636 "%s: all %s %s $(MKHIVE_TARGET) $(CDMAKE_TARGET)\n",
3637 module.name.c_str (),
3638 backend->GetFullName ( *isoboot) .c_str (),
3639 backend->GetFullPath ( livecdReactos ).c_str () );
3640 OutputModuleCopyCommands ( livecdDirectory,
3641 reactosDirectory );
3642 OutputNonModuleCopyCommands ( livecdDirectory,
3643 reactosDirectory );
3644 OutputProfilesDirectoryCommands ( livecdDirectory );
3645 OutputLoaderCommands ( livecdDirectory );
3646 OutputRegistryCommands ( livecdDirectory );
3647 fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
3648 fprintf ( fMakefile,
3649 "\t$(Q)$(CDMAKE_TARGET) -v -m -j -b %s %s REACTOS %s\n",
3650 backend->GetFullName( *isoboot ).c_str (),
3651 backend->GetFullPath ( livecd ).c_str (),
3652 IsoName.c_str() );
3653 fprintf ( fMakefile,
3654 "\n" );
3655 }
3656
3657
3658 MingwTestModuleHandler::MingwTestModuleHandler (
3659 const Module& module_ )
3660
3661 : MingwModuleHandler ( module_ )
3662 {
3663 }
3664
3665 void
3666 MingwTestModuleHandler::Process ()
3667 {
3668 GenerateTestModuleTarget ();
3669 }
3670
3671 /* caller needs to delete the returned object */
3672 void
3673 MingwTestModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUnit*>& compilationUnits )
3674 {
3675 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_hooks.c", false, "", false ) ) );
3676 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_stubs.S", false, "", false ) ) );
3677 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_startup.c", false, "", false ) ) );
3678 }
3679
3680 void
3681 MingwTestModuleHandler::GenerateTestModuleTarget ()
3682 {
3683 string targetMacro ( GetTargetMacro ( module ) );
3684 string workingDirectory = GetWorkingDirectory ( );
3685 string linkDepsMacro = GetLinkingDependenciesMacro ();
3686
3687 GenerateImportLibraryTargetIfNeeded ();
3688
3689 if ( module.non_if_data.compilationUnits.size () > 0 )
3690 {
3691 GenerateRules ();
3692
3693 string dependencies = linkDepsMacro + " " + objectsMacro;
3694
3695 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
3696 module.GetEntryPoint(true).c_str (),
3697 module.baseaddress.c_str () );
3698 GenerateLinkerCommand ( dependencies,
3699 linkerParameters,
3700 "" );
3701 }
3702 else
3703 {
3704 GeneratePhonyTarget();
3705 }
3706 }
3707
3708
3709 MingwRpcServerModuleHandler::MingwRpcServerModuleHandler (
3710 const Module& module_ )
3711
3712 : MingwModuleHandler ( module_ )
3713 {
3714 }
3715
3716 void
3717 MingwRpcServerModuleHandler::Process ()
3718 {
3719 GenerateRules ();
3720 }
3721
3722
3723 MingwRpcClientModuleHandler::MingwRpcClientModuleHandler (
3724 const Module& module_ )
3725
3726 : MingwModuleHandler ( module_ )
3727 {
3728 }
3729
3730 void
3731 MingwRpcClientModuleHandler::Process ()
3732 {
3733 GenerateRules ();
3734 }
3735
3736
3737 MingwRpcProxyModuleHandler::MingwRpcProxyModuleHandler (
3738 const Module& module_ )
3739
3740 : MingwModuleHandler ( module_ )
3741 {
3742 }
3743
3744 void
3745 MingwRpcProxyModuleHandler::Process ()
3746 {
3747 GenerateRules ();
3748 }
3749
3750
3751 MingwAliasModuleHandler::MingwAliasModuleHandler (
3752 const Module& module_ )
3753
3754 : MingwModuleHandler ( module_ )
3755 {
3756 }
3757
3758 void
3759 MingwAliasModuleHandler::Process ()
3760 {
3761 }
3762
3763 MingwMessageHeaderModuleHandler::MingwMessageHeaderModuleHandler (
3764 const Module& module_ )
3765
3766 : MingwModuleHandler ( module_ )
3767 {
3768 }
3769
3770 void
3771 MingwMessageHeaderModuleHandler::Process ()
3772 {
3773 GenerateRules ();
3774 }
3775
3776 MingwIdlHeaderModuleHandler::MingwIdlHeaderModuleHandler (
3777 const Module& module_ )
3778
3779 : MingwModuleHandler ( module_ )
3780 {
3781 }
3782
3783 void
3784 MingwIdlHeaderModuleHandler::Process ()
3785 {
3786 GenerateRules ();
3787 }
3788
3789 MingwCabinetModuleHandler::MingwCabinetModuleHandler (
3790 const Module& module_ )
3791
3792 : MingwModuleHandler ( module_ )
3793 {
3794 }
3795
3796 void
3797 MingwCabinetModuleHandler::Process ()
3798 {
3799 string targetMacro ( GetTargetMacro (module) );
3800
3801 GenerateRules ();
3802
3803 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3804 fprintf ( fMakefile, "%s: $(CABMAN_TARGET) | %s\n",
3805 targetMacro.c_str (),
3806 backend->GetFullPath ( *target_file ).c_str () );
3807
3808 fprintf ( fMakefile, "\t$(ECHO_CABMAN)\n" );
3809 fprintf ( fMakefile,
3810 "\t$(Q)$(CABMAN_TARGET) -M raw -S %s $(%s_SOURCES)\n", // Escape the asterisk for Make
3811 targetMacro.c_str (),
3812 module.name.c_str());
3813 }
3814
3815 MingwElfExecutableModuleHandler::MingwElfExecutableModuleHandler (
3816 const Module& module_ )
3817
3818 : MingwModuleHandler ( module_ )
3819 {
3820 }
3821
3822 void
3823 MingwElfExecutableModuleHandler::Process ()
3824 {
3825 string targetName ( module.output->name );
3826 string targetMacro ( GetTargetMacro (module) );
3827 string workingDirectory = GetWorkingDirectory ();
3828 string objectsMacro = GetObjectsMacro ( module );
3829 string linkDepsMacro = GetLinkingDependenciesMacro ();
3830 string libsMacro = GetLibsMacro ();
3831
3832 GenerateRules ();
3833
3834 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3835 fprintf ( fMakefile, "%s: %s %s | %s\n",
3836 targetMacro.c_str (),
3837 objectsMacro.c_str (),
3838 linkDepsMacro.c_str (),
3839 backend->GetFullPath ( *target_file ).c_str () );
3840
3841 fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
3842
3843 fprintf ( fMakefile, "\t${gcc} $(%s_LINKFORMAT) %s %s -g -o %s\n",
3844 module.buildtype.c_str(),
3845 objectsMacro.c_str(),
3846 libsMacro.c_str(),
3847 targetMacro.c_str () );
3848
3849 delete target_file;
3850 }