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