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