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