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