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