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