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