Add a check to not mix up host and target modules
[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 // Check if host and target modules are not mixed up
782 HostType current = ModuleHandlerInformations[module.type].DefaultHost;
783 std::vector<Library*>::const_iterator it;
784 for ( it = data.libraries.begin(); it != data.libraries.end(); ++it )
785 {
786 HostType imported = ModuleHandlerInformations[(*it)->importedModule->type].DefaultHost;
787 if (current != imported)
788 {
789 throw InvalidOperationException ( __FILE__,
790 __LINE__,
791 "Module '%s' imports module '%s', which is not of the right type",
792 module.name.c_str (),
793 (*it)->importedModule->name.c_str () );
794 }
795 }
796
797 string deps = GenerateImportLibraryDependenciesFromVector ( data.libraries );
798 if ( deps.size () > 0 )
799 {
800 fprintf (
801 fMakefile,
802 "%s %s %s\n",
803 libsMacro.c_str(),
804 assignmentOperation,
805 deps.c_str() );
806 }
807 }
808 }
809
810 void
811 MingwModuleHandler::CleanupCompilationUnitVector ( vector<CompilationUnit*>& compilationUnits )
812 {
813 for ( size_t i = 0; i < compilationUnits.size (); i++ )
814 delete compilationUnits[i];
815 }
816
817 void
818 MingwModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUnit*>& compilationUnits )
819 {
820 }
821
822 void
823 MingwModuleHandler::GenerateSourceMacros (
824 const IfableData& data )
825 {
826 size_t i;
827
828 fprintf ( fMakefile, "# SOURCE MACROS\n" );
829 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
830 vector<const FileLocation *> headers;
831 if ( compilationUnits.size () > 0 )
832 {
833 fprintf (
834 fMakefile,
835 "%s =",
836 sourcesMacro.c_str () );
837 for ( i = 0; i < compilationUnits.size(); i++ )
838 {
839 CompilationUnit& compilationUnit = *compilationUnits[i];
840 const FileLocation& compilationName = compilationUnit.GetFilename ();
841 fprintf (
842 fMakefile,
843 "%s%s",
844 ( i%10 == 9 ? " \\\n\t" : " " ),
845 backend->GetFullName ( compilationName ).c_str () );
846 }
847 fprintf ( fMakefile, "\n" );
848 }
849
850 vector<CompilationUnit*> sourceCompilationUnits;
851 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
852 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
853 {
854 const FileLocation& compilationName = sourceCompilationUnits[i]->GetFilename ();
855 fprintf (
856 fMakefile,
857 "%s += %s\n",
858 sourcesMacro.c_str(),
859 backend->GetFullName ( compilationName ).c_str () );
860 }
861 CleanupCompilationUnitVector ( sourceCompilationUnits );
862 }
863
864 void
865 MingwModuleHandler::GenerateObjectMacros (
866 const IfableData& data )
867 {
868 size_t i;
869 const char* assignmentOperation = "=";
870
871 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
872 vector<const FileLocation *> headers;
873 vector<const FileLocation *> mcheaders;
874 vector<const FileLocation *> mcresources;
875 fprintf ( fMakefile, "# OBJECT MACROS\n" );
876 if ( compilationUnits.size () > 0 )
877 {
878 for ( i = 0; i < compilationUnits.size (); i++ )
879 {
880 CompilationUnit& compilationUnit = *compilationUnits[i];
881 if ( compilationUnit.IsFirstFile () )
882 {
883 const FileLocation& compilationName = compilationUnit.GetFilename ();
884 const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
885 fprintf ( fMakefile,
886 "%s := %s\n",
887 objectsMacro.c_str(),
888 backend->GetFullName ( *object_file ).c_str () );
889 delete object_file;
890 assignmentOperation = "+=";
891 break;
892 }
893 }
894 fprintf (
895 fMakefile,
896 "%s %s",
897 objectsMacro.c_str (),
898 assignmentOperation );
899 for ( i = 0; i < compilationUnits.size(); i++ )
900 {
901 CompilationUnit& compilationUnit = *compilationUnits[i];
902 if ( !compilationUnit.IsFirstFile () )
903 {
904 const FileLocation& compilationName = compilationUnit.GetFilename ();
905 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module );
906 if ( GetExtension ( *objectFilename ) == ".h" )
907 headers.push_back ( objectFilename );
908 else if ( GetExtension ( *objectFilename ) == ".rc" )
909 {
910 const FileLocation *headerFilename = GetMcHeaderFilename ( &compilationUnit.GetFilename () );
911 mcheaders.push_back ( headerFilename );
912 mcresources.push_back ( objectFilename );
913 }
914 else
915 {
916 fprintf (
917 fMakefile,
918 "%s%s",
919 ( i%10 == 9 ? " \\\n\t" : " " ),
920 backend->GetFullName ( *objectFilename ).c_str () );
921 delete objectFilename;
922 }
923 }
924 }
925 fprintf ( fMakefile, "\n" );
926 }
927 if ( headers.size () > 0 )
928 {
929 fprintf (
930 fMakefile,
931 "%s_HEADERS %s",
932 module.name.c_str (),
933 assignmentOperation );
934 for ( i = 0; i < headers.size (); i++ )
935 {
936 fprintf (
937 fMakefile,
938 "%s%s",
939 ( i%10 == 9 ? " \\\n\t" : " " ),
940 backend->GetFullName ( *headers[i] ).c_str () );
941 delete headers[i];
942 }
943 fprintf ( fMakefile, "\n" );
944 }
945
946 if ( mcheaders.size () > 0 )
947 {
948 fprintf (
949 fMakefile,
950 "%s_MCHEADERS %s",
951 module.name.c_str (),
952 assignmentOperation );
953 for ( i = 0; i < mcheaders.size (); i++ )
954 {
955 fprintf (
956 fMakefile,
957 "%s%s",
958 ( i%10 == 9 ? " \\\n\t" : " " ),
959 backend->GetFullName ( *mcheaders[i] ).c_str () );
960 delete mcheaders[i];
961 }
962 fprintf ( fMakefile, "\n" );
963 }
964
965 if ( mcresources.size () > 0 )
966 {
967 fprintf (
968 fMakefile,
969 "%s_RESOURCES %s",
970 module.name.c_str (),
971 assignmentOperation );
972 for ( i = 0; i < mcresources.size (); i++ )
973 {
974 fprintf (
975 fMakefile,
976 "%s%s",
977 ( i%10 == 9 ? " \\\n\t" : " " ),
978 backend->GetFullName ( *mcresources[i] ).c_str () );
979 delete mcresources[i];
980 }
981 fprintf ( fMakefile, "\n" );
982 }
983
984 vector<CompilationUnit*> sourceCompilationUnits;
985 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
986 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
987 {
988 const FileLocation& compilationName = sourceCompilationUnits[i]->GetFilename ();
989 const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
990 fprintf (
991 fMakefile,
992 "%s += %s\n",
993 objectsMacro.c_str(),
994 backend->GetFullName ( *object_file ).c_str () );
995 delete object_file;
996 }
997 CleanupCompilationUnitVector ( sourceCompilationUnits );
998
999 if ( IsSpecDefinitionFile() )
1000 {
1001 const FileLocation *stubs_file = new FileLocation(
1002 IntermediateDirectory,
1003 module.importLibrary->source->relative_path,
1004 ReplaceExtension ( module.importLibrary->source->name, "_" + module.name + ".stubs.o" ) );
1005
1006 fprintf (
1007 fMakefile,
1008 "%s += %s\n",
1009 objectsMacro.c_str(),
1010 backend->GetFullName ( *stubs_file ).c_str () );
1011
1012 delete stubs_file;
1013 }
1014 }
1015
1016 /* caller needs to delete the returned object */
1017 const FileLocation*
1018 MingwModuleHandler::GetPrecompiledHeaderFilename () const
1019 {
1020 if ( !module.pch || !use_pch )
1021 return NULL;
1022 return new FileLocation ( IntermediateDirectory,
1023 module.pch->file->relative_path + "/.gch_" + module.name,
1024 module.pch->file->name + ".gch" );
1025 }
1026
1027 Rule arRule1 ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).a: $($(module_name)_OBJS) $(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n",
1028 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).a",
1029 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1030 Rule arRule2 ( "\t$(ECHO_AR)\n"
1031 "\t${ar} -rc $@ $($(module_name)_OBJS)\n",
1032 NULL );
1033 Rule arHostRule2 ( "\t$(ECHO_AR)\n"
1034 "\t${host_ar} -rc $@ $($(module_name)_OBJS)\n",
1035 NULL );
1036 Rule gasRule ( "$(source): ${$(module_name)_precondition}\n"
1037 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1038 "\t$(ECHO_GAS)\n"
1039 "\t${gcc} -x assembler-with-cpp -o $@ -D__ASM__ $($(module_name)_CFLAGS) -c $<\n",
1040 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
1041 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1042 Rule bootRule ( "$(source): ${$(module_name)_precondition}\n"
1043 "$(module_output): $(source)$(dependencies) | $(OUTPUT)$(SEP)$(source_dir)\n"
1044 "\t$(ECHO_NASM)\n"
1045 "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
1046 "$(OUTPUT)$(SEP)$(source_dir)$(SEP)", NULL );
1047 Rule nasmRule ( "$(source): ${$(module_name)_precondition}\n"
1048 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1049 "\t$(ECHO_NASM)\n"
1050 "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
1051 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
1052 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1053 Rule windresRule ( "$(source): ${$(module_name)_precondition}\n"
1054 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff: $(source)$(dependencies) $(WRC_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir) $(TEMPORARY)\n"
1055 "\t$(ECHO_WRC)\n"
1056 "\t${gcc} -xc -E -DRC_INVOKED ${$(module_name)_RCFLAGS} $(source) > $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp\n"
1057 "\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"
1058 "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp 2>$(NUL)\n"
1059 "\t${windres} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp -o $@\n"
1060 "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp 2>$(NUL)\n",
1061 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff",
1062 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1063 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"
1064 "\t$(ECHO_WMC)\n"
1065 "\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",
1066 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc",
1067 "$(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h",
1068 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1069 Rule winebuildPDefRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1070 "\t$(ECHO_CPP)\n"
1071 "\t${gcc} -xc -E ${$(module_name)_RCFLAGS} $(source) > $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec\n\n"
1072 "$(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"
1073 "\t$(ECHO_WINEBLD)\n"
1074 "\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",
1075 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec",
1076 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.def",
1077 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1078 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"
1079 "\t$(ECHO_WINEBLD)\n"
1080 "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $@ --pedll $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec --filename $(module_dllname)\n\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 | $(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).spec",
1085 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.c",
1086 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.o",
1087 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1088 Rule winebuildDefRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.def: $(source)$(dependencies) $(WINEBUILD_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1089 "\t$(ECHO_WINEBLD)\n"
1090 "\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",
1091 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec",
1092 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.def",
1093 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1094 Rule winebuildRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.c: $(source_path)$(SEP)$(source_name_noext).spec $(WINEBUILD_TARGET)\n"
1095 "\t$(ECHO_WINEBLD)\n"
1096 "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $@ --pedll $(source_path)$(SEP)$(source_name_noext).spec --filename $(module_dllname)\n"
1097 "$(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"
1098 "\t$(ECHO_CC)\n"
1099 "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
1100 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.c",
1101 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.o",
1102 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1103 Rule widlHeaderRule ( "$(source): ${$(module_name)_precondition}\n"
1104 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1105 "\t$(ECHO_WIDL)\n"
1106 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h $(source)\n",
1107 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h",
1108 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1109 Rule widlServerRule ( "$(source): ${$(module_name)_precondition}\n"
1110 "$(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"
1111 "\t$(ECHO_WIDL)\n"
1112 "\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"
1113 "$(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"
1114 "\t$(ECHO_CC)\n"
1115 "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -fno-unit-at-a-time -c $<\n",
1116 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h",
1117 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c",
1118 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.o",
1119 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1120 Rule widlClientRule ( "$(source): ${$(module_name)_precondition}\n"
1121 "$(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"
1122 "\t$(ECHO_WIDL)\n"
1123 "\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"
1124 "$(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"
1125 "\t$(ECHO_CC)\n"
1126 "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -fno-unit-at-a-time -c $<\n",
1127 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h",
1128 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c",
1129 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.o",
1130 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1131 Rule widlProxyRule ( "$(source): ${$(module_name)_precondition}\n"
1132 "$(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"
1133 "\t$(ECHO_WIDL)\n"
1134 "\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"
1135 "$(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"
1136 "\t$(ECHO_CC)\n"
1137 "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -fno-unit-at-a-time -c $<\n",
1138 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h",
1139 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c",
1140 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.o",
1141 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1142 Rule widlTlbRule ( "$(source): ${$(module_name)_precondition}\n"
1143 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(module_name).tlb: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1144 "\t$(ECHO_WIDL)\n"
1145 "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -t -T $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).tlb $(source)\n",
1146 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
1147 Rule gccRule ( "$(source): ${$(module_name)_precondition}\n"
1148 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1149 "\t$(ECHO_CC)\n"
1150 "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
1151 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1152 Rule gccHostRule ( "$(source): ${$(module_name)_precondition}\n"
1153 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1154 "\t$(ECHO_CC)\n"
1155 "\t${host_gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
1156 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1157 Rule gppRule ( "$(source): ${$(module_name)_precondition}\n"
1158 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1159 "\t$(ECHO_CC)\n"
1160 "\t${gpp} -o $@ $($(module_name)_CXXFLAGS)$(compiler_flags) -c $<\n",
1161 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1162 Rule gppHostRule ( "$(source): ${$(module_name)_precondition}\n"
1163 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
1164 "\t$(ECHO_CC)\n"
1165 "\t${host_gpp} -o $@ $($(module_name)_CXXFLAGS)$(compiler_flags) -c $<\n",
1166 "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
1167 Rule emptyRule ( "", NULL );
1168
1169 void
1170 MingwModuleHandler::GenerateGccCommand (
1171 const FileLocation* sourceFile,
1172 const Rule *rule,
1173 const string& extraDependencies )
1174 {
1175 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1176 string dependencies = extraDependencies;
1177
1178 string flags;
1179 string extension = GetExtension ( *sourceFile );
1180 if ( extension == ".cc" || extension == ".cpp" || extension == ".cxx" )
1181 flags = GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, CompilerTypeCPP );
1182 else
1183 flags = GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, CompilerTypeCC );
1184
1185 if ( pchFilename )
1186 {
1187 dependencies += " " + backend->GetFullName ( *pchFilename );
1188 delete pchFilename;
1189 }
1190
1191 /* WIDL generated headers may be used */
1192 vector<FileLocation> rpcDependencies;
1193 GetRpcHeaderDependencies ( rpcDependencies );
1194 if ( rpcDependencies.size () > 0 )
1195 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1196
1197 rule->Execute ( fMakefile, backend, module, sourceFile, clean_files, dependencies, flags );
1198 }
1199
1200 string
1201 MingwModuleHandler::GetPropertyValue ( const Module& module, const std::string& name )
1202 {
1203 const Property* property = module.project.LookupProperty(name);
1204
1205 if (property)
1206 return property->value;
1207 else
1208 return string ( "" );
1209 }
1210
1211 /* caller needs to delete the returned object */
1212 const FileLocation*
1213 MingwModuleHandler::GetRpcServerHeaderFilename ( const FileLocation *base ) const
1214 {
1215 string newname = GetBasename ( base->name ) + "_s.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::GetRpcClientHeaderFilename ( const FileLocation *base ) const
1222 {
1223 string newname = GetBasename ( base->name ) + "_c.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::GetRpcProxyHeaderFilename ( const FileLocation *base ) const
1230 {
1231 string newname = GetBasename ( base->name ) + "_p.h";
1232 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1233 }
1234
1235 /* caller needs to delete the returned object */
1236 const FileLocation*
1237 MingwModuleHandler::GetIdlHeaderFilename ( const FileLocation *base ) const
1238 {
1239 string newname = GetBasename ( base->name ) + ".h";
1240 return new FileLocation ( IntermediateDirectory, base->relative_path, newname );
1241 }
1242
1243 /* caller needs to delete the returned object */
1244 const FileLocation*
1245 MingwModuleHandler::GetMcHeaderFilename ( const FileLocation *base ) const
1246 {
1247 string newname = GetBasename ( base->name ) + ".h";
1248 return new FileLocation ( IntermediateDirectory, "include/reactos" , newname );
1249 }
1250
1251 void
1252 MingwModuleHandler::GenerateCommands (
1253 const CompilationUnit& compilationUnit,
1254 const string& extraDependencies )
1255 {
1256 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1257 string extension = GetExtension ( sourceFile );
1258 std::transform ( extension.begin (), extension.end (), extension.begin (), tolower );
1259
1260 struct
1261 {
1262 HostType host;
1263 ModuleType type;
1264 string extension;
1265 Rule* rule;
1266 } rules[] = {
1267 { HostDontCare, TypeDontCare, ".s", &gasRule },
1268 { HostDontCare, BootSector, ".asm", &bootRule },
1269 { HostDontCare, TypeDontCare, ".asm", &nasmRule },
1270 { HostDontCare, TypeDontCare, ".rc", &windresRule },
1271 { HostDontCare, TypeDontCare, ".mc", &wmcRule },
1272 { HostDontCare, RpcServer, ".idl", &widlServerRule },
1273 { HostDontCare, RpcClient, ".idl", &widlClientRule },
1274 { HostDontCare, RpcProxy, ".idl", &widlProxyRule },
1275 { HostDontCare, EmbeddedTypeLib, ".idl", &widlTlbRule },
1276 { HostDontCare, TypeDontCare, ".idl", &widlHeaderRule },
1277 { HostTrue, TypeDontCare, ".c", &gccHostRule },
1278 { HostTrue, TypeDontCare, ".cc", &gppHostRule },
1279 { HostTrue, TypeDontCare, ".cpp", &gppHostRule },
1280 { HostTrue, TypeDontCare, ".cxx", &gppHostRule },
1281 { HostFalse, TypeDontCare, ".c", &gccRule },
1282 { HostFalse, TypeDontCare, ".cc", &gppRule },
1283 { HostFalse, TypeDontCare, ".cpp", &gppRule },
1284 { HostFalse, TypeDontCare, ".cxx", &gppRule },
1285 { HostFalse, Cabinet, ".*", &emptyRule }
1286 };
1287 size_t i;
1288 Rule *customRule = NULL;
1289
1290 fprintf ( fMakefile, "# COMMANDS\n" );
1291
1292 for ( i = 0; i < sizeof ( rules ) / sizeof ( rules[0] ); i++ )
1293 {
1294 if ( rules[i].host != HostDontCare && rules[i].host != ModuleHandlerInformations[module.type].DefaultHost )
1295 continue;
1296 if ( rules[i].type != TypeDontCare && rules[i].type != module.type )
1297 continue;
1298 if ( rules[i].extension != extension && rules[i].extension != ".*")
1299 continue;
1300 customRule = rules[i].rule;
1301 break;
1302 }
1303
1304 if ( extension == ".c" || extension == ".cc" || extension == ".cpp" || extension == ".cxx" )
1305 {
1306 GenerateGccCommand ( &sourceFile,
1307 customRule,
1308 GetCompilationUnitDependencies ( compilationUnit ) + extraDependencies );
1309 }
1310 else if ( customRule )
1311 customRule->Execute ( fMakefile, backend, module, &sourceFile, clean_files );
1312 else
1313 {
1314 throw InvalidOperationException ( __FILE__,
1315 __LINE__,
1316 "Unsupported filename extension '%s' in file '%s'",
1317 extension.c_str (),
1318 backend->GetFullName ( sourceFile ).c_str () );
1319 }
1320 }
1321
1322 void
1323 MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget )
1324 {
1325 fprintf ( fMakefile, "# BUILD MAP CODE\n" );
1326
1327 fprintf ( fMakefile,
1328 "ifeq ($(ROS_BUILDMAP),full)\n" );
1329
1330 FileLocation mapFilename ( OutputDirectory,
1331 module.output->relative_path,
1332 GetBasename ( module.output->name ) + ".map" );
1333 CLEAN_FILE ( mapFilename );
1334
1335 fprintf ( fMakefile,
1336 "\t$(ECHO_OBJDUMP)\n" );
1337 fprintf ( fMakefile,
1338 "\t$(Q)${objdump} -d -S %s > %s\n",
1339 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1340 backend->GetFullName ( mapFilename ).c_str () );
1341
1342 fprintf ( fMakefile,
1343 "else\n" );
1344 fprintf ( fMakefile,
1345 "ifeq ($(ROS_BUILDMAP),yes)\n" );
1346
1347 fprintf ( fMakefile,
1348 "\t$(ECHO_NM)\n" );
1349 fprintf ( fMakefile,
1350 "\t$(Q)${nm} --numeric-sort %s > %s\n",
1351 mapTarget ? backend->GetFullName ( *mapTarget ).c_str () : "$@",
1352 backend->GetFullName ( mapFilename ).c_str () );
1353
1354 fprintf ( fMakefile,
1355 "endif\n" );
1356
1357 fprintf ( fMakefile,
1358 "endif\n" );
1359 }
1360
1361 void
1362 MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
1363 {
1364 fprintf ( fMakefile, "# BUILD NO STRIP CODE\n" );
1365
1366 fprintf ( fMakefile,
1367 "ifeq ($(ROS_BUILDNOSTRIP),yes)\n" );
1368
1369 FileLocation nostripFilename ( OutputDirectory,
1370 module.output->relative_path,
1371 GetBasename ( module.output->name ) + ".nostrip" + GetExtension ( *module.output ) );
1372 CLEAN_FILE ( nostripFilename );
1373
1374 OutputCopyCommand ( *module.output, nostripFilename );
1375
1376 fprintf ( fMakefile,
1377 "endif\n" );
1378 }
1379
1380 void
1381 MergeStringVector ( const Backend* backend,
1382 const vector<FileLocation>& input,
1383 vector<string>& output )
1384 {
1385 int wrap_at = 25;
1386 string s;
1387 int wrap_count = -1;
1388 for ( size_t i = 0; i < input.size (); i++ )
1389 {
1390 if ( wrap_count++ == wrap_at )
1391 {
1392 output.push_back ( s );
1393 s = "";
1394 wrap_count = 0;
1395 }
1396 else if ( s.size () > 0)
1397 s += " ";
1398 s += backend->GetFullName ( input[i] );
1399 }
1400 if ( s.length () > 0 )
1401 output.push_back ( s );
1402 }
1403
1404 void
1405 MingwModuleHandler::GetObjectsVector ( const IfableData& data,
1406 vector<FileLocation>& objectFiles ) const
1407 {
1408 for ( size_t i = 0; i < data.compilationUnits.size (); i++ )
1409 {
1410 CompilationUnit& compilationUnit = *data.compilationUnits[i];
1411 const FileLocation& compilationName = compilationUnit.GetFilename ();
1412 const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
1413 objectFiles.push_back ( *object_file );
1414 delete object_file;
1415 }
1416 }
1417
1418 void
1419 MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
1420 {
1421 if ( backend->configuration.CleanAsYouGo )
1422 {
1423 vector<FileLocation> objectFiles;
1424 GetObjectsVector ( module.non_if_data,
1425 objectFiles );
1426 vector<string> lines;
1427 MergeStringVector ( backend,
1428 objectFiles,
1429 lines );
1430 for ( size_t i = 0; i < lines.size (); i++ )
1431 {
1432 fprintf ( fMakefile,
1433 "\t-@${rm} %s 2>$(NUL)\n",
1434 lines[i].c_str () );
1435 }
1436 }
1437 }
1438
1439 void
1440 MingwModuleHandler::GenerateRunRsymCode () const
1441 {
1442 fprintf ( fMakefile, "# RUN RSYM CODE\n" );
1443 fprintf ( fMakefile,
1444 "ifneq ($(ROS_GENERATE_RSYM),no)\n" );
1445 fprintf ( fMakefile,
1446 "\t$(ECHO_RSYM)\n" );
1447 fprintf ( fMakefile,
1448 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
1449 fprintf ( fMakefile,
1450 "endif\n" );
1451 }
1452
1453 void
1454 MingwModuleHandler::GenerateRunStripCode () const
1455 {
1456 fprintf ( fMakefile, "# RUN STRIP CODE\n" );
1457 fprintf ( fMakefile,
1458 "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
1459 fprintf ( fMakefile,
1460 "\t$(ECHO_STRIP)\n" );
1461 fprintf ( fMakefile,
1462 "\t${strip} -s -x -X $@\n\n" );
1463 fprintf ( fMakefile,
1464 "endif\n" );
1465 }
1466
1467 void
1468 MingwModuleHandler::GenerateLinkerCommand (
1469 const string& dependencies,
1470 const string& linkerParameters,
1471 const string& pefixupParameters )
1472 {
1473 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1474 const FileLocation *definitionFilename = GetDefinitionFilename ();
1475 string linker = "${ld}";
1476 string objectsMacro = GetObjectsMacro ( module );
1477 string libsMacro = GetLibsMacro ();
1478
1479 fprintf ( fMakefile, "# LINKER COMMAND\n" );
1480
1481 string target_macro ( GetTargetMacro ( module ) );
1482 string target_folder ( backend->GetFullPath ( *target_file ) );
1483
1484 string linkerScriptArgument;
1485 if ( module.linkerScript != NULL )
1486 linkerScriptArgument = ssprintf ( " -T %s", backend->GetFullName ( *module.linkerScript->file ).c_str () );
1487 else
1488 linkerScriptArgument = "";
1489
1490 /* check if we need to add default C++ libraries, ie if we have
1491 * a C++ user-mode module without the -nostdlib linker flag
1492 */
1493 bool link_defaultlibs = module.cplusplus &&
1494 linkerParameters.find ("-nostdlib") == string::npos &&
1495 !(module.type == KernelModeDLL || module.type == KernelModeDriver);
1496
1497 if ( !module.HasImportLibrary() )
1498 {
1499 fprintf ( fMakefile,
1500 "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
1501 target_macro.c_str (),
1502 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1503 dependencies.c_str (),
1504 target_folder.c_str () );
1505 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1506
1507 fprintf ( fMakefile,
1508 "\t%s %s%s %s %s %s %s -o %s\n",
1509 linker.c_str (),
1510 linkerParameters.c_str (),
1511 linkerScriptArgument.c_str (),
1512 objectsMacro.c_str (),
1513 link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "",
1514 libsMacro.c_str (),
1515 GetLinkerMacro ().c_str (),
1516 target_macro.c_str () );
1517 }
1518 else
1519 {
1520 FileLocation temp_exp ( IntermediateDirectory,
1521 module.output->relative_path,
1522 module.name + ".exp" );
1523 CLEAN_FILE ( temp_exp );
1524
1525 fprintf ( fMakefile,
1526 "%s: %s | %s\n",
1527 backend->GetFullName ( temp_exp ).c_str (),
1528 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1529 backend->GetFullPath ( temp_exp ).c_str () );
1530 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
1531
1532 fprintf ( fMakefile,
1533 "\t${dlltool} --dllname %s --def %s --output-exp $@%s%s\n",
1534 module.GetDllName ().c_str (),
1535 definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
1536 module.mangledSymbols ? "" : " --kill-at",
1537 module.underscoreSymbols ? " --add-underscore" : "" );
1538
1539 fprintf ( fMakefile,
1540 "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
1541 target_macro.c_str (),
1542 backend->GetFullName ( temp_exp ).c_str (),
1543 dependencies.c_str (),
1544 target_folder.c_str () );
1545 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
1546
1547 fprintf ( fMakefile,
1548 "\t%s %s%s %s %s %s %s %s -o %s\n",
1549
1550 linker.c_str (),
1551 linkerParameters.c_str (),
1552 linkerScriptArgument.c_str (),
1553 backend->GetFullName ( temp_exp ).c_str (),
1554 objectsMacro.c_str (),
1555 link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "",
1556 libsMacro.c_str (),
1557 GetLinkerMacro ().c_str (),
1558 target_macro.c_str () );
1559
1560 fprintf ( fMakefile,
1561 "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n",
1562 target_macro.c_str (),
1563 pefixupParameters.c_str() );
1564 }
1565
1566 GenerateBuildMapCode ();
1567 GenerateBuildNonSymbolStrippedCode ();
1568 GenerateRunRsymCode ();
1569 GenerateRunStripCode ();
1570 GenerateCleanObjectsAsYouGoCode ();
1571
1572 if ( definitionFilename )
1573 delete definitionFilename;
1574 delete target_file;
1575 }
1576
1577 void
1578 MingwModuleHandler::GeneratePhonyTarget() const
1579 {
1580 string targetMacro ( GetTargetMacro ( module ) );
1581 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1582
1583 fprintf ( fMakefile, "# PHONY TARGET\n" );
1584 fprintf ( fMakefile,
1585 ".PHONY: %s\n\n",
1586 targetMacro.c_str ());
1587 fprintf ( fMakefile, "%s: | %s\n",
1588 targetMacro.c_str (),
1589 backend->GetFullPath ( *target_file ).c_str () );
1590
1591 delete target_file;
1592 }
1593
1594 void
1595 MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
1596 {
1597 size_t i;
1598 string moduleDependencies;
1599
1600 fprintf ( fMakefile, "# OBJECT FILE TARGETS\n" );
1601
1602 const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
1603 for ( i = 0; i < compilationUnits.size (); i++ )
1604 {
1605 CompilationUnit& compilationUnit = *compilationUnits[i];
1606 const FileLocation& compilationName = compilationUnit.GetFilename ();
1607 const FileLocation *objectFilename = GetObjectFilename ( &compilationName, module );
1608 if ( GetExtension ( *objectFilename ) == ".h" )
1609 moduleDependencies += ssprintf ( " $(%s_HEADERS)", module.name.c_str () );
1610 else if ( GetExtension ( *objectFilename ) == ".rc" )
1611 moduleDependencies += ssprintf ( " $(%s_RESOURCES)", module.name.c_str () );
1612 delete objectFilename;
1613 }
1614
1615 for ( i = 0; i < compilationUnits.size (); i++ )
1616 {
1617 GenerateCommands ( *compilationUnits[i],
1618 moduleDependencies );
1619 fprintf ( fMakefile,
1620 "\n" );
1621 }
1622
1623 vector<CompilationUnit*> sourceCompilationUnits;
1624 GetModuleSpecificCompilationUnits ( sourceCompilationUnits );
1625 for ( i = 0; i < sourceCompilationUnits.size (); i++ )
1626 {
1627 GenerateCommands ( *sourceCompilationUnits[i],
1628 moduleDependencies );
1629 }
1630 CleanupCompilationUnitVector ( sourceCompilationUnits );
1631
1632 SpecFileType spec = IsSpecDefinitionFile ();
1633
1634 if ( spec )
1635 {
1636 Rule * defRule;
1637
1638 if (spec == PSpec)
1639 defRule = &winebuildPRule;
1640 else
1641 defRule = &winebuildRule;
1642
1643 defRule->Execute ( fMakefile, backend, module, module.importLibrary->source, clean_files );
1644 }
1645 }
1646
1647 void
1648 MingwModuleHandler::GenerateObjectFileTargets ()
1649 {
1650 const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
1651
1652 fprintf ( fMakefile, "# OBJECT FILE TARGETS\n" );
1653
1654 if ( pchFilename )
1655 {
1656 string cc = ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue ? "${host_gcc}" : "${gcc}" );
1657 string cppc = ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue ? "${host_gpp}" : "${gpp}" );
1658
1659 const FileLocation& baseHeaderFile = *module.pch->file;
1660 CLEAN_FILE ( *pchFilename );
1661 string dependencies = backend->GetFullName ( baseHeaderFile );
1662 /* WIDL generated headers may be used */
1663 vector<FileLocation> rpcDependencies;
1664 GetRpcHeaderDependencies ( rpcDependencies );
1665 if ( rpcDependencies.size () > 0 )
1666 dependencies += " " + v2s ( backend, rpcDependencies, 5 );
1667 fprintf ( fMakefile,
1668 "%s: %s | %s\n",
1669 backend->GetFullName ( *pchFilename ).c_str(),
1670 dependencies.c_str(),
1671 backend->GetFullPath ( *pchFilename ).c_str() );
1672 fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
1673 fprintf ( fMakefile,
1674 "\t%s -o %s %s %s -gstabs+ %s\n\n",
1675 module.cplusplus ? cppc.c_str() : cc.c_str(),
1676 backend->GetFullName ( *pchFilename ).c_str(),
1677 module.cplusplus ? cxxflagsMacro.c_str() : cflagsMacro.c_str(),
1678 GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, module.cplusplus ? CompilerTypeCPP : CompilerTypeCC ).c_str(),
1679 backend->GetFullName ( baseHeaderFile ).c_str() );
1680 delete pchFilename;
1681 }
1682
1683 GenerateObjectFileTargets ( module.non_if_data );
1684 fprintf ( fMakefile, "\n" );
1685 }
1686
1687 /* caller needs to delete the returned object */
1688 const FileLocation*
1689 MingwModuleHandler::GenerateArchiveTarget ()
1690 {
1691 const FileLocation *archiveFilename = GetModuleArchiveFilename ();
1692 const FileLocation *definitionFilename = GetDefinitionFilename ();
1693
1694 fprintf ( fMakefile, "# ARCHIVE TARGET\n" );
1695
1696 if ( IsStaticLibrary ( module ) && definitionFilename )
1697 {
1698 arRule1.Execute ( fMakefile,
1699 backend,
1700 module,
1701 archiveFilename,
1702 clean_files,
1703 backend->GetFullName ( *definitionFilename ).c_str () );
1704
1705 fprintf ( fMakefile,
1706 "\t${dlltool} --dllname %s --def %s --output-lib $@%s%s\n",
1707 module.GetDllName ().c_str (),
1708 backend->GetFullName ( *definitionFilename ).c_str (),
1709 module.mangledSymbols ? "" : " --kill-at",
1710 module.underscoreSymbols ? " --add-underscore" : "" );
1711 }
1712 else
1713 arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1714
1715 if ( definitionFilename )
1716 delete definitionFilename;
1717
1718 if(module.type == HostStaticLibrary)
1719 arHostRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1720 else
1721 arRule2.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
1722
1723 GenerateCleanObjectsAsYouGoCode ();
1724
1725 fprintf ( fMakefile, "\n" );
1726
1727 return archiveFilename;
1728 }
1729
1730 /*static*/ string
1731 MingwModuleHandler::GetObjectsMacro ( const Module& module )
1732 {
1733 return ssprintf ( "$(%s_OBJS)",
1734 module.name.c_str () );
1735 }
1736
1737 string
1738 MingwModuleHandler::GetLinkingDependenciesMacro () const
1739 {
1740 return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
1741 }
1742
1743 string
1744 MingwModuleHandler::GetLibsMacro () const
1745 {
1746 return ssprintf ( "$(%s_LIBS)", module.name.c_str () );
1747 }
1748
1749 string
1750 MingwModuleHandler::GetLinkerMacro () const
1751 {
1752 return ssprintf ( "$(%s_LFLAGS)",
1753 module.name.c_str () );
1754 }
1755
1756 string
1757 MingwModuleHandler::GetModuleTargets ( const Module& module )
1758 {
1759 if ( ReferenceObjects ( module ) )
1760 return GetObjectsMacro ( module );
1761 else
1762 {
1763 const FileLocation *target_file = GetTargetFilename ( module, NULL );
1764 string target = backend->GetFullName ( *target_file ).c_str ();
1765 delete target_file;
1766 return target;
1767 }
1768 }
1769
1770 void
1771 MingwModuleHandler::GenerateSourceMacro ()
1772 {
1773 sourcesMacro = ssprintf ( "%s_SOURCES", module.name.c_str ());
1774
1775 GenerateSourceMacros ( module.non_if_data );
1776
1777 // future references to the macro will be to get its values
1778 sourcesMacro = ssprintf ("$(%s)", sourcesMacro.c_str ());
1779 }
1780
1781 void
1782 MingwModuleHandler::GenerateObjectMacro ()
1783 {
1784 objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ());
1785
1786 GenerateObjectMacros ( module.non_if_data );
1787
1788 // future references to the macro will be to get its values
1789 objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ());
1790 }
1791
1792 void
1793 MingwModuleHandler::GenerateTargetMacro ()
1794 {
1795 fprintf ( fMakefile, "# TARGET MACRO\n" );
1796 fprintf ( fMakefile,
1797 "%s := %s\n",
1798 GetTargetMacro ( module, false ).c_str (),
1799 GetModuleTargets ( module ).c_str () );
1800 }
1801
1802 void
1803 MingwModuleHandler::GetRpcHeaderDependencies (
1804 vector<FileLocation>& dependencies ) const
1805 {
1806 for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
1807 {
1808 Library& library = *module.non_if_data.libraries[i];
1809 if ( library.importedModule->type == RpcServer ||
1810 library.importedModule->type == RpcClient ||
1811 library.importedModule->type == RpcProxy ||
1812 library.importedModule->type == IdlHeader )
1813 {
1814 for ( size_t j = 0; j < library.importedModule->non_if_data.compilationUnits.size (); j++ )
1815 {
1816 CompilationUnit& compilationUnit = *library.importedModule->non_if_data.compilationUnits[j];
1817 const FileLocation& sourceFile = compilationUnit.GetFilename ();
1818 string extension = GetExtension ( sourceFile );
1819 if ( extension == ".idl" || extension == ".IDL" )
1820 {
1821 string basename = GetBasename ( sourceFile.name );
1822 if ( library.importedModule->type == RpcServer )
1823 {
1824 const FileLocation *header = GetRpcServerHeaderFilename ( &sourceFile );
1825 dependencies.push_back ( *header );
1826 delete header;
1827 }
1828 if ( library.importedModule->type == RpcClient )
1829 {
1830 const FileLocation *header = GetRpcClientHeaderFilename ( &sourceFile );
1831 dependencies.push_back ( *header );
1832 delete header;
1833 }
1834 if ( library.importedModule->type == RpcProxy )
1835 {
1836 const FileLocation *header = GetRpcProxyHeaderFilename ( &sourceFile );
1837 dependencies.push_back ( *header );
1838 delete header;
1839 }
1840 if ( library.importedModule->type == IdlHeader )
1841 {
1842 const FileLocation *header = GetIdlHeaderFilename ( &sourceFile );
1843 dependencies.push_back ( *header );
1844 delete header;
1845 }
1846 }
1847 }
1848 }
1849 }
1850 }
1851
1852 void
1853 MingwModuleHandler::GenerateOtherMacros ()
1854 {
1855 set<const Define *> used_defs;
1856
1857 fprintf ( fMakefile, "# OTHER MACROS\n" );
1858
1859 commonflagsMacro = ssprintf ("%s_COMMONFLAGS", module.name.c_str ());
1860 cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
1861 cxxflagsMacro = ssprintf ("%s_CXXFLAGS", module.name.c_str ());
1862 nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
1863 windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
1864 widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());
1865 linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
1866 libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
1867 linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
1868
1869 GenerateMacros (
1870 "=",
1871 module.non_if_data,
1872 &module.linkerFlags,
1873 used_defs );
1874
1875 if ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue )
1876 {
1877 GenerateMacros("+=", module.project.host_non_if_data, NULL, used_defs);
1878 }
1879 else
1880 {
1881 GenerateMacros (
1882 "+=",
1883 module.project.non_if_data,
1884 NULL,
1885 used_defs );
1886 }
1887
1888 if ( IsSpecDefinitionFile() )
1889 {
1890 vector<FileLocation> s;
1891 GetSpecImplibDependencies ( s, module.importLibrary->source );
1892
1893 fprintf (
1894 fMakefile,
1895 "%s +=",
1896 linkDepsMacro.c_str() );
1897 for ( size_t i = 0; i < s.size(); i++ )
1898 fprintf ( fMakefile,
1899 " %s",
1900 backend->GetFullName ( s[i] ).c_str () );
1901 fprintf ( fMakefile, "\n" );
1902 }
1903
1904 string globalCflags = " ";
1905 globalCflags += ssprintf ("$(%s)", commonflagsMacro.c_str ());
1906 if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
1907 {
1908 if ( module.dynamicCRT )
1909 globalCflags += " -D_DLL -D__USE_CRTIMP";
1910 }
1911 else
1912 globalCflags += " -Wall -Wpointer-arith";
1913 globalCflags += " -gstabs+";
1914 if ( backend->usePipe )
1915 globalCflags += " -pipe";
1916 if ( !module.allowWarnings )
1917 globalCflags += " -Werror";
1918 if ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue )
1919 {
1920 if ( module.cplusplus )
1921 globalCflags += " $(HOST_CPPFLAGS)";
1922 else
1923 globalCflags += " -Wno-strict-aliasing $(HOST_CFLAGS)";
1924 }
1925 else
1926 {
1927 if ( module.cplusplus )
1928 {
1929 globalCflags += " $(TARGET_CPPFLAGS)";
1930 }
1931 else
1932 globalCflags += " -nostdinc";
1933 }
1934
1935 // Always force disabling of sibling calls optimisation for GCC
1936 // (TODO: Move to version-specific once this bug is fixed in GCC)
1937 globalCflags += " -fno-optimize-sibling-calls";
1938
1939 if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
1940 {
1941 fprintf (
1942 fMakefile,
1943 "%s +=%s\n",
1944 cflagsMacro.c_str (),
1945 (" $(PROJECT_CFLAGS)" + globalCflags).c_str () );
1946
1947 fprintf (
1948 fMakefile,
1949 "%s +=%s\n",
1950 cxxflagsMacro.c_str (),
1951 (" $(PROJECT_CXXFLAGS)" + globalCflags).c_str () );
1952
1953 fprintf (
1954 fMakefile,
1955 "%s += $(PROJECT_RCFLAGS)\n",
1956 windresflagsMacro.c_str () );
1957
1958 fprintf (
1959 fMakefile,
1960 "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
1961 widlflagsMacro.c_str (),
1962 module.output->relative_path.c_str () );
1963
1964 fprintf (
1965 fMakefile,
1966 "%s_LFLAGS := $(PROJECT_LFLAGS) $(%s_LFLAGS)\n",
1967 module.name.c_str (),
1968 module.name.c_str () );
1969 }
1970 else
1971 {
1972 fprintf (
1973 fMakefile,
1974 "%s +=%s\n",
1975 cflagsMacro.c_str (),
1976 globalCflags.c_str () );
1977
1978 fprintf (
1979 fMakefile,
1980 "%s +=%s\n",
1981 cxxflagsMacro.c_str (),
1982 globalCflags.c_str () );
1983
1984 fprintf (
1985 fMakefile,
1986 "%s_LFLAGS += $(HOST_LFLAGS)\n",
1987 module.name.c_str () );
1988 }
1989
1990 fprintf (
1991 fMakefile,
1992 "%s += $(%s)\n",
1993 linkDepsMacro.c_str (),
1994 libsMacro.c_str () );
1995
1996 const char *cflags = ModuleHandlerInformations[module.type].cflags;
1997 if ( strlen( cflags ) > 0 )
1998 {
1999 fprintf ( fMakefile,
2000 "%s += %s\n\n",
2001 cflagsMacro.c_str (),
2002 cflags );
2003 fprintf ( fMakefile,
2004 "%s += %s\n\n",
2005 cxxflagsMacro.c_str (),
2006 cflags );
2007 }
2008
2009 const char* nasmflags = ModuleHandlerInformations[module.type].nasmflags;
2010 if ( strlen( nasmflags ) > 0 )
2011 {
2012 fprintf ( fMakefile,
2013 "%s += %s\n\n",
2014 nasmflagsMacro.c_str (),
2015 nasmflags );
2016 }
2017
2018 const char *linkerflags = ModuleHandlerInformations[module.type].linkerflags;
2019 if ( strlen( linkerflags ) > 0 )
2020 {
2021 fprintf ( fMakefile,
2022 "%s += %s\n\n",
2023 linkerflagsMacro.c_str (),
2024 linkerflags );
2025 }
2026
2027 fprintf ( fMakefile, "\n\n" );
2028
2029 // future references to the macros will be to get their values
2030 commonflagsMacro = ssprintf ("$(%s)", commonflagsMacro.c_str ());
2031 cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
2032 cxxflagsMacro = ssprintf ("$(%s)", cxxflagsMacro.c_str ());
2033 nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
2034 widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
2035 }
2036
2037 void
2038 MingwModuleHandler::GenerateRules ()
2039 {
2040 SpecFileType spec;
2041
2042 fprintf ( fMakefile, "# RULES\n" );
2043 string targetMacro = GetTargetMacro ( module );
2044 //CLEAN_FILE ( targetMacro );
2045 CLEAN_FILE ( FileLocation ( SourceDirectory, "", targetMacro ) );
2046
2047 // generate phony target for module name
2048 fprintf ( fMakefile, ".PHONY: %s\n",
2049 module.name.c_str () );
2050 string dependencies = GetTargetMacro ( module );
2051 if ( module.type == Test )
2052 dependencies += " $(REGTESTS_RUN_TARGET)";
2053 fprintf ( fMakefile, "%s: %s\n\n",
2054 module.name.c_str (),
2055 dependencies.c_str () );
2056 if ( module.type == Test )
2057 {
2058 fprintf ( fMakefile,
2059 "\t@%s\n",
2060 targetMacro.c_str ());
2061 }
2062
2063 if ( !ReferenceObjects ( module ) )
2064 {
2065 const FileLocation* ar_target = GenerateArchiveTarget ();
2066 delete ar_target;
2067 }
2068
2069
2070 spec = IsSpecDefinitionFile();
2071
2072 if(spec)
2073 {
2074 Rule * defRule;
2075
2076 if (spec == PSpec)
2077 defRule = &winebuildPDefRule;
2078 else
2079 defRule = &winebuildDefRule;
2080
2081 defRule->Execute ( fMakefile, backend, module, module.importLibrary->source, clean_files );
2082 }
2083
2084 GenerateObjectFileTargets ();
2085 }
2086
2087 void
2088 MingwModuleHandler::GetInvocationDependencies (
2089 const Module& module,
2090 string_list& dependencies )
2091 {
2092 for ( size_t i = 0; i < module.invocations.size (); i++ )
2093 {
2094 Invoke& invoke = *module.invocations[i];
2095 if ( invoke.invokeModule == &module )
2096 /* Protect against circular dependencies */
2097 continue;
2098 invoke.GetTargets ( dependencies );
2099 }
2100 }
2101
2102 void
2103 MingwModuleHandler::GenerateInvocations () const
2104 {
2105 if ( module.invocations.size () == 0 )
2106 return;
2107
2108 fprintf ( fMakefile, "# INVOCATIONS\n" );
2109
2110 size_t iend = module.invocations.size ();
2111 for ( size_t i = 0; i < iend; i++ )
2112 {
2113 const Invoke& invoke = *module.invocations[i];
2114
2115 if ( invoke.invokeModule->type != BuildTool )
2116 {
2117 throw XMLInvalidBuildFileException (
2118 module.node.location,
2119 "Only modules of type buildtool can be invoked." );
2120 }
2121
2122 string invokeTarget = module.GetInvocationTarget ( i );
2123 string_list invoke_targets;
2124 assert ( invoke_targets.size() );
2125 invoke.GetTargets ( invoke_targets );
2126 fprintf ( fMakefile,
2127 ".PHONY: %s\n\n",
2128 invokeTarget.c_str () );
2129 fprintf ( fMakefile,
2130 "%s:",
2131 invokeTarget.c_str () );
2132 size_t j, jend = invoke_targets.size();
2133 for ( j = 0; j < jend; j++ )
2134 {
2135 fprintf ( fMakefile,
2136 " %s",
2137 invoke_targets[i].c_str () );
2138 }
2139 fprintf ( fMakefile, "\n\n%s", invoke_targets[0].c_str () );
2140 for ( j = 1; j < jend; j++ )
2141 fprintf ( fMakefile,
2142 " %s",
2143 invoke_targets[i].c_str () );
2144 fprintf ( fMakefile,
2145 ": %s\n",
2146 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str () );
2147 fprintf ( fMakefile, "\t$(ECHO_INVOKE)\n" );
2148 fprintf ( fMakefile,
2149 "\t%s %s\n\n",
2150 NormalizeFilename ( backend->GetFullName ( *invoke.invokeModule->output ) ).c_str (),
2151 invoke.GetParameters ().c_str () );
2152 }
2153 }
2154
2155 string
2156 MingwModuleHandler::GetPreconditionDependenciesName () const
2157 {
2158 return module.name + "_precondition";
2159 }
2160
2161 void
2162 MingwModuleHandler::GetDefaultDependencies (
2163 string_list& dependencies ) const
2164 {
2165 /* Avoid circular dependency */
2166 if ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue )
2167 return;
2168
2169 if (module.name != "psdk" &&
2170 module.name != "dxsdk")
2171 {
2172 dependencies.push_back ( "$(PSDK_TARGET) $(psdk_HEADERS)" );
2173 dependencies.push_back ( "$(DXSDK_TARGET) $(dxsdk_HEADERS)" );
2174 }
2175
2176 if (module.name != "errcodes" &&
2177 module.name != "bugcodes" &&
2178 module.name != "ntstatus")
2179 {
2180 dependencies.push_back ( "$(ERRCODES_TARGET) $(ERRCODES_MCHEADERS)" );
2181 dependencies.push_back ( "$(BUGCODES_TARGET) $(BUGCODES_MCHEADERS)" );
2182 dependencies.push_back ( "$(NTSTATUS_TARGET) $(NTSTATUS_MCHEADERS)" );
2183 }
2184
2185 ///* Check if any dependent library relies on the generated headers */
2186 //for ( size_t i = 0; i < module.project.modules.size (); i++ )
2187 //{
2188 // const Module& m = *module.project.modules[i];
2189 // for ( size_t j = 0; j < m.non_if_data.compilationUnits.size (); j++ )
2190 // {
2191 // CompilationUnit& compilationUnit = *m.non_if_data.compilationUnits[j];
2192 // const FileLocation& sourceFile = compilationUnit.GetFilename ();
2193 // string extension = GetExtension ( sourceFile );
2194 // if (extension == ".mc" || extension == ".MC" )
2195 // {
2196 // string dependency = ssprintf ( "$(%s_MCHEADERS)", m.name.c_str () );
2197 // dependencies.push_back ( dependency );
2198 // }
2199 // }
2200 //}
2201 }
2202
2203 void
2204 MingwModuleHandler::GeneratePreconditionDependencies ()
2205 {
2206 fprintf ( fMakefile, "# PRECONDITION DEPENDENCIES\n" );
2207 string preconditionDependenciesName = GetPreconditionDependenciesName ();
2208 string_list dependencies;
2209 GetDefaultDependencies ( dependencies );
2210 GetModuleDependencies ( dependencies );
2211
2212 GetInvocationDependencies ( module, dependencies );
2213
2214 if ( dependencies.size() )
2215 {
2216 fprintf ( fMakefile,
2217 "%s =",
2218 preconditionDependenciesName.c_str () );
2219 for ( size_t i = 0; i < dependencies.size(); i++ )
2220 fprintf ( fMakefile,
2221 " %s",
2222 dependencies[i].c_str () );
2223 fprintf ( fMakefile, "\n\n" );
2224 }
2225
2226 fprintf ( fMakefile, "\n" );
2227 }
2228
2229 SpecFileType
2230 MingwModuleHandler::IsSpecDefinitionFile () const
2231 {
2232 if(!module.importLibrary)
2233 return None;
2234
2235 std::string ext = GetExtension ( *module.importLibrary->source );
2236
2237 if ( ext == ".spec" )
2238 return Spec;
2239
2240 if ( ext == ".pspec" )
2241 return PSpec;
2242
2243 return None;
2244 }
2245
2246 /* caller needs to delete the returned object */
2247 const FileLocation*
2248 MingwModuleHandler::GetDefinitionFilename () const
2249 {
2250 if ( module.importLibrary == NULL )
2251 return NULL;
2252
2253 if ( IsSpecDefinitionFile () )
2254 {
2255 return new FileLocation ( IntermediateDirectory,
2256 module.importLibrary->source->relative_path,
2257 GetBasename ( module.importLibrary->source->name ) + "_" + module.name + ".auto.def" );
2258 }
2259 else
2260 {
2261 return new FileLocation ( SourceDirectory,
2262 module.importLibrary->source->relative_path,
2263 module.importLibrary->source->name );
2264 }
2265 }
2266
2267 void
2268 MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
2269 {
2270 if ( module.importLibrary != NULL )
2271 {
2272 const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
2273 const FileLocation *defFilename = GetDefinitionFilename ();
2274 string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
2275
2276 fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" );
2277
2278 fprintf ( fMakefile, "%s:",
2279 backend->GetFullName ( *library_target ).c_str () );
2280
2281 if ( defFilename )
2282 {
2283 fprintf ( fMakefile, " %s",
2284 backend->GetFullName ( *defFilename ).c_str () );
2285 }
2286
2287 fprintf ( fMakefile, " | %s\n",
2288 backend->GetFullPath ( *library_target ).c_str () );
2289
2290 fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
2291
2292 fprintf ( fMakefile,
2293 "\t${dlltool} --dllname %s --def %s --output-lib %s%s%s\n\n",
2294 module.GetDllName ().c_str (),
2295 defFilename ? backend->GetFullName ( *defFilename ).c_str ()
2296 : empty.c_str (),
2297 backend->GetFullName ( *library_target ).c_str (),
2298 module.mangledSymbols ? "" : " --kill-at",
2299 module.underscoreSymbols ? " --add-underscore" : "" );
2300
2301 if ( defFilename )
2302 delete defFilename;
2303 delete library_target;
2304 }
2305 }
2306
2307 void
2308 MingwModuleHandler::GetSpecObjectDependencies (
2309 vector<FileLocation>& dependencies,
2310 const FileLocation *file ) const
2311 {
2312 dependencies.push_back ( FileLocation ( IntermediateDirectory,
2313 file->relative_path,
2314 GetBasename ( file->name ) + "_" + module.name + ".stubs.c" ) );
2315 }
2316
2317 void
2318 MingwModuleHandler::GetSpecImplibDependencies (
2319 vector<FileLocation>& dependencies,
2320 const FileLocation *file ) const
2321 {
2322 dependencies.push_back ( FileLocation ( IntermediateDirectory,
2323 file->relative_path,
2324 GetBasename ( file->name ) + "_" + module.name + ".auto.def" ) );
2325 }
2326
2327 void
2328 MingwModuleHandler::GetMcObjectDependencies (
2329 vector<FileLocation>& dependencies,
2330 const FileLocation *file ) const
2331 {
2332 string basename = GetBasename ( file->name );
2333
2334 FileLocation defDependency ( IntermediateDirectory,
2335 "include/reactos",
2336 basename + ".h" );
2337 dependencies.push_back ( defDependency );
2338
2339 FileLocation stubsDependency ( IntermediateDirectory,
2340 file->relative_path,
2341 basename + ".rc" );
2342 dependencies.push_back ( stubsDependency );
2343 }
2344
2345 void
2346 MingwModuleHandler::GetWidlObjectDependencies (
2347 vector<FileLocation>& dependencies,
2348 const FileLocation *file ) const
2349 {
2350 string basename = GetBasename ( file->name );
2351 const FileLocation *generatedHeaderFilename = GetRpcServerHeaderFilename ( file );
2352
2353 FileLocation serverSourceDependency ( IntermediateDirectory,
2354 file->relative_path,
2355 basename + "_s.c" );
2356 dependencies.push_back ( serverSourceDependency );
2357 dependencies.push_back ( *generatedHeaderFilename );
2358
2359 delete generatedHeaderFilename;
2360 }
2361
2362 void
2363 MingwModuleHandler::GetDefinitionDependencies (
2364 vector<FileLocation>& dependencies ) const
2365 {
2366 const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
2367 for ( size_t i = 0; i < compilationUnits.size (); i++ )
2368 {
2369 const CompilationUnit& compilationUnit = *compilationUnits[i];
2370 const FileLocation& sourceFile = compilationUnit.GetFilename ();
2371 string extension = GetExtension ( sourceFile );
2372
2373 if (extension == ".spec" || extension == ".pspec")
2374 GetSpecObjectDependencies ( dependencies, &sourceFile );
2375
2376 if (extension == ".idl")
2377 {
2378 if ( ( module.type == RpcServer ) || ( module.type == RpcClient ) || ( module.type == RpcProxy ) )
2379 GetWidlObjectDependencies ( dependencies, &sourceFile );
2380 }
2381 }
2382 }
2383
2384 enum DebugSupportType
2385 {
2386 DebugKernelMode,
2387 DebugUserMode
2388 };
2389
2390 static void
2391 MingwAddDebugSupportLibraries ( Module& module, DebugSupportType type )
2392 {
2393 Library* pLibrary;
2394
2395 switch(type)
2396 {
2397 case DebugKernelMode:
2398 pLibrary = new Library ( module, "debugsup_ntoskrnl" );
2399 break;
2400
2401 case DebugUserMode:
2402 pLibrary = new Library ( module, "debugsup_ntdll" );
2403 break;
2404
2405 default:
2406 assert(0);
2407 }
2408
2409 module.non_if_data.libraries.push_back(pLibrary);
2410 }
2411
2412 static void
2413 MingwAddCRTLibrary( Module &module )
2414 {
2415 const char * crtAttr = module.CRT.c_str ();
2416 const char * crtLib = NULL;
2417
2418 if ( stricmp ( crtAttr, "libc" ) == 0 )
2419 crtLib = "crt";
2420 else if ( stricmp ( crtAttr, "msvcrt" ) == 0 )
2421 crtLib = "msvcrt";
2422 else if ( stricmp ( crtAttr, "libcntpr" ) == 0 )
2423 crtLib = "libcntpr";
2424 else if ( stricmp ( crtAttr, "ntdll" ) == 0 )
2425 crtLib = "ntdll";
2426
2427 if ( crtLib )
2428 {
2429 Library* pLibrary = new Library ( module, std::string ( crtLib ) );
2430
2431 if ( pLibrary->importedModule == NULL)
2432 {
2433 throw XMLInvalidBuildFileException (
2434 module.node.location,
2435 "module '%s' trying to import non-existant C runtime module '%s'",
2436 module.name.c_str(),
2437 crtLib );
2438 }
2439
2440 module.non_if_data.libraries.push_back ( pLibrary );
2441 }
2442 }
2443
2444 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler ( const Module& module_ )
2445 : MingwModuleHandler ( module_ )
2446 {
2447 }
2448
2449 void
2450 MingwBuildToolModuleHandler::Process ()
2451 {
2452 GenerateBuildToolModuleTarget ();
2453 }
2454
2455 void
2456 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
2457 {
2458 string targetMacro ( GetTargetMacro (module) );
2459 string objectsMacro = GetObjectsMacro ( module );
2460 string linkDepsMacro = GetLinkingDependenciesMacro ();
2461 string libsMacro = GetLibsMacro ();
2462
2463 GenerateRules ();
2464
2465 fprintf ( fMakefile, "# BUILD TOOL MODULE TARGET\n" );
2466
2467 string linker;
2468 if ( module.cplusplus )
2469 linker = "${host_gpp}";
2470 else
2471 linker = "${host_gcc}";
2472
2473 const FileLocation *target_file = GetTargetFilename ( module, NULL );
2474 fprintf ( fMakefile, "%s: %s %s | %s\n",
2475 targetMacro.c_str (),
2476 objectsMacro.c_str (),
2477 linkDepsMacro.c_str (),
2478 backend->GetFullPath ( *target_file ).c_str () );
2479 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2480 fprintf ( fMakefile,
2481 "\t%s %s -o $@ %s %s\n\n",
2482 linker.c_str (),
2483 GetLinkerMacro ().c_str (),
2484 objectsMacro.c_str (),
2485 libsMacro.c_str () );
2486
2487 delete target_file;
2488 }
2489
2490
2491 MingwKernelModuleHandler::MingwKernelModuleHandler (
2492 const Module& module_ )
2493
2494 : MingwModuleHandler ( module_ )
2495 {
2496 }
2497
2498 void
2499 MingwKernelModuleHandler::Process ()
2500 {
2501 GenerateKernelModuleTarget ();
2502 }
2503
2504 void
2505 MingwKernelModuleHandler::GenerateKernelModuleTarget ()
2506 {
2507 string targetMacro ( GetTargetMacro ( module ) );
2508 string workingDirectory = GetWorkingDirectory ( );
2509 string linkDepsMacro = GetLinkingDependenciesMacro ();
2510
2511 GenerateImportLibraryTargetIfNeeded ();
2512
2513 if ( module.non_if_data.compilationUnits.size () > 0 )
2514 {
2515 GenerateRules ();
2516
2517 string dependencies = linkDepsMacro + " " + objectsMacro;
2518
2519 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s",
2520 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2521 module.baseaddress.c_str () );
2522
2523 GenerateLinkerCommand ( dependencies,
2524 linkerParameters + " $(NTOSKRNL_SHARED)",
2525 " -sections" );
2526 }
2527 else
2528 {
2529 GeneratePhonyTarget();
2530 }
2531 }
2532
2533
2534 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
2535 const Module& module_ )
2536
2537 : MingwModuleHandler ( module_ )
2538 {
2539 }
2540
2541
2542 void
2543 MingwKernelModeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2544 {
2545 MingwAddCRTLibrary ( module );
2546 MingwAddDebugSupportLibraries ( module, DebugKernelMode );
2547 }
2548
2549 void
2550 MingwKernelModeDLLModuleHandler::Process ()
2551 {
2552 GenerateKernelModeDLLModuleTarget ();
2553 }
2554
2555 void
2556 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
2557 {
2558 string targetMacro ( GetTargetMacro ( module ) );
2559 string workingDirectory = GetWorkingDirectory ();
2560 string linkDepsMacro = GetLinkingDependenciesMacro ();
2561
2562 GenerateImportLibraryTargetIfNeeded ();
2563
2564 if ( module.non_if_data.compilationUnits.size () > 0 )
2565 {
2566 GenerateRules ();
2567
2568 string dependencies = linkDepsMacro + " " + objectsMacro;
2569
2570 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2571 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2572 module.baseaddress.c_str () );
2573 GenerateLinkerCommand ( dependencies,
2574 linkerParameters,
2575 " -sections" );
2576 }
2577 else
2578 {
2579 GeneratePhonyTarget();
2580 }
2581 }
2582
2583
2584 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler (
2585 const Module& module_ )
2586
2587 : MingwModuleHandler ( module_ )
2588 {
2589 }
2590
2591 void
2592 MingwNativeDLLModuleHandler::AddImplicitLibraries ( Module& module )
2593 {
2594 MingwAddCRTLibrary ( module );
2595 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2596 }
2597
2598 void
2599 MingwNativeDLLModuleHandler::Process ()
2600 {
2601 GenerateNativeDLLModuleTarget ();
2602 }
2603
2604 void
2605 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
2606 {
2607 string targetMacro ( GetTargetMacro (module) );
2608 string workingDirectory = GetWorkingDirectory ( );
2609 string linkDepsMacro = GetLinkingDependenciesMacro ();
2610
2611 GenerateImportLibraryTargetIfNeeded ();
2612
2613 if ( module.non_if_data.compilationUnits.size () > 0 )
2614 {
2615 GenerateRules ();
2616
2617 string dependencies = linkDepsMacro + " " + objectsMacro;
2618
2619 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2620 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2621 module.baseaddress.c_str () );
2622 GenerateLinkerCommand ( dependencies,
2623 linkerParameters,
2624 "" );
2625 }
2626 else
2627 {
2628 GeneratePhonyTarget();
2629 }
2630 }
2631
2632
2633 MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler (
2634 const Module& module_ )
2635
2636 : MingwModuleHandler ( module_ )
2637 {
2638 }
2639
2640 void
2641 MingwNativeCUIModuleHandler::AddImplicitLibraries ( Module& module )
2642 {
2643 MingwAddCRTLibrary ( module );
2644 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2645 }
2646
2647 void
2648 MingwNativeCUIModuleHandler::Process ()
2649 {
2650 GenerateNativeCUIModuleTarget ();
2651 }
2652
2653 void
2654 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
2655 {
2656 string targetMacro ( GetTargetMacro (module) );
2657 string workingDirectory = GetWorkingDirectory ( );
2658 string linkDepsMacro = GetLinkingDependenciesMacro ();
2659
2660 GenerateImportLibraryTargetIfNeeded ();
2661
2662 if ( module.non_if_data.compilationUnits.size () > 0 )
2663 {
2664 GenerateRules ();
2665
2666 string dependencies = linkDepsMacro + " " + objectsMacro;
2667
2668 string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
2669 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2670 module.baseaddress.c_str () );
2671 GenerateLinkerCommand ( dependencies,
2672 linkerParameters,
2673 "" );
2674 }
2675 else
2676 {
2677 GeneratePhonyTarget();
2678 }
2679 }
2680
2681
2682 MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler (
2683 const Module& module_ )
2684
2685 : MingwModuleHandler ( module_ )
2686 {
2687 }
2688
2689 MingwWin32OCXModuleHandler::MingwWin32OCXModuleHandler (
2690 const Module& module_ )
2691
2692 : MingwModuleHandler ( module_ )
2693 {
2694 }
2695
2696 static void
2697 MingwAddImplicitLibraries( Module &module )
2698 {
2699 Library* pLibrary;
2700
2701 if ( module.type != Win32DLL
2702 && module.type != Win32OCX
2703 && module.type != Win32CUI
2704 && module.type != Win32GUI
2705 && module.type != Win32SCR)
2706 {
2707 return;
2708 }
2709
2710 if ( module.isDefaultEntryPoint )
2711 {
2712 if ( module.IsDLL () )
2713 {
2714 //pLibrary = new Library ( module, "__mingw_dllmain" );
2715 //module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
2716 }
2717 else
2718 {
2719 pLibrary = new Library ( module, module.isUnicode ? "mingw_wmain" : "mingw_main" );
2720 module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
2721 }
2722 }
2723
2724 pLibrary = new Library ( module, "mingw_common" );
2725 module.non_if_data.libraries.push_back ( pLibrary );
2726
2727 MingwAddCRTLibrary ( module );
2728 MingwAddDebugSupportLibraries ( module, DebugUserMode );
2729 }
2730
2731 void
2732 MingwWin32DLLModuleHandler::AddImplicitLibraries ( Module& module )
2733 {
2734 MingwAddImplicitLibraries ( module );
2735 }
2736
2737 void
2738 MingwWin32DLLModuleHandler::Process ()
2739 {
2740 GenerateWin32DLLModuleTarget ();
2741 }
2742
2743 void
2744 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
2745 {
2746 string targetMacro ( GetTargetMacro (module) );
2747 string workingDirectory = GetWorkingDirectory ( );
2748 string linkDepsMacro = GetLinkingDependenciesMacro ();
2749
2750 GenerateImportLibraryTargetIfNeeded ();
2751
2752 if ( module.non_if_data.compilationUnits.size () > 0 )
2753 {
2754 GenerateRules ();
2755
2756 string dependencies = linkDepsMacro + " " + objectsMacro;
2757
2758 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2759 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2760 module.baseaddress.c_str () );
2761 GenerateLinkerCommand ( dependencies,
2762 linkerParameters,
2763 "" );
2764 }
2765 else
2766 {
2767 GeneratePhonyTarget();
2768 }
2769 }
2770
2771
2772 void
2773 MingwWin32OCXModuleHandler::AddImplicitLibraries ( Module& module )
2774 {
2775 MingwAddImplicitLibraries ( module );
2776 }
2777
2778 void
2779 MingwWin32OCXModuleHandler::Process ()
2780 {
2781 GenerateWin32OCXModuleTarget ();
2782 }
2783
2784 void
2785 MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget ()
2786 {
2787 string targetMacro ( GetTargetMacro (module) );
2788 string workingDirectory = GetWorkingDirectory ( );
2789 string linkDepsMacro = GetLinkingDependenciesMacro ();
2790
2791 GenerateImportLibraryTargetIfNeeded ();
2792
2793 if ( module.non_if_data.compilationUnits.size () > 0 )
2794 {
2795 GenerateRules ();
2796
2797 string dependencies = linkDepsMacro + " " + objectsMacro;
2798
2799 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
2800 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2801 module.baseaddress.c_str () );
2802 GenerateLinkerCommand ( dependencies,
2803 linkerParameters,
2804 "" );
2805 }
2806 else
2807 {
2808 GeneratePhonyTarget();
2809 }
2810 }
2811
2812
2813 MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler (
2814 const Module& module_ )
2815
2816 : MingwModuleHandler ( module_ )
2817 {
2818 }
2819
2820 void
2821 MingwWin32CUIModuleHandler::AddImplicitLibraries ( Module& module )
2822 {
2823 MingwAddImplicitLibraries ( module );
2824 }
2825
2826 void
2827 MingwWin32CUIModuleHandler::Process ()
2828 {
2829 GenerateWin32CUIModuleTarget ();
2830 }
2831
2832 void
2833 MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ()
2834 {
2835 string targetMacro ( GetTargetMacro (module) );
2836 string workingDirectory = GetWorkingDirectory ( );
2837 string linkDepsMacro = GetLinkingDependenciesMacro ();
2838
2839 GenerateImportLibraryTargetIfNeeded ();
2840
2841 if ( module.non_if_data.compilationUnits.size () > 0 )
2842 {
2843 GenerateRules ();
2844
2845 string dependencies = linkDepsMacro + " " + objectsMacro;
2846
2847 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
2848 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2849 module.baseaddress.c_str () );
2850 GenerateLinkerCommand ( dependencies,
2851 linkerParameters,
2852 "" );
2853 }
2854 else
2855 {
2856 GeneratePhonyTarget();
2857 }
2858 }
2859
2860
2861 MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler (
2862 const Module& module_ )
2863
2864 : MingwModuleHandler ( module_ )
2865 {
2866 }
2867
2868 void
2869 MingwWin32GUIModuleHandler::AddImplicitLibraries ( Module& module )
2870 {
2871 MingwAddImplicitLibraries ( module );
2872 }
2873
2874 void
2875 MingwWin32GUIModuleHandler::Process ()
2876 {
2877 GenerateWin32GUIModuleTarget ();
2878 }
2879
2880 void
2881 MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ()
2882 {
2883 string targetMacro ( GetTargetMacro (module) );
2884 string workingDirectory = GetWorkingDirectory ( );
2885 string linkDepsMacro = GetLinkingDependenciesMacro ();
2886
2887 GenerateImportLibraryTargetIfNeeded ();
2888
2889 if ( module.non_if_data.compilationUnits.size () > 0 )
2890 {
2891 GenerateRules ();
2892
2893 string dependencies = linkDepsMacro + " " + objectsMacro;
2894
2895 string linkerParameters = ssprintf ( "-subsystem=windows -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
2896 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
2897 module.baseaddress.c_str () );
2898 GenerateLinkerCommand ( dependencies,
2899 linkerParameters,
2900 "" );
2901 }
2902 else
2903 {
2904 GeneratePhonyTarget();
2905 }
2906 }
2907
2908
2909 MingwBootLoaderModuleHandler::MingwBootLoaderModuleHandler (
2910 const Module& module_ )
2911
2912 : MingwModuleHandler ( module_ )
2913 {
2914 }
2915
2916 void
2917 MingwBootLoaderModuleHandler::Process ()
2918 {
2919 GenerateBootLoaderModuleTarget ();
2920 }
2921
2922 void
2923 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
2924 {
2925 string targetName ( module.output->name );
2926 string targetMacro ( GetTargetMacro (module) );
2927 string workingDirectory = GetWorkingDirectory ();
2928 FileLocation junk_tmp ( TemporaryDirectory,
2929 "",
2930 module.name + ".junk.tmp" );
2931 CLEAN_FILE ( junk_tmp );
2932 string objectsMacro = GetObjectsMacro ( module );
2933 string linkDepsMacro = GetLinkingDependenciesMacro ();
2934
2935 GenerateRules ();
2936
2937 fprintf ( fMakefile, "# BOOT LOADER MODULE TARGET\n" );
2938
2939 const FileLocation *target_file = GetTargetFilename ( module, NULL );
2940 fprintf ( fMakefile, "%s: %s %s | %s\n",
2941 targetMacro.c_str (),
2942 objectsMacro.c_str (),
2943 linkDepsMacro.c_str (),
2944 backend->GetFullPath ( *target_file ).c_str () );
2945
2946 fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
2947
2948 if (Environment::GetArch() == "arm")
2949 {
2950 fprintf ( fMakefile,
2951 "\t${gcc} -Wl,--subsystem,native -Wl,--section-start,startup=0x8000 -o %s %s %s %s\n",
2952 backend->GetFullName ( junk_tmp ).c_str (),
2953 objectsMacro.c_str (),
2954 linkDepsMacro.c_str (),
2955 GetLinkerMacro ().c_str ());
2956 }
2957 else
2958 {
2959 fprintf ( fMakefile,
2960 "\t${gcc} -Wl,--subsystem,native -Wl,-Ttext,0x8000 -o %s %s %s %s\n",
2961 backend->GetFullName ( junk_tmp ).c_str (),
2962 objectsMacro.c_str (),
2963 linkDepsMacro.c_str (),
2964 GetLinkerMacro ().c_str ());
2965 }
2966 fprintf ( fMakefile,
2967 "\t${objcopy} -O binary %s $@\n",
2968 backend->GetFullName ( junk_tmp ).c_str () );
2969 GenerateBuildMapCode ( &junk_tmp );
2970 fprintf ( fMakefile,
2971 "\t-@${rm} %s 2>$(NUL)\n",
2972 backend->GetFullName ( junk_tmp ).c_str () );
2973
2974 delete target_file;
2975 }
2976
2977
2978 MingwBootProgramModuleHandler::MingwBootProgramModuleHandler (
2979 const Module& module_ )
2980 : MingwModuleHandler ( module_ )
2981 {
2982 }
2983
2984 void
2985 MingwBootProgramModuleHandler::Process ()
2986 {
2987 GenerateBootProgramModuleTarget ();
2988 }
2989
2990 void
2991 MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
2992 {
2993 string targetName ( module.output->name );
2994 string targetMacro ( GetTargetMacro (module) );
2995 string workingDirectory = GetWorkingDirectory ();
2996 FileLocation junk_tmp ( TemporaryDirectory,
2997 "",
2998 module.name + ".junk.tmp" );
2999 FileLocation junk_elf ( TemporaryDirectory,
3000 "",
3001 module.name + ".junk.elf" );
3002 FileLocation junk_cpy ( TemporaryDirectory,
3003 "",
3004 module.name + ".junk.elf" );
3005 CLEAN_FILE ( junk_tmp );
3006 CLEAN_FILE ( junk_elf );
3007 CLEAN_FILE ( junk_cpy );
3008 string objectsMacro = GetObjectsMacro ( module );
3009 string linkDepsMacro = GetLinkingDependenciesMacro ();
3010 const Module *payload = module.project.LocateModule ( module.payload );
3011
3012 GenerateRules ();
3013
3014 fprintf ( fMakefile, "# BOOT PROGRAM MODULE TARGET\n" );
3015
3016 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3017 fprintf ( fMakefile, "%s: %s %s %s | %s\n",
3018 targetMacro.c_str (),
3019 objectsMacro.c_str (),
3020 linkDepsMacro.c_str (),
3021 payload->name.c_str (),
3022 backend->GetFullPath ( *target_file ).c_str () );
3023
3024 fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
3025
3026 fprintf ( fMakefile, "\t$(%s_PREPARE) $(OUTPUT)$(SEP)%s %s\n",
3027 module.buildtype.c_str (),
3028 NormalizeFilename( backend->GetFullName ( *payload->output ) ).c_str (),
3029 backend->GetFullName ( junk_cpy ).c_str () );
3030
3031 fprintf ( fMakefile, "\t${objcopy} $(%s_FLATFORMAT) %s %s\n",
3032 module.buildtype.c_str (),
3033 backend->GetFullName ( junk_cpy ).c_str (),
3034 backend->GetFullName ( junk_tmp ).c_str () );
3035
3036 fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -o %s\n",
3037 module.buildtype.c_str (),
3038 linkDepsMacro.c_str (),
3039 backend->GetFullName ( junk_tmp ).c_str (),
3040 backend->GetFullName ( junk_elf ).c_str () );
3041
3042 fprintf ( fMakefile, "\t${objcopy} $(%s_COPYFORMAT) %s $(INTERMEDIATE)$(SEP)%s\n",
3043 module.buildtype.c_str (),
3044 backend->GetFullName ( junk_elf ).c_str (),
3045 backend->GetFullName ( *module.output ) .c_str () );
3046
3047 fprintf ( fMakefile,
3048 "\t-@${rm} %s %s %s 2>$(NUL)\n",
3049 backend->GetFullName ( junk_tmp ).c_str (),
3050 backend->GetFullName ( junk_elf ).c_str (),
3051 backend->GetFullName ( junk_cpy ).c_str () );
3052
3053 delete target_file;
3054 }
3055
3056
3057 MingwIsoModuleHandler::MingwIsoModuleHandler (
3058 const Module& module_ )
3059
3060 : MingwModuleHandler ( module_ )
3061 {
3062 }
3063
3064 void
3065 MingwIsoModuleHandler::Process ()
3066 {
3067 GenerateIsoModuleTarget ();
3068 }
3069
3070 void
3071 MingwIsoModuleHandler::OutputBootstrapfileCopyCommands (
3072 const string& bootcdDirectory )
3073 {
3074 for ( std::map<std::string, Module*>::const_iterator p = module.project.modules.begin (); p != module.project.modules.end (); ++ p )
3075 {
3076 const Module& m = *p->second;
3077 if ( !m.enabled )
3078 continue;
3079 if ( m.bootstrap != NULL )
3080 {
3081 FileLocation targetFile ( OutputDirectory,
3082 m.bootstrap->base.length () > 0
3083 ? bootcdDirectory + sSep + m.bootstrap->base
3084 : bootcdDirectory,
3085 m.bootstrap->nameoncd );
3086 OutputCopyCommand ( *m.output, targetFile );
3087 }
3088 }
3089 }
3090
3091 void
3092 MingwIsoModuleHandler::OutputCdfileCopyCommands (
3093 const string& bootcdDirectory )
3094 {
3095 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3096 {
3097 const CDFile& cdfile = *module.project.cdfiles[i];
3098 FileLocation targetFile ( OutputDirectory,
3099 cdfile.target->relative_path.length () > 0
3100 ? bootcdDirectory + sSep + cdfile.target->relative_path
3101 : bootcdDirectory,
3102 cdfile.target->name );
3103 OutputCopyCommand ( *cdfile.source, targetFile );
3104 }
3105 }
3106
3107 void
3108 MingwIsoModuleHandler::GetBootstrapCdDirectories ( vector<FileLocation>& out,
3109 const string& bootcdDirectory )
3110 {
3111 for ( std::map<std::string, Module*>::const_iterator p = module.project.modules.begin (); p != module.project.modules.end (); ++ p )
3112 {
3113 const Module& m = *p->second;
3114 if ( !m.enabled )
3115 continue;
3116 if ( m.bootstrap != NULL )
3117 {
3118 FileLocation targetDirectory ( OutputDirectory,
3119 m.bootstrap->base.length () > 0
3120 ? bootcdDirectory + sSep + m.bootstrap->base
3121 : bootcdDirectory,
3122 "" );
3123 out.push_back ( targetDirectory );
3124 }
3125 }
3126 }
3127
3128 void
3129 MingwIsoModuleHandler::GetNonModuleCdDirectories ( vector<FileLocation>& out,
3130 const string& bootcdDirectory )
3131 {
3132 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3133 {
3134 const CDFile& cdfile = *module.project.cdfiles[i];
3135 FileLocation targetDirectory ( OutputDirectory,
3136 cdfile.target->relative_path.length () > 0
3137 ? bootcdDirectory + sSep + cdfile.target->relative_path
3138 : bootcdDirectory,
3139 "" );
3140 out.push_back( targetDirectory );
3141 }
3142 }
3143
3144 void
3145 MingwIsoModuleHandler::GetCdDirectories ( vector<FileLocation>& out,
3146 const string& bootcdDirectory )
3147 {
3148 GetBootstrapCdDirectories ( out, bootcdDirectory );
3149 GetNonModuleCdDirectories ( out, bootcdDirectory );
3150 }
3151
3152 void
3153 MingwIsoModuleHandler::GetBootstrapCdFiles (
3154 vector<FileLocation>& out ) const
3155 {
3156 for ( std::map<std::string, Module*>::const_iterator p = module.project.modules.begin (); p != module.project.modules.end (); ++ p )
3157 {
3158 const Module& m = *p->second;
3159 if ( !m.enabled )
3160 continue;
3161 if ( m.bootstrap != NULL )
3162 {
3163 out.push_back ( *m.output );
3164 }
3165 }
3166 }
3167
3168 void
3169 MingwIsoModuleHandler::GetNonModuleCdFiles (
3170 vector<FileLocation>& out ) const
3171 {
3172 for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
3173 {
3174 const CDFile& cdfile = *module.project.cdfiles[i];
3175 out.push_back ( *cdfile.source );
3176 }
3177 }
3178
3179 void
3180 MingwIsoModuleHandler::GetCdFiles (
3181 vector<FileLocation>& out ) const
3182 {
3183 GetBootstrapCdFiles ( out );
3184 GetNonModuleCdFiles ( out );
3185 }
3186
3187 void
3188 MingwIsoModuleHandler::GenerateIsoModuleTarget ()
3189 {
3190 fprintf ( fMakefile, "# ISO MODULE TARGET\n" );
3191 string bootcdDirectory = "cd";
3192 FileLocation bootcd ( OutputDirectory,
3193 bootcdDirectory,
3194 "" );
3195 FileLocation bootcdReactos ( OutputDirectory,
3196 bootcdDirectory + sSep + Environment::GetCdOutputPath (),
3197 "" );
3198 vector<FileLocation> vSourceFiles, vCdFiles;
3199 vector<FileLocation> vCdDirectories;
3200
3201 // unattend.inf
3202 FileLocation srcunattend ( SourceDirectory,
3203 "boot" + sSep + "bootdata" + sSep + "bootcdregtest",
3204 "unattend.inf" );
3205 FileLocation tarunattend ( bootcdReactos.directory,
3206 bootcdReactos.relative_path,
3207 "unattend.inf" );
3208 if (module.type == IsoRegTest)
3209 vSourceFiles.push_back ( srcunattend );
3210
3211 // bootsector
3212 const Module* bootModule = module.bootSector->bootSectorModule;
3213
3214 if (!bootModule)
3215 {
3216 throw InvalidOperationException ( module.node.location.c_str(),
3217 0,
3218 "Invalid bootsector. module '%s' requires <bootsector>",
3219 module.name.c_str ());
3220 }
3221
3222 const FileLocation *isoboot = bootModule->output;
3223 vSourceFiles.push_back ( *isoboot );
3224
3225 // prepare reactos.dff and reactos.inf
3226 FileLocation reactosDff ( SourceDirectory,
3227 "boot" + sSep + "bootdata" + sSep + "packages",
3228 "reactos.dff" );
3229 FileLocation reactosInf ( bootcdReactos.directory,
3230 bootcdReactos.relative_path,
3231 "reactos.inf" );
3232
3233 vSourceFiles.push_back ( reactosDff );
3234
3235 /*
3236 We use only the name and not full FileLocation(ouput) because Iso/LiveIso are an exception to the general rule.
3237 Iso/LiveIso outputs are generated in code base root
3238 */
3239 string IsoName = module.output->name;
3240
3241 string sourceFiles = v2s ( backend, vSourceFiles, 5 );
3242
3243 // fill cdrom
3244 GetCdDirectories ( vCdDirectories, bootcdDirectory );
3245 GetCdFiles ( vCdFiles );
3246 string cdDirectories = "";//v2s ( vCdDirectories, 5 );
3247 string cdFiles = v2s ( backend, vCdFiles, 5 );
3248
3249 fprintf ( fMakefile, ".PHONY: %s\n\n",
3250 module.name.c_str ());
3251 fprintf ( fMakefile,
3252 "%s: all %s %s %s $(CABMAN_TARGET) $(CDMAKE_TARGET) %s\n",
3253 module.name.c_str (),
3254 backend->GetFullName ( *isoboot ).c_str (),
3255 sourceFiles.c_str (),
3256 cdFiles.c_str (),
3257 cdDirectories.c_str () );
3258 fprintf ( fMakefile,
3259 "\t$(Q)$(CABMAN_TARGET) -C %s -L %s -I -P $(OUTPUT)\n",
3260 backend->GetFullName ( reactosDff ).c_str (),
3261 backend->GetFullPath ( bootcdReactos ).c_str () );
3262 fprintf ( fMakefile,
3263 "\t$(Q)$(CABMAN_TARGET) -C %s -RC %s -L %s -N -P $(OUTPUT)\n",
3264 backend->GetFullName ( reactosDff ).c_str (),
3265 backend->GetFullName ( reactosInf ).c_str (),
3266 backend->GetFullPath ( bootcdReactos ).c_str ());
3267 fprintf ( fMakefile,
3268 "\t-@${rm} %s 2>$(NUL)\n",
3269 backend->GetFullName ( reactosInf ).c_str () );
3270 OutputBootstrapfileCopyCommands ( bootcdDirectory );
3271 OutputCdfileCopyCommands ( bootcdDirectory );
3272
3273 if (module.type == IsoRegTest)
3274 OutputCopyCommand ( srcunattend, tarunattend );
3275
3276 fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
3277 fprintf ( fMakefile,
3278 "\t$(Q)$(CDMAKE_TARGET) -v -j -m -b %s %s REACTOS %s\n",
3279 backend->GetFullName ( *isoboot ).c_str (),
3280 backend->GetFullPath ( bootcd ).c_str (),
3281 IsoName.c_str() );
3282 fprintf ( fMakefile,
3283 "\n" );
3284 }
3285
3286
3287 MingwLiveIsoModuleHandler::MingwLiveIsoModuleHandler (
3288 const Module& module_ )
3289
3290 : MingwModuleHandler ( module_ )
3291 {
3292 }
3293
3294 void
3295 MingwLiveIsoModuleHandler::Process ()
3296 {
3297 GenerateLiveIsoModuleTarget ();
3298 }
3299
3300 void
3301 MingwLiveIsoModuleHandler::CreateDirectory ( const string& directory )
3302 {
3303 FileLocation dir ( OutputDirectory,
3304 directory,
3305 "" );
3306 MingwModuleHandler::PassThruCacheDirectory ( &dir );
3307 }
3308
3309 void
3310 MingwLiveIsoModuleHandler::OutputModuleCopyCommands ( string& livecdDirectory,
3311 string& reactosDirectory )
3312 {
3313 for ( std::map<std::string, Module*>::const_iterator p = module.project.modules.begin (); p != module.project.modules.end (); ++ p )
3314 {
3315 const Module& m = *p->second;
3316 if ( !m.enabled )
3317 continue;
3318 if ( m.install )
3319 {
3320 const Module& aliasedModule = backend->GetAliasedModuleOrModule ( m );
3321 FileLocation destination ( OutputDirectory,
3322 m.install->relative_path.length () > 0
3323 ? livecdDirectory + sSep + reactosDirectory + sSep + m.install->relative_path
3324 : livecdDirectory + sSep + reactosDirectory,
3325 m.install->name );
3326 OutputCopyCommand ( *aliasedModule.output,
3327 destination);
3328 }
3329 }
3330 }
3331
3332 void
3333 MingwLiveIsoModuleHandler::OutputNonModuleCopyCommands ( string& livecdDirectory,
3334 string& reactosDirectory )
3335 {
3336 for ( size_t i = 0; i < module.project.installfiles.size (); i++ )
3337 {
3338 const InstallFile& installfile = *module.project.installfiles[i];
3339 FileLocation target ( OutputDirectory,
3340 installfile.target->relative_path.length () > 0
3341 ? livecdDirectory + sSep + reactosDirectory + sSep + installfile.target->relative_path
3342 : livecdDirectory + sSep + reactosDirectory,
3343 installfile.target->name );
3344 OutputCopyCommand ( *installfile.source, target );
3345 }
3346 }
3347
3348 void
3349 MingwLiveIsoModuleHandler::OutputProfilesDirectoryCommands ( string& livecdDirectory )
3350 {
3351 CreateDirectory ( livecdDirectory + sSep + "Profiles" );
3352 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "All Users") ;
3353 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "All Users" + sSep + "Desktop" );
3354 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" );
3355 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" + sSep + "Desktop" );
3356 CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "Default User" + sSep + "My Documents" );
3357
3358 FileLocation livecdIni ( SourceDirectory,
3359 "boot" + sSep + "bootdata",
3360 "livecd.ini" );
3361 FileLocation destination ( OutputDirectory,
3362 livecdDirectory,
3363 "freeldr.ini" );
3364 OutputCopyCommand ( livecdIni,
3365 destination );
3366 }
3367
3368 void
3369 MingwLiveIsoModuleHandler::OutputLoaderCommands ( string& livecdDirectory )
3370 {
3371 FileLocation freeldr ( OutputDirectory,
3372 "boot" + sSep + "freeldr" + sSep + "freeldr",
3373 "freeldr.sys" );
3374 FileLocation destination ( OutputDirectory,
3375 livecdDirectory + sSep + "loader",
3376 "setupldr.sys" );
3377 OutputCopyCommand ( freeldr,
3378 destination );
3379 }
3380
3381 void
3382 MingwLiveIsoModuleHandler::OutputRegistryCommands ( string& livecdDirectory )
3383 {
3384 fprintf ( fMakefile, "# REGISTRY COMMANDS\n" );
3385 FileLocation reactosSystem32ConfigDirectory ( OutputDirectory,
3386 livecdDirectory + sSep + "reactos" + sSep + "system32" + sSep + "config",
3387 "" );
3388 fprintf ( fMakefile,
3389 "\t$(ECHO_MKHIVE)\n" );
3390 fprintf ( fMakefile,
3391 "\t$(MKHIVE_TARGET) boot%cbootdata %s $(ARCH) boot%cbootdata%clivecd.inf boot%cbootdata%chiveinst_$(ARCH).inf\n",
3392 cSep, backend->GetFullPath ( reactosSystem32ConfigDirectory ).c_str (),
3393 cSep, cSep, cSep, cSep );
3394 }
3395
3396 void
3397 MingwLiveIsoModuleHandler::GenerateLiveIsoModuleTarget ()
3398 {
3399 fprintf ( fMakefile, "# LIVE ISO MODULE TARGET\n" );
3400 string livecdDirectory = module.name;
3401 FileLocation livecd ( OutputDirectory, livecdDirectory, "" );
3402
3403 string IsoName;
3404
3405 // bootsector
3406 const Module* bootModule = module.bootSector->bootSectorModule;
3407
3408 if (!bootModule)
3409 {
3410 throw InvalidOperationException ( module.node.location.c_str(),
3411 0,
3412 "Invalid bootsector. module '%s' requires <bootsector>",
3413 module.name.c_str ());
3414 }
3415
3416 const FileLocation *isoboot = bootModule->output;
3417
3418 /*
3419 We use only the name and not full FileLocation(ouput) because Iso/LiveIso are an exception to the general rule.
3420 Iso/LiveIso outputs are generated in code base root
3421 */
3422 IsoName = module.output->name;
3423
3424 string reactosDirectory = "reactos";
3425 string livecdReactosNoFixup = livecdDirectory + sSep + reactosDirectory;
3426 FileLocation livecdReactos ( OutputDirectory,
3427 livecdReactosNoFixup,
3428 "" );
3429 CLEAN_FILE ( livecdReactos );
3430
3431 fprintf ( fMakefile, ".PHONY: %s\n\n",
3432 module.name.c_str ());
3433 fprintf ( fMakefile,
3434 "%s: all %s %s $(MKHIVE_TARGET) $(CDMAKE_TARGET)\n",
3435 module.name.c_str (),
3436 backend->GetFullName ( *isoboot) .c_str (),
3437 backend->GetFullPath ( livecdReactos ).c_str () );
3438 OutputModuleCopyCommands ( livecdDirectory,
3439 reactosDirectory );
3440 OutputNonModuleCopyCommands ( livecdDirectory,
3441 reactosDirectory );
3442 OutputProfilesDirectoryCommands ( livecdDirectory );
3443 OutputLoaderCommands ( livecdDirectory );
3444 OutputRegistryCommands ( livecdDirectory );
3445 fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
3446 fprintf ( fMakefile,
3447 "\t$(Q)$(CDMAKE_TARGET) -v -m -j -b %s %s REACTOS %s\n",
3448 backend->GetFullName( *isoboot ).c_str (),
3449 backend->GetFullPath ( livecd ).c_str (),
3450 IsoName.c_str() );
3451 fprintf ( fMakefile,
3452 "\n" );
3453 }
3454
3455
3456 MingwTestModuleHandler::MingwTestModuleHandler (
3457 const Module& module_ )
3458
3459 : MingwModuleHandler ( module_ )
3460 {
3461 }
3462
3463 void
3464 MingwTestModuleHandler::Process ()
3465 {
3466 GenerateTestModuleTarget ();
3467 }
3468
3469 /* caller needs to delete the returned object */
3470 void
3471 MingwTestModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUnit*>& compilationUnits )
3472 {
3473 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_hooks.c", false, "", false ) ) );
3474 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_stubs.S", false, "", false ) ) );
3475 compilationUnits.push_back ( new CompilationUnit ( new File ( IntermediateDirectory, module.output->relative_path + sSep + "..", module.name + "_startup.c", false, "", false ) ) );
3476 }
3477
3478 void
3479 MingwTestModuleHandler::GenerateTestModuleTarget ()
3480 {
3481 string targetMacro ( GetTargetMacro ( module ) );
3482 string workingDirectory = GetWorkingDirectory ( );
3483 string linkDepsMacro = GetLinkingDependenciesMacro ();
3484
3485 GenerateImportLibraryTargetIfNeeded ();
3486
3487 if ( module.non_if_data.compilationUnits.size () > 0 )
3488 {
3489 GenerateRules ();
3490
3491 string dependencies = linkDepsMacro + " " + objectsMacro;
3492
3493 string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
3494 module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
3495 module.baseaddress.c_str () );
3496 GenerateLinkerCommand ( dependencies,
3497 linkerParameters,
3498 "" );
3499 }
3500 else
3501 {
3502 GeneratePhonyTarget();
3503 }
3504 }
3505
3506
3507 MingwAliasModuleHandler::MingwAliasModuleHandler (
3508 const Module& module_ )
3509
3510 : MingwModuleHandler ( module_ )
3511 {
3512 }
3513
3514 void
3515 MingwAliasModuleHandler::Process ()
3516 {
3517 }
3518
3519
3520 MingwCabinetModuleHandler::MingwCabinetModuleHandler (
3521 const Module& module_ )
3522
3523 : MingwModuleHandler ( module_ )
3524 {
3525 }
3526
3527 void
3528 MingwCabinetModuleHandler::Process ()
3529 {
3530 string targetMacro ( GetTargetMacro (module) );
3531
3532 GenerateRules ();
3533
3534 fprintf ( fMakefile, "# CABINET MODULE TARGET\n" );
3535 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3536 fprintf ( fMakefile, "%s: $(CABMAN_TARGET) | %s\n",
3537 targetMacro.c_str (),
3538 backend->GetFullPath ( *target_file ).c_str () );
3539
3540 fprintf ( fMakefile, "\t$(ECHO_CABMAN)\n" );
3541 fprintf ( fMakefile,
3542 "\t$(Q)$(CABMAN_TARGET) -M raw -S %s $(%s_SOURCES)\n", // Escape the asterisk for Make
3543 targetMacro.c_str (),
3544 module.name.c_str());
3545 }
3546
3547 MingwElfExecutableModuleHandler::MingwElfExecutableModuleHandler (
3548 const Module& module_ )
3549
3550 : MingwModuleHandler ( module_ )
3551 {
3552 }
3553
3554 void
3555 MingwElfExecutableModuleHandler::Process ()
3556 {
3557 string targetName ( module.output->name );
3558 string targetMacro ( GetTargetMacro (module) );
3559 string workingDirectory = GetWorkingDirectory ();
3560 string objectsMacro = GetObjectsMacro ( module );
3561 string linkDepsMacro = GetLinkingDependenciesMacro ();
3562 string libsMacro = GetLibsMacro ();
3563
3564 GenerateRules ();
3565
3566 fprintf ( fMakefile, "# ELF EXECUTABLE TARGET\n" );
3567 const FileLocation *target_file = GetTargetFilename ( module, NULL );
3568 fprintf ( fMakefile, "%s: %s %s | %s\n",
3569 targetMacro.c_str (),
3570 objectsMacro.c_str (),
3571 linkDepsMacro.c_str (),
3572 backend->GetFullPath ( *target_file ).c_str () );
3573
3574 fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
3575
3576 fprintf ( fMakefile, "\t${gcc} $(%s_LINKFORMAT) %s %s -gstabs+ -o %s\n",
3577 module.buildtype.c_str(),
3578 objectsMacro.c_str(),
3579 libsMacro.c_str(),
3580 targetMacro.c_str () );
3581
3582 delete target_file;
3583 }