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