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