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