5 #include "../../rbuild.h"
7 #include "modulehandler.h"
13 map
<ModuleType
,MingwModuleHandler
*>*
14 MingwModuleHandler::handler_map
= NULL
;
16 MingwModuleHandler::ref
= 0;
19 MingwModuleHandler::fMakefile
= NULL
;
21 MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype
)
24 handler_map
= new map
<ModuleType
,MingwModuleHandler
*>;
25 (*handler_map
)[moduletype
] = this;
28 MingwModuleHandler::~MingwModuleHandler()
38 MingwModuleHandler::SetMakefile ( FILE* f
)
43 /*static*/ MingwModuleHandler
*
44 MingwModuleHandler::LookupHandler ( const string
& location
,
45 ModuleType moduletype
)
48 throw Exception ( "internal tool error: no registered module handlers" );
49 MingwModuleHandler
* h
= (*handler_map
)[moduletype
];
52 throw UnknownModuleTypeException ( location
, moduletype
);
59 MingwModuleHandler::GetWorkingDirectory () const
65 MingwModuleHandler::GetExtension ( const string
& filename
) const
67 size_t index
= filename
.find_last_of ( '.' );
68 if (index
!= string::npos
)
69 return filename
.substr ( index
);
74 MingwModuleHandler::ReplaceExtension ( const string
& filename
,
75 const string
& newExtension
) const
77 size_t index
= filename
.find_last_of ( '.' );
78 if (index
!= string::npos
)
79 return filename
.substr ( 0, index
) + newExtension
;
84 MingwModuleHandler::GetModuleArchiveFilename ( const Module
& module
) const
86 return ReplaceExtension ( FixupTargetFilename ( module
.GetPath () ).c_str (),
91 MingwModuleHandler::GetImportLibraryDependencies ( const Module
& module
) const
93 if ( module
.libraries
.size () == 0 )
96 string
dependencies ( "" );
97 for ( size_t i
= 0; i
< module
.libraries
.size (); i
++ )
99 if ( dependencies
.size () > 0 )
101 const Module
* importedModule
= module
.project
.LocateModule ( module
.libraries
[i
]->name
);
102 assert ( importedModule
!= NULL
);
103 dependencies
+= FixupTargetFilename ( importedModule
->GetDependencyPath () ).c_str ();
109 MingwModuleHandler::GetModuleDependencies ( const Module
& module
) const
111 if ( module
.dependencies
.size () == 0 )
114 string
dependencies ( "" );
115 for ( size_t i
= 0; i
< module
.dependencies
.size (); i
++ )
117 if ( dependencies
.size () > 0 )
119 const Dependency
* dependency
= module
.dependencies
[i
];
120 const Module
* dependencyModule
= dependency
->dependencyModule
;
121 dependencies
+= dependencyModule
->GetTargets ();
127 MingwModuleHandler::GetAllDependencies ( const Module
& module
) const
129 string dependencies
= GetImportLibraryDependencies ( module
);
130 string s
= GetModuleDependencies ( module
);
140 MingwModuleHandler::GetSourceFilenames ( const Module
& module
) const
142 if ( module
.files
.size () == 0 )
145 string
sourceFilenames ( "" );
146 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
148 if ( sourceFilenames
.size () > 0 )
149 sourceFilenames
+= " ";
150 sourceFilenames
+= module
.files
[i
]->name
;
152 return sourceFilenames
;
156 MingwModuleHandler::GetObjectFilename ( const string
& sourceFilename
) const
158 return FixupTargetFilename ( ReplaceExtension ( sourceFilename
,
163 MingwModuleHandler::GetObjectFilenames ( const Module
& module
) const
165 if ( module
.files
.size () == 0 )
168 string
objectFilenames ( "" );
169 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
171 if ( objectFilenames
.size () > 0 )
172 objectFilenames
+= " ";
173 objectFilenames
+= GetObjectFilename ( module
.files
[i
]->name
);
175 return objectFilenames
;
179 MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector
<Define
*>& defines
) const
182 for (size_t i
= 0; i
< defines
.size (); i
++)
184 Define
& define
= *defines
[i
];
185 if (parameters
.length () > 0)
188 parameters
+= define
.name
;
189 if (define
.value
.length () > 0)
192 parameters
+= define
.value
;
199 MingwModuleHandler::GenerateGccDefineParameters ( const Module
& module
) const
201 string parameters
= GenerateGccDefineParametersFromVector ( module
.project
.defines
);
202 string s
= GenerateGccDefineParametersFromVector ( module
.defines
);
212 MingwModuleHandler::ConcatenatePaths ( const string
& path1
,
213 const string
& path2
) const
215 if ( ( path1
.length () == 0 ) || ( path1
== "." ) || ( path1
== "./" ) )
217 if ( path1
[path1
.length ()] == CSEP
)
218 return path1
+ path2
;
220 return path1
+ CSEP
+ path2
;
224 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector
<Include
*>& includes
) const
227 for ( size_t i
= 0; i
< includes
.size (); i
++ )
229 Include
& include
= *includes
[i
];
230 if (parameters
.length () > 0)
232 parameters
+= "-I" + include
.directory
;
238 MingwModuleHandler::GenerateGccModuleIncludeVariable ( const Module
& module
) const
241 string
name ( module
.name
+ "_CFLAGS" );
245 GenerateGccDefineParameters(module
).c_str(),
246 GenerateGccIncludeParameters(module
).c_str() );
251 MingwModuleHandler::GenerateGccIncludeParameters ( const Module
& module
) const
253 string parameters
= GenerateGccIncludeParametersFromVector ( module
.includes
);
254 string s
= GenerateGccIncludeParametersFromVector ( module
.project
.includes
);
255 if ( s
.length () > 0 )
264 MingwModuleHandler::GenerateMacros (
265 const Module
& module
,
267 const vector
<File
*>& files
,
268 const vector
<Include
*>* includes
,
269 const vector
<Define
*>& defines
,
270 const vector
<If
*>* ifs
,
271 const string
& cflags_macro
,
272 const string
& nasmflags_macro
,
273 const string
& objs_macro
) const
277 if ( (includes
&& includes
->size()) || defines
.size() )
282 cflags_macro
.c_str(),
285 for ( i
= 0; i
< includes
->size(); i
++ )
289 (*includes
)[i
]->directory
.c_str() );
290 for ( i
= 0; i
< module
.defines
.size(); i
++ )
292 Define
& d
= *module
.defines
[i
];
297 if ( d
.value
.size() )
303 fprintf ( fMakefile
, "\n" );
313 for ( i
= 0; i
< files
.size(); i
++ )
318 ( i
%10 == 9 ? "\\\n\t" : " " ),
319 GetObjectFilename(files
[i
]->name
).c_str() );
321 fprintf ( fMakefile
, "\n" );
324 if ( ifs
&& ifs
->size() )
326 for ( size_t i
= 0; i
< module
.ifs
.size(); i
++ )
328 If
& rIf
= *(*ifs
)[i
];
329 if ( rIf
.defines
.size() || rIf
.files
.size() || rIf
.ifs
.size() )
333 "ifeq ($(%s),\"%s\")\n",
334 rIf
.property
.c_str(),
355 MingwModuleHandler::GenerateMacros (
356 const Module
& module
,
357 const string
& cflags_macro
,
358 const string
& nasmflags_macro
,
359 const string
& objs_macro
) const
371 fprintf ( fMakefile
, "\n" );
373 for ( size_t i
= 0; i
< module
.ifs
.size(); i
++ )
375 If
& rIf
= *module
.ifs
[i
];
376 if ( rIf
.defines
.size() || rIf
.files
.size() || rIf
.ifs
.size() )
380 "ifeq ($(%s),\"%s\")\n",
381 rIf
.property
.c_str(),
401 MingwModuleHandler::GenerateGccCommand ( const Module
& module
,
402 const string
& sourceFilename
,
404 const string
& cflagsMacro
) const
406 string objectFilename
= GetObjectFilename ( sourceFilename
);
407 return ssprintf ( "%s -c %s -o %s %s\n",
409 sourceFilename
.c_str (),
410 objectFilename
.c_str (),
411 cflagsMacro
.c_str () );
415 MingwModuleHandler::GenerateGccAssemblerCommand ( const Module
& module
,
416 const string
& sourceFilename
,
418 const string
& cflagsMacro
) const
420 string objectFilename
= GetObjectFilename ( sourceFilename
);
421 return ssprintf ( "%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",
423 sourceFilename
.c_str (),
424 objectFilename
.c_str (),
425 cflagsMacro
.c_str () );
429 MingwModuleHandler::GenerateNasmCommand ( const Module
& module
,
430 const string
& sourceFilename
,
431 const string
& nasmflagsMacro
) const
433 string objectFilename
= GetObjectFilename ( sourceFilename
);
434 return ssprintf ( "%s -f win32 %s -o %s %s\n",
436 sourceFilename
.c_str (),
437 objectFilename
.c_str (),
438 nasmflagsMacro
.c_str () );
442 MingwModuleHandler::GenerateCommand ( const Module
& module
,
443 const string
& sourceFilename
,
445 const string
& cflagsMacro
,
446 const string
& nasmflagsMacro
) const
448 string extension
= GetExtension ( sourceFilename
);
449 if ( extension
== ".c" || extension
== ".C" )
450 return GenerateGccCommand ( module
,
454 else if ( extension
== ".s" || extension
== ".S" )
455 return GenerateGccAssemblerCommand ( module
,
459 else if ( extension
== ".asm" || extension
== ".ASM" )
460 return GenerateNasmCommand ( module
,
464 throw InvalidOperationException ( __FILE__
,
466 "Unsupported filename extension '%s' in file '%s'",
468 sourceFilename
.c_str () );
472 MingwModuleHandler::GenerateObjectFileTargets ( const Module
& module
,
473 const vector
<File
*>& files
,
475 const string
& cflagsMacro
,
476 const string
& nasmflagsMacro
) const
478 if ( files
.size () == 0 )
481 for ( size_t i
= 0; i
< files
.size (); i
++ )
483 string sourceFilename
= files
[i
]->name
;
484 string objectFilename
= GetObjectFilename ( sourceFilename
);
487 objectFilename
.c_str (),
488 sourceFilename
.c_str () );
491 GenerateCommand ( module
,
495 nasmflagsMacro
).c_str () );
498 fprintf ( fMakefile
, "\n" );
502 MingwModuleHandler::GenerateObjectFileTargets ( const Module
& module
,
504 const string
& cflagsMacro
,
505 const string
& nasmflagsMacro
) const
507 GenerateObjectFileTargets ( module
, module
.files
, cc
, cflagsMacro
, nasmflagsMacro
);
508 for ( size_t i
= 0; i
< module
.ifs
.size(); i
++ )
509 GenerateObjectFileTargets ( module
, module
.ifs
[i
]->files
, cc
, cflagsMacro
, nasmflagsMacro
);
513 MingwModuleHandler::GenerateArchiveTarget ( const Module
& module
,
515 const string
& objs_macro
) const
517 string archiveFilename
= GetModuleArchiveFilename ( module
);
518 string sourceFilenames
= GetSourceFilenames ( module
);
522 archiveFilename
.c_str (),
523 objs_macro
.c_str ());
526 "\t%s -rc %s %s\n\n",
528 archiveFilename
.c_str (),
529 objs_macro
.c_str ());
533 MingwModuleHandler::GenerateMacrosAndTargets (
534 const Module
& module
,
536 const string
& ar
) const
538 string cflagsMacro
= ssprintf("%s_CFLAGS",module
.name
.c_str());
539 string nasmflagsMacro
= ssprintf("%s_NASMFLAGS",module
.name
.c_str());
540 string objectsMacro
= ssprintf("%s_OBJS",module
.name
.c_str());
542 GenerateMacros ( module
, cflagsMacro
, nasmflagsMacro
, objectsMacro
);
544 // future references to the macros will be to get their values
545 cflagsMacro
= ssprintf("$(%s)",cflagsMacro
.c_str());
546 nasmflagsMacro
= ssprintf("$(%s)",nasmflagsMacro
.c_str());
547 objectsMacro
= ssprintf("$(%s)",objectsMacro
.c_str());
549 GenerateArchiveTarget ( module
, ar
, objectsMacro
);
550 GenerateObjectFileTargets ( module
, cc
, cflagsMacro
, nasmflagsMacro
);
554 MingwModuleHandler::GenerateMacrosAndTargetsHost ( const Module
& module
) const
556 GenerateMacrosAndTargets ( module
, "${host_gcc}", "${host_ar}" );
560 MingwModuleHandler::GenerateMacrosAndTargetsTarget ( const Module
& module
) const
562 GenerateMacrosAndTargets ( module
, "${gcc}", "${ar}" );
566 MingwModuleHandler::GetInvocationDependencies ( const Module
& module
) const
569 for ( size_t i
= 0; i
< module
.invocations
.size (); i
++ )
571 Invoke
& invoke
= *module
.invocations
[i
];
572 if (invoke
.invokeModule
== &module
)
573 /* Protect against circular dependencies */
575 if ( dependencies
.length () > 0 )
577 dependencies
+= invoke
.GetTargets ();
583 MingwModuleHandler::GetInvocationParameters ( const Invoke
& invoke
) const
585 string
parameters ( "" );
587 for (i
= 0; i
< invoke
.output
.size (); i
++)
589 if (parameters
.length () > 0)
591 InvokeFile
& invokeFile
= *invoke
.output
[i
];
592 if (invokeFile
.switches
.length () > 0)
594 parameters
+= invokeFile
.switches
;
597 parameters
+= invokeFile
.name
;
600 for (i
= 0; i
< invoke
.input
.size (); i
++)
602 if (parameters
.length () > 0)
604 InvokeFile
& invokeFile
= *invoke
.input
[i
];
605 if (invokeFile
.switches
.length () > 0)
607 parameters
+= invokeFile
.switches
;
610 parameters
+= invokeFile
.name
;
617 MingwModuleHandler::GenerateInvocations ( const Module
& module
) const
619 if ( module
.invocations
.size () == 0 )
622 for ( size_t i
= 0; i
< module
.invocations
.size (); i
++ )
624 const Invoke
& invoke
= *module
.invocations
[i
];
626 if ( invoke
.invokeModule
->type
!= BuildTool
)
627 throw InvalidBuildFileException ( module
.node
.location
,
628 "Only modules of type buildtool can be invoked." );
630 string invokeTarget
= module
.GetInvocationTarget ( i
);
633 invoke
.GetTargets ().c_str (),
634 invokeTarget
.c_str () );
637 invokeTarget
.c_str (),
638 FixupTargetFilename ( invoke
.invokeModule
->GetPath () ).c_str () );
641 FixupTargetFilename ( invoke
.invokeModule
->GetPath () ).c_str (),
642 GetInvocationParameters ( invoke
).c_str () );
645 invokeTarget
.c_str () );
650 MingwModuleHandler::GetPreconditionDependenciesName ( const Module
& module
) const
652 return ssprintf ( "%s_precondition",
653 module
.name
.c_str () );
657 MingwModuleHandler::GeneratePreconditionDependencies ( const Module
& module
) const
659 string preconditionDependenciesName
= GetPreconditionDependenciesName ( module
);
660 string sourceFilenames
= GetSourceFilenames ( module
);
661 string dependencies
= GetModuleDependencies ( module
);
662 string s
= GetInvocationDependencies ( module
);
663 if ( s
.length () > 0 )
665 if ( dependencies
.length () > 0 )
672 preconditionDependenciesName
.c_str () );
675 preconditionDependenciesName
.c_str (),
676 dependencies
.c_str () );
677 const char* p
= sourceFilenames
.c_str();
678 const char* end
= p
+ strlen(p
);
681 const char* p2
= &p
[512];
684 while ( p2
> p
&& !isspace(*p2
) )
688 p2
= strpbrk ( p
, " \t" );
696 preconditionDependenciesName
.c_str ());
698 p
+= strspn ( p
, " \t" );
700 fprintf ( fMakefile
, "\n" );
704 static MingwBuildToolModuleHandler buildtool_handler
;
706 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler()
707 : MingwModuleHandler ( BuildTool
)
712 MingwBuildToolModuleHandler::Process ( const Module
& module
)
714 GeneratePreconditionDependencies ( module
);
715 GenerateBuildToolModuleTarget ( module
);
716 GenerateInvocations ( module
);
720 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module
& module
)
722 string
target ( FixupTargetFilename ( module
.GetPath () ) );
723 string archiveFilename
= GetModuleArchiveFilename ( module
);
724 fprintf ( fMakefile
, "%s: %s\n",
726 archiveFilename
.c_str () );
728 "\t${host_gcc} -o %s %s\n\n",
730 archiveFilename
.c_str () );
731 GenerateMacrosAndTargetsHost ( module
);
734 static MingwKernelModuleHandler kernelmodule_handler
;
736 MingwKernelModuleHandler::MingwKernelModuleHandler ()
737 : MingwModuleHandler ( Kernel
)
742 MingwKernelModuleHandler::Process ( const Module
& module
)
744 GeneratePreconditionDependencies ( module
);
745 GenerateKernelModuleTarget ( module
);
746 GenerateInvocations ( module
);
750 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module
& module
)
752 static string
ros_junk ( "$(ROS_TEMPORARY)" );
753 //static string ros_output ( "$(ROS_INTERMEDIATE)" );
754 string
target ( FixupTargetFilename(module
.GetPath()) );
755 string workingDirectory
= GetWorkingDirectory ( );
756 string archiveFilename
= GetModuleArchiveFilename ( module
);
757 string importLibraryDependencies
= GetImportLibraryDependencies ( module
);
758 string base_tmp
= ros_junk
+ module
.name
+ ".base.tmp";
759 string junk_tmp
= ros_junk
+ module
.name
+ ".junk.tmp";
760 string temp_exp
= ros_junk
+ module
.name
+ ".temp.exp";
761 string gccOptions
= ssprintf ("-Wl,-T,%s" SSEP
"ntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,_NtProcessStartup -Wl,--image-base,0xC0000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
762 module
.GetBasePath ().c_str () );
763 fprintf ( fMakefile
, "%s: %s %s\n",
765 archiveFilename
.c_str (),
766 importLibraryDependencies
.c_str () );
768 "\t${gcc} %s -Wl,--base-file,%s -o %s %s %s\n",
772 archiveFilename
.c_str (),
773 importLibraryDependencies
.c_str () );
778 "\t${dlltool} --dllname %s --base-file %s --output-exp %s --kill-at\n",
786 "\t${gcc} %s -Wl,%s -o %s %s %s\n",
790 archiveFilename
.c_str (),
791 importLibraryDependencies
.c_str () );
796 GenerateMacrosAndTargetsTarget ( module
);
800 static MingwStaticLibraryModuleHandler staticlibrary_handler
;
802 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()
803 : MingwModuleHandler ( StaticLibrary
)
808 MingwStaticLibraryModuleHandler::Process ( const Module
& module
)
810 GeneratePreconditionDependencies ( module
);
811 GenerateStaticLibraryModuleTarget ( module
);
812 GenerateInvocations ( module
);
816 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module
& module
)
818 GenerateMacrosAndTargetsTarget ( module
);
822 static MingwKernelModeDLLModuleHandler kernelmodedll_handler
;
824 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler ()
825 : MingwModuleHandler ( KernelModeDLL
)
830 MingwKernelModeDLLModuleHandler::Process ( const Module
& module
)
832 GeneratePreconditionDependencies ( module
);
833 GenerateKernelModeDLLModuleTarget ( module
);
834 GenerateInvocations ( module
);
838 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Module
& module
)
840 static string
ros_junk ( "$(ROS_TEMPORARY)" );
841 string
target ( FixupTargetFilename ( module
.GetPath () ) );
842 string workingDirectory
= GetWorkingDirectory ( );
843 string archiveFilename
= GetModuleArchiveFilename ( module
);
844 string importLibraryDependencies
= GetImportLibraryDependencies ( module
);
846 if (module
.importLibrary
!= NULL
)
848 fprintf ( fMakefile
, "%s:\n",
849 module
.GetDependencyPath ().c_str () );
852 "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",
853 module
.GetTargetName ().c_str (),
854 FixupTargetFilename ( module
.GetBasePath () + SSEP
+ module
.importLibrary
->definition
).c_str (),
855 FixupTargetFilename ( module
.GetDependencyPath () ).c_str () );
858 if (module
.files
.size () > 0)
860 fprintf ( fMakefile
, "%s: %s %s\n",
862 archiveFilename
.c_str (),
863 importLibraryDependencies
.c_str () );
866 "\t${gcc} -Wl,--subsystem,native -Wl,--entry,_DriverEntry@8 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll -o %s %s %s\n\n",
868 archiveFilename
.c_str (),
869 importLibraryDependencies
.c_str () );
871 GenerateMacrosAndTargetsTarget ( module
);
875 fprintf ( fMakefile
, "%s:\n",
877 fprintf ( fMakefile
, ".PHONY: %s\n\n",
883 static MingwNativeDLLModuleHandler nativedll_handler
;
885 MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler ()
886 : MingwModuleHandler ( NativeDLL
)
891 MingwNativeDLLModuleHandler::Process ( const Module
& module
)
893 GeneratePreconditionDependencies ( module
);
894 GenerateNativeDLLModuleTarget ( module
);
895 GenerateInvocations ( module
);
899 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ( const Module
& module
)
901 static string
ros_junk ( "$(ROS_TEMPORARY)" );
902 string
target ( FixupTargetFilename ( module
.GetPath () ) );
903 string workingDirectory
= GetWorkingDirectory ( );
904 string archiveFilename
= GetModuleArchiveFilename ( module
);
905 string importLibraryDependencies
= GetImportLibraryDependencies ( module
);
907 if (module
.importLibrary
!= NULL
)
909 fprintf ( fMakefile
, "%s:\n",
910 module
.GetDependencyPath ().c_str () );
913 "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",
914 module
.GetTargetName ().c_str (),
915 FixupTargetFilename ( module
.GetBasePath () + SSEP
+ module
.importLibrary
->definition
).c_str (),
916 FixupTargetFilename ( module
.GetDependencyPath () ).c_str () );
919 if (module
.files
.size () > 0)
921 fprintf ( fMakefile
, "%s: %s %s\n",
923 archiveFilename
.c_str (),
924 importLibraryDependencies
.c_str () );
927 "\t${gcc} -Wl,--subsystem,native -Wl,--entry,_DllMainCRTStartup@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll -o %s %s %s\n\n",
929 archiveFilename
.c_str (),
930 importLibraryDependencies
.c_str () );
932 GenerateMacrosAndTargetsTarget ( module
);
936 fprintf ( fMakefile
, "%s:\n\n",
938 fprintf ( fMakefile
, ".PHONY: %s\n\n",