-Add a new module type 'cabinet' to handle .cab files generation
[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 Cabinet:
248 handler = new MingwCabinetModuleHandler ( module );
249 break;
250 case EmbeddedTypeLib:
251 handler = new MingwEmbeddedTypeLibModuleHandler ( module );
252 break;
253 case ElfExecutable:
254 handler = new MingwElfExecutableModuleHandler ( module );
255 break;
256 default:
257 throw UnknownModuleTypeException (
258 module.node.location,
259 module.type );
260 break;
261 }
262 return handler;
263 }
264
265 string
266 MingwModuleHandler::GetWorkingDirectory () const
267 {
268 return ".";
269 }
270
271 string
272 MingwModuleHandler::GetBasename ( const string& filename ) const
273 {
274 size_t index = filename.find_last_of ( '.' );
275 if ( index != string::npos )
276 return filename.substr ( 0, index );
277 return "";
278 }
279
280 /* caller needs to delete the returned object */
281 const FileLocation*
282 MingwModuleHandler::GetActualSourceFilename (
283 const FileLocation* file ) const
284 {
285 string filename = file->name;
286
287 string extension = GetExtension ( *file );
288 if ( extension == ".spec" || extension == ".SPEC" )
289 {
290 const FileLocation *objectFile = GetObjectFilename ( file, module );
291 FileLocation *sourceFile = new FileLocation (
292 objectFile->directory,
293 objectFile->relative_path,
294 ReplaceExtension ( objectFile->name, ".c" ) );
295 delete objectFile;
296 return sourceFile;
297 }
298 else if ( ( extension == ".idl" || extension == ".IDL" ) &&
299 ( module.type == RpcServer || module.type == RpcClient || module.type == RpcProxy ) )
300 {
301 const FileLocation *objectFile = GetObjectFilename ( file, module );
302 FileLocation *sourceFile = new FileLocation (
303 objectFile->directory,
304 objectFile->relative_path,
305 ReplaceExtension ( objectFile->name, ".c" ) );
306 delete objectFile;
307 return sourceFile;
308 }
309 else if ( extension == ".mc" || extension == ".MC" )
310 {
311 const FileLocation *objectFile = GetObjectFilename ( file, module );
312 FileLocation *sourceFile = new FileLocation (
313 objectFile->directory,
314 objectFile->relative_path,
315 ReplaceExtension ( objectFile->name, ".rc" ) );
316 delete objectFile;
317 return sourceFile;
318 }
319 else
320 return new FileLocation ( *file );
321 }
322
323 string
324 MingwModuleHandler::GetExtraDependencies (
325 const FileLocation *file ) const
326 {
327 string extension = GetExtension ( *file );
328 if ( extension == ".idl" || extension == ".IDL" )
329 {
330 const FileLocation *header;
331 switch ( module.type )
332 {
333 case RpcServer: header = GetRpcServerHeaderFilename ( file ); break;
334 case RpcClient: header = GetRpcClientHeaderFilename ( file ); break;
335 case RpcProxy: header = GetRpcProxyHeaderFilename ( file ); break;
336 case IdlHeader: header = GetIdlHeaderFilename ( file ); break;
337 default: header = NULL; break;
338 }
339 if ( !header )
340 return "";
341
342 string dependencies = backend->GetFullName ( *header );
343 delete header;
344 return " " + dependencies;
345 }
346 else
347 return "";
348 }
349
350 string
351 MingwModuleHandler::GetCompilationUnitDependencies (
352 const CompilationUnit& compilationUnit ) const
353 {
354 if ( compilationUnit.GetFiles ().size () <= 1 )
355 return "";
356 vector<string> sourceFiles;
357 for ( size_t i = 0; i < compilationUnit.GetFiles ().size (); i++ )
358 {
359 const File& file = *compilationUnit.GetFiles ()[i];
360 sourceFiles.push_back ( backend->GetFullName ( file.file ) );
361 }
362 return string ( " " ) + v2s ( sourceFiles, 10 );
363 }
364
365 /* caller needs to delete the returned object */
366 const FileLocation*
367 MingwModuleHandler::GetModuleArchiveFilename () const
368 {
369 if ( IsStaticLibrary ( module ) )
370 return GetTargetFilename ( module, NULL );
371 return new FileLocation ( IntermediateDirectory,
372 module.output->relative_path,
373 ReplaceExtension ( module.name, ".temp.a" ) );
374 }
375
376 bool
377 MingwModuleHandler::IsGeneratedFile ( const File& file ) const
378 {
379 string extension = GetExtension ( file.file );
380 return ( extension == ".spec" || extension == ".SPEC" );
381 }
382
383 /*static*/ bool
384 MingwModuleHandler::ReferenceObjects (
385 const Module& module )
386 {
387 if ( module.type == ObjectLibrary )
388 return true;
389 if ( module.type == RpcServer )
390 return true;
391 if ( module.type == RpcClient )
392 return true;
393 if ( module.type == RpcProxy )
394 return true;
395 if ( module.type == IdlHeader )
396 return true;
397 return false;
398 }
399
400 void
401 MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
402 const FileLocation& destination )
403 {
404 fprintf ( fMakefile,
405 "\t$(ECHO_CP)\n" );
406 fprintf ( fMakefile,
407 "\t${cp} %s %s 1>$(NUL)\n",
408 backend->GetFullName ( source ).c_str (),
409 backend->GetFullName ( *PassThruCacheDirectory ( &destination ) ).c_str () );
410 }
411
412 string
413 MingwModuleHandler::GetImportLibraryDependency (
414 const Module& importedModule )
415 {
416 string dep;
417 if ( ReferenceObjects ( importedModule ) )
418 {
419 const vector<CompilationUnit*>& compilationUnits = importedModule.non_if_data.compilationUnits;
420 size_t i;
421
422 dep = GetTargetMacro ( importedModule );
423 for ( i = 0; i < compilationUnits.size (); i++ )
424 {
425 CompilationUnit& compilationUnit = *compilationUnits[i];
426 const FileLocation& compilationName = compilationUnit.GetFilename ();
427 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, importedModule );
428 if ( GetExtension ( *objectFilename ) == ".h" )
429 dep += ssprintf ( " $(%s_HEADERS)", importedModule.name.c_str () );
430 else if ( GetExtension ( *objectFilename ) == ".rc" )
431 dep += ssprintf ( " $(%s_MCHEADERS)", importedModule.name.c_str () );
432 }
433 }
434 else
435 {
436 const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL );
437 dep = backend->GetFullName ( *library_target );
438 delete library_target;
439 }
440 return dep;
441 }
442
443 void
444 MingwModuleHandler::GetTargets ( const Module& dependencyModule,
445 string_list& targets )
446 {
447 if ( dependencyModule.invocations.size () > 0 )
448 {
449 for ( size_t i = 0; i < dependencyModule.invocations.size (); i++ )
450 {
451 Invoke& invoke = *dependencyModule.invocations[i];
452 invoke.GetTargets ( targets );
453 }
454 }
455 else
456 targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
457 }
458
459 void
460 MingwModuleHandler::GetModuleDependencies (
461 string_list& dependencies )
462 {
463 size_t iend = module.dependencies.size ();
464
465 if ( iend == 0 )
466 return;
467
468 for ( size_t i = 0; i < iend; i++ )
469 {
470 const Dependency& dependency = *module.dependencies[i];
471 const Module& dependencyModule = *dependency.dependencyModule;
472 GetTargets ( dependencyModule,
473 dependencies );
474 }
475 vector<FileLocation> v;
476 GetDefinitionDependencies ( v );
477
478 for ( size_t i = 0; i < v.size (); i++ )
479 {
480 const FileLocation& file = v[i];
481 dependencies.push_back ( backend->GetFullName ( file ) );
482 }
483 }
484
485 void
486 MingwModuleHandler::GetSourceFilenames ( vector<FileLocation>& list,
487 bool includeGeneratedFiles ) const
488 {
489 size_t i;
490
491 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
492 for ( i = 0; i < compilationUnits.size (); i++ )
493 {
494 if ( includeGeneratedFiles || !compilationUnits[i]->IsGeneratedFile () )
495 {
496 const FileLocation& compilationName = compilationUnits[i]->GetFilename ();
497 const FileLocation* sourceFileLocation = GetActualSourceFilename ( &compilationName );
498 list.push_back ( *sourceFileLocation );
499 delete sourceFileLocation;
500 }
501 }
502 // intentionally make a copy so that we can append more work in
503 // the middle of processing without having to go recursive
504 vector<If*> v = module.non_if_data.ifs;
505 for ( i = 0; i < v.size (); i++ )
506 {
507 size_t j;
508 If& rIf = *v[i];
509 // check for sub-ifs to add to list
510 const vector<If*>& ifs = rIf.data.ifs;
511 for ( j = 0; j < ifs.size (); j++ )
512 v.push_back ( ifs[j] );
513 const vector<CompilationUnit*>& compilationUnits = rIf.data.compilationUnits;
514 for ( j = 0; j < compilationUnits.size (); j++ )
515 {
516 CompilationUnit& compilationUnit = *compilationUnits[j];
517 if ( includeGeneratedFiles || !compilationUnit.IsGeneratedFile () )
518 {
519 const FileLocation& compilationName = compilationUnit.GetFilename ();
520 const FileLocation* sourceFileLocation = GetActualSourceFilename ( &compilationName );
521 list.push_back ( *sourceFileLocation );
522 delete sourceFileLocation;
523 }
524 }
525 }
526 }
527
528 void
529 MingwModuleHandler::GetSourceFilenamesWithoutGeneratedFiles (
530 vector<FileLocation>& list ) const
531 {
532 GetSourceFilenames ( list, false );
533 }
534
535 /* caller needs to delete the returned object */
536 const FileLocation*
537 MingwModuleHandler::GetObjectFilename (
538 const FileLocation* sourceFile,
539 const Module& module ) const
540 {
541 DirectoryLocation destination_directory;
542 string newExtension;
543 string extension = GetExtension ( *sourceFile );
544
545 if ( module.type == BootSector )
546 return new FileLocation ( *module.output );
547 else if ( extension == ".rc" || extension == ".RC" )
548 newExtension = "_" + module.name + ".coff";
549 else if ( extension == ".mc" || extension == ".MC" )
550 newExtension = ".rc";
551 else if ( extension == ".spec" || extension == ".SPEC" )
552 newExtension = ".stubs.o";
553 else if ( extension == ".idl" || extension == ".IDL" )
554 {
555 if ( module.type == RpcServer )
556 newExtension = "_s.o";
557 else if ( module.type == RpcClient )
558 newExtension = "_c.o";
559 else if ( module.type == RpcProxy )
560 newExtension = "_p.o";
561 else
562 newExtension = ".h";
563 }
564 else
565 newExtension = "_" + module.name + ".o";
566
567 if ( module.type == BootSector )
568 destination_directory = OutputDirectory;
569 else
570 destination_directory = IntermediateDirectory;
571
572 const FileLocation *obj_file = new FileLocation(
573 destination_directory,
574 sourceFile->relative_path,
575 ReplaceExtension ( sourceFile->name, newExtension ) );
576 PassThruCacheDirectory ( obj_file );
577
578 return obj_file;
579 }
580
581 string
582 MingwModuleHandler::GetModuleCleanTarget ( const Module& module ) const
583 {
584 return module.name + "_clean";
585 }
586
587 void
588 MingwModuleHandler::GetReferencedObjectLibraryModuleCleanTargets ( vector<string>& moduleNames ) const
589 {
590 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
591 {
592 Library& library = *module.non_if_data.libraries[i];
593 if ( library.importedModule->type == ObjectLibrary )
594 moduleNames.push_back ( GetModuleCleanTarget ( *library.importedModule ) );
595 }
596 }
597
598 void
599 MingwModuleHandler::GenerateCleanTarget () const
600 {
601 if ( module.type == Alias )
602 return;
603
604 fprintf ( fMakefile,
605 ".PHONY: %s_clean\n",
606 module.name.c_str() );
607 vector<string> referencedModuleNames;
608 GetReferencedObjectLibraryModuleCleanTargets ( referencedModuleNames );
609 fprintf ( fMakefile,
610 "%s: %s\n\t-@${rm}",
611 GetModuleCleanTarget ( module ).c_str(),
612 v2s ( referencedModuleNames, 10 ).c_str () );
613 for ( size_t i = 0; i < clean_files.size(); i++ )
614 {
615 if ( ( i + 1 ) % 10 == 9 )
616 fprintf ( fMakefile, " 2>$(NUL)\n\t-@${rm}" );
617 fprintf ( fMakefile, " %s", clean_files[i].c_str() );
618 }
619 fprintf ( fMakefile, " 2>$(NUL)\n" );
620
621 if( ProxyMakefile::GenerateProxyMakefile(module) )
622 {
623 DirectoryLocation root;
624
625 if ( backend->configuration.GenerateProxyMakefilesInSourceTree )
626 root = SourceDirectory;
627 else
628 root = OutputDirectory;
629
630 FileLocation proxyMakefile ( root,
631 module.output->relative_path,
632 "GNUmakefile" );
633 fprintf ( fMakefile, "\t-@${rm} %s 2>$(NUL)\n",
634 backend->GetFullName ( proxyMakefile ).c_str () );
635 }
636
637 fprintf ( fMakefile, "clean: %s_clean\n\n", module.name.c_str() );
638 }
639
640 void
641 MingwModuleHandler::GenerateInstallTarget () const
642 {
643 if ( !module.install )
644 return;
645 fprintf ( fMakefile, ".PHONY: %s_install\n", module.name.c_str() );
646 fprintf ( fMakefile,
647 "%s_install: %s\n",
648 module.name.c_str (),
649 backend->GetFullName ( *module.install ).c_str () );
650 }
651
652 void
653 MingwModuleHandler::GenerateDependsTarget () const
654 {
655 fprintf ( fMakefile,
656 ".PHONY: %s_depends\n",
657 module.name.c_str() );
658 fprintf ( fMakefile,
659 "%s_depends: $(RBUILD_TARGET)\n",
660 module.name.c_str () );
661 fprintf ( fMakefile,
662 "\t$(ECHO_RBUILD)\n" );
663 fprintf ( fMakefile,
664 "\t$(Q)$(RBUILD_TARGET) $(RBUILD_FLAGS) -dm%s mingw\n",
665 module.name.c_str () );
666 }
667
668 string
669 MingwModuleHandler::GetObjectFilenames ()
670 {
671 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
672 if ( compilationUnits.size () == 0 )
673 return "";
674
675 string objectFilenames ( "" );
676 for ( size_t i = 0; i < compilationUnits.size (); i++ )
677 {
678 if ( objectFilenames.size () > 0 )
679 objectFilenames += " ";
680 const FileLocation& compilationName = compilationUnits[i]->GetFilename ();
681 const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
682 objectFilenames += backend->GetFullName ( *object_file );
683 delete object_file;
684 }
685 return objectFilenames;
686 }
687
688 /* static */ string
689 MingwModuleHandler::GenerateGccDefineParametersFromVector (
690 const vector<Define*>& defines,
691 set<string>& used_defs)
692 {
693 string parameters;
694
695 for ( size_t i = 0; i < defines.size (); i++ )
696 {
697 Define& define = *defines[i];
698 if (used_defs.find(define.name) != used_defs.end())
699 continue;
700 if (parameters.length () > 0)
701 parameters += " ";
702 if (define.name.find('(') != string::npos)
703 parameters += "$(QT)";
704 parameters += "-D";
705 parameters += define.name;
706 if (define.value.length () > 0)
707 {
708 parameters += "=";
709 parameters += define.value;
710 }
711 if (define.name.find('(') != string::npos)
712 parameters += "$(QT)";
713 used_defs.insert(used_defs.begin(),define.name);
714 }
715 return parameters;
716 }
717
718 string
719 MingwModuleHandler::GenerateGccDefineParameters () const
720 {
721 set<string> used_defs;
722 string parameters = GenerateGccDefineParametersFromVector ( module.project.non_if_data.defines, used_defs );
723 string s = GenerateGccDefineParametersFromVector ( module.non_if_data.defines, used_defs );
724 if ( s.length () > 0 )
725 {
726 parameters += " ";
727 parameters += s;
728 }
729 return parameters;
730 }
731
732 string
733 MingwModuleHandler::ConcatenatePaths (
734 const string& path1,
735 const string& path2 ) const
736 {
737 if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )
738 return path2;
739 if ( path1[path1.length ()] == cSep )
740 return path1 + path2;
741 else
742 return path1 + cSep + path2;
743 }
744
745 /* static */ string
746 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes )
747 {
748 string parameters, path_prefix;
749 for ( size_t i = 0; i < includes.size (); i++ )
750 {
751 Include& include = *includes[i];
752 if ( parameters.length () > 0 )
753 parameters += " ";
754 parameters += "-I" + backend->GetFullPath ( *include.directory );;
755 }
756 return parameters;
757 }
758
759 string
760 MingwModuleHandler::GenerateGccIncludeParameters () const
761 {
762 string parameters = GenerateGccIncludeParametersFromVector ( module.non_if_data.includes );
763 string s = GenerateGccIncludeParametersFromVector ( module.project.non_if_data.includes );
764 if ( s.length () > 0 )
765 {
766 parameters += " ";
767 parameters += s;
768 }
769 return parameters;
770 }
771
772 string
773 MingwModuleHandler::GenerateCompilerParametersFromVector ( const vector<CompilerFlag*>& compilerFlags, const CompilerType type ) const
774 {
775 string parameters;
776 for ( size_t i = 0; i < compilerFlags.size (); i++ )
777 {
778 CompilerFlag& compilerFlag = *compilerFlags[i];
779 if ( compilerFlag.compiler == type )
780 parameters += " " + compilerFlag.flag;
781 }
782 return parameters;
783 }
784
785 string
786 MingwModuleHandler::GenerateLinkerParametersFromVector ( const vector<LinkerFlag*>& linkerFlags ) const
787 {
788 string parameters;
789 for ( size_t i = 0; i < linkerFlags.size (); i++ )
790 {
791 LinkerFlag& linkerFlag = *linkerFlags[i];
792 if ( parameters.length () > 0 )
793 parameters += " ";
794 parameters += linkerFlag.flag;
795 }
796 return parameters;
797 }
798
799 string
800 MingwModuleHandler::GenerateImportLibraryDependenciesFromVector (
801 const vector<Library*>& libraries )
802 {
803 string dependencies ( "" );
804 int wrap_count = 0;
805 for ( size_t i = 0; i < libraries.size (); i++ )
806 {
807 if ( wrap_count++ == 5 )
808 dependencies += " \\\n\t\t", wrap_count = 0;
809 else if ( dependencies.size () > 0 )
810 dependencies += " ";
811 dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule );
812 }
813 return dependencies;
814 }
815
816 string
817 MingwModuleHandler::GenerateLinkerParameters () const
818 {
819 return GenerateLinkerParametersFromVector ( module.linkerFlags );
820 }
821
822 void
823 MingwModuleHandler::GenerateMacro (
824 const char* assignmentOperation,
825 const string& macro,
826 const IfableData& data,
827 set<const Define *> *used_defs,
828 bool generatingCompilerMacro )
829 {
830 size_t i;
831 bool generateAssignment;
832
833 if ( generatingCompilerMacro )
834 generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0 || data.compilerFlags.size () > 0;
835 else
836 generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0;
837 if ( generateAssignment )
838 {
839 fprintf ( fMakefile,
840 "%s %s",
841 macro.c_str(),
842 assignmentOperation );
843 }
844
845 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
846 if ( pchFilename )
847 {
848 fprintf ( fMakefile,
849 " -I%s",
850 backend->GetFullPath ( *pchFilename ).c_str () );
851 delete pchFilename;
852 }
853
854 if ( generatingCompilerMacro )
855 {
856 string compilerParameters = GenerateCompilerParametersFromVector ( data.compilerFlags, CompilerTypeDontCare );
857 if ( compilerParameters.size () > 0 )
858 {
859 fprintf (
860 fMakefile,
861 "%s",
862 compilerParameters.c_str () );
863 }
864 }
865 for ( i = 0; i < data.includes.size(); i++ )
866 {
867 const Include& include = *data.includes[i];
868 const FileLocation* includeDirectory = include.directory;
869 fprintf (
870 fMakefile,
871 " -I%s",
872 backend->GetFullPath ( *includeDirectory ).c_str() );
873 }
874 for ( i = 0; i < data.defines.size(); i++ )
875 {
876 const Define& define = *data.defines[i];
877 if ( used_defs )
878 {
879 set<const Define *>::const_iterator last_define;
880 for (last_define = used_defs->begin ();
881 last_define != used_defs->end ();
882 last_define++)
883 {
884 if ( (*last_define)->name != define.name )
885 continue;
886 if ( !define.overridable )
887 {
888 throw InvalidOperationException ( (*last_define)->node->location.c_str (),
889 0,
890 "Invalid override of define '%s', already defined at %s",
891 define.name.c_str (),
892 define.node->location.c_str () );
893 }
894 if ( backend->configuration.Verbose )
895 printf("%s: Overriding '%s' already defined at %s\n",
896 (*last_define)->node->location.c_str (), define.name.c_str (),
897 define.node->location.c_str () );
898 break;
899 }
900 if ( last_define != used_defs->end () )
901 continue;
902 }
903 fprintf (
904 fMakefile,
905 " -D%s",
906 define.name.c_str() );
907 if (define.value.length () > 0)
908 fprintf (
909 fMakefile,
910 "=%s",
911 define.value.c_str() );
912 if ( used_defs )
913 used_defs->insert( used_defs->begin (), &define );
914 }
915 if ( generateAssignment )
916 {
917 fprintf ( fMakefile, "\n" );
918 }
919 }
920
921 void
922 MingwModuleHandler::GenerateMacros (
923 const char* assignmentOperation,
924 const IfableData& data,
925 const vector<LinkerFlag*>* linkerFlags,
926 set<const Define *>& used_defs )
927 {
928 size_t i;
929
930 GenerateMacro ( assignmentOperation,
931 cflagsMacro,
932 data,
933 &used_defs,
934 true );
935 GenerateMacro ( assignmentOperation,
936 windresflagsMacro,
937 data,
938 NULL,
939 false );
940
941 if ( linkerFlags != NULL )
942 {
943 string linkerParameters = GenerateLinkerParametersFromVector ( *linkerFlags );
944 if ( linkerParameters.size () > 0 )
945 {
946 fprintf (
947 fMakefile,
948 "%s %s %s\n",
949 linkerflagsMacro.c_str (),
950 assignmentOperation,
951 linkerParameters.c_str() );
952 }
953 }
954
955 if ( data.libraries.size () > 0 )
956 {
957 string deps = GenerateImportLibraryDependenciesFromVector ( data.libraries );
958 if ( deps.size () > 0 )
959 {
960 fprintf (
961 fMakefile,
962 "%s %s %s\n",
963 libsMacro.c_str(),
964 assignmentOperation,
965 deps.c_str() );
966 }
967 }
968
969 const vector<If*>& ifs = data.ifs;
970 for ( i = 0; i < ifs.size(); i++ )
971 {
972 If& rIf = *ifs[i];
973 if ( rIf.data.defines.size()
974 || rIf.data.includes.size()
975 || rIf.data.libraries.size()
976 || rIf.data.compilationUnits.size()
977 || rIf.data.compilerFlags.size()
978 || rIf.data.ifs.size() )
979 {
980 fprintf (
981 fMakefile,
982 "%s (\"$(%s)\",\"%s\")\n",
983 rIf.negated ? "ifneq" : "ifeq",
984 rIf.property.c_str(),
985 rIf.value.c_str() );
986 GenerateMacros (
987 "+=",
988 rIf.data,
989 NULL,
990 used_defs );
991 fprintf (
992 fMakefile,
993 "endif\n\n" );
994 }
995 }
996 }
997
998 void
999 MingwModuleHandler::CleanupCompilationUnitVector ( vector<CompilationUnit*>& compilationUnits )
1000 {
1001 for ( size_t i = 0; i < compilationUnits.size (); i++ )
1002 delete compilationUnits[i];
1003 }
1004
1005 void
1006 MingwModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUnit*>& compilationUnits )
1007 {
1008 }
1009
1010 void
1011 MingwModuleHandler::GenerateSourceMacros (
1012 const char* assignmentOperation,
1013 const IfableData& data )
1014 {
1015 size_t i;
1016
1017 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1018 vector<const FileLocation *> headers;
1019 if ( compilationUnits.size () > 0 )
1020 {
1021 fprintf (
1022 fMakefile,
1023 "%s %s",
1024 sourcesMacro.c_str (),
1025 assignmentOperation );
1026 for ( i = 0; i < compilationUnits.size(); i++ )
1027 {
1028 CompilationUnit& compilationUnit = *compilationUnits[i];
1029 const FileLocation& compilationName = compilationUnit.GetFilename ();
1030 fprintf (
1031 fMakefile,
1032 "%s%s",
1033 ( i%10 == 9 ? " \\\n\t" : " " ),
1034 backend->GetFullName ( compilationName ).c_str () );
1035 }
1036 fprintf ( fMakefile, "\n" );
1037 }
1038
1039 const vector<If*>& ifs = data.ifs;
1040 for ( i = 0; i < ifs.size(); i++ )
1041 {
1042 If& rIf = *ifs[i];
1043 if ( rIf.data.defines.size()
1044 || rIf.data.includes.size()
1045 || rIf.data.libraries.size()
1046 || rIf.data.compilationUnits.size()
1047 || rIf.data.compilerFlags.size()
1048 || rIf.data.ifs.size() )
1049 {
1050 fprintf (
1051 fMakefile,
1052 "%s (\"$(%s)\",\"%s\")\n",
1053 rIf.negated ? "ifneq" : "ifeq",
1054 rIf.property.c_str(),
1055 rIf.value.c_str() );
1056 GenerateSourceMacros (
1057 "+=",
1058 rIf.data );
1059 fprintf (
1060 fMakefile,
1061 "endif\n\n" );
1062 }
1063 }
1064
1065 vector<CompilationUnit*> sourceCompilationUnits;
1066 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1067 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1068 {
1069 const FileLocation& compilationName = sourceCompilationUnits[i]->GetFilename ();
1070 fprintf (
1071 fMakefile,
1072 "%s += %s\n",
1073 sourcesMacro.c_str(),
1074 backend->GetFullName ( compilationName ).c_str () );
1075 }
1076 CleanupCompilationUnitVector ( sourceCompilationUnits );
1077 }
1078
1079 void
1080 MingwModuleHandler::GenerateObjectMacros (
1081 const char* assignmentOperation,
1082 const IfableData& data )
1083 {
1084 size_t i;
1085
1086 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1087 vector<const FileLocation *> headers;
1088 vector<const FileLocation *> mcheaders;
1089 vector<const FileLocation *> mcresources;
1090 if ( compilationUnits.size () > 0 )
1091 {
1092 for ( i = 0; i < compilationUnits.size (); i++ )
1093 {
1094 CompilationUnit& compilationUnit = *compilationUnits[i];
1095 if ( compilationUnit.IsFirstFile () )
1096 {
1097 const FileLocation& compilationName = compilationUnit.GetFilename ();
1098 const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
1099 fprintf ( fMakefile,
1100 "%s := %s $(%s)\n",
1101 objectsMacro.c_str(),
1102 backend->GetFullName ( *object_file ).c_str (),
1103 objectsMacro.c_str() );
1104 delete object_file;
1105 }
1106 }
1107 fprintf (
1108 fMakefile,
1109 "%s %s",
1110 objectsMacro.c_str (),
1111 assignmentOperation );
1112 for ( i = 0; i < compilationUnits.size(); i++ )
1113 {
1114 CompilationUnit& compilationUnit = *compilationUnits[i];
1115 if ( !compilationUnit.IsFirstFile () )
1116 {
1117 const FileLocation& compilationName = compilationUnit.GetFilename ();
1118 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module );
1119 if ( GetExtension ( *objectFilename ) == ".h" )
1120 headers.push_back ( objectFilename );
1121 else if ( GetExtension ( *objectFilename ) == ".rc" )
1122 {
1123 const FileLocation *headerFilename = GetMcHeaderFilename ( &compilationUnit.GetFilename () );
1124 mcheaders.push_back ( headerFilename );
1125 mcresources.push_back ( objectFilename );
1126 }
1127 else
1128 {
1129 fprintf (
1130 fMakefile,
1131 "%s%s",
1132 ( i%10 == 9 ? " \\\n\t" : " " ),
1133 backend->GetFullName ( *objectFilename ).c_str () );
1134 delete objectFilename;
1135 }
1136 }
1137 }
1138 fprintf ( fMakefile, "\n" );
1139 }
1140 if ( headers.size () > 0 )
1141 {
1142 fprintf (
1143 fMakefile,
1144 "%s_HEADERS %s",
1145 module.name.c_str (),
1146 assignmentOperation );
1147 for ( i = 0; i < headers.size (); i++ )
1148 {
1149 fprintf (
1150 fMakefile,
1151 "%s%s",
1152 ( i%10 == 9 ? " \\\n\t" : " " ),
1153 backend->GetFullName ( *headers[i] ).c_str () );
1154 delete headers[i];
1155 }
1156 fprintf ( fMakefile, "\n" );
1157 }
1158
1159 if ( mcheaders.size () > 0 )
1160 {
1161 fprintf (
1162 fMakefile,
1163 "%s_MCHEADERS %s",
1164 module.name.c_str (),
1165 assignmentOperation );
1166 for ( i = 0; i < mcheaders.size (); i++ )
1167 {
1168 fprintf (
1169 fMakefile,
1170 "%s%s",
1171 ( i%10 == 9 ? " \\\n\t" : " " ),
1172 backend->GetFullName ( *mcheaders[i] ).c_str () );
1173 delete mcheaders[i];
1174 }
1175 fprintf ( fMakefile, "\n" );
1176 }
1177
1178 if ( mcresources.size () > 0 )
1179 {
1180 fprintf (
1181 fMakefile,
1182 "%s_RESOURCES %s",
1183 module.name.c_str (),
1184 assignmentOperation );
1185 for ( i = 0; i < mcresources.size (); i++ )
1186 {
1187 fprintf (
1188 fMakefile,
1189 "%s%s",
1190 ( i%10 == 9 ? " \\\n\t" : " " ),
1191 backend->GetFullName ( *mcresources[i] ).c_str () );
1192 delete mcresources[i];
1193 }
1194 fprintf ( fMakefile, "\n" );
1195 }
1196
1197 const vector<If*>& ifs = data.ifs;
1198 for ( i = 0; i < ifs.size(); i++ )
1199 {
1200 If& rIf = *ifs[i];
1201 if ( rIf.data.defines.size()
1202 || rIf.data.includes.size()
1203 || rIf.data.libraries.size()
1204 || rIf.data.compilationUnits.size()
1205 || rIf.data.compilerFlags.size()
1206 || rIf.data.ifs.size() )
1207 {
1208 fprintf (
1209 fMakefile,
1210 "%s (\"$(%s)\",\"%s\")\n",
1211 rIf.negated ? "ifneq" : "ifeq",
1212 rIf.property.c_str(),
1213 rIf.value.c_str() );
1214 GenerateObjectMacros (
1215 "+=",
1216 rIf.data );
1217 fprintf (
1218 fMakefile,
1219 "endif\n\n" );
1220 }
1221 }
1222
1223 vector<CompilationUnit*> sourceCompilationUnits;
1224 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1225 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1226 {
1227 const FileLocation& compilationName = sourceCompilationUnits[i]->GetFilename ();
1228 const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
1229 fprintf (
1230 fMakefile,
1231 "%s += %s\n",
1232 objectsMacro.c_str(),
1233 backend->GetFullName ( *object_file ).c_str () );
1234 delete object_file;
1235 }
1236 CleanupCompilationUnitVector ( sourceCompilationUnits );
1237 }
1238
1239 /* caller needs to delete the returned object */
1240 const FileLocation*
1241 MingwModuleHandler::GetPrecompiledHeaderFilename () const
1242 {
1243 if ( !module.pch || !use_pch )
1244 return NULL;
1245 return new FileLocation ( IntermediateDirectory,
1246 module.pch->file->relative_path,
1247 ReplaceExtension ( module.pch->file->name, "_" + module.name + ".gch" ) );
1248 }
1249
1250 Rule arRule1 ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).a: $($(module_name)_OBJS) | $(INTERMEDIATE)$(SEP)$(source_dir)\n",
1251 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).a",
1252 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1253 Rule arRule2 ( "\t$(ECHO_AR)\n"
1254 "\t${ar} -rc $@ $($(module_name)_OBJS)\n",
1255 NULL );
1256 Rule arHostRule2 ( "\t$(ECHO_AR)\n"
1257 "\t${host_ar} -rc $@ $($(module_name)_OBJS)\n",
1258 NULL );
1259 Rule gasRule ( "$(source): ${$(module_name)_precondition}\n"
1260 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1261 "\t$(ECHO_GAS)\n"
1262 "\t${gcc} -x assembler-with-cpp -c $< -o $@ -D__ASM__ $($(module_name)_CFLAGS)\n",
1263 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
1264 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1265 Rule bootRule ( "$(source): ${$(module_name)_precondition}\n"
1266 "$(module_output): $(source)$(dependencies) | $(OUTPUT)$(SEP)$(source_dir)\n"
1267 "\t$(ECHO_NASM)\n"
1268 "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
1269 "$(OUTPUT)$(SEP)$(source_dir)$(SEP)", NULL );
1270 Rule nasmRule ( "$(source): ${$(module_name)_precondition}\n"
1271 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1272 "\t$(ECHO_NASM)\n"
1273 "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
1274 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
1275 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1276 Rule windresRule ( "$(source): ${$(module_name)_precondition}\n"
1277 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff: $(source)$(dependencies) $(WRC_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir) $(TEMPORARY)\n"
1278 "\t$(ECHO_WRC)\n"
1279 "\t${gcc} -xc -E -DRC_INVOKED ${$(module_name)_RCFLAGS} $(source) > $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp\n"
1280 "\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"
1281 "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp 2>$(NUL)\n"
1282 "\t${windres} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp -o $@\n"
1283 "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp 2>$(NUL)\n",
1284 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff",
1285 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1286 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"
1287 "\t$(ECHO_WMC)\n"
1288 "\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",
1289 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc", "$(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h", NULL );
1290 Rule winebuildRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def: $(source)$(dependencies) $(WINEBUILD_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1291 "\t$(ECHO_WINEBLD)\n"
1292 "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).spec.def --def -E $(source)\n"
1293 "$(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).stubs.c: $(source_path)$(SEP)$(source_name_noext).spec $(WINEBUILD_TARGET)\n"
1294 "\t$(ECHO_WINEBLD)\n"
1295 "\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"
1296 "$(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"
1297 "\t$(ECHO_CC)\n"
1298 "\t${gcc} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1299 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def",
1300 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.c",
1301 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.o",
1302 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1303 Rule widlHeaderRule ( "$(source): ${$(module_name)_precondition}\n"
1304 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1305 "\t$(ECHO_WIDL)\n"
1306 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h $(source)\n",
1307 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h",
1308 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1309 Rule widlServerRule ( "$(source): ${$(module_name)_precondition}\n"
1310 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1311 "\t$(ECHO_WIDL)\n"
1312 "\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"
1313 "$(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"
1314 "\t$(ECHO_CC)\n"
1315 "\t${gcc} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1316 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h",
1317 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c",
1318 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.o",
1319 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1320 Rule widlClientRule ( "$(source): ${$(module_name)_precondition}\n"
1321 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1322 "\t$(ECHO_WIDL)\n"
1323 "\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"
1324 "$(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"
1325 "\t$(ECHO_CC)\n"
1326 "\t${gcc} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1327 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h",
1328 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c",
1329 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.o",
1330 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1331 Rule widlProxyRule ( "$(source): ${$(module_name)_precondition}\n"
1332 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1333 "\t$(ECHO_WIDL)\n"
1334 "\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"
1335 "$(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"
1336 "\t$(ECHO_CC)\n"
1337 "\t${gcc} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1338 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h",
1339 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c",
1340 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.o",
1341 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1342 Rule widlTlbRule ( "$(source): ${$(module_name)_precondition}\n"
1343 "$(OUTPUT)$(SEP)$(source_dir)$(SEP)$(module_name).tlb: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1344 "\t$(ECHO_WIDL)\n"
1345 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -t -T $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).tlb $(source)\n",
1346 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1347 Rule gccRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source) ${$(module_name)_precondition}$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1348 "\t$(ECHO_CC)\n"
1349 "\t${gcc} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1350 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1351 Rule gccHostRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source) ${$(module_name)_precondition}$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1352 "\t$(ECHO_CC)\n"
1353 "\t${host_gcc} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1354 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1355 Rule gppRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source) ${$(module_name)_precondition}$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1356 "\t$(ECHO_CC)\n"
1357 "\t${gpp} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1358 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1359 Rule gppHostRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source) ${$(module_name)_precondition}$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1360 "\t$(ECHO_CC)\n"
1361 "\t${host_gpp} -c $< -o $@ $($(module_name)_CFLAGS)$(compiler_flags)\n",
1362 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1363 Rule emptyRule ( "", NULL );
1364
1365 void
1366 MingwModuleHandler::GenerateGccCommand (
1367 const FileLocation* sourceFile,
1368 const Rule *rule,
1369 const string& extraDependencies )
1370 {
1371 const FileLocation *generatedSourceFileName = GetActualSourceFilename ( sourceFile );
1372 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1373 string dependencies = extraDependencies;
1374
1375 string flags;
1376 string extension = GetExtension ( *sourceFile );
1377 if ( extension == ".cc" || extension == ".cpp" || extension == ".cxx" )
1378 flags = GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, CompilerTypeCPP );
1379 else
1380 flags = GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, CompilerTypeCC );
1381
1382 if ( pchFilename )
1383 {
1384 dependencies += " " + backend->GetFullName ( *pchFilename );
1385 delete pchFilename;
1386 }
1387
1388 /* WIDL generated headers may be used */
1389 vector<FileLocation> rpcDependencies;
1390 GetRpcHeaderDependencies ( rpcDependencies );
1391 if ( rpcDependencies.size () > 0 )
1392 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1393
1394 rule->Execute ( fMakefile, backend, module, generatedSourceFileName, clean_files, dependencies, flags );
1395
1396 delete generatedSourceFileName;
1397 }
1398
1399 string
1400 MingwModuleHandler::GetPropertyValue ( const Module& module, const std::string& name )
1401 {
1402 for ( size_t i = 0; i < module.project.non_if_data.properties.size (); i++ )
1403 {
1404 const Property& property = *module.project.non_if_data.properties[i];
1405 if ( property.name == name )
1406 return property.value;
1407 }
1408 return string ( "" );
1409 }
1410
1411 /* caller needs to delete the returned object */
1412 const FileLocation*
1413 MingwModuleHandler::GetRpcServerHeaderFilename ( const FileLocation *base ) const
1414 {
1415 string newname = GetBasename ( base->name ) + "_s.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::GetRpcClientHeaderFilename ( const FileLocation *base ) const
1422 {
1423 string newname = GetBasename ( base->name ) + "_c.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::GetRpcProxyHeaderFilename ( const FileLocation *base ) const
1430 {
1431 string newname = GetBasename ( base->name ) + "_p.h";
1432 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1433 }
1434
1435 /* caller needs to delete the returned object */
1436 const FileLocation*
1437 MingwModuleHandler::GetIdlHeaderFilename ( const FileLocation *base ) const
1438 {
1439 string newname = GetBasename ( base->name ) + ".h";
1440 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1441 }
1442
1443 /* caller needs to delete the returned object */
1444 const FileLocation*
1445 MingwModuleHandler::GetMcHeaderFilename ( const FileLocation *base ) const
1446 {
1447 string newname = GetBasename ( base->name ) + ".h";
1448 return new FileLocation ( IntermediateDirectory, "include/reactos" , newname );
1449 }
1450
1451 void
1452 MingwModuleHandler::GenerateCommands (
1453 const CompilationUnit& compilationUnit,
1454 const string& extraDependencies )
1455 {
1456 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1457 string extension = GetExtension ( sourceFile );
1458 std::transform ( extension.begin (), extension.end (), extension.begin (), tolower );
1459
1460 struct
1461 {
1462 HostType host;
1463 ModuleType type;
1464 string extension;
1465 Rule* rule;
1466 } rules[] = {
1467 { HostDontCare, TypeDontCare, ".s", &gasRule },
1468 { HostDontCare, BootSector, ".asm", &bootRule },
1469 { HostDontCare, TypeDontCare, ".asm", &nasmRule },
1470 { HostDontCare, TypeDontCare, ".rc", &windresRule },
1471 { HostDontCare, TypeDontCare, ".mc", &wmcRule },
1472 { HostDontCare, TypeDontCare, ".spec", &winebuildRule },
1473 { HostDontCare, RpcServer, ".idl", &widlServerRule },
1474 { HostDontCare, RpcClient, ".idl", &widlClientRule },
1475 { HostDontCare, RpcProxy, ".idl", &widlProxyRule },
1476 { HostDontCare, EmbeddedTypeLib, ".idl", &widlTlbRule },
1477 { HostDontCare, TypeDontCare, ".idl", &widlHeaderRule },
1478 { HostTrue, TypeDontCare, ".c", &gccHostRule },
1479 { HostTrue, TypeDontCare, ".cc", &gppHostRule },
1480 { HostTrue, TypeDontCare, ".cpp", &gppHostRule },
1481 { HostTrue, TypeDontCare, ".cxx", &gppHostRule },
1482 { HostFalse, TypeDontCare, ".c", &gccRule },
1483 { HostFalse, TypeDontCare, ".cc", &gppRule },
1484 { HostFalse, TypeDontCare, ".cpp", &gppRule },
1485 { HostFalse, TypeDontCare, ".cxx", &gppRule },
1486 { HostFalse, Cabinet, ".*", &emptyRule }
1487 };
1488 size_t i;
1489 Rule *customRule = NULL;
1490
1491 for ( i = 0; i < sizeof ( rules ) / sizeof ( rules[0] ); i++ )
1492 {
1493 if ( rules[i].host != HostDontCare && rules[i].host != module.host )
1494 continue;
1495 if ( rules[i].type != TypeDontCare && rules[i].type != module.type )
1496 continue;
1497 if ( rules[i].extension != extension && rules[i].extension != ".*")
1498 continue;
1499 customRule = rules[i].rule;
1500 break;
1501 }
1502
1503 if ( extension == ".c" || extension == ".cc" || extension == ".cpp" || extension == ".cxx" )
1504 {
1505 GenerateGccCommand ( &sourceFile,
1506 customRule,
1507 GetCompilationUnitDependencies ( compilationUnit ) + GetExtraDependencies ( &sourceFile ) + extraDependencies );
1508 }
1509 else if ( customRule )
1510 customRule->Execute ( fMakefile, backend, module, &sourceFile, clean_files );
1511 else
1512 {
1513 throw InvalidOperationException ( __FILE__,
1514 __LINE__,
1515 "Unsupported filename extension '%s' in file '%s'",
1516 extension.c_str (),
1517 backend->GetFullName ( sourceFile ).c_str () );
1518 }
1519 }
1520
1521 void
1522 MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget )
1523 {
1524 fprintf ( fMakefile,
1525 "ifeq ($(ROS_BUILDMAP),full)\n" );
1526
1527 FileLocation mapFilename ( OutputDirectory,
1528 module.output->relative_path,
1529 GetBasename ( module.output->name ) + ".map" );
1530 CLEAN_FILE ( mapFilename );
1531
1532 fprintf ( fMakefile,
1533 "\t$(ECHO_OBJDUMP)\n" );
1534 fprintf ( fMakefile,
1535 "\t$(Q)${objdump} -d -S %s > %s\n",
1536 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1537 backend->GetFullName ( mapFilename ).c_str () );
1538
1539 fprintf ( fMakefile,
1540 "else\n" );
1541 fprintf ( fMakefile,
1542 "ifeq ($(ROS_BUILDMAP),yes)\n" );
1543
1544 fprintf ( fMakefile,
1545 "\t$(ECHO_NM)\n" );
1546 fprintf ( fMakefile,
1547 "\t$(Q)${nm} --numeric-sort %s > %s\n",
1548 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1549 backend->GetFullName ( mapFilename ).c_str () );
1550
1551 fprintf ( fMakefile,
1552 "endif\n" );
1553
1554 fprintf ( fMakefile,
1555 "endif\n" );
1556 }
1557
1558 void
1559 MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
1560 {
1561 fprintf ( fMakefile,
1562 "ifeq ($(ROS_BUILDNOSTRIP),yes)\n" );
1563
1564 FileLocation nostripFilename ( OutputDirectory,
1565 module.output->relative_path,
1566 GetBasename ( module.output->name ) + ".nostrip" + GetExtension ( *module.output ) );
1567 CLEAN_FILE ( nostripFilename );
1568
1569 OutputCopyCommand ( *module.output, nostripFilename );
1570
1571 fprintf ( fMakefile,
1572 "endif\n" );
1573 }
1574
1575 void
1576 MergeStringVector ( const Backend* backend,
1577 const vector<FileLocation>& input,
1578 vector<string>& output )
1579 {
1580 int wrap_at = 25;
1581 string s;
1582 int wrap_count = -1;
1583 for ( size_t i = 0; i < input.size (); i++ )
1584 {
1585 if ( wrap_count++ == wrap_at )
1586 {
1587 output.push_back ( s );
1588 s = "";
1589 wrap_count = 0;
1590 }
1591 else if ( s.size () > 0)
1592 s += " ";
1593 s += backend->GetFullName ( input[i] );
1594 }
1595 if ( s.length () > 0 )
1596 output.push_back ( s );
1597 }
1598
1599 void
1600 MingwModuleHandler::GetObjectsVector ( const IfableData& data,
1601 vector<FileLocation>& objectFiles ) const
1602 {
1603 for ( size_t i = 0; i < data.compilationUnits.size (); i++ )
1604 {
1605 CompilationUnit& compilationUnit = *data.compilationUnits[i];
1606 const FileLocation& compilationName = compilationUnit.GetFilename ();
1607 const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
1608 objectFiles.push_back ( *object_file );
1609 delete object_file;
1610 }
1611 }
1612
1613 void
1614 MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
1615 {
1616 if ( backend->configuration.CleanAsYouGo )
1617 {
1618 vector<FileLocation> objectFiles;
1619 GetObjectsVector ( module.non_if_data,
1620 objectFiles );
1621 vector<string> lines;
1622 MergeStringVector ( backend,
1623 objectFiles,
1624 lines );
1625 for ( size_t i = 0; i < lines.size (); i++ )
1626 {
1627 fprintf ( fMakefile,
1628 "\t-@${rm} %s 2>$(NUL)\n",
1629 lines[i].c_str () );
1630 }
1631 }
1632 }
1633
1634 void
1635 MingwModuleHandler::GenerateRunRsymCode () const
1636 {
1637 fprintf ( fMakefile,
1638 "\t$(ECHO_RSYM)\n" );
1639 fprintf ( fMakefile,
1640 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
1641 }
1642
1643 void
1644 MingwModuleHandler::GenerateRunStripCode () const
1645 {
1646 fprintf ( fMakefile,
1647 "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
1648 fprintf ( fMakefile,
1649 "\t$(ECHO_STRIP)\n" );
1650 fprintf ( fMakefile,
1651 "\t${strip} -s -x -X $@\n\n" );
1652 fprintf ( fMakefile,
1653 "endif\n" );
1654 }
1655
1656 void
1657 MingwModuleHandler::GenerateLinkerCommand (
1658 const string& dependencies,
1659 const string& linkerParameters,
1660 const string& pefixupParameters )
1661 {
1662 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1663 const FileLocation *definitionFilename = GetDefinitionFilename ();
1664 string linker = module.cplusplus ? "${gpp}" : "${gcc}";
1665 string objectsMacro = GetObjectsMacro ( module );
1666 string libsMacro = GetLibsMacro ();
1667
1668 string target_macro ( GetTargetMacro ( module ) );
1669 string target_folder ( backend->GetFullPath ( *target_file ) );
1670
1671 string linkerScriptArgument;
1672 if ( module.linkerScript != NULL )
1673 linkerScriptArgument = ssprintf ( " -Wl,-T,%s", backend->GetFullName ( *module.linkerScript->file ).c_str () );
1674 else
1675 linkerScriptArgument = "";
1676
1677 fprintf ( fMakefile,
1678 "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
1679 target_macro.c_str (),
1680 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1681 dependencies.c_str (),
1682 target_folder.c_str () );
1683 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1684 string targetName ( module.output->name );
1685
1686 if ( !module.IsDLL () )
1687 {
1688 fprintf ( fMakefile,
1689 "\t%s %s%s -o %s %s %s %s\n",
1690 linker.c_str (),
1691 linkerParameters.c_str (),
1692 linkerScriptArgument.c_str (),
1693 target_macro.c_str (),
1694 objectsMacro.c_str (),
1695 libsMacro.c_str (),
1696 GetLinkerMacro ().c_str () );
1697 }
1698 else if ( module.HasImportLibrary () )
1699 {
1700 FileLocation temp_exp ( TemporaryDirectory,
1701 "",
1702 module.name + ".temp.exp" );
1703 CLEAN_FILE ( temp_exp );
1704
1705 fprintf ( fMakefile,
1706 "\t${dlltool} --dllname %s --def %s --output-exp %s%s%s\n",
1707 targetName.c_str (),
1708 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1709 backend->GetFullName ( temp_exp ).c_str (),
1710 module.mangledSymbols ? "" : " --kill-at",
1711 module.underscoreSymbols ? " --add-underscore" : "" );
1712
1713 fprintf ( fMakefile,
1714 "\t%s %s%s %s -o %s %s %s %s\n",
1715 linker.c_str (),
1716 linkerParameters.c_str (),
1717 linkerScriptArgument.c_str (),
1718 backend->GetFullName ( temp_exp ).c_str (),
1719 target_macro.c_str (),
1720 objectsMacro.c_str (),
1721 libsMacro.c_str (),
1722 GetLinkerMacro ().c_str () );
1723
1724 fprintf ( fMakefile,
1725 "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n",
1726 target_macro.c_str (),
1727 pefixupParameters.c_str() );
1728
1729 fprintf ( fMakefile,
1730 "\t-@${rm} %s 2>$(NUL)\n",
1731 backend->GetFullName ( temp_exp ).c_str () );
1732 }
1733 else
1734 {
1735 /* XXX: need to workaround binutils bug, which exports
1736 * all functions in a dll if no .def file or an empty
1737 * one has been provided... */
1738 /* See bug 1244 */
1739 //printf ( "%s will have all its functions exported\n",
1740 // module.target->name.c_str () );
1741 fprintf ( fMakefile,
1742 "\t%s %s%s -o %s %s %s %s\n",
1743 linker.c_str (),
1744 linkerParameters.c_str (),
1745 linkerScriptArgument.c_str (),
1746 target_macro.c_str (),
1747 objectsMacro.c_str (),
1748 libsMacro.c_str (),
1749 GetLinkerMacro ().c_str () );
1750 }
1751
1752 GenerateBuildMapCode ();
1753 GenerateBuildNonSymbolStrippedCode ();
1754 GenerateRunRsymCode ();
1755 GenerateRunStripCode ();
1756 GenerateCleanObjectsAsYouGoCode ();
1757
1758 if ( definitionFilename )
1759 delete definitionFilename;
1760 delete target_file;
1761 }
1762
1763 void
1764 MingwModuleHandler::GeneratePhonyTarget() const
1765 {
1766 string targetMacro ( GetTargetMacro ( module ) );
1767 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1768
1769 fprintf ( fMakefile,
1770 ".PHONY: %s\n\n",
1771 targetMacro.c_str ());
1772 fprintf ( fMakefile, "%s: | %s\n",
1773 targetMacro.c_str (),
1774 backend->GetFullPath ( *target_file ).c_str () );
1775
1776 delete target_file;
1777 }
1778
1779 void
1780 MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
1781 {
1782 size_t i;
1783 string moduleDependencies;
1784
1785 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1786 for ( i = 0; i < compilationUnits.size (); i++ )
1787 {
1788 CompilationUnit& compilationUnit = *compilationUnits[i];
1789 const FileLocation& compilationName = compilationUnit.GetFilename ();
1790 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module );
1791 if ( GetExtension ( *objectFilename ) == ".h" )
1792 moduleDependencies += ssprintf ( " $(%s_HEADERS)", module.name.c_str () );
1793 else if ( GetExtension ( *objectFilename ) == ".rc" )
1794 moduleDependencies += ssprintf ( " $(%s_RESOURCES)", module.name.c_str () );
1795 delete objectFilename;
1796 }
1797
1798 for ( i = 0; i < compilationUnits.size (); i++ )
1799 {
1800 GenerateCommands ( *compilationUnits[i],
1801 moduleDependencies );
1802 fprintf ( fMakefile,
1803 "\n" );
1804 }
1805
1806 const vector<If*>& ifs = data.ifs;
1807 for ( i = 0; i < ifs.size(); i++ )
1808 {
1809 GenerateObjectFileTargets ( ifs[i]->data );
1810 }
1811
1812 vector<CompilationUnit*> sourceCompilationUnits;
1813 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1814 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1815 {
1816 GenerateCommands ( *sourceCompilationUnits[i],
1817 moduleDependencies );
1818 }
1819 CleanupCompilationUnitVector ( sourceCompilationUnits );
1820 }
1821
1822 void
1823 MingwModuleHandler::GenerateObjectFileTargets ()
1824 {
1825 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1826
1827 if ( pchFilename )
1828 {
1829 string cc = ( module.host == HostTrue ? "${host_gcc}" : "${gcc}" );
1830 string cppc = ( module.host == HostTrue ? "${host_gpp}" : "${gpp}" );
1831
1832 const FileLocation& baseHeaderFile = *module.pch->file;
1833 CLEAN_FILE ( *pchFilename );
1834 string dependencies = backend->GetFullName ( baseHeaderFile );
1835 /* WIDL generated headers may be used */
1836 vector<FileLocation> rpcDependencies;
1837 GetRpcHeaderDependencies ( rpcDependencies );
1838 if ( rpcDependencies.size () > 0 )
1839 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1840 fprintf ( fMakefile,
1841 "%s: %s ${%s_precondition} | %s\n",
1842 backend->GetFullName ( *pchFilename ).c_str(),
1843 dependencies.c_str(),
1844 module.name.c_str (),
1845 backend->GetFullPath ( *pchFilename ).c_str() );
1846 fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
1847 fprintf ( fMakefile,
1848 "\t%s -o %s %s -g %s\n\n",
1849 module.cplusplus ? cppc.c_str() : cc.c_str(),
1850 backend->GetFullName ( *pchFilename ).c_str(),
1851 cflagsMacro.c_str(),
1852 backend->GetFullName ( baseHeaderFile ).c_str() );
1853 delete pchFilename;
1854 }
1855
1856 GenerateObjectFileTargets ( module.non_if_data );
1857 fprintf ( fMakefile, "\n" );
1858 }
1859
1860 /* caller needs to delete the returned object */
1861 const FileLocation*
1862 MingwModuleHandler::GenerateArchiveTarget ()
1863 {
1864 const FileLocation *archiveFilename = GetModuleArchiveFilename ();
1865 const FileLocation *definitionFilename = GetDefinitionFilename ();
1866
1867 arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1868
1869 if ( IsStaticLibrary ( module ) && definitionFilename )
1870 {
1871 fprintf ( fMakefile,
1872 "\t${dlltool} --dllname %s --def %s --output-lib $@%s%s\n",
1873 module.importLibrary->dllname.c_str (),
1874 backend->GetFullName ( *definitionFilename ).c_str (),
1875 module.mangledSymbols ? "" : " --kill-at",
1876 module.underscoreSymbols ? " --add-underscore" : "" );
1877 }
1878
1879 if ( definitionFilename )
1880 delete definitionFilename;
1881
1882 if(module.type == HostStaticLibrary)
1883 arHostRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1884 else
1885 arRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1886
1887 GenerateCleanObjectsAsYouGoCode ();
1888
1889 fprintf ( fMakefile, "\n" );
1890
1891 return archiveFilename;
1892 }
1893
1894 string
1895 MingwModuleHandler::GetCFlagsMacro () const
1896 {
1897 return ssprintf ( "$(%s_CFLAGS)",
1898 module.name.c_str () );
1899 }
1900
1901 /*static*/ string
1902 MingwModuleHandler::GetObjectsMacro ( const Module& module )
1903 {
1904 return ssprintf ( "$(%s_OBJS)",
1905 module.name.c_str () );
1906 }
1907
1908 string
1909 MingwModuleHandler::GetLinkingDependenciesMacro () const
1910 {
1911 return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
1912 }
1913
1914 string
1915 MingwModuleHandler::GetLibsMacro () const
1916 {
1917 return ssprintf ( "$(%s_LIBS)", module.name.c_str () );
1918 }
1919
1920 string
1921 MingwModuleHandler::GetLinkerMacro () const
1922 {
1923 return ssprintf ( "$(%s_LFLAGS)",
1924 module.name.c_str () );
1925 }
1926
1927 string
1928 MingwModuleHandler::GetModuleTargets ( const Module& module )
1929 {
1930 if ( ReferenceObjects ( module ) )
1931 return GetObjectsMacro ( module );
1932 else
1933 {
1934 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1935 string target = backend->GetFullName ( *target_file ).c_str ();
1936 delete target_file;
1937 return target;
1938 }
1939 }
1940
1941 void
1942 MingwModuleHandler::GenerateSourceMacro ()
1943 {
1944 sourcesMacro = ssprintf ( "%s_SOURCES", module.name.c_str ());
1945
1946 GenerateSourceMacros (
1947 "=",
1948 module.non_if_data );
1949
1950 // future references to the macro will be to get its values
1951 sourcesMacro = ssprintf ("$(%s)", sourcesMacro.c_str ());
1952 }
1953
1954 void
1955 MingwModuleHandler::GenerateObjectMacro ()
1956 {
1957 objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
1958
1959 GenerateObjectMacros (
1960 "=",
1961 module.non_if_data );
1962
1963 // future references to the macro will be to get its values
1964 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
1965 }
1966
1967 void
1968 MingwModuleHandler::GenerateTargetMacro ()
1969 {
1970 fprintf ( fMakefile,
1971 "%s := %s\n",
1972 GetTargetMacro ( module, false ).c_str (),
1973 GetModuleTargets ( module ).c_str () );
1974 }
1975
1976 void
1977 MingwModuleHandler::GetRpcHeaderDependencies (
1978 vector<FileLocation>& dependencies ) const
1979 {
1980 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
1981 {
1982 Library& library = *module.non_if_data.libraries[i];
1983 if ( library.importedModule->type == RpcServer ||
1984 library.importedModule->type == RpcClient ||
1985 library.importedModule->type == RpcProxy ||
1986 library.importedModule->type == IdlHeader )
1987 {
1988 for ( size_t j = 0; j < library.importedModule->non_if_data.compilationUnits.size (); j++ )
1989 {
1990 CompilationUnit& compilationUnit = *library.importedModule->non_if_data.compilationUnits[j];
1991 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1992 string extension = GetExtension ( sourceFile );
1993 if ( extension == ".idl" || extension == ".IDL" )
1994 {
1995 string basename = GetBasename ( sourceFile.name );
1996 if ( library.importedModule->type == RpcServer )
1997 {
1998 const FileLocation *header = GetRpcServerHeaderFilename ( &sourceFile );
1999 dependencies.push_back ( *header );
2000 delete header;
2001 }
2002 if ( library.importedModule->type == RpcClient )
2003 {
2004 const FileLocation *header = GetRpcClientHeaderFilename ( &sourceFile );
2005 dependencies.push_back ( *header );
2006 delete header;
2007 }
2008 if ( library.importedModule->type == RpcProxy )
2009 {
2010 const FileLocation *header = GetRpcProxyHeaderFilename ( &sourceFile );
2011 dependencies.push_back ( *header );
2012 delete header;
2013 }
2014 if ( library.importedModule->type == IdlHeader )
2015 {
2016 const FileLocation *header = GetIdlHeaderFilename ( &sourceFile );
2017 dependencies.push_back ( *header );
2018 delete header;
2019 }
2020 }
2021 }
2022 }
2023 }
2024 }
2025
2026 void
2027 MingwModuleHandler::GenerateOtherMacros ()
2028 {
2029 set<const Define *> used_defs;
2030
2031 cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
2032 nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
2033 windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
2034 widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());
2035 linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
2036 libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
2037 linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
2038
2039 GenerateMacros (
2040 "=",
2041 module.non_if_data,
2042 &module.linkerFlags,
2043 used_defs );
2044
2045 if ( module.host == HostFalse )
2046 {
2047 GenerateMacros (
2048 "+=",
2049 module.project.non_if_data,
2050 NULL,
2051 used_defs );
2052 }
2053
2054 vector<FileLocation> s;
2055 if ( module.importLibrary )
2056 {
2057 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2058 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2059 {
2060 CompilationUnit& compilationUnit = *compilationUnits[i];
2061 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2062 string extension = GetExtension ( sourceFile );
2063 if ( extension == ".spec" || extension == ".SPEC" )
2064 GetSpecObjectDependencies ( s, &sourceFile );
2065 }
2066 }
2067 if ( s.size () > 0 )
2068 {
2069 fprintf (
2070 fMakefile,
2071 "%s +=",
2072 linkDepsMacro.c_str() );
2073 for ( size_t i = 0; i < s.size(); i++ )
2074 fprintf ( fMakefile,
2075 " %s",
2076 backend->GetFullName ( s[i] ).c_str () );
2077 fprintf ( fMakefile, "\n" );
2078 }
2079
2080 string globalCflags = "";
2081 if ( module.host == HostFalse )
2082 globalCflags += " $(PROJECT_CFLAGS)";
2083 else
2084 globalCflags += " -Wall -Wpointer-arith -D__REACTOS__";
2085 globalCflags += " -g";
2086 if ( backend->usePipe )
2087 globalCflags += " -pipe";
2088 if ( !module.allowWarnings )
2089 globalCflags += " -Werror";
2090 if ( module.host == HostTrue )
2091 {
2092 if ( module.cplusplus )
2093 globalCflags += " $(HOST_CPPFLAGS)";
2094 else
2095 globalCflags += " -Wno-strict-aliasing $(HOST_CFLAGS)";
2096 }
2097 else
2098 {
2099 if ( module.cplusplus )
2100 {
2101 // HACK: use host headers when building C++
2102 globalCflags += " $(HOST_CPPFLAGS)";
2103 }
2104 else
2105 globalCflags += " -nostdinc";
2106 }
2107
2108 // Always force disabling of sibling calls optimisation for GCC
2109 // (TODO: Move to version-specific once this bug is fixed in GCC)
2110 globalCflags += " -fno-optimize-sibling-calls";
2111
2112 fprintf (
2113 fMakefile,
2114 "%s +=%s\n",
2115 cflagsMacro.c_str (),
2116 globalCflags.c_str () );
2117
2118 if ( module.host == HostFalse )
2119 {
2120 fprintf (
2121 fMakefile,
2122 "%s += $(PROJECT_RCFLAGS)\n",
2123 windresflagsMacro.c_str () );
2124
2125 fprintf (
2126 fMakefile,
2127 "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
2128 widlflagsMacro.c_str (),
2129 module.output->relative_path.c_str () );
2130
2131 fprintf (
2132 fMakefile,
2133 "%s_LFLAGS += $(PROJECT_LFLAGS) -g\n",
2134 module.name.c_str () );
2135 }
2136 else
2137 {
2138 fprintf (
2139 fMakefile,
2140 "%s_LFLAGS += $(HOST_LFLAGS)\n",
2141 module.name.c_str () );
2142 }
2143
2144 fprintf (
2145 fMakefile,
2146 "%s += $(%s)\n",
2147 linkDepsMacro.c_str (),
2148 libsMacro.c_str () );
2149
2150 string cflags = TypeSpecificCFlags();
2151 if ( cflags.size() > 0 )
2152 {
2153 fprintf ( fMakefile,
2154 "%s += %s\n\n",
2155 cflagsMacro.c_str (),
2156 cflags.c_str () );
2157 }
2158
2159 string nasmflags = TypeSpecificNasmFlags();
2160 if ( nasmflags.size () > 0 )
2161 {
2162 fprintf ( fMakefile,
2163 "%s += %s\n\n",
2164 nasmflagsMacro.c_str (),
2165 nasmflags.c_str () );
2166 }
2167
2168 string linkerflags = TypeSpecificLinkerFlags();
2169 if ( linkerflags.size() > 0 )
2170 {
2171 fprintf ( fMakefile,
2172 "%s += %s\n\n",
2173 linkerflagsMacro.c_str (),
2174 linkerflags.c_str () );
2175 }
2176
2177 if ( IsStaticLibrary ( module ) && module.isStartupLib )
2178 {
2179 fprintf ( fMakefile,
2180 "%s += -Wno-main\n\n",
2181 cflagsMacro.c_str () );
2182 }
2183
2184 fprintf ( fMakefile, "\n\n" );
2185
2186 // future references to the macros will be to get their values
2187 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
2188 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
2189 widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
2190 }
2191
2192 void
2193 MingwModuleHandler::GenerateRules ()
2194 {
2195 string targetMacro = GetTargetMacro ( module );
2196 //CLEAN_FILE ( targetMacro );
2197 CLEAN_FILE ( FileLocation ( SourceDirectory, "", targetMacro ) );
2198
2199 // generate phony target for module name
2200 fprintf ( fMakefile, ".PHONY: %s\n",
2201 module.name.c_str () );
2202 string dependencies = GetTargetMacro ( module );
2203 if ( module.type == Test )
2204 dependencies += " $(REGTESTS_RUN_TARGET)";
2205 fprintf ( fMakefile, "%s: %s\n\n",
2206 module.name.c_str (),
2207 dependencies.c_str () );
2208 if ( module.type == Test )
2209 {
2210 fprintf ( fMakefile,
2211 "\t@%s\n",
2212 targetMacro.c_str ());
2213 }
2214
2215 if ( !ReferenceObjects ( module ) )
2216 {
2217 const FileLocation* ar_target = GenerateArchiveTarget ();
2218 delete ar_target;
2219 }
2220
2221 GenerateObjectFileTargets ();
2222 }
2223
2224 void
2225 MingwModuleHandler::GetInvocationDependencies (
2226 const Module& module,
2227 string_list& dependencies )
2228 {
2229 for ( size_t i = 0; i < module.invocations.size (); i++ )
2230 {
2231 Invoke& invoke = *module.invocations[i];
2232 if ( invoke.invokeModule == &module )
2233 /* Protect against circular dependencies */
2234 continue;
2235 invoke.GetTargets ( dependencies );
2236 }
2237 }
2238
2239 void
2240 MingwModuleHandler::GenerateInvocations () const
2241 {
2242 if ( module.invocations.size () == 0 )
2243 return;
2244
2245 size_t iend = module.invocations.size ();
2246 for ( size_t i = 0; i < iend; i++ )
2247 {
2248 const Invoke& invoke = *module.invocations[i];
2249
2250 if ( invoke.invokeModule->type != BuildTool )
2251 {
2252 throw XMLInvalidBuildFileException (
2253 module.node.location,
2254 "Only modules of type buildtool can be invoked." );
2255 }
2256
2257 string invokeTarget = module.GetInvocationTarget ( i );
2258 string_list invoke_targets;
2259 assert ( invoke_targets.size() );
2260 invoke.GetTargets ( invoke_targets );
2261 fprintf ( fMakefile,
2262 ".PHONY: %s\n\n",
2263 invokeTarget.c_str () );
2264 fprintf ( fMakefile,
2265 "%s:",
2266 invokeTarget.c_str () );
2267 size_t j, jend = invoke_targets.size();
2268 for ( j = 0; j < jend; j++ )
2269 {
2270 fprintf ( fMakefile,
2271 " %s",
2272 invoke_targets[i].c_str () );
2273 }
2274 fprintf ( fMakefile, "\n\n%s", invoke_targets[0].c_str () );
2275 for ( j = 1; j < jend; j++ )
2276 fprintf ( fMakefile,
2277 " %s",
2278 invoke_targets[i].c_str () );
2279 fprintf ( fMakefile,
2280 ": %s\n",
2281 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str () );
2282 fprintf ( fMakefile, "\t$(ECHO_INVOKE)\n" );
2283 fprintf ( fMakefile,
2284 "\t%s %s\n\n",
2285 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str (),
2286 invoke.GetParameters ().c_str () );
2287 }
2288 }
2289
2290 string
2291 MingwModuleHandler::GetPreconditionDependenciesName () const
2292 {
2293 return module.name + "_precondition";
2294 }
2295
2296 void
2297 MingwModuleHandler::GetDefaultDependencies (
2298 string_list& dependencies ) const
2299 {
2300 /* Avoid circular dependency */
2301 if ( module.host == HostTrue )
2302 return;
2303
2304 if ( module.name != "psdk" )
2305 dependencies.push_back ( "$(PSDK_TARGET) $(psdk_HEADERS)" );
2306
2307 /* Check if any dependent library relies on the generated headers */
2308 for ( size_t i = 0; i < module.project.modules.size (); i++ )
2309 {
2310 const Module& m = *module.project.modules[i];
2311 for ( size_t j = 0; j < m.non_if_data.compilationUnits.size (); j++ )
2312 {
2313 CompilationUnit& compilationUnit = *m.non_if_data.compilationUnits[j];
2314 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2315 string extension = GetExtension ( sourceFile );
2316 if (extension == ".mc" || extension == ".MC" )
2317 {
2318 string dependency = ssprintf ( "$(%s_MCHEADERS)", m.name.c_str () );
2319 dependencies.push_back ( dependency );
2320 }
2321 }
2322 }
2323 }
2324
2325 void
2326 MingwModuleHandler::GeneratePreconditionDependencies ()
2327 {
2328 string preconditionDependenciesName = GetPreconditionDependenciesName ();
2329 vector<FileLocation> sourceFilenames;
2330 GetSourceFilenamesWithoutGeneratedFiles ( sourceFilenames );
2331 string_list dependencies;
2332 GetDefaultDependencies ( dependencies );
2333 GetModuleDependencies ( dependencies );
2334
2335 GetInvocationDependencies ( module, dependencies );
2336
2337 if ( dependencies.size() )
2338 {
2339 fprintf ( fMakefile,
2340 "%s =",
2341 preconditionDependenciesName.c_str () );
2342 for ( size_t i = 0; i < dependencies.size(); i++ )
2343 fprintf ( fMakefile,
2344 " %s",
2345 dependencies[i].c_str () );
2346 fprintf ( fMakefile, "\n\n" );
2347 }
2348
2349 fprintf ( fMakefile, "\n" );
2350 }
2351
2352 bool
2353 MingwModuleHandler::IsWineModule () const
2354 {
2355 if ( module.importLibrary == NULL)
2356 return false;
2357
2358 size_t index = module.importLibrary->source->name.rfind ( ".spec.def" );
2359 return ( index != string::npos );
2360 }
2361
2362 /* caller needs to delete the returned object */
2363 const FileLocation*
2364 MingwModuleHandler::GetDefinitionFilename () const
2365 {
2366 if ( module.importLibrary == NULL )
2367 return NULL;
2368
2369 DirectoryLocation directory;
2370 if ( IsWineModule () )
2371 directory = IntermediateDirectory;
2372 else
2373 directory = SourceDirectory;
2374
2375 return new FileLocation ( directory,
2376 module.importLibrary->source->relative_path,
2377 module.importLibrary->source->name );
2378 }
2379
2380 void
2381 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
2382 {
2383 if ( module.importLibrary != NULL )
2384 {
2385 const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
2386 const FileLocation *defFilename = GetDefinitionFilename ();
2387 string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
2388
2389 vector<FileLocation> deps;
2390 GetDefinitionDependencies ( deps );
2391
2392 fprintf ( fMakefile, "# IMPORT LIBRARY RULE:\n" );
2393
2394 fprintf ( fMakefile, "%s:",
2395 backend->GetFullName ( *library_target ).c_str () );
2396
2397 if ( defFilename )
2398 {
2399 fprintf ( fMakefile, " %s",
2400 backend->GetFullName ( *defFilename ).c_str () );
2401 }
2402
2403 size_t i, iend = deps.size();
2404 for ( i = 0; i < iend; i++ )
2405 fprintf ( fMakefile, " %s",
2406 backend->GetFullName ( deps[i] ).c_str () );
2407
2408 fprintf ( fMakefile, " | %s\n",
2409 backend->GetFullPath ( *library_target ).c_str () );
2410
2411 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
2412
2413 fprintf ( fMakefile,
2414 "\t${dlltool} --dllname %s --def %s --output-lib %s%s%s\n\n",
2415 module.output->name.c_str (),
2416 defFilename ? backend->GetFullName ( *defFilename ).c_str ()
2417 : empty.c_str (),
2418 backend->GetFullName ( *library_target ).c_str (),
2419 module.mangledSymbols ? "" : " --kill-at",
2420 module.underscoreSymbols ? " --add-underscore" : "" );
2421
2422 if ( defFilename )
2423 delete defFilename;
2424 delete library_target;
2425 }
2426 }
2427
2428 void
2429 MingwModuleHandler::GetSpecObjectDependencies (
2430 vector<FileLocation>& dependencies,
2431 const FileLocation *file ) const
2432 {
2433 string basename = GetBasename ( file->name );
2434
2435 FileLocation defDependency ( IntermediateDirectory,
2436 file->relative_path,
2437 basename + ".spec.def" );
2438 dependencies.push_back ( defDependency );
2439
2440 FileLocation stubsDependency ( IntermediateDirectory,
2441 file->relative_path,
2442 basename + ".stubs.c" );
2443 dependencies.push_back ( stubsDependency );
2444 }
2445
2446 void
2447 MingwModuleHandler::GetMcObjectDependencies (
2448 vector<FileLocation>& dependencies,
2449 const FileLocation *file ) const
2450 {
2451 string basename = GetBasename ( file->name );
2452
2453 FileLocation defDependency ( IntermediateDirectory,
2454 "include/reactos",
2455 basename + ".h" );
2456 dependencies.push_back ( defDependency );
2457
2458 FileLocation stubsDependency ( IntermediateDirectory,
2459 file->relative_path,
2460 basename + ".rc" );
2461 dependencies.push_back ( stubsDependency );
2462 }
2463
2464 void
2465 MingwModuleHandler::GetWidlObjectDependencies (
2466 vector<FileLocation>& dependencies,
2467 const FileLocation *file ) const
2468 {
2469 string basename = GetBasename ( file->name );
2470 const FileLocation *generatedHeaderFilename = GetRpcServerHeaderFilename ( file );
2471
2472 FileLocation serverSourceDependency ( IntermediateDirectory,
2473 file->relative_path,
2474 basename + "_s.c" );
2475 dependencies.push_back ( serverSourceDependency );
2476 dependencies.push_back ( *generatedHeaderFilename );
2477
2478 delete generatedHeaderFilename;
2479 }
2480
2481 void
2482 MingwModuleHandler::GetDefinitionDependencies (
2483 vector<FileLocation>& dependencies ) const
2484 {
2485 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2486 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2487 {
2488 const CompilationUnit& compilationUnit = *compilationUnits[i];
2489 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2490 string extension = GetExtension ( sourceFile );
2491 if ( extension == ".spec" || extension == ".SPEC" )
2492 GetSpecObjectDependencies ( dependencies, &sourceFile );
2493 if ( extension == ".idl" || extension == ".IDL" )
2494 {
2495 if ( ( module.type == RpcServer ) || ( module.type == RpcClient ) || ( module.type == RpcProxy ) )
2496 GetWidlObjectDependencies ( dependencies, &sourceFile );
2497 }
2498 }
2499 }
2500
2501 enum DebugSupportType
2502 {
2503 DebugKernelMode,
2504 DebugUserMode
2505 };
2506
2507 static void
2508 MingwAddDebugSupportLibraries ( Module& module, DebugSupportType type )
2509 {
2510 Library* pLibrary;
2511
2512 switch(type)
2513 {
2514 case DebugKernelMode:
2515 pLibrary = new Library ( module, "debugsup_ntoskrnl" );
2516 break;
2517
2518 case DebugUserMode:
2519 pLibrary = new Library ( module, "debugsup_ntdll" );
2520 break;
2521
2522 default:
2523 assert(0);
2524 }
2525
2526 module.non_if_data.libraries.push_back(pLibrary);
2527 }
2528
2529 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler ( const Module& module_ )
2530 : MingwModuleHandler ( module_ )
2531 {
2532 }
2533
2534 void
2535 MingwBuildToolModuleHandler::Process ()
2536 {
2537 GenerateBuildToolModuleTarget ();
2538 }
2539
2540 void
2541 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
2542 {
2543 string targetMacro ( GetTargetMacro (module) );
2544 string objectsMacro = GetObjectsMacro ( module );
2545 string linkDepsMacro = GetLinkingDependenciesMacro ();
2546 string libsMacro = GetLibsMacro ();
2547
2548 GenerateRules ();
2549
2550 string linker;
2551 if ( module.cplusplus )
2552 linker = "${host_gpp}";
2553 else
2554 linker = "${host_gcc}";
2555
2556 const FileLocation *target_file = GetTargetFilename ( module, NULL );
2557 fprintf ( fMakefile, "%s: %s %s | %s\n",
2558 targetMacro.c_str (),
2559 objectsMacro.c_str (),
2560 linkDepsMacro.c_str (),
2561 backend->GetFullPath ( *target_file ).c_str () );
2562 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2563 fprintf ( fMakefile,
2564 "\t%s %s -o $@ %s %s\n\n",
2565 linker.c_str (),
2566 GetLinkerMacro ().c_str (),
2567 objectsMacro.c_str (),
2568 libsMacro.c_str () );
2569
2570 delete target_file;
2571 }
2572
2573
2574 MingwKernelModuleHandler::MingwKernelModuleHandler (
2575 const Module& module_ )
2576
2577 : MingwModuleHandler ( module_ )
2578 {
2579 }
2580
2581 void
2582 MingwKernelModuleHandler::Process ()
2583 {
2584 GenerateKernelModuleTarget ();
2585 }
2586
2587 void
2588 MingwKernelModuleHandler::GenerateKernelModuleTarget ()
2589 {
2590 string targetMacro ( GetTargetMacro ( module ) );
2591 string workingDirectory = GetWorkingDirectory ( );
2592 string linkDepsMacro = GetLinkingDependenciesMacro ();
2593
2594 GenerateImportLibraryTargetIfNeeded ();
2595
2596 if ( module.non_if_data.compilationUnits.size () > 0 )
2597 {
2598 GenerateRules ();
2599
2600 string dependencies = linkDepsMacro + " " + objectsMacro;
2601
2602 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s",
2603 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2604 module.baseaddress.c_str () );
2605
2606 GenerateLinkerCommand ( dependencies,
2607 linkerParameters + " $(NTOSKRNL_SHARED)",
2608 " -sections" );
2609 }
2610 else
2611 {
2612 GeneratePhonyTarget();
2613 }
2614 }
2615
2616
2617 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler (
2618 const Module& module_ )
2619
2620 : MingwModuleHandler ( module_ )
2621 {
2622 }
2623
2624 void
2625 MingwStaticLibraryModuleHandler::Process ()
2626 {
2627 GenerateStaticLibraryModuleTarget ();
2628 }
2629
2630 void
2631 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ()
2632 {
2633 GenerateRules ();
2634 }
2635
2636
2637 MingwHostStaticLibraryModuleHandler::MingwHostStaticLibraryModuleHandler (
2638 const Module& module_ )
2639
2640 : MingwModuleHandler ( module_ )
2641 {
2642 }
2643
2644 void
2645 MingwHostStaticLibraryModuleHandler::Process ()
2646 {
2647 GenerateHostStaticLibraryModuleTarget ();
2648 }
2649
2650 void
2651 MingwHostStaticLibraryModuleHandler::GenerateHostStaticLibraryModuleTarget ()
2652 {
2653 GenerateRules ();
2654 }
2655
2656
2657 MingwObjectLibraryModuleHandler::MingwObjectLibraryModuleHandler (
2658 const Module& module_ )
2659
2660 : MingwModuleHandler ( module_ )
2661 {
2662 }
2663
2664 void
2665 MingwObjectLibraryModuleHandler::Process ()
2666 {
2667 GenerateObjectLibraryModuleTarget ();
2668 }
2669
2670 void
2671 MingwObjectLibraryModuleHandler::GenerateObjectLibraryModuleTarget ()
2672 {
2673 GenerateRules ();
2674 }
2675
2676
2677 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
2678 const Module& module_ )
2679
2680 : MingwModuleHandler ( module_ )
2681 {
2682 }
2683
2684 MingwEmbeddedTypeLibModuleHandler::MingwEmbeddedTypeLibModuleHandler (
2685 const Module& module_ )
2686
2687 : MingwModuleHandler ( module_ )
2688 {
2689 }
2690
2691 void
2692 MingwEmbeddedTypeLibModuleHandler::Process ()
2693 {
2694 GenerateRules ();
2695 }
2696
2697
2698 void
2699 MingwKernelModeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2700 {
2701 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2702 }
2703
2704 void
2705 MingwKernelModeDLLModuleHandler::Process ()
2706 {
2707 GenerateKernelModeDLLModuleTarget ();
2708 }
2709
2710 void
2711 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
2712 {
2713 string targetMacro ( GetTargetMacro ( module ) );
2714 string workingDirectory = GetWorkingDirectory ( );
2715 string linkDepsMacro = GetLinkingDependenciesMacro ();
2716
2717 GenerateImportLibraryTargetIfNeeded ();
2718
2719 if ( module.non_if_data.compilationUnits.size () > 0 )
2720 {
2721 GenerateRules ();
2722
2723 string dependencies = linkDepsMacro + " " + objectsMacro;
2724
2725 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
2726 module.GetEntryPoint(true).c_str (),
2727 module.baseaddress.c_str () );
2728 GenerateLinkerCommand ( dependencies,
2729 linkerParameters,
2730 " -sections" );
2731 }
2732 else
2733 {
2734 GeneratePhonyTarget();
2735 }
2736 }
2737
2738
2739 MingwKernelModeDriverModuleHandler::MingwKernelModeDriverModuleHandler (
2740 const Module& module_ )
2741
2742 : MingwModuleHandler ( module_ )
2743 {
2744 }
2745
2746 void
2747 MingwKernelModeDriverModuleHandler::AddImplicitLibraries ( Module& module )
2748 {
2749 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2750 }
2751
2752 void
2753 MingwKernelModeDriverModuleHandler::Process ()
2754 {
2755 GenerateKernelModeDriverModuleTarget ();
2756 }
2757
2758
2759 void
2760 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ()
2761 {
2762 string targetMacro ( GetTargetMacro (module) );
2763 string workingDirectory = GetWorkingDirectory ();
2764 string linkDepsMacro = GetLinkingDependenciesMacro ();
2765
2766 GenerateImportLibraryTargetIfNeeded ();
2767
2768 if ( module.non_if_data.compilationUnits.size () > 0 )
2769 {
2770 GenerateRules ();
2771
2772 string dependencies = linkDepsMacro + " " + objectsMacro;
2773
2774 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
2775 module.GetEntryPoint(true).c_str (),
2776 module.baseaddress.c_str () );
2777 GenerateLinkerCommand ( dependencies,
2778 linkerParameters,
2779 " -sections" );
2780 }
2781 else
2782 {
2783 GeneratePhonyTarget();
2784 }
2785 }
2786
2787
2788 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler (
2789 const Module& module_ )
2790
2791 : MingwModuleHandler ( module_ )
2792 {
2793 }
2794
2795 void
2796 MingwNativeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2797 {
2798 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2799 }
2800
2801 void
2802 MingwNativeDLLModuleHandler::Process ()
2803 {
2804 GenerateNativeDLLModuleTarget ();
2805 }
2806
2807 void
2808 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
2809 {
2810 string targetMacro ( GetTargetMacro (module) );
2811 string workingDirectory = GetWorkingDirectory ( );
2812 string linkDepsMacro = GetLinkingDependenciesMacro ();
2813
2814 GenerateImportLibraryTargetIfNeeded ();
2815
2816 if ( module.non_if_data.compilationUnits.size () > 0 )
2817 {
2818 GenerateRules ();
2819
2820 string dependencies = linkDepsMacro + " " + objectsMacro;
2821
2822 string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -shared",
2823 module.GetEntryPoint(true).c_str (),
2824 module.baseaddress.c_str () );
2825 GenerateLinkerCommand ( dependencies,
2826 linkerParameters,
2827 "" );
2828 }
2829 else
2830 {
2831 GeneratePhonyTarget();
2832 }
2833 }
2834
2835
2836 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler (
2837 const Module& module_ )
2838
2839 : MingwModuleHandler ( module_ )
2840 {
2841 }
2842
2843 void
2844 MingwNativeCUIModuleHandler::AddImplicitLibraries ( Module& module )
2845 {
2846 MingwAddDebugSupportLibraries ( module, DebugUserMode );