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