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