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