Add support for mc files and remove hardcoded WMC instructions from Makefile . Thanks...
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
1 /*
2 * Copyright (C) 2005 Casper S. Hornstrup
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 #include "../../pch.h"
19 #include <assert.h>
20
21 #include "../../rbuild.h"
22 #include "mingw.h"
23 #include "modulehandler.h"
24
25 using std::set;
26 using std::string;
27 using std::vector;
28
29 #define CLEAN_FILE(f) clean_files.push_back ( (f).name.length () > 0 ? backend->GetFullName ( f ) : backend->GetFullPath ( f ) );
30
31 MingwBackend*
32 MingwModuleHandler::backend = NULL;
33 FILE*
34 MingwModuleHandler::fMakefile = NULL;
35
36 string
37 PrefixFilename (
38 const string& filename,
39 const string& prefix )
40 {
41 if ( !prefix.length() )
42 return filename;
43 string out;
44 const char* pfilename = filename.c_str();
45 const char* p1 = strrchr ( pfilename, '/' );
46 const char* p2 = strrchr ( pfilename, '\\' );
47 if ( p1 || p2 )
48 {
49 if ( p2 > p1 )
50 p1 = p2;
51 out += string(pfilename,p1-pfilename) + cSep;
52 pfilename = p1 + 1;
53 }
54 out += prefix + pfilename;
55 return out;
56 }
57
58 string
59 GetTargetMacro ( const Module& module, bool with_dollar )
60 {
61 string s ( module.name );
62 strupr ( &s[0] );
63 s += "_TARGET";
64 if ( with_dollar )
65 return ssprintf ( "$(%s)", s.c_str() );
66 return s;
67 }
68
69 MingwModuleHandler::MingwModuleHandler (
70 const Module& module_ )
71
72 : module(module_)
73 {
74 use_pch = false;
75 }
76
77 MingwModuleHandler::~MingwModuleHandler()
78 {
79 }
80
81 /*static*/ void
82 MingwModuleHandler::SetBackend ( MingwBackend* backend_ )
83 {
84 backend = backend_;
85 }
86
87 /*static*/ void
88 MingwModuleHandler::SetMakefile ( FILE* f )
89 {
90 fMakefile = f;
91 }
92
93 void
94 MingwModuleHandler::EnablePreCompiledHeaderSupport ()
95 {
96 use_pch = true;
97 }
98
99 /*static*/ const FileLocation*
100 MingwModuleHandler::PassThruCacheDirectory (const FileLocation* file )
101 {
102 switch ( file->directory )
103 {
104 case SourceDirectory:
105 break;
106 case IntermediateDirectory:
107 backend->AddDirectoryTarget ( file->relative_path, backend->intermediateDirectory );
108 break;
109 case OutputDirectory:
110 backend->AddDirectoryTarget ( file->relative_path, backend->outputDirectory );
111 break;
112 case InstallDirectory:
113 backend->AddDirectoryTarget ( file->relative_path, backend->installDirectory );
114 break;
115 default:
116 throw InvalidOperationException ( __FILE__,
117 __LINE__,
118 "Invalid directory %d.",
119 file->directory );
120 }
121
122 return file;
123 }
124
125 /*static*/ const FileLocation*
126 MingwModuleHandler::GetTargetFilename (
127 const Module& module,
128 string_list* pclean_files )
129 {
130 FileLocation *target = new FileLocation ( *module.output );
131 if ( pclean_files )
132 {
133 string_list& clean_files = *pclean_files;
134 CLEAN_FILE ( *target );
135 }
136 return target;
137 }
138
139 /*static*/ const FileLocation*
140 MingwModuleHandler::GetImportLibraryFilename (
141 const Module& module,
142 string_list* pclean_files )
143 {
144 FileLocation *target = new FileLocation ( *module.dependency );
145 if ( pclean_files )
146 {
147 string_list& clean_files = *pclean_files;
148 CLEAN_FILE ( *target );
149 }
150 return target;
151 }
152
153 /*static*/ MingwModuleHandler*
154 MingwModuleHandler::InstanciateHandler (
155 const Module& module,
156 MingwBackend* backend )
157 {
158 MingwModuleHandler* handler;
159 switch ( module.type )
160 {
161 case BuildTool:
162 handler = new MingwBuildToolModuleHandler ( module );
163 break;
164 case StaticLibrary:
165 handler = new MingwStaticLibraryModuleHandler ( module );
166 break;
167 case ObjectLibrary:
168 handler = new MingwObjectLibraryModuleHandler ( module );
169 break;
170 case Kernel:
171 handler = new MingwKernelModuleHandler ( module );
172 break;
173 case NativeCUI:
174 handler = new MingwNativeCUIModuleHandler ( module );
175 break;
176 case Win32CUI:
177 handler = new MingwWin32CUIModuleHandler ( module );
178 break;
179 case Win32SCR:
180 case Win32GUI:
181 handler = new MingwWin32GUIModuleHandler ( module );
182 break;
183 case KernelModeDLL:
184 handler = new MingwKernelModeDLLModuleHandler ( module );
185 break;
186 case NativeDLL:
187 handler = new MingwNativeDLLModuleHandler ( module );
188 break;
189 case Win32DLL:
190 handler = new MingwWin32DLLModuleHandler ( module );
191 break;
192 case Win32OCX:
193 handler = new MingwWin32OCXModuleHandler ( module );
194 break;
195 case KernelModeDriver:
196 handler = new MingwKernelModeDriverModuleHandler ( module );
197 break;
198 case BootLoader:
199 handler = new MingwBootLoaderModuleHandler ( module );
200 break;
201 case BootSector:
202 handler = new MingwBootSectorModuleHandler ( module );
203 break;
204 case BootProgram:
205 handler = new MingwBootProgramModuleHandler ( module );
206 break;
207 case Iso:
208 handler = new MingwIsoModuleHandler ( module );
209 break;
210 case LiveIso:
211 handler = new MingwLiveIsoModuleHandler ( module );
212 break;
213 case IsoRegTest:
214 handler = new MingwIsoModuleHandler ( module );
215 break;
216 case LiveIsoRegTest:
217 handler = new MingwLiveIsoModuleHandler ( module );
218 break;
219 case Test:
220 handler = new MingwTestModuleHandler ( module );
221 break;
222 case RpcServer:
223 handler = new MingwRpcServerModuleHandler ( module );
224 break;
225 case RpcClient:
226 handler = new MingwRpcClientModuleHandler ( module );
227 break;
228 case Alias:
229 handler = new MingwAliasModuleHandler ( module );
230 break;
231 case IdlHeader:
232 handler = new MingwIdlHeaderModuleHandler ( module );
233 break;
234 case EmbeddedTypeLib:
235 handler = new MingwEmbeddedTypeLibModuleHandler ( module );
236 break;
237 case ElfExecutable:
238 handler = new MingwElfExecutableModuleHandler ( module );
239 break;
240 default:
241 throw UnknownModuleTypeException (
242 module.node.location,
243 module.type );
244 break;
245 }
246 return handler;
247 }
248
249 string
250 MingwModuleHandler::GetWorkingDirectory () const
251 {
252 return ".";
253 }
254
255 string
256 MingwModuleHandler::GetBasename ( const string& filename ) const
257 {
258 size_t index = filename.find_last_of ( '.' );
259 if ( index != string::npos )
260 return filename.substr ( 0, index );
261 return "";
262 }
263
264 const FileLocation*
265 MingwModuleHandler::GetActualSourceFilename (
266 const FileLocation* file ) const
267 {
268 string filename = file->name;
269
270 string extension = GetExtension ( *file );
271 if ( extension == ".spec" || extension == ".SPEC" )
272 {
273 const FileLocation *objectFile = GetObjectFilename ( file, module, NULL );
274 FileLocation *sourceFile = new FileLocation (
275 objectFile->directory,
276 objectFile->relative_path,
277 ReplaceExtension ( objectFile->name, ".c" ) );
278 delete objectFile;
279 return sourceFile;
280 }
281 else if ( ( extension == ".idl" || extension == ".IDL" ) &&
282 ( module.type == RpcServer || module.type == RpcClient ) )
283 {
284 const FileLocation *objectFile = GetObjectFilename ( file, module, NULL );
285 FileLocation *sourceFile = new FileLocation (
286 objectFile->directory,
287 objectFile->relative_path,
288 ReplaceExtension ( objectFile->name, ".c" ) );
289 delete objectFile;
290 return sourceFile;
291 }
292 else if ( extension == ".mc" || extension == ".MC" )
293 {
294 const FileLocation *objectFile = GetObjectFilename ( file, module, NULL );
295 FileLocation *sourceFile = new FileLocation (
296 objectFile->directory,
297 objectFile->relative_path,
298 ReplaceExtension ( objectFile->name, ".rc" ) );
299 delete objectFile;
300 return sourceFile;
301 }
302 else
303 return new FileLocation ( *file );
304 }
305
306 string
307 MingwModuleHandler::GetExtraDependencies (
308 const FileLocation *file ) const
309 {
310 string extension = GetExtension ( *file );
311 if ( extension == ".idl" || extension == ".IDL" )
312 {
313 if ( (module.type == RpcServer) || (module.type == RpcClient) )
314 return backend->GetFullName ( *GetRpcServerHeaderFilename ( file ) )
315 + " "
316 + backend->GetFullName ( *GetRpcClientHeaderFilename ( file ) );
317 else if ( module.type == IdlHeader )
318 return backend->GetFullName ( *GetIdlHeaderFilename ( file ) );
319 else
320 return "";
321 }
322 else
323 return "";
324 }
325
326 string
327 MingwModuleHandler::GetCompilationUnitDependencies (
328 const CompilationUnit& compilationUnit ) const
329 {
330 if ( compilationUnit.files.size () <= 1 )
331 return "";
332 vector<string> sourceFiles;
333 for ( size_t i = 0; i < compilationUnit.files.size (); i++ )
334 {
335 File& file = *compilationUnit.files[i];
336 sourceFiles.push_back ( backend->GetFullName ( file.file ) );
337 }
338 return v2s ( sourceFiles, 10 );
339 }
340
341 const FileLocation*
342 MingwModuleHandler::GetModuleArchiveFilename () const
343 {
344 if ( module.type == StaticLibrary )
345 return new FileLocation ( *GetTargetFilename ( module, NULL ) );
346 return new FileLocation ( IntermediateDirectory,
347 module.output->relative_path,
348 ReplaceExtension ( module.name, ".temp.a" ) );
349 }
350
351 bool
352 MingwModuleHandler::IsGeneratedFile ( const File& file ) const
353 {
354 string extension = GetExtension ( file.file );
355 return ( extension == ".spec" || extension == ".SPEC" );
356 }
357
358 /*static*/ bool
359 MingwModuleHandler::ReferenceObjects (
360 const Module& module )
361 {
362 if ( module.type == ObjectLibrary )
363 return true;
364 if ( module.type == RpcServer )
365 return true;
366 if ( module.type == RpcClient )
367 return true;
368 if ( module.type == IdlHeader )
369 return true;
370 return false;
371 }
372
373 void
374 MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
375 const FileLocation& destination )
376 {
377 fprintf ( fMakefile,
378 "\t$(ECHO_CP)\n" );
379 fprintf ( fMakefile,
380 "\t${cp} %s %s 1>$(NUL)\n",
381 backend->GetFullName ( source ).c_str (),
382 backend->GetFullName ( *PassThruCacheDirectory ( &destination ) ).c_str () );
383 }
384
385 string
386 MingwModuleHandler::GetImportLibraryDependency (
387 const Module& importedModule )
388 {
389 string dep;
390 if ( ReferenceObjects ( importedModule ) )
391 {
392 const vector<CompilationUnit*>& compilationUnits = importedModule.non_if_data.compilationUnits;
393 size_t i;
394
395 dep = GetTargetMacro ( importedModule );
396 for ( i = 0; i < compilationUnits.size (); i++ )
397 {
398 CompilationUnit& compilationUnit = *compilationUnits[i];
399 const FileLocation *objectFilename = GetObjectFilename ( compilationUnit.GetFilename (), importedModule, NULL );
400 if ( GetExtension ( *objectFilename ) == ".h" )
401 {
402 dep += ssprintf ( " $(%s_HEADERS)", importedModule.name.c_str () );
403 break;
404 }
405 if ( GetExtension ( *objectFilename ) == ".rc" )
406 {
407 dep += ssprintf ( " $(%s_MCHEADERS)", importedModule.name.c_str () );
408 break;
409 }
410 }
411 }
412 else
413 dep = backend->GetFullName ( *GetImportLibraryFilename ( importedModule, NULL ) );
414 return dep;
415 }
416
417 void
418 MingwModuleHandler::GetTargets ( const Module& dependencyModule,
419 string_list& targets )
420 {
421 if ( dependencyModule.invocations.size () > 0 )
422 {
423 for ( size_t i = 0; i < dependencyModule.invocations.size (); i++ )
424 {
425 Invoke& invoke = *dependencyModule.invocations[i];
426 invoke.GetTargets ( targets );
427 }
428 }
429 else
430 targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
431 }
432
433 void
434 MingwModuleHandler::GetModuleDependencies (
435 string_list& dependencies )
436 {
437 size_t iend = module.dependencies.size ();
438
439 if ( iend == 0 )
440 return;
441
442 for ( size_t i = 0; i < iend; i++ )
443 {
444 const Dependency& dependency = *module.dependencies[i];
445 const Module& dependencyModule = *dependency.dependencyModule;
446 GetTargets ( dependencyModule,
447 dependencies );
448 }
449 vector<FileLocation> v;
450 GetDefinitionDependencies ( v );
451
452 for ( size_t i = 0; i < v.size (); i++ )
453 {
454 const FileLocation& file = v[i];
455 dependencies.push_back ( backend->GetFullName ( file ) );
456 }
457 }
458
459 void
460 MingwModuleHandler::GetSourceFilenames ( vector<FileLocation>& list,
461 bool includeGeneratedFiles ) const
462 {
463 size_t i;
464
465 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
466 for ( i = 0; i < compilationUnits.size (); i++ )
467 {
468 if ( includeGeneratedFiles || !compilationUnits[i]->IsGeneratedFile () )
469 {
470 const FileLocation* sourceFileLocation = GetActualSourceFilename (
471 compilationUnits[i]->GetFilename () );
472 list.push_back ( *sourceFileLocation );
473 }
474 }
475 // intentionally make a copy so that we can append more work in
476 // the middle of processing without having to go recursive
477 vector<If*> v = module.non_if_data.ifs;
478 for ( i = 0; i < v.size (); i++ )
479 {
480 size_t j;
481 If& rIf = *v[i];
482 // check for sub-ifs to add to list
483 const vector<If*>& ifs = rIf.data.ifs;
484 for ( j = 0; j < ifs.size (); j++ )
485 v.push_back ( ifs[j] );
486 const vector<CompilationUnit*>& compilationUnits = rIf.data.compilationUnits;
487 for ( j = 0; j < compilationUnits.size (); j++ )
488 {
489 CompilationUnit& compilationUnit = *compilationUnits[j];
490 if ( includeGeneratedFiles || !compilationUnit.IsGeneratedFile () )
491 {
492 const FileLocation* sourceFileLocation = GetActualSourceFilename (
493 compilationUnit.GetFilename () );
494 list.push_back ( *sourceFileLocation );
495 }
496 }
497 }
498 }
499
500 void
501 MingwModuleHandler::GetSourceFilenamesWithoutGeneratedFiles (
502 vector<FileLocation>& list ) const
503 {
504 GetSourceFilenames ( list, false );
505 }
506
507 const FileLocation*
508 MingwModuleHandler::GetObjectFilename (
509 const FileLocation* sourceFile,
510 const Module& module,
511 string_list* pclean_files ) const
512 {
513 DirectoryLocation destination_directory;
514 string newExtension;
515 string extension = GetExtension ( *sourceFile );
516
517 if ( module.type == BootSector )
518 return new FileLocation ( *module.output );
519 else if ( extension == ".rc" || extension == ".RC" )
520 newExtension = "_" + module.name + ".coff";
521 else if ( extension == ".mc" || extension == ".MC" )
522 newExtension = ".rc";
523 else if ( extension == ".spec" || extension == ".SPEC" )
524 newExtension = ".stubs.o";
525 else if ( extension == ".idl" || extension == ".IDL" )
526 {
527 if ( module.type == RpcServer )
528 newExtension = "_s.o";
529 else if ( module.type == RpcClient )
530 newExtension = "_c.o";
531 else
532 newExtension = ".h";
533 }
534 else
535 newExtension = "_" + module.name + ".o";
536
537 if ( module.type == BootSector )
538 destination_directory = OutputDirectory;
539 else
540 destination_directory = IntermediateDirectory;
541
542 const FileLocation *obj_file = new FileLocation(
543 destination_directory,
544 sourceFile->relative_path,
545 ReplaceExtension ( sourceFile->name, newExtension ) );
546
547 if ( pclean_files )
548 {
549 string_list& clean_files = *pclean_files;
550 CLEAN_FILE ( *obj_file );
551 }
552 return obj_file;
553 }
554
555 string
556 MingwModuleHandler::GetModuleCleanTarget ( const Module& module ) const
557 {
558 return module.name + "_clean";
559 }
560
561 void
562 MingwModuleHandler::GetReferencedObjectLibraryModuleCleanTargets ( vector<string>& moduleNames ) const
563 {
564 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
565 {
566 Library& library = *module.non_if_data.libraries[i];
567 if ( library.importedModule->type == ObjectLibrary )
568 moduleNames.push_back ( GetModuleCleanTarget ( *library.importedModule ) );
569 }
570 }
571
572 void
573 MingwModuleHandler::GenerateCleanTarget () const
574 {
575 if ( module.type == Alias )
576 return;
577
578 fprintf ( fMakefile,
579 ".PHONY: %s_clean\n",
580 module.name.c_str() );
581 vector<string> referencedModuleNames;
582 GetReferencedObjectLibraryModuleCleanTargets ( referencedModuleNames );
583 fprintf ( fMakefile,
584 "%s: %s\n\t-@${rm}",
585 GetModuleCleanTarget ( module ).c_str(),
586 v2s ( referencedModuleNames, 10 ).c_str () );
587 for ( size_t i = 0; i < clean_files.size(); i++ )
588 {
589 if ( ( i + 1 ) % 10 == 9 )
590 fprintf ( fMakefile, " 2>$(NUL)\n\t-@${rm}" );
591 fprintf ( fMakefile, " %s", clean_files[i].c_str() );
592 }
593 fprintf ( fMakefile, " 2>$(NUL)\n" );
594
595 if ( module.name != "zlib" ) /* Avoid make warning */
596 {
597 DirectoryLocation root;
598 if ( backend->configuration.GenerateProxyMakefilesInSourceTree )
599 root = SourceDirectory;
600 else
601 root = OutputDirectory;
602 FileLocation proxyMakefile ( root,
603 module.output->relative_path,
604 "GNUmakefile" );
605 fprintf ( fMakefile, "\t-@${rm} %s 2>$(NUL)\n",
606 backend->GetFullName ( proxyMakefile ).c_str () );
607 }
608
609 fprintf ( fMakefile, "clean: %s_clean\n\n", module.name.c_str() );
610 }
611
612 void
613 MingwModuleHandler::GenerateInstallTarget () const
614 {
615 if ( !module.install )
616 return;
617 fprintf ( fMakefile, ".PHONY: %s_install\n", module.name.c_str() );
618 fprintf ( fMakefile,
619 "%s_install: %s\n",
620 module.name.c_str (),
621 backend->GetFullName ( *module.install ).c_str () );
622 }
623
624 void
625 MingwModuleHandler::GenerateDependsTarget () const
626 {
627 fprintf ( fMakefile,
628 ".PHONY: %s_depends\n",
629 module.name.c_str() );
630 fprintf ( fMakefile,
631 "%s_depends: $(RBUILD_TARGET)\n",
632 module.name.c_str () );
633 fprintf ( fMakefile,
634 "\t$(ECHO_RBUILD)\n" );
635 fprintf ( fMakefile,
636 "\t$(Q)$(RBUILD_TARGET) $(RBUILD_FLAGS) -dm%s mingw\n",
637 module.name.c_str () );
638 }
639
640 string
641 MingwModuleHandler::GetObjectFilenames ()
642 {
643 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
644 if ( compilationUnits.size () == 0 )
645 return "";
646
647 string objectFilenames ( "" );
648 for ( size_t i = 0; i < compilationUnits.size (); i++ )
649 {
650 if ( objectFilenames.size () > 0 )
651 objectFilenames += " ";
652 objectFilenames += backend->GetFullName ( *GetObjectFilename ( compilationUnits[i]->GetFilename (), module, NULL ) );
653 }
654 return objectFilenames;
655 }
656
657 /* static */ string
658 MingwModuleHandler::GenerateGccDefineParametersFromVector (
659 const vector<Define*>& defines,
660 set<string>& used_defs)
661 {
662 string parameters;
663
664 for ( size_t i = 0; i < defines.size (); i++ )
665 {
666 Define& define = *defines[i];
667 if (used_defs.find(define.name) != used_defs.end())
668 continue;
669 if (parameters.length () > 0)
670 parameters += " ";
671 if (define.name.find('(') != string::npos)
672 parameters += "$(QT)";
673 parameters += "-D";
674 parameters += define.name;
675 if (define.value.length () > 0)
676 {
677 parameters += "=";
678 parameters += define.value;
679 }
680 if (define.name.find('(') != string::npos)
681 parameters += "$(QT)";
682 used_defs.insert(used_defs.begin(),define.name);
683 }
684 return parameters;
685 }
686
687 string
688 MingwModuleHandler::GenerateGccDefineParameters () const
689 {
690 set<string> used_defs;
691 string parameters = GenerateGccDefineParametersFromVector ( module.project.non_if_data.defines, used_defs );
692 string s = GenerateGccDefineParametersFromVector ( module.non_if_data.defines, used_defs );
693 if ( s.length () > 0 )
694 {
695 parameters += " ";
696 parameters += s;
697 }
698 return parameters;
699 }
700
701 string
702 MingwModuleHandler::ConcatenatePaths (
703 const string& path1,
704 const string& path2 ) const
705 {
706 if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )
707 return path2;
708 if ( path1[path1.length ()] == cSep )
709 return path1 + path2;
710 else
711 return path1 + cSep + path2;
712 }
713
714 /* static */ string
715 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes )
716 {
717 string parameters, path_prefix;
718 for ( size_t i = 0; i < includes.size (); i++ )
719 {
720 Include& include = *includes[i];
721 if ( parameters.length () > 0 )
722 parameters += " ";
723 parameters += "-I" + backend->GetFullPath ( *include.directory );;
724 }
725 return parameters;
726 }
727
728 string
729 MingwModuleHandler::GenerateGccIncludeParameters () const
730 {
731 string parameters = GenerateGccIncludeParametersFromVector ( module.non_if_data.includes );
732 string s = GenerateGccIncludeParametersFromVector ( module.project.non_if_data.includes );
733 if ( s.length () > 0 )
734 {
735 parameters += " ";
736 parameters += s;
737 }
738 return parameters;
739 }
740
741 string
742 MingwModuleHandler::GenerateCompilerParametersFromVector ( const vector<CompilerFlag*>& compilerFlags ) const
743 {
744 string parameters;
745 for ( size_t i = 0; i < compilerFlags.size (); i++ )
746 {
747 CompilerFlag& compilerFlag = *compilerFlags[i];
748 if ( parameters.length () > 0 )
749 parameters += " ";
750 parameters += compilerFlag.flag;
751 }
752 return parameters;
753 }
754
755 string
756 MingwModuleHandler::GenerateLinkerParametersFromVector ( const vector<LinkerFlag*>& linkerFlags ) const
757 {
758 string parameters;
759 for ( size_t i = 0; i < linkerFlags.size (); i++ )
760 {
761 LinkerFlag& linkerFlag = *linkerFlags[i];
762 if ( parameters.length () > 0 )
763 parameters += " ";
764 parameters += linkerFlag.flag;
765 }
766 return parameters;
767 }
768
769 string
770 MingwModuleHandler::GenerateImportLibraryDependenciesFromVector (
771 const vector<Library*>& libraries )
772 {
773 string dependencies ( "" );
774 int wrap_count = 0;
775 for ( size_t i = 0; i < libraries.size (); i++ )
776 {
777 if ( wrap_count++ == 5 )
778 dependencies += " \\\n\t\t", wrap_count = 0;
779 else if ( dependencies.size () > 0 )
780 dependencies += " ";
781 dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule );
782 }
783 return dependencies;
784 }
785
786 string
787 MingwModuleHandler::GenerateLinkerParameters () const
788 {
789 return GenerateLinkerParametersFromVector ( module.linkerFlags );
790 }
791
792 void
793 MingwModuleHandler::GenerateMacro (
794 const char* assignmentOperation,
795 const string& macro,
796 const IfableData& data,
797 set<const Define *> *used_defs,
798 bool generatingCompilerMacro )
799 {
800 size_t i;
801 bool generateAssignment;
802
803 if ( generatingCompilerMacro )
804 generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0 || data.compilerFlags.size () > 0;
805 else
806 generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0;
807 if ( generateAssignment )
808 {
809 fprintf ( fMakefile,
810 "%s %s",
811 macro.c_str(),
812 assignmentOperation );
813 }
814
815 if ( use_pch && module.pch != NULL )
816 {
817 fprintf ( fMakefile,
818 " -I%s",
819 backend->GetFullPath ( *GetPrecompiledHeaderFilename () ).c_str () );
820 }
821
822 if ( generatingCompilerMacro )
823 {
824 string compilerParameters = GenerateCompilerParametersFromVector ( data.compilerFlags );
825 if ( compilerParameters.size () > 0 )
826 {
827 fprintf (
828 fMakefile,
829 " %s",
830 compilerParameters.c_str () );
831 }
832 }
833 for ( i = 0; i < data.includes.size(); i++ )
834 {
835 const Include& include = *data.includes[i];
836 const FileLocation* includeDirectory = include.directory;
837 fprintf (
838 fMakefile,
839 " -I%s",
840 backend->GetFullPath ( *includeDirectory ).c_str() );
841 }
842 for ( i = 0; i < data.defines.size(); i++ )
843 {
844 const Define& define = *data.defines[i];
845 if ( used_defs )
846 {
847 set<const Define *>::const_iterator last_define;
848 for (last_define = used_defs->begin ();
849 last_define != used_defs->end ();
850 last_define++)
851 {
852 if ( (*last_define)->name != define.name )
853 continue;
854 if ( !define.overridable )
855 {
856 throw InvalidOperationException ( (*last_define)->node->location.c_str (),
857 0,
858 "Invalid override of define '%s', already defined at %s",
859 define.name.c_str (),
860 define.node->location.c_str () );
861 }
862 if ( backend->configuration.Verbose )
863 printf("%s: Overriding '%s' already defined at %s\n",
864 (*last_define)->node->location.c_str (), define.name.c_str (),
865 define.node->location.c_str () );
866 break;
867 }
868 if ( last_define != used_defs->end () )
869 continue;
870 }
871 fprintf (
872 fMakefile,
873 " -D%s",
874 define.name.c_str() );
875 if (define.value.length () > 0)
876 fprintf (
877 fMakefile,
878 "=%s",
879 define.value.c_str() );
880 if ( used_defs )
881 used_defs->insert( used_defs->begin (), &define );
882 }
883 if ( generateAssignment )
884 {
885 fprintf ( fMakefile, "\n" );
886 }
887 }
888
889 void
890 MingwModuleHandler::GenerateMacros (
891 const char* assignmentOperation,
892 const IfableData& data,
893 const vector<LinkerFlag*>* linkerFlags,
894 set<const Define *>& used_defs )
895 {
896 size_t i;
897
898 GenerateMacro ( assignmentOperation,
899 cflagsMacro,
900 data,
901 &used_defs,
902 true );
903 GenerateMacro ( assignmentOperation,
904 windresflagsMacro,
905 data,
906 NULL,
907 false );
908
909 if ( linkerFlags != NULL )
910 {
911 string linkerParameters = GenerateLinkerParametersFromVector ( *linkerFlags );
912 if ( linkerParameters.size () > 0 )
913 {
914 fprintf (
915 fMakefile,
916 "%s %s %s\n",
917 linkerflagsMacro.c_str (),
918 assignmentOperation,
919 linkerParameters.c_str() );
920 }
921 }
922
923 if ( data.libraries.size () > 0 )
924 {
925 string deps = GenerateImportLibraryDependenciesFromVector ( data.libraries );
926 if ( deps.size () > 0 )
927 {
928 fprintf (
929 fMakefile,
930 "%s %s %s\n",
931 libsMacro.c_str(),
932 assignmentOperation,
933 deps.c_str() );
934 }
935 }
936
937 const vector<If*>& ifs = data.ifs;
938 for ( i = 0; i < ifs.size(); i++ )
939 {
940 If& rIf = *ifs[i];
941 if ( rIf.data.defines.size()
942 || rIf.data.includes.size()
943 || rIf.data.libraries.size()
944 || rIf.data.compilationUnits.size()
945 || rIf.data.compilerFlags.size()
946 || rIf.data.ifs.size() )
947 {
948 fprintf (
949 fMakefile,
950 "%s (\"$(%s)\",\"%s\")\n",
951 rIf.negated ? "ifneq" : "ifeq",
952 rIf.property.c_str(),
953 rIf.value.c_str() );
954 GenerateMacros (
955 "+=",
956 rIf.data,
957 NULL,
958 used_defs );
959 fprintf (
960 fMakefile,
961 "endif\n\n" );
962 }
963 }
964 }
965
966 void
967 MingwModuleHandler::CleanupCompilationUnitVector ( vector<CompilationUnit*>& compilationUnits )
968 {
969 for (size_t i = 0; i < compilationUnits.size (); i++)
970 delete compilationUnits[i];
971 }
972
973 void
974 MingwModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUnit*>& compilationUnits )
975 {
976 }
977
978 void
979 MingwModuleHandler::GenerateSourceMacros (
980 const char* assignmentOperation,
981 const IfableData& data )
982 {
983 size_t i;
984
985 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
986 vector<const FileLocation *> headers;
987 if ( compilationUnits.size () > 0 )
988 {
989 fprintf (
990 fMakefile,
991 "%s %s",
992 sourcesMacro.c_str (),
993 assignmentOperation );
994 for ( i = 0; i < compilationUnits.size(); i++ )
995 {
996 CompilationUnit& compilationUnit = *compilationUnits[i];
997 fprintf (
998 fMakefile,
999 "%s%s",
1000 ( i%10 == 9 ? " \\\n\t" : " " ),
1001 backend->GetFullName ( *compilationUnit.GetFilename () ).c_str () );
1002 }
1003 fprintf ( fMakefile, "\n" );
1004 }
1005
1006 const vector<If*>& ifs = data.ifs;
1007 for ( i = 0; i < ifs.size(); i++ )
1008 {
1009 If& rIf = *ifs[i];
1010 if ( rIf.data.defines.size()
1011 || rIf.data.includes.size()
1012 || rIf.data.libraries.size()
1013 || rIf.data.compilationUnits.size()
1014 || rIf.data.compilerFlags.size()
1015 || rIf.data.ifs.size() )
1016 {
1017 fprintf (
1018 fMakefile,
1019 "%s (\"$(%s)\",\"%s\")\n",
1020 rIf.negated ? "ifneq" : "ifeq",
1021 rIf.property.c_str(),
1022 rIf.value.c_str() );
1023 GenerateSourceMacros (
1024 "+=",
1025 rIf.data );
1026 fprintf (
1027 fMakefile,
1028 "endif\n\n" );
1029 }
1030 }
1031
1032 vector<CompilationUnit*> sourceCompilationUnits;
1033 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1034 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1035 {
1036 fprintf (
1037 fMakefile,
1038 "%s += %s\n",
1039 sourcesMacro.c_str(),
1040 backend->GetFullName ( *sourceCompilationUnits[i]->GetFilename () ).c_str () );
1041 }
1042 CleanupCompilationUnitVector ( sourceCompilationUnits );
1043 }
1044
1045 void
1046 MingwModuleHandler::GenerateObjectMacros (
1047 const char* assignmentOperation,
1048 const IfableData& data )
1049 {
1050 size_t i;
1051
1052 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1053 vector<const FileLocation *> headers;
1054 vector<const FileLocation *> mcheaders;
1055 vector<const FileLocation *> mcresources;
1056 if ( compilationUnits.size () > 0 )
1057 {
1058 for ( i = 0; i < compilationUnits.size (); i++ )
1059 {
1060 CompilationUnit& compilationUnit = *compilationUnits[i];
1061 if ( compilationUnit.IsFirstFile () )
1062 {
1063 fprintf ( fMakefile,
1064 "%s := %s $(%s)\n",
1065 objectsMacro.c_str(),
1066 backend->GetFullName ( *GetObjectFilename ( compilationUnit.GetFilename (), module, NULL ) ).c_str (),
1067 objectsMacro.c_str() );
1068 }
1069 }
1070 fprintf (
1071 fMakefile,
1072 "%s %s",
1073 objectsMacro.c_str (),
1074 assignmentOperation );
1075 for ( i = 0; i < compilationUnits.size(); i++ )
1076 {
1077 CompilationUnit& compilationUnit = *compilationUnits[i];
1078 if ( !compilationUnit.IsFirstFile () )
1079 {
1080 const FileLocation *objectFilename = GetObjectFilename ( compilationUnit.GetFilename (), module, NULL );
1081 if ( GetExtension ( *objectFilename ) == ".h" )
1082 headers.push_back ( objectFilename );
1083 else if ( GetExtension ( *objectFilename ) == ".rc" )
1084 {
1085 const FileLocation *headerFilename = GetMcHeaderFilename ( compilationUnit.GetFilename () );
1086 mcheaders.push_back ( headerFilename );
1087 mcresources.push_back ( objectFilename );
1088 }
1089 else
1090 fprintf (
1091 fMakefile,
1092 "%s%s",
1093 ( i%10 == 9 ? " \\\n\t" : " " ),
1094 backend->GetFullName ( *objectFilename ).c_str () );
1095 }
1096 }
1097 fprintf ( fMakefile, "\n" );
1098 }
1099 if ( headers.size () > 0 )
1100 {
1101 fprintf (
1102 fMakefile,
1103 "%s_HEADERS %s",
1104 module.name.c_str (),
1105 assignmentOperation );
1106 for ( i = 0; i < headers.size (); i++ )
1107 fprintf (
1108 fMakefile,
1109 "%s%s",
1110 ( i%10 == 9 ? " \\\n\t" : " " ),
1111 backend->GetFullName ( *headers[i] ).c_str () );
1112 fprintf ( fMakefile, "\n" );
1113 }
1114
1115 if ( mcheaders.size () > 0 )
1116 {
1117 fprintf (
1118 fMakefile,
1119 "%s_MCHEADERS %s",
1120 module.name.c_str (),
1121 assignmentOperation );
1122 for ( i = 0; i < mcheaders.size (); i++ )
1123 fprintf (
1124 fMakefile,
1125 "%s%s",
1126 ( i%10 == 9 ? " \\\n\t" : " " ),
1127 backend->GetFullName ( *mcheaders[i] ).c_str () );
1128 fprintf ( fMakefile, "\n" );
1129 }
1130
1131 if ( mcresources.size () > 0 )
1132 {
1133 fprintf (
1134 fMakefile,
1135 "%s_RESOURCES %s",
1136 module.name.c_str (),
1137 assignmentOperation );
1138 for ( i = 0; i < mcresources.size (); i++ )
1139 fprintf (
1140 fMakefile,
1141 "%s%s",
1142 ( i%10 == 9 ? " \\\n\t" : " " ),
1143 backend->GetFullName ( *mcresources[i] ).c_str () );
1144 fprintf ( fMakefile, "\n" );
1145 }
1146
1147 const vector<If*>& ifs = data.ifs;
1148 for ( i = 0; i < ifs.size(); i++ )
1149 {
1150 If& rIf = *ifs[i];
1151 if ( rIf.data.defines.size()
1152 || rIf.data.includes.size()
1153 || rIf.data.libraries.size()
1154 || rIf.data.compilationUnits.size()
1155 || rIf.data.compilerFlags.size()
1156 || rIf.data.ifs.size() )
1157 {
1158 fprintf (
1159 fMakefile,
1160 "%s (\"$(%s)\",\"%s\")\n",
1161 rIf.negated ? "ifneq" : "ifeq",
1162 rIf.property.c_str(),
1163 rIf.value.c_str() );
1164 GenerateObjectMacros (
1165 "+=",
1166 rIf.data );
1167 fprintf (
1168 fMakefile,
1169 "endif\n\n" );
1170 }
1171 }
1172
1173 vector<CompilationUnit*> sourceCompilationUnits;
1174 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1175 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1176 {
1177 fprintf (
1178 fMakefile,
1179 "%s += %s\n",
1180 objectsMacro.c_str(),
1181 backend->GetFullName ( *GetObjectFilename ( sourceCompilationUnits[i]->GetFilename (), module, NULL ) ).c_str () );
1182 }
1183 CleanupCompilationUnitVector ( sourceCompilationUnits );
1184 }
1185
1186 const FileLocation*
1187 MingwModuleHandler::GetPrecompiledHeaderFilename () const
1188 {
1189 return new FileLocation ( IntermediateDirectory,
1190 module.pch->file.relative_path,
1191 ReplaceExtension ( module.pch->file.name, "_" + module.name + ".gch" ) );
1192 }
1193
1194 void
1195 MingwModuleHandler::GenerateGccCommand (
1196 const FileLocation* sourceFile,
1197 const string& extraDependencies,
1198 const string& cc,
1199 const string& cflagsMacro )
1200 {
1201 const FileLocation *generatedSourceFileName = GetActualSourceFilename ( sourceFile );
1202 string dependencies = backend->GetFullName ( *generatedSourceFileName );
1203 if ( extraDependencies != "" )
1204 dependencies += " " + extraDependencies;
1205 if ( module.pch && use_pch )
1206 dependencies += " " + backend->GetFullName ( *GetPrecompiledHeaderFilename () );
1207
1208 /* WIDL generated headers may be used */
1209 vector<FileLocation> rpcDependencies;
1210 GetRpcHeaderDependencies ( rpcDependencies );
1211 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1212 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1213
1214 const FileLocation *objectFilename = GetObjectFilename (
1215 sourceFile, module, &clean_files );
1216 fprintf ( fMakefile,
1217 "%s: %s | %s\n",
1218 backend->GetFullName ( *objectFilename ).c_str (),
1219 dependencies.c_str (),
1220 backend->GetFullPath ( *objectFilename ).c_str () );
1221 fprintf ( fMakefile, "\t$(ECHO_CC)\n" );
1222 fprintf ( fMakefile,
1223 "\t%s -c $< -o $@ %s\n",
1224 cc.c_str (),
1225 cflagsMacro.c_str () );
1226 }
1227
1228 void
1229 MingwModuleHandler::GenerateGccAssemblerCommand (
1230 const FileLocation* sourceFile,
1231 const string& cc,
1232 const string& cflagsMacro )
1233 {
1234 string dependencies = backend->GetFullName ( *sourceFile );
1235 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1236
1237 const FileLocation *objectFilename = GetObjectFilename (
1238 sourceFile, module, &clean_files );
1239 fprintf ( fMakefile,
1240 "%s: %s | %s\n",
1241 backend->GetFullName ( *objectFilename ).c_str (),
1242 dependencies.c_str (),
1243 backend->GetFullPath ( *objectFilename ).c_str () );
1244 fprintf ( fMakefile, "\t$(ECHO_GAS)\n" );
1245 fprintf ( fMakefile,
1246 "\t%s -x assembler-with-cpp -c $< -o $@ -D__ASM__ %s\n",
1247 cc.c_str (),
1248 cflagsMacro.c_str () );
1249 }
1250
1251 void
1252 MingwModuleHandler::GenerateNasmCommand (
1253 const FileLocation* sourceFile,
1254 const string& nasmflagsMacro )
1255 {
1256 string dependencies = backend->GetFullName ( *sourceFile );
1257 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1258
1259 const FileLocation *objectFilename = GetObjectFilename (
1260 sourceFile, module, &clean_files );
1261 fprintf ( fMakefile,
1262 "%s: %s | %s\n",
1263 backend->GetFullName ( *objectFilename ).c_str (),
1264 dependencies.c_str (),
1265 backend->GetFullPath ( *objectFilename ).c_str () );
1266 fprintf ( fMakefile, "\t$(ECHO_NASM)\n" );
1267 fprintf ( fMakefile,
1268 "\t%s -f win32 $< -o $@ %s\n",
1269 "$(Q)${nasm}",
1270 nasmflagsMacro.c_str () );
1271 }
1272
1273 void
1274 MingwModuleHandler::GenerateWindresCommand (
1275 const FileLocation* sourceFile,
1276 const string& windresflagsMacro )
1277 {
1278 string dependencies = backend->GetFullName ( *sourceFile );
1279 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1280
1281 const FileLocation *objectFilename = GetObjectFilename ( sourceFile, module, &clean_files );
1282
1283 string sourceFilenamePart = module.name + "." + ReplaceExtension ( sourceFile->name, "" );
1284 FileLocation rciFilename ( TemporaryDirectory,
1285 "",
1286 sourceFilenamePart + ".rci.tmp" );
1287 FileLocation resFilename ( TemporaryDirectory,
1288 "",
1289 sourceFilenamePart + ".res.tmp" );
1290
1291 fprintf ( fMakefile,
1292 "%s: %s $(WRC_TARGET) | %s\n",
1293 backend->GetFullName ( *objectFilename ).c_str (),
1294 dependencies.c_str (),
1295 backend->GetFullPath ( *objectFilename ).c_str () );
1296 fprintf ( fMakefile, "\t$(ECHO_WRC)\n" );
1297 fprintf ( fMakefile,
1298 "\t${gcc} -xc -E -DRC_INVOKED ${%s} %s > %s\n",
1299 windresflagsMacro.c_str (),
1300 backend->GetFullName ( *sourceFile ).c_str (),
1301 backend->GetFullName ( rciFilename ).c_str () );
1302 fprintf ( fMakefile,
1303 "\t$(Q)$(WRC_TARGET) ${%s} %s %s\n",
1304 windresflagsMacro.c_str (),
1305 backend->GetFullName ( rciFilename ).c_str (),
1306 backend->GetFullName ( resFilename ).c_str () );
1307 fprintf ( fMakefile,
1308 "\t-@${rm} %s 2>$(NUL)\n",
1309 backend->GetFullName ( rciFilename ).c_str () );
1310 fprintf ( fMakefile,
1311 "\t${windres} %s -o $@\n",
1312 backend->GetFullName ( resFilename ).c_str () );
1313 fprintf ( fMakefile,
1314 "\t-@${rm} %s 2>$(NUL)\n",
1315 backend->GetFullName ( resFilename ).c_str () );
1316 }
1317
1318 void
1319 MingwModuleHandler::GenerateWinebuildCommands (
1320 const FileLocation* sourceFile )
1321 {
1322 string dependencies = backend->GetFullName ( *sourceFile );
1323 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1324
1325 string basename = GetBasename ( sourceFile->name );
1326 FileLocation def_file ( IntermediateDirectory,
1327 sourceFile->relative_path,
1328 basename + ".spec.def" );
1329 CLEAN_FILE ( def_file );
1330
1331 FileLocation stub_file ( *GetActualSourceFilename ( sourceFile ) );
1332 CLEAN_FILE ( stub_file );
1333
1334 fprintf ( fMakefile,
1335 "%s: %s $(WINEBUILD_TARGET) | %s\n",
1336 backend->GetFullName ( def_file ).c_str (),
1337 dependencies.c_str (),
1338 backend->GetFullPath ( def_file ).c_str () );
1339 fprintf ( fMakefile, "\t$(ECHO_WINEBLD)\n" );
1340 fprintf ( fMakefile,
1341 "\t%s -o %s --def -E %s\n",
1342 "$(Q)$(WINEBUILD_TARGET)",
1343 backend->GetFullName ( def_file ).c_str (),
1344 backend->GetFullName ( *sourceFile ).c_str () );
1345 fprintf ( fMakefile,
1346 "%s: %s $(WINEBUILD_TARGET)\n",
1347 backend->GetFullName ( stub_file ).c_str (),
1348 backend->GetFullName ( *sourceFile ).c_str () );
1349 fprintf ( fMakefile, "\t$(ECHO_WINEBLD)\n" );
1350 fprintf ( fMakefile,
1351 "\t%s -o %s --pedll %s\n",
1352 "$(Q)$(WINEBUILD_TARGET)",
1353 backend->GetFullName ( stub_file ).c_str (),
1354 backend->GetFullName ( *sourceFile ).c_str () );
1355 }
1356
1357 void
1358 MingwModuleHandler::GenerateWmcCommands (
1359 const FileLocation* sourceFile )
1360 {
1361 string dependencies = backend->GetFullName ( *sourceFile );
1362 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1363
1364 string basename = GetBasename ( sourceFile->name );
1365 FileLocation rc_file ( IntermediateDirectory,
1366 sourceFile->relative_path,
1367 basename + ".rc" );
1368 FileLocation h_file ( IntermediateDirectory,
1369 "include/reactos",
1370 basename + ".h" );
1371 CLEAN_FILE ( rc_file );
1372 CLEAN_FILE ( h_file );
1373
1374 fprintf ( fMakefile,
1375 "%s %s: $(WMC_TARGET) %s\n",
1376 backend->GetFullName ( rc_file ).c_str (),
1377 backend->GetFullName ( h_file ).c_str (),
1378 backend->GetFullName ( *sourceFile ).c_str () );
1379 fprintf ( fMakefile, "\t$(ECHO_WMC)\n" );
1380 fprintf ( fMakefile,
1381 "\t%s -i -H %s -o %s %s\n",
1382 "$(Q)$(WMC_TARGET)",
1383 backend->GetFullName ( h_file ).c_str (),
1384 backend->GetFullName ( rc_file ).c_str (),
1385 backend->GetFullName ( *sourceFile ).c_str () );
1386 }
1387
1388 string
1389 MingwModuleHandler::GetWidlFlags ( const CompilationUnit& compilationUnit )
1390 {
1391 return compilationUnit.GetSwitches ();
1392 }
1393
1394 string
1395 MingwModuleHandler::GetPropertyValue ( const Module& module, const std::string& name )
1396 {
1397 for ( size_t i = 0; i < module.project.non_if_data.properties.size (); i++ )
1398 {
1399 const Property& property = *module.project.non_if_data.properties[i];
1400 if ( property.name == name )
1401 return property.value;
1402 }
1403 return string ( "" );
1404 }
1405
1406 const FileLocation*
1407 MingwModuleHandler::GetRpcServerHeaderFilename ( const FileLocation *base ) const
1408 {
1409 string newname = GetBasename ( base->name ) + "_s.h";
1410 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1411 }
1412
1413 void
1414 MingwModuleHandler::GenerateWidlCommandsServer (
1415 const CompilationUnit& compilationUnit,
1416 const string& widlflagsMacro )
1417 {
1418 const FileLocation* sourceFile = compilationUnit.GetFilename ();
1419 string dependencies = backend->GetFullName ( *sourceFile );
1420 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1421
1422 string basename = GetBasename ( sourceFile->name );
1423
1424 const FileLocation *generatedHeaderFilename = GetRpcServerHeaderFilename ( sourceFile );
1425 CLEAN_FILE ( *generatedHeaderFilename );
1426
1427 FileLocation generatedServerFilename ( IntermediateDirectory,
1428 sourceFile->relative_path,
1429 basename + "_s.c" );
1430 CLEAN_FILE ( generatedServerFilename );
1431
1432 fprintf ( fMakefile,
1433 "%s %s: %s $(WIDL_TARGET) | %s\n",
1434 backend->GetFullName ( generatedServerFilename ).c_str (),
1435 backend->GetFullName ( *generatedHeaderFilename ).c_str (),
1436 dependencies.c_str (),
1437 backend->GetFullPath ( generatedServerFilename ).c_str () );
1438 fprintf ( fMakefile, "\t$(ECHO_WIDL)\n" );
1439 fprintf ( fMakefile,
1440 "\t%s %s %s -h -H %s -s -S %s %s\n",
1441 "$(Q)$(WIDL_TARGET)",
1442 GetWidlFlags ( compilationUnit ).c_str (),
1443 widlflagsMacro.c_str (),
1444 backend->GetFullName ( *generatedHeaderFilename ).c_str (),
1445 backend->GetFullName ( generatedServerFilename ).c_str (),
1446 backend->GetFullName ( *sourceFile ).c_str () );
1447 }
1448
1449 const FileLocation*
1450 MingwModuleHandler::GetRpcClientHeaderFilename ( const FileLocation *base ) const
1451 {
1452 string newname = GetBasename ( base->name ) + "_c.h";
1453 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1454 }
1455
1456 const FileLocation*
1457 MingwModuleHandler::GetIdlHeaderFilename ( const FileLocation *base ) const
1458 {
1459 string newname = GetBasename ( base->name ) + ".h";
1460 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1461 }
1462
1463 const FileLocation*
1464 MingwModuleHandler::GetMcHeaderFilename ( const FileLocation *base ) const
1465 {
1466 string newname = GetBasename ( base->name ) + ".h";
1467 return new FileLocation ( IntermediateDirectory, "include/reactos" , newname );
1468 }
1469
1470 void
1471 MingwModuleHandler::GenerateWidlCommandsEmbeddedTypeLib (
1472 const CompilationUnit& compilationUnit,
1473 const string& widlflagsMacro )
1474 {
1475 const FileLocation* sourceFile = compilationUnit.GetFilename ();
1476 string dependencies = backend->GetFullName ( *sourceFile );
1477 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1478
1479 string basename = GetBasename ( sourceFile->name );
1480
1481 FileLocation EmbeddedTypeLibFilename ( IntermediateDirectory,
1482 sourceFile->relative_path,
1483 basename + ".tlb" );
1484
1485 fprintf ( fMakefile,
1486 "%s: %s $(WIDL_TARGET) | %s\n",
1487 GetTargetMacro ( module ).c_str (),
1488 dependencies.c_str (),
1489 backend->GetFullPath ( EmbeddedTypeLibFilename ).c_str () );
1490 fprintf ( fMakefile, "\t$(ECHO_WIDL)\n" );
1491 fprintf ( fMakefile,
1492 "\t%s %s %s -t -T %s %s\n",
1493 "$(Q)$(WIDL_TARGET)",
1494 GetWidlFlags ( compilationUnit ).c_str (),
1495 widlflagsMacro.c_str (),
1496 backend->GetFullName ( EmbeddedTypeLibFilename ).c_str(),
1497 backend->GetFullName ( *sourceFile ).c_str () );
1498 }
1499
1500 void
1501 MingwModuleHandler::GenerateWidlCommandsClient (
1502 const CompilationUnit& compilationUnit,
1503 const string& widlflagsMacro )
1504 {
1505 const FileLocation* sourceFile = compilationUnit.GetFilename ();
1506 string dependencies = backend->GetFullName ( *sourceFile );
1507 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1508
1509 string basename = GetBasename ( sourceFile->name );
1510
1511 const FileLocation *generatedHeaderFilename = GetRpcClientHeaderFilename ( sourceFile );
1512 CLEAN_FILE ( *generatedHeaderFilename );
1513
1514 FileLocation generatedClientFilename ( IntermediateDirectory,
1515 sourceFile->relative_path,
1516 basename + "_c.c" );
1517 CLEAN_FILE ( generatedClientFilename );
1518
1519 fprintf ( fMakefile,
1520 "%s %s: %s $(WIDL_TARGET) | %s\n",
1521 backend->GetFullName ( generatedClientFilename ).c_str (),
1522 backend->GetFullName ( *generatedHeaderFilename ).c_str (),
1523 dependencies.c_str (),
1524 backend->GetFullPath ( generatedClientFilename ).c_str () );
1525 fprintf ( fMakefile, "\t$(ECHO_WIDL)\n" );
1526 fprintf ( fMakefile,
1527 "\t%s %s %s -h -H %s -c -C %s %s\n",
1528 "$(Q)$(WIDL_TARGET)",
1529 GetWidlFlags ( compilationUnit ).c_str (),
1530 widlflagsMacro.c_str (),
1531 backend->GetFullName ( *generatedHeaderFilename ).c_str (),
1532 backend->GetFullName ( generatedClientFilename ).c_str (),
1533 backend->GetFullName ( *sourceFile ).c_str () );
1534 }
1535
1536 void
1537 MingwModuleHandler::GenerateWidlCommandsIdlHeader (
1538 const CompilationUnit& compilationUnit,
1539 const string& widlflagsMacro )
1540 {
1541 const FileLocation* sourceFile = compilationUnit.GetFilename ();
1542 string dependencies = backend->GetFullName ( *sourceFile );
1543 dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
1544
1545 string basename = GetBasename ( sourceFile->name );
1546
1547 const FileLocation *generatedHeader = GetIdlHeaderFilename ( sourceFile );
1548 CLEAN_FILE ( *generatedHeader );
1549
1550 fprintf ( fMakefile,
1551 "%s: %s $(WIDL_TARGET) | %s\n",
1552 backend->GetFullName( *generatedHeader ).c_str (),
1553 dependencies.c_str (),
1554 backend->GetFullPath ( *generatedHeader ).c_str () );
1555 fprintf ( fMakefile, "\t$(ECHO_WIDL)\n" );
1556 fprintf ( fMakefile,
1557 "\t%s %s %s -h -H %s %s\n",
1558 "$(Q)$(WIDL_TARGET)",
1559 GetWidlFlags ( compilationUnit ).c_str (),
1560 widlflagsMacro.c_str (),
1561 backend->GetFullName ( *generatedHeader ).c_str (),
1562 backend->GetFullName ( *sourceFile ).c_str () );
1563 }
1564
1565 void
1566 MingwModuleHandler::GenerateWidlCommands (
1567 const CompilationUnit& compilationUnit,
1568 const string& widlflagsMacro )
1569 {
1570 if ( module.type == RpcServer )
1571 GenerateWidlCommandsServer ( compilationUnit,
1572 widlflagsMacro );
1573 else if ( module.type == RpcClient )
1574 GenerateWidlCommandsClient ( compilationUnit,
1575 widlflagsMacro );
1576 else if ( module.type == EmbeddedTypeLib )
1577 GenerateWidlCommandsEmbeddedTypeLib ( compilationUnit,
1578 widlflagsMacro );
1579 else // applies also for other module.types which include idl files
1580 GenerateWidlCommandsIdlHeader ( compilationUnit,
1581 widlflagsMacro );
1582 }
1583
1584 void
1585 MingwModuleHandler::GenerateCommands (
1586 const CompilationUnit& compilationUnit,
1587 const string& extraDependencies,
1588 const string& cc,
1589 const string& cppc,
1590 const string& cflagsMacro,
1591 const string& nasmflagsMacro,
1592 const string& windresflagsMacro,
1593 const string& widlflagsMacro )
1594 {
1595 const FileLocation* sourceFile = compilationUnit.GetFilename ();
1596 string extension = GetExtension ( *sourceFile );
1597 if ( extension == ".c" || extension == ".C" )
1598 {
1599 GenerateGccCommand ( sourceFile,
1600 GetCompilationUnitDependencies ( compilationUnit ) + extraDependencies,
1601 cc,
1602 cflagsMacro );
1603 return;
1604 }
1605 else if ( extension == ".cc" || extension == ".CC" ||
1606 extension == ".cpp" || extension == ".CPP" ||
1607 extension == ".cxx" || extension == ".CXX" )
1608 {
1609 GenerateGccCommand ( sourceFile,
1610 GetCompilationUnitDependencies ( compilationUnit ) + extraDependencies,
1611 cppc,
1612 cflagsMacro );
1613 return;
1614 }
1615 else if ( extension == ".s" || extension == ".S" )
1616 {
1617 GenerateGccAssemblerCommand ( sourceFile,
1618 cc,
1619 cflagsMacro );
1620 return;
1621 }
1622 else if ( extension == ".asm" || extension == ".ASM" )
1623 {
1624 GenerateNasmCommand ( sourceFile,
1625 nasmflagsMacro );
1626 return;
1627 }
1628 else if ( extension == ".rc" || extension == ".RC" )
1629 {
1630 GenerateWindresCommand ( sourceFile,
1631 windresflagsMacro );
1632 return;
1633 }
1634 else if ( extension == ".mc" || extension == ".MC" )
1635 {
1636 GenerateWmcCommands ( sourceFile );
1637 return;
1638 }
1639 else if ( extension == ".spec" || extension == ".SPEC" )
1640 {
1641 GenerateWinebuildCommands ( sourceFile );
1642 GenerateGccCommand ( sourceFile,
1643 extraDependencies,
1644 cc,
1645 cflagsMacro );
1646 return;
1647 }
1648 else if ( extension == ".idl" || extension == ".IDL" )
1649 {
1650 GenerateWidlCommands ( compilationUnit,
1651 widlflagsMacro );
1652 if ( (module.type == RpcServer) || (module.type == RpcClient) )
1653 {
1654 GenerateGccCommand ( sourceFile,
1655 GetExtraDependencies ( sourceFile ),
1656 cc,
1657 cflagsMacro );
1658 }
1659 return;
1660 }
1661
1662 throw InvalidOperationException ( __FILE__,
1663 __LINE__,
1664 "Unsupported filename extension '%s' in file '%s'",
1665 extension.c_str (),
1666 backend->GetFullName ( *sourceFile ).c_str () );
1667 }
1668
1669 void
1670 MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget )
1671 {
1672 fprintf ( fMakefile,
1673 "ifeq ($(ROS_BUILDMAP),full)\n" );
1674
1675 FileLocation mapFilename ( OutputDirectory,
1676 module.output->relative_path,
1677 GetBasename ( module.output->name ) + ".map" );
1678 CLEAN_FILE ( mapFilename );
1679
1680 fprintf ( fMakefile,
1681 "\t$(ECHO_OBJDUMP)\n" );
1682 fprintf ( fMakefile,
1683 "\t$(Q)${objdump} -d -S %s > %s\n",
1684 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1685 backend->GetFullName ( mapFilename ).c_str () );
1686
1687 fprintf ( fMakefile,
1688 "else\n" );
1689 fprintf ( fMakefile,
1690 "ifeq ($(ROS_BUILDMAP),yes)\n" );
1691
1692 fprintf ( fMakefile,
1693 "\t$(ECHO_NM)\n" );
1694 fprintf ( fMakefile,
1695 "\t$(Q)${nm} --numeric-sort %s > %s\n",
1696 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1697 backend->GetFullName ( mapFilename ).c_str () );
1698
1699 fprintf ( fMakefile,
1700 "endif\n" );
1701
1702 fprintf ( fMakefile,
1703 "endif\n" );
1704 }
1705
1706 void
1707 MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
1708 {
1709 fprintf ( fMakefile,
1710 "ifeq ($(ROS_BUILDNOSTRIP),yes)\n" );
1711
1712 FileLocation nostripFilename ( OutputDirectory,
1713 module.output->relative_path,
1714 GetBasename ( module.output->name ) + ".nostrip" + GetExtension ( *module.output ) );
1715 CLEAN_FILE ( nostripFilename );
1716
1717 OutputCopyCommand ( *module.output, nostripFilename );
1718
1719 fprintf ( fMakefile,
1720 "endif\n" );
1721 }
1722
1723 void
1724 MergeStringVector ( const Backend* backend,
1725 const vector<FileLocation>& input,
1726 vector<string>& output )
1727 {
1728 int wrap_at = 25;
1729 string s;
1730 int wrap_count = -1;
1731 for ( size_t i = 0; i < input.size (); i++ )
1732 {
1733 if ( wrap_count++ == wrap_at )
1734 {
1735 output.push_back ( s );
1736 s = "";
1737 wrap_count = 0;
1738 }
1739 else if ( s.size () > 0)
1740 s += " ";
1741 s += backend->GetFullName ( input[i] );
1742 }
1743 if ( s.length () > 0 )
1744 output.push_back ( s );
1745 }
1746
1747 void
1748 MingwModuleHandler::GetObjectsVector ( const IfableData& data,
1749 vector<FileLocation>& objectFiles ) const
1750 {
1751 for ( size_t i = 0; i < data.compilationUnits.size (); i++ )
1752 {
1753 CompilationUnit& compilationUnit = *data.compilationUnits[i];
1754 objectFiles.push_back ( *GetObjectFilename ( compilationUnit.GetFilename (), module, NULL ) );
1755 }
1756 }
1757
1758 void
1759 MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
1760 {
1761 if ( backend->configuration.CleanAsYouGo )
1762 {
1763 vector<FileLocation> objectFiles;
1764 GetObjectsVector ( module.non_if_data,
1765 objectFiles );
1766 vector<string> lines;
1767 MergeStringVector ( backend,
1768 objectFiles,
1769 lines );
1770 for ( size_t i = 0; i < lines.size (); i++ )
1771 {
1772 fprintf ( fMakefile,
1773 "\t-@${rm} %s 2>$(NUL)\n",
1774 lines[i].c_str () );
1775 }
1776 }
1777 }
1778
1779 void
1780 MingwModuleHandler::GenerateRunRsymCode () const
1781 {
1782 fprintf ( fMakefile,
1783 "\t$(ECHO_RSYM)\n" );
1784 fprintf ( fMakefile,
1785 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
1786 }
1787
1788 void
1789 MingwModuleHandler::GenerateRunStripCode () const
1790 {
1791 fprintf ( fMakefile,
1792 "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
1793 fprintf ( fMakefile,
1794 "\t$(ECHO_STRIP)\n" );
1795 fprintf ( fMakefile,
1796 "\t${strip} -s -x -X $@\n\n" );
1797 fprintf ( fMakefile,
1798 "endif\n" );
1799 }
1800
1801 void
1802 MingwModuleHandler::GenerateLinkerCommand (
1803 const string& dependencies,
1804 const string& linker,
1805 const string& linkerParameters,
1806 const string& objectsMacro,
1807 const string& libsMacro,
1808 const string& pefixupParameters )
1809 {
1810 string target ( GetTargetMacro ( module ) );
1811 string target_folder ( backend->GetFullPath ( *GetTargetFilename ( module, NULL ) ) );
1812 const FileLocation *definitionFilename = GetDefinitionFilename ();
1813
1814 string linkerScriptArgument;
1815 if ( module.linkerScript != NULL )
1816 linkerScriptArgument = ssprintf ( "-Wl,-T,%s", backend->GetFullName ( module.linkerScript->file ).c_str () );
1817 else
1818 linkerScriptArgument = "";
1819
1820 fprintf ( fMakefile,
1821 "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
1822 target.c_str (),
1823 backend->GetFullName ( *definitionFilename ).c_str (),
1824 dependencies.c_str (),
1825 target_folder.c_str () );
1826 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1827 string targetName ( module.output->name );
1828
1829 if ( !module.IsDLL () )
1830 {
1831 fprintf ( fMakefile,
1832 "\t%s %s %s -o %s %s %s %s\n",
1833 linker.c_str (),
1834 linkerParameters.c_str (),
1835 linkerScriptArgument.c_str (),
1836 target.c_str (),
1837 objectsMacro.c_str (),
1838 libsMacro.c_str (),
1839 GetLinkerMacro ().c_str () );
1840 }
1841 else if ( module.HasImportLibrary () )
1842 {
1843 FileLocation temp_exp ( TemporaryDirectory,
1844 "",
1845 module.name + ".temp.exp" );
1846 CLEAN_FILE ( temp_exp );
1847
1848 fprintf ( fMakefile,
1849 "\t${dlltool} --dllname %s --def %s --output-exp %s %s %s\n",
1850 targetName.c_str (),
1851 backend->GetFullName ( *definitionFilename ).c_str (),
1852 backend->GetFullName ( temp_exp ).c_str (),
1853 module.mangledSymbols ? "" : "--kill-at",
1854 module.underscoreSymbols ? "--add-underscore" : "" );
1855
1856 fprintf ( fMakefile,
1857 "\t%s %s %s %s -o %s %s %s %s\n",
1858 linker.c_str (),
1859 linkerParameters.c_str (),
1860 linkerScriptArgument.c_str (),
1861 backend->GetFullName ( temp_exp ).c_str (),
1862 target.c_str (),
1863 objectsMacro.c_str (),
1864 libsMacro.c_str (),
1865 GetLinkerMacro ().c_str () );
1866
1867 fprintf ( fMakefile,
1868 "\t$(Q)$(PEFIXUP_TARGET) %s -exports %s\n",
1869 target.c_str (),
1870 pefixupParameters.c_str() );
1871
1872 fprintf ( fMakefile,
1873 "\t-@${rm} %s 2>$(NUL)\n",
1874 backend->GetFullName ( temp_exp ).c_str () );
1875 }
1876 else
1877 {
1878 /* XXX: need to workaround binutils bug, which exports
1879 * all functions in a dll if no .def file or an empty
1880 * one has been provided... */
1881 /* See bug 1244 */
1882 //printf ( "%s will have all its functions exported\n",
1883 // module.target->name.c_str () );
1884 fprintf ( fMakefile,
1885 "\t%s %s %s -o %s %s %s %s\n",
1886 linker.c_str (),
1887 linkerParameters.c_str (),
1888 linkerScriptArgument.c_str (),
1889 target.c_str (),
1890 objectsMacro.c_str (),
1891 libsMacro.c_str (),
1892 GetLinkerMacro ().c_str () );
1893 }
1894
1895 GenerateBuildMapCode ();
1896 GenerateBuildNonSymbolStrippedCode ();
1897 GenerateRunRsymCode ();
1898 GenerateRunStripCode ();
1899 GenerateCleanObjectsAsYouGoCode ();
1900 }
1901
1902 void
1903 MingwModuleHandler::GeneratePhonyTarget() const
1904 {
1905 string targetMacro ( GetTargetMacro ( module ) );
1906 fprintf ( fMakefile,
1907 ".PHONY: %s\n\n",
1908 targetMacro.c_str ());
1909 fprintf ( fMakefile, "%s: | %s\n",
1910 targetMacro.c_str (),
1911 backend->GetFullPath ( *GetTargetFilename ( module, NULL ) ).c_str () );
1912 }
1913
1914 void
1915 MingwModuleHandler::GenerateObjectFileTargets (
1916 const IfableData& data,
1917 const string& cc,
1918 const string& cppc,
1919 const string& cflagsMacro,
1920 const string& nasmflagsMacro,
1921 const string& windresflagsMacro,
1922 const string& widlflagsMacro )
1923 {
1924 size_t i;
1925 string moduleDependencies;
1926
1927 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1928 for ( i = 0; i < compilationUnits.size (); i++ )
1929 {
1930 CompilationUnit& compilationUnit = *compilationUnits[i];
1931 const FileLocation *objectFilename = GetObjectFilename ( compilationUnit.GetFilename (), module, NULL );
1932 if ( GetExtension ( *objectFilename ) == ".h" )
1933 {
1934 moduleDependencies += ssprintf ( " $(%s_HEADERS)", module.name.c_str () );
1935 break;
1936 }
1937 if ( GetExtension ( *objectFilename ) == ".rc" )
1938 {
1939 moduleDependencies += ssprintf ( " $(%s_RESOURCES)", module.name.c_str () );
1940 break;
1941 }
1942 }
1943
1944 for ( i = 0; i < compilationUnits.size (); i++ )
1945 {
1946 GenerateCommands ( *compilationUnits[i],
1947 moduleDependencies,
1948 cc,
1949 cppc,
1950 cflagsMacro,
1951 nasmflagsMacro,
1952 windresflagsMacro,
1953 widlflagsMacro );
1954 fprintf ( fMakefile,
1955 "\n" );
1956 }
1957
1958 const vector<If*>& ifs = data.ifs;
1959 for ( i = 0; i < ifs.size(); i++ )
1960 {
1961 GenerateObjectFileTargets ( ifs[i]->data,
1962 cc,
1963 cppc,
1964 cflagsMacro,
1965 nasmflagsMacro,
1966 windresflagsMacro,
1967 widlflagsMacro );
1968 }
1969
1970 vector<CompilationUnit*> sourceCompilationUnits;
1971 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1972 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1973 {
1974 GenerateCommands ( *sourceCompilationUnits[i],
1975 moduleDependencies,
1976 cc,
1977 cppc,
1978 cflagsMacro,
1979 nasmflagsMacro,
1980 windresflagsMacro,
1981 widlflagsMacro );
1982 }
1983 CleanupCompilationUnitVector ( sourceCompilationUnits );
1984 }
1985
1986 void
1987 MingwModuleHandler::GenerateObjectFileTargets (
1988 const string& cc,
1989 const string& cppc,
1990 const string& cflagsMacro,
1991 const string& nasmflagsMacro,
1992 const string& windresflagsMacro,
1993 const string& widlflagsMacro )
1994 {
1995 if ( module.pch && use_pch )
1996 {
1997 const FileLocation& baseHeaderFile = module.pch->file;
1998 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1999 CLEAN_FILE ( *pchFilename );
2000 string dependencies = backend->GetFullName ( baseHeaderFile );
2001 /* WIDL generated headers may be used */
2002 vector<FileLocation> rpcDependencies;
2003 GetRpcHeaderDependencies ( rpcDependencies );
2004 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
2005 fprintf ( fMakefile,
2006 "%s: %s | %s\n",
2007 backend->GetFullName ( *pchFilename ).c_str(),
2008 dependencies.c_str(),
2009 backend->GetFullPath ( *pchFilename ).c_str() );
2010 fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
2011 fprintf ( fMakefile,
2012 "\t%s -o %s %s -g %s\n\n",
2013 module.cplusplus ? cppc.c_str() : cc.c_str(),
2014 backend->GetFullName ( *pchFilename ).c_str(),
2015 cflagsMacro.c_str(),
2016 backend->GetFullName ( baseHeaderFile ).c_str() );
2017 }
2018
2019 GenerateObjectFileTargets ( module.non_if_data,
2020 cc,
2021 cppc,
2022 cflagsMacro,
2023 nasmflagsMacro,
2024 windresflagsMacro,
2025 widlflagsMacro );
2026 fprintf ( fMakefile, "\n" );
2027 }
2028
2029 const FileLocation*
2030 MingwModuleHandler::GenerateArchiveTarget ( const string& ar,
2031 const string& objs_macro ) const
2032 {
2033 const FileLocation *archiveFilename = GetModuleArchiveFilename ();
2034
2035 fprintf ( fMakefile,
2036 "%s: %s | %s\n",
2037 backend->GetFullName ( *archiveFilename ).c_str (),
2038 objs_macro.c_str (),
2039 backend->GetFullPath ( *archiveFilename ).c_str() );
2040
2041 if ( module.type == StaticLibrary && module.importLibrary )
2042 {
2043 const FileLocation *definitionFilename ( GetDefinitionFilename () );
2044
2045 fprintf ( fMakefile,
2046 "\t${dlltool} --dllname %s --def %s --output-lib $@ %s %s\n",
2047 module.importLibrary->dllname.c_str (),
2048 backend->GetFullName ( *definitionFilename ).c_str (),
2049 module.mangledSymbols ? "" : "--kill-at",
2050 module.underscoreSymbols ? "--add-underscore" : "" );
2051 }
2052
2053 fprintf ( fMakefile, "\t$(ECHO_AR)\n" );
2054
2055 fprintf ( fMakefile,
2056 "\t%s -rc $@ %s\n",
2057 ar.c_str (),
2058 objs_macro.c_str ());
2059
2060 GenerateCleanObjectsAsYouGoCode ();
2061
2062 fprintf ( fMakefile, "\n" );
2063
2064 return archiveFilename;
2065 }
2066
2067 string
2068 MingwModuleHandler::GetCFlagsMacro () const
2069 {
2070 return ssprintf ( "$(%s_CFLAGS)",
2071 module.name.c_str () );
2072 }
2073
2074 /*static*/ string
2075 MingwModuleHandler::GetObjectsMacro ( const Module& module )
2076 {
2077 return ssprintf ( "$(%s_OBJS)",
2078 module.name.c_str () );
2079 }
2080
2081 string
2082 MingwModuleHandler::GetLinkingDependenciesMacro () const
2083 {
2084 return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
2085 }
2086
2087 string
2088 MingwModuleHandler::GetLibsMacro () const
2089 {
2090 return ssprintf ( "$(%s_LIBS)", module.name.c_str () );
2091 }
2092
2093 string
2094 MingwModuleHandler::GetLinkerMacro () const
2095 {
2096 return ssprintf ( "$(%s_LFLAGS)",
2097 module.name.c_str () );
2098 }
2099
2100 string
2101 MingwModuleHandler::GetModuleTargets ( const Module& module )
2102 {
2103 if ( ReferenceObjects ( module ) )
2104 return GetObjectsMacro ( module );
2105 else
2106 return backend->GetFullName ( *GetTargetFilename ( module, NULL ) ).c_str ();
2107 }
2108
2109 void
2110 MingwModuleHandler::GenerateSourceMacro ()
2111 {
2112 sourcesMacro = ssprintf ( "%s_SOURCES", module.name.c_str ());
2113
2114 GenerateSourceMacros (
2115 "=",
2116 module.non_if_data );
2117
2118 // future references to the macro will be to get its values
2119 sourcesMacro = ssprintf ("$(%s)", sourcesMacro.c_str ());
2120 }
2121
2122 void
2123 MingwModuleHandler::GenerateObjectMacro ()
2124 {
2125 objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
2126
2127 GenerateObjectMacros (
2128 "=",
2129 module.non_if_data );
2130
2131 // future references to the macro will be to get its values
2132 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
2133 }
2134
2135 void
2136 MingwModuleHandler::GenerateTargetMacro ()
2137 {
2138 fprintf ( fMakefile,
2139 "%s := %s\n",
2140 GetTargetMacro ( module, false ).c_str (),
2141 GetModuleTargets ( module ).c_str () );
2142 }
2143
2144 void
2145 MingwModuleHandler::GetRpcHeaderDependencies (
2146 vector<FileLocation>& dependencies ) const
2147 {
2148 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
2149 {
2150 Library& library = *module.non_if_data.libraries[i];
2151 if ( library.importedModule->type == RpcServer ||
2152 library.importedModule->type == RpcClient ||
2153 library.importedModule->type == IdlHeader )
2154 {
2155 for ( size_t j = 0; j < library.importedModule->non_if_data.compilationUnits.size (); j++ )
2156 {
2157 CompilationUnit& compilationUnit = *library.importedModule->non_if_data.compilationUnits[j];
2158 const FileLocation* sourceFile = compilationUnit.GetFilename ();
2159 string extension = GetExtension ( *sourceFile );
2160 if ( extension == ".idl" || extension == ".IDL" )
2161 {
2162 string basename = GetBasename ( sourceFile->name );
2163 if ( library.importedModule->type == RpcServer )
2164 dependencies.push_back ( *GetRpcServerHeaderFilename ( sourceFile ) );
2165 if ( library.importedModule->type == RpcClient )
2166 dependencies.push_back ( *GetRpcClientHeaderFilename ( sourceFile ) );
2167 if ( library.importedModule->type == IdlHeader )
2168 dependencies.push_back ( *GetIdlHeaderFilename ( sourceFile ) );
2169 }
2170 }
2171 }
2172 }
2173 }
2174
2175 void
2176 MingwModuleHandler::GenerateOtherMacros ()
2177 {
2178 set<const Define *> used_defs;
2179
2180 cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
2181 nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
2182 windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
2183 widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());
2184 linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
2185 libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
2186 linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
2187
2188 GenerateMacros (
2189 "=",
2190 module.non_if_data,
2191 &module.linkerFlags,
2192 used_defs );
2193
2194 GenerateMacros (
2195 "+=",
2196 module.project.non_if_data,
2197 NULL,
2198 used_defs );
2199
2200 vector<FileLocation> s;
2201 if ( module.importLibrary )
2202 {
2203 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2204 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2205 {
2206 CompilationUnit& compilationUnit = *compilationUnits[i];
2207 const FileLocation* sourceFile = compilationUnit.GetFilename ();
2208 string extension = GetExtension ( *sourceFile );
2209 if ( extension == ".spec" || extension == ".SPEC" )
2210 GetSpecObjectDependencies ( s, sourceFile );
2211 }
2212 }
2213 if ( s.size () > 0 )
2214 {
2215 fprintf (
2216 fMakefile,
2217 "%s +=",
2218 linkDepsMacro.c_str() );
2219 for ( size_t i = 0; i < s.size(); i++ )
2220 fprintf ( fMakefile,
2221 " %s",
2222 backend->GetFullName ( s[i] ).c_str () );
2223 fprintf ( fMakefile, "\n" );
2224 }
2225
2226 string globalCflags = "-g";
2227 if ( backend->usePipe )
2228 globalCflags += " -pipe";
2229 if ( !module.allowWarnings )
2230 globalCflags += " -Werror";
2231 if ( module.host == HostTrue )
2232 {
2233 if ( module.cplusplus )
2234 globalCflags += " $(HOST_CPPFLAGS)";
2235 else
2236 globalCflags += " $(HOST_CFLAGS)";
2237 }
2238 else
2239 {
2240 if ( module.cplusplus )
2241 {
2242 // HACK: use host headers when building C++
2243 globalCflags += " $(HOST_CPPFLAGS)";
2244 }
2245 else
2246 globalCflags += " -nostdinc";
2247 }
2248
2249 // Always force disabling of sibling calls optimisation for GCC
2250 // (TODO: Move to version-specific once this bug is fixed in GCC)
2251 globalCflags += " -fno-optimize-sibling-calls";
2252
2253 fprintf (
2254 fMakefile,
2255 "%s += $(PROJECT_CFLAGS) %s\n",
2256 cflagsMacro.c_str (),
2257 globalCflags.c_str () );
2258
2259 fprintf (
2260 fMakefile,
2261 "%s += $(PROJECT_RCFLAGS)\n",
2262 windresflagsMacro.c_str () );
2263
2264 fprintf (
2265 fMakefile,
2266 "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
2267 widlflagsMacro.c_str (),
2268 module.output->relative_path.c_str () );
2269
2270 fprintf (
2271 fMakefile,
2272 "%s_LFLAGS += $(PROJECT_LFLAGS) -g\n",
2273 module.name.c_str () );
2274
2275 fprintf (
2276 fMakefile,
2277 "%s += $(%s)\n",
2278 linkDepsMacro.c_str (),
2279 libsMacro.c_str () );
2280
2281 string cflags = TypeSpecificCFlags();
2282 if ( cflags.size() > 0 )
2283 {
2284 fprintf ( fMakefile,
2285 "%s += %s\n\n",
2286 cflagsMacro.c_str (),
2287 cflags.c_str () );
2288 }
2289
2290 string nasmflags = TypeSpecificNasmFlags();
2291 if ( nasmflags.size () > 0 )
2292 {
2293 fprintf ( fMakefile,
2294 "%s += %s\n\n",
2295 nasmflagsMacro.c_str (),
2296 nasmflags.c_str () );
2297 }
2298
2299 string linkerflags = TypeSpecificLinkerFlags();
2300 if ( linkerflags.size() > 0 )
2301 {
2302 fprintf ( fMakefile,
2303 "%s += %s\n\n",
2304 linkerflagsMacro.c_str (),
2305 linkerflags.c_str () );
2306 }
2307
2308 if ( module.type == StaticLibrary && module.isStartupLib )
2309 {
2310 fprintf ( fMakefile,
2311 "%s += -Wno-main\n\n",
2312 cflagsMacro.c_str () );
2313 }
2314
2315 fprintf ( fMakefile, "\n\n" );
2316
2317 // future references to the macros will be to get their values
2318 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
2319 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
2320 widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
2321 }
2322
2323 void
2324 MingwModuleHandler::GenerateRules ()
2325 {
2326 string cc = ( module.host == HostTrue ? "${host_gcc}" : "${gcc}" );
2327 string cppc = ( module.host == HostTrue ? "${host_gpp}" : "${gpp}" );
2328 string ar = ( module.host == HostTrue ? "${host_ar}" : "${ar}" );
2329
2330 string targetMacro = GetTargetMacro ( module );
2331 //CLEAN_FILE ( targetMacro );
2332 CLEAN_FILE ( FileLocation ( SourceDirectory, "", targetMacro ) );
2333
2334 // generate phony target for module name
2335 fprintf ( fMakefile, ".PHONY: %s\n",
2336 module.name.c_str () );
2337 string dependencies = GetTargetMacro ( module );
2338 if ( module.type == Test )
2339 dependencies += " $(REGTESTS_RUN_TARGET)";
2340 fprintf ( fMakefile, "%s: %s\n\n",
2341 module.name.c_str (),
2342 dependencies.c_str () );
2343 if ( module.type == Test )
2344 {
2345 fprintf ( fMakefile,
2346 "\t@%s\n",
2347 targetMacro.c_str ());
2348 }
2349
2350 if ( !ReferenceObjects ( module ) )
2351 {
2352 const FileLocation* ar_target = GenerateArchiveTarget ( ar, objectsMacro );
2353 CLEAN_FILE ( *ar_target );
2354 }
2355
2356 GenerateObjectFileTargets ( cc,
2357 cppc,
2358 cflagsMacro,
2359 nasmflagsMacro,
2360 windresflagsMacro,
2361 widlflagsMacro );
2362 }
2363
2364 void
2365 MingwModuleHandler::GetInvocationDependencies (
2366 const Module& module,
2367 string_list& dependencies )
2368 {
2369 for ( size_t i = 0; i < module.invocations.size (); i++ )
2370 {
2371 Invoke& invoke = *module.invocations[i];
2372 if ( invoke.invokeModule == &module )
2373 /* Protect against circular dependencies */
2374 continue;
2375 invoke.GetTargets ( dependencies );
2376 }
2377 }
2378
2379 void
2380 MingwModuleHandler::GenerateInvocations () const
2381 {
2382 if ( module.invocations.size () == 0 )
2383 return;
2384
2385 size_t iend = module.invocations.size ();
2386 for ( size_t i = 0; i < iend; i++ )
2387 {
2388 const Invoke& invoke = *module.invocations[i];
2389
2390 if ( invoke.invokeModule->type != BuildTool )
2391 {
2392 throw XMLInvalidBuildFileException (
2393 module.node.location,
2394 "Only modules of type buildtool can be invoked." );
2395 }
2396
2397 string invokeTarget = module.GetInvocationTarget ( i );
2398 string_list invoke_targets;
2399 assert ( invoke_targets.size() );
2400 invoke.GetTargets ( invoke_targets );
2401 fprintf ( fMakefile,
2402 ".PHONY: %s\n\n",
2403 invokeTarget.c_str () );
2404 fprintf ( fMakefile,
2405 "%s:",
2406 invokeTarget.c_str () );
2407 size_t j, jend = invoke_targets.size();
2408 for ( j = 0; j < jend; j++ )
2409 {
2410 fprintf ( fMakefile,
2411 " %s",
2412 invoke_targets[i].c_str () );
2413 }
2414 fprintf ( fMakefile, "\n\n%s", invoke_targets[0].c_str () );
2415 for ( j = 1; j < jend; j++ )
2416 fprintf ( fMakefile,
2417 " %s",
2418 invoke_targets[i].c_str () );
2419 fprintf ( fMakefile,
2420 ": %s\n",
2421 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str () );
2422 fprintf ( fMakefile, "\t$(ECHO_INVOKE)\n" );
2423 fprintf ( fMakefile,
2424 "\t%s %s\n\n",
2425 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str (),
2426 invoke.GetParameters ().c_str () );
2427 }
2428 }
2429
2430 string
2431 MingwModuleHandler::GetPreconditionDependenciesName () const
2432 {
2433 return module.name + "_precondition";
2434 }
2435
2436 void
2437 MingwModuleHandler::GetDefaultDependencies (
2438 string_list& dependencies ) const
2439 {
2440 /* Avoid circular dependency */
2441 if ( module.type != BuildTool
2442 && module.name != "zlib"
2443 && module.name != "hostzlib" )
2444
2445 dependencies.push_back ( "$(INIT)" );
2446
2447 if ( module.type != BuildTool
2448 && module.name != "psdk" )
2449
2450 dependencies.push_back ( "$(PSDK_TARGET) $(psdk_HEADERS)" );
2451
2452 /* Check if any dependent library relays on the generated headers */
2453 for ( size_t i = 0; i < module.project.modules.size (); i++ )
2454 {
2455 const Module& m = *module.project.modules[i];
2456 for ( size_t j = 0; j < m.non_if_data.compilationUnits.size (); j++ )
2457 {
2458 CompilationUnit& compilationUnit = *m.non_if_data.compilationUnits[j];
2459 const FileLocation* sourceFile = compilationUnit.GetFilename ();
2460 string extension = GetExtension ( *sourceFile );
2461 if (extension == ".mc" || extension == ".MC" )
2462 {
2463 string dependency = ssprintf ( " $(%s_MCHEADERS)", m.name.c_str () );
2464 dependencies.push_back ( dependency );
2465 }
2466 }
2467 }
2468 }
2469
2470 void
2471 MingwModuleHandler::GeneratePreconditionDependencies ()
2472 {
2473 string preconditionDependenciesName = GetPreconditionDependenciesName ();
2474 vector<FileLocation> sourceFilenames;
2475 GetSourceFilenamesWithoutGeneratedFiles ( sourceFilenames );
2476 string_list dependencies;
2477 GetDefaultDependencies ( dependencies );
2478 GetModuleDependencies ( dependencies );
2479
2480 GetInvocationDependencies ( module, dependencies );
2481
2482 if ( dependencies.size() )
2483 {
2484 fprintf ( fMakefile,
2485 "%s =",
2486 preconditionDependenciesName.c_str () );
2487 for ( size_t i = 0; i < dependencies.size(); i++ )
2488 fprintf ( fMakefile,
2489 " %s",
2490 dependencies[i].c_str () );
2491 fprintf ( fMakefile, "\n\n" );
2492 }
2493
2494 for ( size_t i = 0; i < sourceFilenames.size(); i++ )
2495 {
2496 fprintf ( fMakefile,
2497 "%s: ${%s}\n",
2498 backend->GetFullName ( sourceFilenames[i] ).c_str (),
2499 preconditionDependenciesName.c_str ());
2500 }
2501 fprintf ( fMakefile, "\n" );
2502 }
2503
2504 bool
2505 MingwModuleHandler::IsWineModule () const
2506 {
2507 if ( module.importLibrary == NULL)
2508 return false;
2509
2510 size_t index = module.importLibrary->source->name.rfind ( ".spec.def" );
2511 return ( index != string::npos );
2512 }
2513
2514 const FileLocation*
2515 MingwModuleHandler::GetDefinitionFilename () const
2516 {
2517 if ( module.importLibrary != NULL )
2518 {
2519 DirectoryLocation directory;
2520 if ( IsWineModule () )
2521 directory = IntermediateDirectory;
2522 else
2523 directory = SourceDirectory;
2524
2525 return new FileLocation ( directory,
2526 module.importLibrary->source->relative_path,
2527 module.importLibrary->source->name );
2528 }
2529 else
2530 return new FileLocation ( SourceDirectory, "tools" + sSep + "rbuild", "empty.def" );
2531 }
2532
2533 void
2534 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
2535 {
2536 if ( module.importLibrary != NULL )
2537 {
2538 const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
2539 const FileLocation *defFilename = GetDefinitionFilename ();
2540
2541 vector<FileLocation> deps;
2542 GetDefinitionDependencies ( deps );
2543
2544 fprintf ( fMakefile, "# IMPORT LIBRARY RULE:\n" );
2545
2546 fprintf ( fMakefile, "%s: %s",
2547 backend->GetFullName ( *library_target ).c_str (),
2548 backend->GetFullName ( *defFilename ).c_str () );
2549
2550 size_t i, iend = deps.size();
2551 for ( i = 0; i < iend; i++ )
2552 fprintf ( fMakefile, " %s",
2553 backend->GetFullName ( deps[i] ).c_str () );
2554
2555 fprintf ( fMakefile, " | %s\n",
2556 backend->GetFullPath ( *GetImportLibraryFilename ( module, NULL ) ).c_str () );
2557
2558 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
2559
2560 fprintf ( fMakefile,
2561 "\t${dlltool} --dllname %s --def %s --output-lib %s %s %s\n\n",
2562 module.output->name.c_str (),
2563 backend->GetFullName ( *defFilename ).c_str (),
2564 backend->GetFullName ( *library_target ).c_str (),
2565 module.mangledSymbols ? "" : "--kill-at",
2566 module.underscoreSymbols ? "--add-underscore" : "" );
2567 }
2568 }
2569
2570 void
2571 MingwModuleHandler::GetSpecObjectDependencies (
2572 vector<FileLocation>& dependencies,
2573 const FileLocation *file ) const
2574 {
2575 string basename = GetBasename ( file->name );
2576
2577 FileLocation defDependency ( IntermediateDirectory,
2578 file->relative_path,
2579 basename + ".spec.def" );
2580 dependencies.push_back ( defDependency );
2581
2582 FileLocation stubsDependency ( IntermediateDirectory,
2583 file->relative_path,
2584 basename + ".stubs.c" );
2585 dependencies.push_back ( stubsDependency );
2586 }
2587
2588 void
2589 MingwModuleHandler::GetMcObjectDependencies (
2590 vector<FileLocation>& dependencies,
2591 const FileLocation *file ) const
2592 {
2593 string basename = GetBasename ( file->name );
2594
2595 FileLocation defDependency ( IntermediateDirectory,
2596 "include/reactos",
2597 basename + ".h" );
2598 dependencies.push_back ( defDependency );
2599
2600 FileLocation stubsDependency ( IntermediateDirectory,
2601 file->relative_path,
2602 basename + ".rc" );
2603 dependencies.push_back ( stubsDependency );
2604 }
2605
2606 void
2607 MingwModuleHandler::GetWidlObjectDependencies (
2608 vector<FileLocation>& dependencies,
2609 const FileLocation *file ) const
2610 {
2611 string basename = GetBasename ( file->name );
2612
2613 FileLocation serverSourceDependency ( IntermediateDirectory,
2614 file->relative_path,
2615 basename + "_s.c" );
2616 dependencies.push_back ( serverSourceDependency );
2617 dependencies.push_back ( *GetRpcServerHeaderFilename ( file ) );
2618 }
2619
2620 void
2621 MingwModuleHandler::GetDefinitionDependencies (
2622 vector<FileLocation>& dependencies ) const
2623 {
2624 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2625 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2626 {
2627 CompilationUnit& compilationUnit = *compilationUnits[i];
2628 const FileLocation* sourceFile = compilationUnit.GetFilename ();
2629 string extension = GetExtension ( *sourceFile );
2630 if ( extension == ".spec" || extension == ".SPEC" )
2631 GetSpecObjectDependencies ( dependencies, sourceFile );
2632 if ( extension == ".idl" || extension == ".IDL" )
2633 {
2634 if ( ( module.type == RpcServer ) || ( module.type == RpcClient ) )
2635 GetWidlObjectDependencies ( dependencies, sourceFile );
2636 }
2637 }
2638 }
2639
2640 enum DebugSupportType
2641 {
2642 DebugKernelMode,
2643 DebugUserMode
2644 };
2645
2646 static void
2647 MingwAddDebugSupportLibraries ( Module& module, DebugSupportType type )
2648 {
2649 Library* pLibrary;
2650
2651 switch(type)
2652 {
2653 case DebugKernelMode:
2654 pLibrary = new Library ( module, "debugsup_ntoskrnl" );
2655 break;
2656
2657 case DebugUserMode:
2658 pLibrary = new Library ( module, "debugsup_ntdll" );
2659 break;
2660
2661 default:
2662 assert(0);
2663 }
2664
2665 module.non_if_data.libraries.push_back(pLibrary);
2666 }
2667
2668 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler ( const Module& module_ )
2669 : MingwModuleHandler ( module_ )
2670 {
2671 }
2672
2673 void
2674 MingwBuildToolModuleHandler::Process ()
2675 {
2676 GenerateBuildToolModuleTarget ();
2677 }
2678
2679 void
2680 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
2681 {
2682 string targetMacro ( GetTargetMacro (module) );
2683 string objectsMacro = GetObjectsMacro ( module );
2684 string linkDepsMacro = GetLinkingDependenciesMacro ();
2685 string libsMacro = GetLibsMacro ();
2686
2687 GenerateRules ();
2688
2689 string linker;
2690 if ( module.cplusplus )
2691 linker = "${host_gpp}";
2692 else
2693 linker = "${host_gcc}";
2694
2695 fprintf ( fMakefile, "%s: %s %s | %s\n",
2696 targetMacro.c_str (),
2697 objectsMacro.c_str (),
2698 linkDepsMacro.c_str (),
2699 backend->GetFullPath ( *GetTargetFilename ( module, NULL ) ).c_str () );
2700 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2701 fprintf ( fMakefile,
2702 "\t%s %s -o $@ %s %s\n\n",
2703 linker.c_str (),
2704 GetLinkerMacro ().c_str (),
2705 objectsMacro.c_str (),
2706 libsMacro.c_str () );
2707 }
2708
2709
2710 MingwKernelModuleHandler::MingwKernelModuleHandler (
2711 const Module& module_ )
2712
2713 : MingwModuleHandler ( module_ )
2714 {
2715 }
2716
2717 void
2718 MingwKernelModuleHandler::Process ()
2719 {
2720 GenerateKernelModuleTarget ();
2721 }
2722
2723 void
2724 MingwKernelModuleHandler::GenerateKernelModuleTarget ()
2725 {
2726 string targetMacro ( GetTargetMacro ( module ) );
2727 string workingDirectory = GetWorkingDirectory ( );
2728 string objectsMacro = GetObjectsMacro ( module );
2729 string linkDepsMacro = GetLinkingDependenciesMacro ();
2730 string libsMacro = GetLibsMacro ();
2731
2732 GenerateImportLibraryTargetIfNeeded ();
2733
2734 if ( module.non_if_data.compilationUnits.size () > 0 )
2735 {
2736 GenerateRules ();
2737
2738 string dependencies = linkDepsMacro + " " + objectsMacro;
2739
2740 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s",
2741 module.GetEntryPoint(true).c_str (),
2742 module.baseaddress.c_str () );
2743 GenerateLinkerCommand ( dependencies,
2744 "${gcc}",
2745 linkerParameters + " $(NTOSKRNL_SHARED)",
2746 objectsMacro,
2747 libsMacro,
2748 "-sections" );
2749 }
2750 else
2751 {
2752 GeneratePhonyTarget();
2753 }
2754 }
2755
2756
2757 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler (
2758 const Module& module_ )
2759
2760 : MingwModuleHandler ( module_ )
2761 {
2762 }
2763
2764 void
2765 MingwStaticLibraryModuleHandler::Process ()
2766 {
2767 GenerateStaticLibraryModuleTarget ();
2768 }
2769
2770 void
2771 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ()
2772 {
2773 GenerateRules ();
2774 }
2775
2776
2777 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler (
2778 const Module& module_ )
2779
2780 : MingwModuleHandler ( module_ )
2781 {
2782 }
2783
2784 void
2785 MingwObjectLibraryModuleHandler::Process ()
2786 {
2787 GenerateObjectLibraryModuleTarget ();
2788 }
2789
2790 void
2791 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ()
2792 {
2793 GenerateRules ();
2794 }
2795
2796
2797 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
2798 const Module& module_ )
2799
2800 : MingwModuleHandler ( module_ )
2801 {
2802 }
2803
2804 MingwEmbeddedTypeLibModuleHandler::MingwEmbeddedTypeLibModuleHandler (
2805 const Module& module_ )
2806
2807 : MingwModuleHandler ( module_ )
2808 {
2809 }
2810
2811 void
2812 MingwEmbeddedTypeLibModuleHandler::Process ()
2813 {
2814 GenerateRules ();
2815 }
2816
2817
2818 void
2819 MingwKernelModeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2820 {
2821 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2822 }
2823
2824 void
2825 MingwKernelModeDLLModuleHandler::Process ()
2826 {
2827 GenerateKernelModeDLLModuleTarget ();
2828 }
2829
2830 void
2831 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
2832 {
2833 string targetMacro ( GetTargetMacro ( module ) );
2834 string workingDirectory = GetWorkingDirectory ( );
2835 string objectsMacro = GetObjectsMacro ( module );
2836 string linkDepsMacro = GetLinkingDependenciesMacro ();
2837 string libsMacro = GetLibsMacro ();
2838
2839 GenerateImportLibraryTargetIfNeeded ();
2840
2841 if ( module.non_if_data.compilationUnits.size () > 0 )
2842 {
2843 GenerateRules ();
2844
2845 string dependencies = linkDepsMacro + " " + objectsMacro;
2846
2847 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
2848 module.GetEntryPoint(true).c_str (),
2849 module.baseaddress.c_str () );
2850 GenerateLinkerCommand ( dependencies,
2851 "${gcc}",
2852 linkerParameters,
2853 objectsMacro,
2854