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