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