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