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