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