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