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