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