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