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