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