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