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