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