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