Add support for a new environment variable ROS_GENERATE_RSYM to disable RSYM during...
[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 "ifneq ($(ROS_GENERATE_RSYM),no)\n" );
1555 fprintf ( fMakefile,
1556 "\t$(ECHO_RSYM)\n" );
1557 fprintf ( fMakefile,
1558 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
1559 fprintf ( fMakefile,
1560 "endif\n" );
1561 }
1562
1563 void
1564 MingwModuleHandler::GenerateRunStripCode () const
1565 {
1566 fprintf ( fMakefile,
1567 "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
1568 fprintf ( fMakefile,
1569 "\t$(ECHO_STRIP)\n" );
1570 fprintf ( fMakefile,
1571 "\t${strip} -s -x -X $@\n\n" );
1572 fprintf ( fMakefile,
1573 "endif\n" );
1574 }
1575
1576 void
1577 MingwModuleHandler::GenerateLinkerCommand (
1578 const string& dependencies,
1579 const string& linkerParameters,
1580 const string& pefixupParameters )
1581 {
1582 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1583 const FileLocation *definitionFilename = GetDefinitionFilename ();
1584 string linker = module.cplusplus ? "${gpp}" : "${gcc}";
1585 string objectsMacro = GetObjectsMacro ( module );
1586 string libsMacro = GetLibsMacro ();
1587
1588 string target_macro ( GetTargetMacro ( module ) );
1589 string target_folder ( backend->GetFullPath ( *target_file ) );
1590
1591 string linkerScriptArgument;
1592 if ( module.linkerScript != NULL )
1593 linkerScriptArgument = ssprintf ( " -Wl,-T,%s", backend->GetFullName ( *module.linkerScript->file ).c_str () );
1594 else
1595 linkerScriptArgument = "";
1596
1597 fprintf ( fMakefile,
1598 "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
1599 target_macro.c_str (),
1600 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1601 dependencies.c_str (),
1602 target_folder.c_str () );
1603 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1604 string targetName ( module.output->name );
1605
1606 if ( !module.IsDLL () )
1607 {
1608 fprintf ( fMakefile,
1609 "\t%s %s%s -o %s %s %s %s\n",
1610 linker.c_str (),
1611 linkerParameters.c_str (),
1612 linkerScriptArgument.c_str (),
1613 target_macro.c_str (),
1614 objectsMacro.c_str (),
1615 libsMacro.c_str (),
1616 GetLinkerMacro ().c_str () );
1617 }
1618 else if ( module.HasImportLibrary () )
1619 {
1620 FileLocation temp_exp ( TemporaryDirectory,
1621 "",
1622 module.name + ".temp.exp" );
1623 CLEAN_FILE ( temp_exp );
1624
1625 fprintf ( fMakefile,
1626 "\t${dlltool} --dllname %s --def %s --output-exp %s%s%s\n",
1627 targetName.c_str (),
1628 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1629 backend->GetFullName ( temp_exp ).c_str (),
1630 module.mangledSymbols ? "" : " --kill-at",
1631 module.underscoreSymbols ? " --add-underscore" : "" );
1632
1633 fprintf ( fMakefile,
1634 "\t%s %s%s %s -o %s %s %s %s\n",
1635 linker.c_str (),
1636 linkerParameters.c_str (),
1637 linkerScriptArgument.c_str (),
1638 backend->GetFullName ( temp_exp ).c_str (),
1639 target_macro.c_str (),
1640 objectsMacro.c_str (),
1641 libsMacro.c_str (),
1642 GetLinkerMacro ().c_str () );
1643
1644 fprintf ( fMakefile,
1645 "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n",
1646 target_macro.c_str (),
1647 pefixupParameters.c_str() );
1648
1649 fprintf ( fMakefile,
1650 "\t-@${rm} %s 2>$(NUL)\n",
1651 backend->GetFullName ( temp_exp ).c_str () );
1652 }
1653 else
1654 {
1655 /* XXX: need to workaround binutils bug, which exports
1656 * all functions in a dll if no .def file or an empty
1657 * one has been provided... */
1658 /* See bug 1244 */
1659 //printf ( "%s will have all its functions exported\n",
1660 // module.target->name.c_str () );
1661 fprintf ( fMakefile,
1662 "\t%s %s%s -o %s %s %s %s\n",
1663 linker.c_str (),
1664 linkerParameters.c_str (),
1665 linkerScriptArgument.c_str (),
1666 target_macro.c_str (),
1667 objectsMacro.c_str (),
1668 libsMacro.c_str (),
1669 GetLinkerMacro ().c_str () );
1670 }
1671
1672 GenerateBuildMapCode ();
1673 GenerateBuildNonSymbolStrippedCode ();
1674 GenerateRunRsymCode ();
1675 GenerateRunStripCode ();
1676 GenerateCleanObjectsAsYouGoCode ();
1677
1678 if ( definitionFilename )
1679 delete definitionFilename;
1680 delete target_file;
1681 }
1682
1683 void
1684 MingwModuleHandler::GeneratePhonyTarget() const
1685 {
1686 string targetMacro ( GetTargetMacro ( module ) );
1687 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1688
1689 fprintf ( fMakefile,
1690 ".PHONY: %s\n\n",
1691 targetMacro.c_str ());
1692 fprintf ( fMakefile, "%s: | %s\n",
1693 targetMacro.c_str (),
1694 backend->GetFullPath ( *target_file ).c_str () );
1695
1696 delete target_file;
1697 }
1698
1699 void
1700 MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
1701 {
1702 size_t i;
1703 string moduleDependencies;
1704
1705 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1706 for ( i = 0; i < compilationUnits.size (); i++ )
1707 {
1708 CompilationUnit& compilationUnit = *compilationUnits[i];
1709 const FileLocation& compilationName = compilationUnit.GetFilename ();
1710 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module );
1711 if ( GetExtension ( *objectFilename ) == ".h" )
1712 moduleDependencies += ssprintf ( " $(%s_HEADERS)", module.name.c_str () );
1713 else if ( GetExtension ( *objectFilename ) == ".rc" )
1714 moduleDependencies += ssprintf ( " $(%s_RESOURCES)", module.name.c_str () );
1715 delete objectFilename;
1716 }
1717
1718 for ( i = 0; i < compilationUnits.size (); i++ )
1719 {
1720 GenerateCommands ( *compilationUnits[i],
1721 moduleDependencies );
1722 fprintf ( fMakefile,
1723 "\n" );
1724 }
1725
1726 const vector<If*>& ifs = data.ifs;
1727 for ( i = 0; i < ifs.size(); i++ )
1728 {
1729 GenerateObjectFileTargets ( ifs[i]->data );
1730 }
1731
1732 vector<CompilationUnit*> sourceCompilationUnits;
1733 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1734 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1735 {
1736 GenerateCommands ( *sourceCompilationUnits[i],
1737 moduleDependencies );
1738 }
1739 CleanupCompilationUnitVector ( sourceCompilationUnits );
1740 }
1741
1742 void
1743 MingwModuleHandler::GenerateObjectFileTargets ()
1744 {
1745 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1746
1747 if ( pchFilename )
1748 {
1749 string cc = ( module.host == HostTrue ? "${host_gcc}" : "${gcc}" );
1750 string cppc = ( module.host == HostTrue ? "${host_gpp}" : "${gpp}" );
1751
1752 const FileLocation& baseHeaderFile = *module.pch->file;
1753 CLEAN_FILE ( *pchFilename );
1754 string dependencies = backend->GetFullName ( baseHeaderFile );
1755 /* WIDL generated headers may be used */
1756 vector<FileLocation> rpcDependencies;
1757 GetRpcHeaderDependencies ( rpcDependencies );
1758 if ( rpcDependencies.size () > 0 )
1759 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1760 fprintf ( fMakefile,
1761 "%s: %s | %s\n",
1762 backend->GetFullName ( *pchFilename ).c_str(),
1763 dependencies.c_str(),
1764 backend->GetFullPath ( *pchFilename ).c_str() );
1765 fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
1766 fprintf ( fMakefile,
1767 "\t%s -o %s %s -g %s\n\n",
1768 module.cplusplus ? cppc.c_str() : cc.c_str(),
1769 backend->GetFullName ( *pchFilename ).c_str(),
1770 cflagsMacro.c_str(),
1771 backend->GetFullName ( baseHeaderFile ).c_str() );
1772 delete pchFilename;
1773 }
1774
1775 GenerateObjectFileTargets ( module.non_if_data );
1776 fprintf ( fMakefile, "\n" );
1777 }
1778
1779 /* caller needs to delete the returned object */
1780 const FileLocation*
1781 MingwModuleHandler::GenerateArchiveTarget ()
1782 {
1783 const FileLocation *archiveFilename = GetModuleArchiveFilename ();
1784 const FileLocation *definitionFilename = GetDefinitionFilename ();
1785
1786 arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1787
1788 if ( IsStaticLibrary ( module ) && definitionFilename )
1789 {
1790 fprintf ( fMakefile,
1791 "\t${dlltool} --dllname %s --def %s --output-lib $@%s%s\n",
1792 module.importLibrary->dllname.c_str (),
1793 backend->GetFullName ( *definitionFilename ).c_str (),
1794 module.mangledSymbols ? "" : " --kill-at",
1795 module.underscoreSymbols ? " --add-underscore" : "" );
1796 }
1797
1798 if ( definitionFilename )
1799 delete definitionFilename;
1800
1801 if(module.type == HostStaticLibrary)
1802 arHostRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1803 else
1804 arRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1805
1806 GenerateCleanObjectsAsYouGoCode ();
1807
1808 fprintf ( fMakefile, "\n" );
1809
1810 return archiveFilename;
1811 }
1812
1813 string
1814 MingwModuleHandler::GetCFlagsMacro () const
1815 {
1816 return ssprintf ( "$(%s_CFLAGS)",
1817 module.name.c_str () );
1818 }
1819
1820 /*static*/ string
1821 MingwModuleHandler::GetObjectsMacro ( const Module& module )
1822 {
1823 return ssprintf ( "$(%s_OBJS)",
1824 module.name.c_str () );
1825 }
1826
1827 string
1828 MingwModuleHandler::GetLinkingDependenciesMacro () const
1829 {
1830 return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
1831 }
1832
1833 string
1834 MingwModuleHandler::GetLibsMacro () const
1835 {
1836 return ssprintf ( "$(%s_LIBS)", module.name.c_str () );
1837 }
1838
1839 string
1840 MingwModuleHandler::GetLinkerMacro () const
1841 {
1842 return ssprintf ( "$(%s_LFLAGS)",
1843 module.name.c_str () );
1844 }
1845
1846 string
1847 MingwModuleHandler::GetModuleTargets ( const Module& module )
1848 {
1849 if ( ReferenceObjects ( module ) )
1850 return GetObjectsMacro ( module );
1851 else
1852 {
1853 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1854 string target = backend->GetFullName ( *target_file ).c_str ();
1855 delete target_file;
1856 return target;
1857 }
1858 }
1859
1860 void
1861 MingwModuleHandler::GenerateSourceMacro ()
1862 {
1863 sourcesMacro = ssprintf ( "%s_SOURCES", module.name.c_str ());
1864
1865 GenerateSourceMacros (
1866 "=",
1867 module.non_if_data );
1868
1869 // future references to the macro will be to get its values
1870 sourcesMacro = ssprintf ("$(%s)", sourcesMacro.c_str ());
1871 }
1872
1873 void
1874 MingwModuleHandler::GenerateObjectMacro ()
1875 {
1876 objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
1877
1878 GenerateObjectMacros (
1879 "=",
1880 module.non_if_data );
1881
1882 // future references to the macro will be to get its values
1883 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
1884 }
1885
1886 void
1887 MingwModuleHandler::GenerateTargetMacro ()
1888 {
1889 fprintf ( fMakefile,
1890 "%s := %s\n",
1891 GetTargetMacro ( module, false ).c_str (),
1892 GetModuleTargets ( module ).c_str () );
1893 }
1894
1895 void
1896 MingwModuleHandler::GetRpcHeaderDependencies (
1897 vector<FileLocation>& dependencies ) const
1898 {
1899 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
1900 {
1901 Library& library = *module.non_if_data.libraries[i];
1902 if ( library.importedModule->type == RpcServer ||
1903 library.importedModule->type == RpcClient ||
1904 library.importedModule->type == RpcProxy ||
1905 library.importedModule->type == IdlHeader )
1906 {
1907 for ( size_t j = 0; j < library.importedModule->non_if_data.compilationUnits.size (); j++ )
1908 {
1909 CompilationUnit& compilationUnit = *library.importedModule->non_if_data.compilationUnits[j];
1910 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1911 string extension = GetExtension ( sourceFile );
1912 if ( extension == ".idl" || extension == ".IDL" )
1913 {
1914 string basename = GetBasename ( sourceFile.name );
1915 if ( library.importedModule->type == RpcServer )
1916 {
1917 const FileLocation *header = GetRpcServerHeaderFilename ( &sourceFile );
1918 dependencies.push_back ( *header );
1919 delete header;
1920 }
1921 if ( library.importedModule->type == RpcClient )
1922 {
1923 const FileLocation *header = GetRpcClientHeaderFilename ( &sourceFile );
1924 dependencies.push_back ( *header );
1925 delete header;
1926 }
1927 if ( library.importedModule->type == RpcProxy )
1928 {
1929 const FileLocation *header = GetRpcProxyHeaderFilename ( &sourceFile );
1930 dependencies.push_back ( *header );
1931 delete header;
1932 }
1933 if ( library.importedModule->type == IdlHeader )
1934 {
1935 const FileLocation *header = GetIdlHeaderFilename ( &sourceFile );
1936 dependencies.push_back ( *header );
1937 delete header;
1938 }
1939 }
1940 }
1941 }
1942 }
1943 }
1944
1945 void
1946 MingwModuleHandler::GenerateOtherMacros ()
1947 {
1948 set<const Define *> used_defs;
1949
1950 cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
1951 nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
1952 windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
1953 widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());
1954 linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
1955 libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
1956 linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
1957
1958 GenerateMacros (
1959 "=",
1960 module.non_if_data,
1961 &module.linkerFlags,
1962 used_defs );
1963
1964 if ( module.host == HostFalse )
1965 {
1966 GenerateMacros (
1967 "+=",
1968 module.project.non_if_data,
1969 NULL,
1970 used_defs );
1971 }
1972
1973 vector<FileLocation> s;
1974 if ( module.importLibrary )
1975 {
1976 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
1977 for ( size_t i = 0; i < compilationUnits.size (); i++ )
1978 {
1979 CompilationUnit& compilationUnit = *compilationUnits[i];
1980 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1981 string extension = GetExtension ( sourceFile );
1982 if ( extension == ".spec" || extension == ".SPEC" )
1983 GetSpecObjectDependencies ( s, &sourceFile );
1984 }
1985 }
1986 if ( s.size () > 0 )
1987 {
1988 fprintf (
1989 fMakefile,
1990 "%s +=",
1991 linkDepsMacro.c_str() );
1992 for ( size_t i = 0; i < s.size(); i++ )
1993 fprintf ( fMakefile,
1994 " %s",
1995 backend->GetFullName ( s[i] ).c_str () );
1996 fprintf ( fMakefile, "\n" );
1997 }
1998
1999 string globalCflags = "";
2000 if ( module.host == HostFalse )
2001 globalCflags += " $(PROJECT_CFLAGS)";
2002 else
2003 globalCflags += " -Wall -Wpointer-arith -D__REACTOS__";
2004 globalCflags += " -g";
2005 if ( backend->usePipe )
2006 globalCflags += " -pipe";
2007 if ( !module.allowWarnings )
2008 globalCflags += " -Werror";
2009 if ( module.host == HostTrue )
2010 {
2011 if ( module.cplusplus )
2012 globalCflags += " $(HOST_CPPFLAGS)";
2013 else
2014 globalCflags += " -Wno-strict-aliasing $(HOST_CFLAGS)";
2015 }
2016 else
2017 {
2018 if ( module.cplusplus )
2019 {
2020 // HACK: use host headers when building C++
2021 globalCflags += " $(HOST_CPPFLAGS)";
2022 }
2023 else
2024 globalCflags += " -nostdinc";
2025 }
2026
2027 // Always force disabling of sibling calls optimisation for GCC
2028 // (TODO: Move to version-specific once this bug is fixed in GCC)
2029 globalCflags += " -fno-optimize-sibling-calls";
2030
2031 fprintf (
2032 fMakefile,
2033 "%s +=%s\n",
2034 cflagsMacro.c_str (),
2035 globalCflags.c_str () );
2036
2037 if ( module.host == HostFalse )
2038 {
2039 fprintf (
2040 fMakefile,
2041 "%s += $(PROJECT_RCFLAGS)\n",
2042 windresflagsMacro.c_str () );
2043
2044 fprintf (
2045 fMakefile,
2046 "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
2047 widlflagsMacro.c_str (),
2048 module.output->relative_path.c_str () );
2049
2050 fprintf (
2051 fMakefile,
2052 "%s_LFLAGS += $(PROJECT_LFLAGS) -g\n",
2053 module.name.c_str () );
2054 }
2055 else
2056 {
2057 fprintf (
2058 fMakefile,
2059 "%s_LFLAGS += $(HOST_LFLAGS)\n",
2060 module.name.c_str () );
2061 }
2062
2063 fprintf (
2064 fMakefile,
2065 "%s += $(%s)\n",
2066 linkDepsMacro.c_str (),
2067 libsMacro.c_str () );
2068
2069 string cflags = TypeSpecificCFlags();
2070 if ( cflags.size() > 0 )
2071 {
2072 fprintf ( fMakefile,
2073 "%s += %s\n\n",
2074 cflagsMacro.c_str (),
2075 cflags.c_str () );
2076 }
2077
2078 string nasmflags = TypeSpecificNasmFlags();
2079 if ( nasmflags.size () > 0 )
2080 {
2081 fprintf ( fMakefile,
2082 "%s += %s\n\n",
2083 nasmflagsMacro.c_str (),
2084 nasmflags.c_str () );
2085 }
2086
2087 string linkerflags = TypeSpecificLinkerFlags();
2088 if ( linkerflags.size() > 0 )
2089 {
2090 fprintf ( fMakefile,
2091 "%s += %s\n\n",
2092 linkerflagsMacro.c_str (),
2093 linkerflags.c_str () );
2094 }
2095
2096 if ( IsStaticLibrary ( module ) && module.isStartupLib )
2097 {
2098 fprintf ( fMakefile,
2099 "%s += -Wno-main\n\n",
2100 cflagsMacro.c_str () );
2101 }
2102
2103 fprintf ( fMakefile, "\n\n" );
2104
2105 // future references to the macros will be to get their values
2106 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
2107 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
2108 widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
2109 }
2110
2111 void
2112 MingwModuleHandler::GenerateRules ()
2113 {
2114 string targetMacro = GetTargetMacro ( module );
2115 //CLEAN_FILE ( targetMacro );
2116 CLEAN_FILE ( FileLocation ( SourceDirectory, "", targetMacro ) );
2117
2118 // generate phony target for module name
2119 fprintf ( fMakefile, ".PHONY: %s\n",
2120 module.name.c_str () );
2121 string dependencies = GetTargetMacro ( module );
2122 if ( module.type == Test )
2123 dependencies += " $(REGTESTS_RUN_TARGET)";
2124 fprintf ( fMakefile, "%s: %s\n\n",
2125 module.name.c_str (),
2126 dependencies.c_str () );
2127 if ( module.type == Test )
2128 {
2129 fprintf ( fMakefile,
2130 "\t@%s\n",
2131 targetMacro.c_str ());
2132 }
2133
2134 if ( !ReferenceObjects ( module ) )
2135 {
2136 const FileLocation* ar_target = GenerateArchiveTarget ();
2137 delete ar_target;
2138 }
2139
2140 GenerateObjectFileTargets ();
2141 }
2142
2143 void
2144 MingwModuleHandler::GetInvocationDependencies (
2145 const Module& module,
2146 string_list& dependencies )
2147 {
2148 for ( size_t i = 0; i < module.invocations.size (); i++ )
2149 {
2150 Invoke& invoke = *module.invocations[i];
2151 if ( invoke.invokeModule == &module )
2152 /* Protect against circular dependencies */
2153 continue;
2154 invoke.GetTargets ( dependencies );
2155 }
2156 }
2157
2158 void
2159 MingwModuleHandler::GenerateInvocations () const
2160 {
2161 if ( module.invocations.size () == 0 )
2162 return;
2163
2164 size_t iend = module.invocations.size ();
2165 for ( size_t i = 0; i < iend; i++ )
2166 {
2167 const Invoke& invoke = *module.invocations[i];
2168
2169 if ( invoke.invokeModule->type != BuildTool )
2170 {
2171 throw XMLInvalidBuildFileException (
2172 module.node.location,
2173 "Only modules of type buildtool can be invoked." );
2174 }
2175
2176 string invokeTarget = module.GetInvocationTarget ( i );
2177 string_list invoke_targets;
2178 assert ( invoke_targets.size() );
2179 invoke.GetTargets ( invoke_targets );
2180 fprintf ( fMakefile,
2181 ".PHONY: %s\n\n",
2182 invokeTarget.c_str () );
2183 fprintf ( fMakefile,
2184 "%s:",
2185 invokeTarget.c_str () );
2186 size_t j, jend = invoke_targets.size();
2187 for ( j = 0; j < jend; j++ )
2188 {
2189 fprintf ( fMakefile,
2190 " %s",
2191 invoke_targets[i].c_str () );
2192 }
2193 fprintf ( fMakefile, "\n\n%s", invoke_targets[0].c_str () );
2194 for ( j = 1; j < jend; j++ )
2195 fprintf ( fMakefile,
2196 " %s",
2197 invoke_targets[i].c_str () );
2198 fprintf ( fMakefile,
2199 ": %s\n",
2200 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str () );
2201 fprintf ( fMakefile, "\t$(ECHO_INVOKE)\n" );
2202 fprintf ( fMakefile,
2203 "\t%s %s\n\n",
2204 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str (),
2205 invoke.GetParameters ().c_str () );
2206 }
2207 }
2208
2209 string
2210 MingwModuleHandler::GetPreconditionDependenciesName () const
2211 {
2212 return module.name + "_precondition";
2213 }
2214
2215 void
2216 MingwModuleHandler::GetDefaultDependencies (
2217 string_list& dependencies ) const
2218 {
2219 /* Avoid circular dependency */
2220 if ( module.host == HostTrue )
2221 return;
2222
2223 if (module.name != "psdk" &&
2224 module.name != "dxsdk")
2225 {
2226 dependencies.push_back ( "$(PSDK_TARGET) $(psdk_HEADERS)" );
2227 dependencies.push_back ( "$(DXSDK_TARGET) $(dxsdk_HEADERS)" );
2228 }
2229
2230 if (module.name != "errcodes" &&
2231 module.name != "bugcodes" &&
2232 module.name != "ntstatus")
2233 {
2234 dependencies.push_back ( "$(ERRCODES_TARGET) $(ERRCODES_MCHEADERS)" );
2235 dependencies.push_back ( "$(BUGCODES_TARGET) $(BUGCODES_MCHEADERS)" );
2236 dependencies.push_back ( "$(NTSTATUS_TARGET) $(NTSTATUS_MCHEADERS)" );
2237 }
2238
2239 ///* Check if any dependent library relies on the generated headers */
2240 //for ( size_t i = 0; i < module.project.modules.size (); i++ )
2241 //{
2242 // const Module& m = *module.project.modules[i];
2243 // for ( size_t j = 0; j < m.non_if_data.compilationUnits.size (); j++ )
2244 // {
2245 // CompilationUnit& compilationUnit = *m.non_if_data.compilationUnits[j];
2246 // const FileLocation& sourceFile = compilationUnit.GetFilename ();
2247 // string extension = GetExtension ( sourceFile );
2248 // if (extension == ".mc" || extension == ".MC" )
2249 // {
2250 // string dependency = ssprintf ( "$(%s_MCHEADERS)", m.name.c_str () );
2251 // dependencies.push_back ( dependency );
2252 // }
2253 // }
2254 //}
2255 }
2256
2257 void
2258 MingwModuleHandler::GeneratePreconditionDependencies ()
2259 {
2260 string preconditionDependenciesName = GetPreconditionDependenciesName ();
2261 string_list dependencies;
2262 GetDefaultDependencies ( dependencies );
2263 GetModuleDependencies ( dependencies );
2264
2265 GetInvocationDependencies ( module, dependencies );
2266
2267 if ( dependencies.size() )
2268 {
2269 fprintf ( fMakefile,
2270 "%s =",
2271 preconditionDependenciesName.c_str () );
2272 for ( size_t i = 0; i < dependencies.size(); i++ )
2273 fprintf ( fMakefile,
2274 " %s",
2275 dependencies[i].c_str () );
2276 fprintf ( fMakefile, "\n\n" );
2277 }
2278
2279 fprintf ( fMakefile, "\n" );
2280 }
2281
2282 bool
2283 MingwModuleHandler::IsWineModule () const
2284 {
2285 if ( module.importLibrary == NULL)
2286 return false;
2287
2288 size_t index = module.importLibrary->source->name.rfind ( ".spec.def" );
2289 return ( index != string::npos );
2290 }
2291
2292 /* caller needs to delete the returned object */
2293 const FileLocation*
2294 MingwModuleHandler::GetDefinitionFilename () const
2295 {
2296 if ( module.importLibrary == NULL )
2297 return NULL;
2298
2299 DirectoryLocation directory;
2300 if ( IsWineModule () )
2301 directory = IntermediateDirectory;
2302 else
2303 directory = SourceDirectory;
2304
2305 return new FileLocation ( directory,
2306 module.importLibrary->source->relative_path,
2307 module.importLibrary->source->name );
2308 }
2309
2310 void
2311 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
2312 {
2313 if ( module.importLibrary != NULL )
2314 {
2315 const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
2316 const FileLocation *defFilename = GetDefinitionFilename ();
2317 string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
2318
2319 vector<FileLocation> deps;
2320 GetDefinitionDependencies ( deps );
2321
2322 fprintf ( fMakefile, "# IMPORT LIBRARY RULE:\n" );
2323
2324 fprintf ( fMakefile, "%s:",
2325 backend->GetFullName ( *library_target ).c_str () );
2326
2327 if ( defFilename )
2328 {
2329 fprintf ( fMakefile, " %s",
2330 backend->GetFullName ( *defFilename ).c_str () );
2331 }
2332
2333 size_t i, iend = deps.size();
2334 for ( i = 0; i < iend; i++ )
2335 fprintf ( fMakefile, " %s",
2336 backend->GetFullName ( deps[i] ).c_str () );
2337
2338 fprintf ( fMakefile, " | %s\n",
2339 backend->GetFullPath ( *library_target ).c_str () );
2340
2341 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
2342
2343 fprintf ( fMakefile,
2344 "\t${dlltool} --dllname %s --def %s --output-lib %s%s%s\n\n",
2345 module.output->name.c_str (),
2346 defFilename ? backend->GetFullName ( *defFilename ).c_str ()
2347 : empty.c_str (),
2348 backend->GetFullName ( *library_target ).c_str (),
2349 module.mangledSymbols ? "" : " --kill-at",
2350 module.underscoreSymbols ? " --add-underscore" : "" );
2351
2352 if ( defFilename )
2353 delete defFilename;
2354 delete library_target;
2355 }
2356 }
2357
2358 void
2359 MingwModuleHandler::GetSpecObjectDependencies (
2360 vector<FileLocation>& dependencies,
2361 const FileLocation *file ) const
2362 {
2363 string basename = GetBasename ( file->name );
2364
2365 FileLocation defDependency ( IntermediateDirectory,
2366 file->relative_path,
2367 basename + ".spec.def" );
2368 dependencies.push_back ( defDependency );
2369
2370 FileLocation stubsDependency ( IntermediateDirectory,
2371 file->relative_path,
2372 basename + ".stubs.c" );
2373 dependencies.push_back ( stubsDependency );
2374 }
2375
2376 void
2377 MingwModuleHandler::GetMcObjectDependencies (
2378 vector<FileLocation>& dependencies,
2379 const FileLocation *file ) const
2380 {
2381 string basename = GetBasename ( file->name );
2382
2383 FileLocation defDependency ( IntermediateDirectory,
2384 "include/reactos",
2385 basename + ".h" );
2386 dependencies.push_back ( defDependency );
2387
2388 FileLocation stubsDependency ( IntermediateDirectory,
2389 file->relative_path,
2390 basename + ".rc" );
2391 dependencies.push_back ( stubsDependency );
2392 }
2393
2394 void
2395 MingwModuleHandler::GetWidlObjectDependencies (
2396 vector<FileLocation>& dependencies,
2397 const FileLocation *file ) const
2398 {
2399 string basename = GetBasename ( file->name );
2400 const FileLocation *generatedHeaderFilename = GetRpcServerHeaderFilename ( file );
2401
2402 FileLocation serverSourceDependency ( IntermediateDirectory,
2403 file->relative_path,
2404 basename + "_s.c" );
2405 dependencies.push_back ( serverSourceDependency );
2406 dependencies.push_back ( *generatedHeaderFilename );
2407
2408 delete generatedHeaderFilename;
2409 }
2410
2411 void
2412 MingwModuleHandler::GetDefinitionDependencies (
2413 vector<FileLocation>& dependencies ) const
2414 {
2415 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2416 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2417 {
2418 const CompilationUnit& compilationUnit = *compilationUnits[i];
2419 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2420 string extension = GetExtension ( sourceFile );
2421 if ( extension == ".spec" || extension == ".SPEC" )
2422 GetSpecObjectDependencies ( dependencies, &sourceFile );
2423 if ( extension == ".idl" || extension == ".IDL" )
2424 {
2425 if ( ( module.type == RpcServer ) || ( module.type == RpcClient ) || ( module.type == RpcProxy ) )
2426 GetWidlObjectDependencies ( dependencies, &sourceFile );
2427 }
2428 }
2429 }
2430
2431 enum DebugSupportType
2432 {
2433 DebugKernelMode,
2434 DebugUserMode
2435 };
2436
2437 static void
2438 MingwAddDebugSupportLibraries ( Module& module, DebugSupportType type )
2439 {
2440 Library* pLibrary;
2441
2442 switch(type)
2443 {
2444 case DebugKernelMode:
2445 pLibrary = new Library ( module, "debugsup_ntoskrnl" );
2446 break;
2447
2448 case DebugUserMode:
2449 pLibrary = new Library ( module, "debugsup_ntdll" );
2450 break;
2451
2452 default:
2453 assert(0);
2454 }
2455
2456 module.non_if_data.libraries.push_back(pLibrary);
2457 }
2458
2459 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler ( const Module& module_ )
2460 : MingwModuleHandler ( module_ )
2461 {
2462 }
2463
2464 void
2465 MingwBuildToolModuleHandler::Process ()
2466 {
2467 GenerateBuildToolModuleTarget ();
2468 }
2469
2470 void
2471 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
2472 {
2473 string targetMacro ( GetTargetMacro (module) );
2474 string objectsMacro = GetObjectsMacro ( module );
2475 string linkDepsMacro = GetLinkingDependenciesMacro ();
2476 string libsMacro = GetLibsMacro ();
2477
2478 GenerateRules ();
2479
2480 string linker;
2481 if ( module.cplusplus )
2482 linker = "${host_gpp}";
2483 else
2484 linker = "${host_gcc}";
2485
2486 const FileLocation *target_file = GetTargetFilename ( module, NULL );
2487 fprintf ( fMakefile, "%s: %s %s | %s\n",
2488 targetMacro.c_str (),
2489 objectsMacro.c_str (),
2490 linkDepsMacro.c_str (),
2491 backend->GetFullPath ( *target_file ).c_str () );
2492 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2493 fprintf ( fMakefile,
2494 "\t%s %s -o $@ %s %s\n\n",
2495 linker.c_str (),
2496 GetLinkerMacro ().c_str (),
2497 objectsMacro.c_str (),
2498 libsMacro.c_str () );
2499
2500 delete target_file;
2501 }
2502
2503
2504 MingwKernelModuleHandler::MingwKernelModuleHandler (
2505 const Module& module_ )
2506
2507 : MingwModuleHandler ( module_ )
2508 {
2509 }
2510
2511 void
2512 MingwKernelModuleHandler::Process ()
2513 {
2514 GenerateKernelModuleTarget ();
2515 }
2516
2517 void
2518 MingwKernelModuleHandler::GenerateKernelModuleTarget ()
2519 {
2520 string targetMacro ( GetTargetMacro ( module ) );
2521 string workingDirectory = GetWorkingDirectory ( );
2522 string linkDepsMacro = GetLinkingDependenciesMacro ();
2523
2524 GenerateImportLibraryTargetIfNeeded ();
2525
2526 if ( module.non_if_data.compilationUnits.size () > 0 )
2527 {
2528 GenerateRules ();
2529
2530 string dependencies = linkDepsMacro + " " + objectsMacro;
2531
2532 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s",
2533 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2534 module.baseaddress.c_str () );
2535
2536 GenerateLinkerCommand ( dependencies,
2537 linkerParameters + " $(NTOSKRNL_SHARED)",
2538 " -sections" );
2539 }
2540 else
2541 {
2542 GeneratePhonyTarget();
2543 }
2544 }
2545
2546
2547 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler (
2548 const Module& module_ )
2549
2550 : MingwModuleHandler ( module_ )
2551 {
2552 }
2553
2554 void
2555 MingwStaticLibraryModuleHandler::Process ()
2556 {
2557 GenerateStaticLibraryModuleTarget ();
2558 }
2559
2560 void
2561 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ()
2562 {
2563 GenerateRules ();
2564 }
2565
2566
2567 MingwHostStaticLibraryModuleHandler::MingwHostStaticLibraryModuleHandler (
2568 const Module& module_ )
2569
2570 : MingwModuleHandler ( module_ )
2571 {
2572 }
2573
2574 void
2575 MingwHostStaticLibraryModuleHandler::Process ()
2576 {
2577 GenerateHostStaticLibraryModuleTarget ();
2578 }
2579
2580 void
2581 MingwHostStaticLibraryModuleHandler::GenerateHostStaticLibraryModuleTarget ()
2582 {
2583 GenerateRules ();
2584 }
2585
2586
2587 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler (
2588 const Module& module_ )
2589
2590 : MingwModuleHandler ( module_ )
2591 {
2592 }
2593
2594 void
2595 MingwObjectLibraryModuleHandler::Process ()
2596 {
2597 GenerateObjectLibraryModuleTarget ();
2598 }
2599
2600 void
2601 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ()
2602 {
2603 GenerateRules ();
2604 }
2605
2606
2607 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
2608 const Module& module_ )
2609
2610 : MingwModuleHandler ( module_ )
2611 {
2612 }
2613
2614 MingwEmbeddedTypeLibModuleHandler::MingwEmbeddedTypeLibModuleHandler (
2615 const Module& module_ )
2616
2617 : MingwModuleHandler ( module_ )
2618 {
2619 }
2620
2621 void
2622 MingwEmbeddedTypeLibModuleHandler::Process ()
2623 {
2624 GenerateRules ();
2625 }
2626
2627
2628 void
2629 MingwKernelModeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2630 {
2631 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2632 }
2633
2634 void
2635 MingwKernelModeDLLModuleHandler::Process ()
2636 {
2637 GenerateKernelModeDLLModuleTarget ();
2638 }
2639
2640 void
2641 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
2642 {
2643 string targetMacro ( GetTargetMacro ( module ) );
2644 string workingDirectory = GetWorkingDirectory ( );
2645 string linkDepsMacro = GetLinkingDependenciesMacro ();
2646
2647 GenerateImportLibraryTargetIfNeeded ();
2648
2649 if ( module.non_if_data.compilationUnits.size () > 0 )
2650 {
2651 GenerateRules ();
2652
2653 string dependencies = linkDepsMacro + " " + objectsMacro;
2654
2655 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
2656 module.GetEntryPoint(true).c_str (),
2657 module.baseaddress.c_str () );
2658 GenerateLinkerCommand ( dependencies,
2659 linkerParameters,
2660 " -sections" );
2661 }
2662 else
2663 {
2664 GeneratePhonyTarget();
2665 }
2666 }
2667
2668
2669 MingwKernelModeDriverModuleHandler::MingwKernelModeDriverModuleHandler (
2670 const Module& module_ )
2671
2672 : MingwModuleHandler ( module_ )
2673 {
2674 }
2675
2676 void
2677 MingwKernelModeDriverModuleHandler::AddImplicitLibraries ( Module& module )
2678 {
2679 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2680 }
2681
2682 void
2683 MingwKernelModeDriverModuleHandler::Process ()
2684 {
2685 GenerateKernelModeDriverModuleTarget ();
2686 }
2687
2688
2689 void
2690 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ()
2691 {
2692 string targetMacro ( GetTargetMacro (module) );
2693 string workingDirectory = GetWorkingDirectory ();
2694 string linkDepsMacro = GetLinkingDependenciesMacro ();
2695
2696 GenerateImportLibraryTargetIfNeeded ();
2697
2698 if ( module.non_if_data.compilationUnits.size () > 0 )
2699 {
2700 GenerateRules ();
2701
2702 string dependencies = linkDepsMacro + " " + objectsMacro;
2703
2704 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
2705 module.GetEntryPoint(true).c_str (),
2706 module.baseaddress.c_str () );
2707 GenerateLinkerCommand ( dependencies,
2708 linkerParameters,
2709 " -sections" );
2710 }
2711 else
2712 {
2713 GeneratePhonyTarget();
2714 }
2715 }
2716
2717
2718 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler (
2719 const Module& module_ )
2720
2721 : MingwModuleHandler ( module_ )
2722 {
2723 }
2724
2725 void
2726 MingwNativeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2727 {
2728 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2729 }
2730
2731 void
2732 MingwNativeDLLModuleHandler::Process ()
2733 {
2734 GenerateNativeDLLModuleTarget ();
2735 }
2736
2737 void
2738 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
2739 {
2740 string targetMacro ( GetTargetMacro (module) );
2741 string workingDirectory = GetWorkingDirectory ( );
2742 string linkDepsMacro = GetLinkingDependenciesMacro ();
2743
2744 GenerateImportLibraryTargetIfNeeded ();
2745
2746 if ( module.non_if_data.compilationUnits.size () > 0 )
2747 {
2748 GenerateRules ();
2749
2750 string dependencies = linkDepsMacro + " " + objectsMacro;
2751
2752 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -shared",
2753 module.GetEntryPoint(true).c_str (),
2754 module.baseaddress.c_str () );
2755 GenerateLinkerCommand ( dependencies,
2756 linkerParameters,
2757 "" );
2758 }
2759 else
2760 {
2761 GeneratePhonyTarget();
2762 }
2763 }
2764
2765
2766 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler (
2767 const Module& module_ )
2768
2769 : MingwModuleHandler ( module_ )
2770 {
2771 }
2772
2773 void
2774 MingwNativeCUIModuleHandler::AddImplicitLibraries ( Module& module )
2775 {
2776 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2777 }
2778
2779 void
2780 MingwNativeCUIModuleHandler::Process ()
2781 {
2782 GenerateNativeCUIModuleTarget ();
2783 }
2784
2785 void
2786 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
2787 {
2788 string targetMacro ( GetTargetMacro (module) );
2789 string workingDirectory = GetWorkingDirectory ( );
2790 string linkDepsMacro = GetLinkingDependenciesMacro ();
2791
2792 GenerateImportLibraryTargetIfNeeded ();
2793
2794 if ( module.non_if_data.compilationUnits.size () > 0 )
2795 {
2796 GenerateRules ();
2797
2798 string dependencies = linkDepsMacro + " " + objectsMacro;
2799
2800 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib",
2801 module.GetEntryPoint(true).c_str (),
2802 module.baseaddress.c_str () );
2803 GenerateLinkerCommand ( dependencies,
2804 linkerParameters,
2805 "" );
2806 }
2807 else
2808 {
2809 GeneratePhonyTarget();
2810 }
2811 }
2812
2813
2814 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler (
2815 const Module& module_ )
2816
2817 : MingwModuleHandler ( module_ )
2818 {
2819 }
2820
2821 MingwWin32OCXModuleHandler::MingwWin32OCXModuleHandler (
2822 const Module& module_ )
2823
2824 : MingwModuleHandler ( module_ )
2825 {
2826 }
2827
2828 static bool
2829 LinksToCrt( Module &module )
2830 {
2831 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
2832 {
2833 Library& library = *module.non_if_data.libraries[i];
2834 if ( library.name == "libcntpr" || library.name == "crt" )
2835 return true;
2836 }
2837 return false;
2838 }
2839
2840 static void
2841 MingwAddImplicitLibraries( Module &module )
2842 {
2843 Library* pLibrary;
2844 bool links_to_crt;
2845
2846 if ( module.type != Win32DLL
2847 && module.type != Win32OCX
2848 && module.type != Win32CUI
2849 && module.type != Win32GUI
2850 && module.type != Win32SCR)
2851 {
2852 // no implicit libraries
2853 return;
2854 }
2855
2856 links_to_crt = LinksToCrt ( module );
2857
2858 if ( !module.isDefaultEntryPoint )
2859 {
2860 if ( module.GetEntryPoint(false) == "0" )
2861 {
2862 if ( !links_to_crt )
2863 {