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