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