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