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