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