create a couple more variables to reduce makefile size
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index 2a539c1..de6c5e8 100644 (file)
 \r
 #include "../../pch.h"\r
+#include <assert.h>\r
 \r
 #include "../../rbuild.h"\r
 #include "mingw.h"\r
 #include "modulehandler.h"\r
 \r
-MingwModuleHandler::MingwModuleHandler ()\r
+using std::string;\r
+using std::vector;\r
+using std::map;\r
+\r
+map<ModuleType,MingwModuleHandler*>*\r
+MingwModuleHandler::handler_map = NULL;\r
+int\r
+MingwModuleHandler::ref = 0;\r
+\r
+FILE*\r
+MingwModuleHandler::fMakefile = NULL;\r
+\r
+MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype )\r
+{\r
+       if ( !ref++ )\r
+               handler_map = new map<ModuleType,MingwModuleHandler*>;\r
+       (*handler_map)[moduletype] = this;\r
+}\r
+\r
+MingwModuleHandler::~MingwModuleHandler()\r
+{\r
+       if ( !--ref )\r
+       {\r
+               delete handler_map;\r
+               handler_map = NULL;\r
+       }\r
+}\r
+\r
+/*static*/ void\r
+MingwModuleHandler::SetMakefile ( FILE* f )\r
+{\r
+       fMakefile = f;\r
+}\r
+\r
+/*static*/ MingwModuleHandler*\r
+MingwModuleHandler::LookupHandler ( const string& location,\r
+                                    ModuleType moduletype )\r
+{\r
+       if ( !handler_map )\r
+               throw Exception ( "internal tool error: no registered module handlers" );\r
+       MingwModuleHandler* h = (*handler_map)[moduletype];\r
+       if ( !h )\r
+       {\r
+               throw UnknownModuleTypeException ( location, moduletype );\r
+               return NULL;\r
+       }\r
+       return h;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetWorkingDirectory () const\r
+{\r
+       return ".";\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetExtension ( const string& filename ) const\r
+{\r
+       size_t index = filename.find_last_of ( '.' );\r
+       if (index != string::npos)\r
+               return filename.substr ( index );\r
+       return "";\r
+}\r
+\r
+string\r
+MingwModuleHandler::ReplaceExtension ( const string& filename,\r
+                                          const string& newExtension ) const\r
+{\r
+       size_t index = filename.find_last_of ( '.' );\r
+       if (index != string::npos)\r
+               return filename.substr ( 0, index ) + newExtension;\r
+       return filename;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetModuleArchiveFilename ( const Module& module ) const\r
+{\r
+       return ReplaceExtension ( FixupTargetFilename ( module.GetPath () ).c_str (),\r
+                                 ".a" );\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetImportLibraryDependencies ( const Module& module ) const\r
+{\r
+       if ( module.libraries.size () == 0 )\r
+               return "";\r
+       \r
+       string dependencies ( "" );\r
+       for ( size_t i = 0; i < module.libraries.size (); i++ )\r
+       {\r
+               if ( dependencies.size () > 0 )\r
+                       dependencies += " ";\r
+               const Module* importedModule = module.project.LocateModule ( module.libraries[i]->name );\r
+               assert ( importedModule != NULL );\r
+               dependencies += FixupTargetFilename ( importedModule->GetDependencyPath () ).c_str ();\r
+       }\r
+       return dependencies;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetModuleDependencies ( const Module& module ) const\r
 {\r
+       if ( module.dependencies.size () == 0 )\r
+               return "";\r
+       \r
+       string dependencies ( "" );\r
+       for ( size_t i = 0; i < module.dependencies.size (); i++ )\r
+       {\r
+               if ( dependencies.size () > 0 )\r
+                       dependencies += " ";\r
+               const Dependency* dependency = module.dependencies[i];\r
+               const Module* dependencyModule = dependency->dependencyModule;\r
+               dependencies += dependencyModule->GetTargets ();\r
+       }\r
+       return dependencies;\r
 }\r
 \r
+string\r
+MingwModuleHandler::GetAllDependencies ( const Module& module ) const\r
+{\r
+       string dependencies = GetImportLibraryDependencies ( module );\r
+       string s = GetModuleDependencies ( module );\r
+       if (s.length () > 0)\r
+       {\r
+               dependencies += " ";\r
+               dependencies += s;\r
+       }\r
+       return dependencies;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetSourceFilenames ( const Module& module ) const\r
+{\r
+       if ( module.files.size () == 0 )\r
+               return "";\r
+       \r
+       string sourceFilenames ( "" );\r
+       for ( size_t i = 0; i < module.files.size (); i++ )\r
+       {\r
+               if ( sourceFilenames.size () > 0 )\r
+                       sourceFilenames += " ";\r
+               sourceFilenames += module.files[i]->name;\r
+       }\r
+       return sourceFilenames;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const\r
+{\r
+       return FixupTargetFilename ( ReplaceExtension ( sourceFilename,\r
+                                                       ".o" ) );\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetObjectFilenames ( const Module& module ) const\r
+{\r
+       if ( module.files.size () == 0 )\r
+               return "";\r
+       \r
+       string objectFilenames ( "" );\r
+       for ( size_t i = 0; i < module.files.size (); i++ )\r
+       {\r
+               if ( objectFilenames.size () > 0 )\r
+                       objectFilenames += " ";\r
+               objectFilenames += GetObjectFilename ( module.files[i]->name );\r
+       }\r
+       return objectFilenames;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector<Define*>& defines ) const\r
+{\r
+       string parameters;\r
+       for (size_t i = 0; i < defines.size (); i++)\r
+       {\r
+               Define& define = *defines[i];\r
+               if (parameters.length () > 0)\r
+                       parameters += " ";\r
+               parameters += "-D";\r
+               parameters += define.name;\r
+               if (define.value.length () > 0)\r
+               {\r
+                       parameters += "=";\r
+                       parameters += define.value;\r
+               }\r
+       }\r
+       return parameters;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const\r
+{\r
+       string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );\r
+       string s = GenerateGccDefineParametersFromVector ( module.defines );\r
+       if (s.length () > 0)\r
+       {\r
+               parameters += " ";\r
+               parameters += s;\r
+       }\r
+       return parameters;\r
+}\r
+\r
+string\r
+MingwModuleHandler::ConcatenatePaths ( const string& path1,\r
+                                          const string& path2 ) const\r
+{\r
+       if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )\r
+               return path2;\r
+       if ( path1[path1.length ()] == CSEP )\r
+               return path1 + path2;\r
+       else\r
+               return path1 + CSEP + path2;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes ) const\r
+{\r
+       string parameters;\r
+       for ( size_t i = 0; i < includes.size (); i++ )\r
+       {\r
+               Include& include = *includes[i];\r
+               if (parameters.length () > 0)\r
+                       parameters += " ";\r
+               parameters += "-I" + include.directory;\r
+       }\r
+       return parameters;\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateGccModuleIncludeVariable ( const Module& module ) const\r
+{\r
+       string name ( module.name + "_CFLAGS" );\r
+       fprintf ( fMakefile,\r
+                 "%s := %s %s\n",\r
+                 name.c_str(),\r
+                         GenerateGccDefineParameters(module).c_str(),\r
+                 GenerateGccIncludeParameters(module).c_str() );\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const\r
+{\r
+       string parameters = GenerateGccIncludeParametersFromVector ( module.includes );\r
+       string s = GenerateGccIncludeParametersFromVector ( module.project.includes );\r
+       if ( s.length () > 0 )\r
+       {\r
+               parameters += " ";\r
+               parameters += s;\r
+       }\r
+       return parameters;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateGccParameters ( const Module& module ) const\r
+{\r
+       return ssprintf(" $(%s_CFLAGS)", module.name.c_str());\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateNasmParameters ( const Module& module ) const\r
+{\r
+       return "";\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateGccCommand ( const Module& module,\r
+                                            const string& sourceFilename,\r
+                                            const string& cc ) const\r
+{\r
+       string objectFilename = GetObjectFilename ( sourceFilename );\r
+       return ssprintf ( "%s -c %s -o %s %s\n",\r
+                             cc.c_str (),\r
+                             sourceFilename.c_str (),\r
+                             objectFilename.c_str (),\r
+                             GenerateGccParameters ( module ).c_str () );\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateGccAssemblerCommand ( const Module& module,\r
+                                                     const string& sourceFilename,\r
+                                                     const string& cc ) const\r
+{\r
+       string objectFilename = GetObjectFilename ( sourceFilename );\r
+       return ssprintf ( "%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",\r
+                             cc.c_str (),\r
+                             sourceFilename.c_str (),\r
+                             objectFilename.c_str (),\r
+                             GenerateGccParameters ( module ).c_str () );\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateNasmCommand ( const Module& module,\r
+                                             const string& sourceFilename ) const\r
+{\r
+       string objectFilename = GetObjectFilename ( sourceFilename );\r
+       return ssprintf ( "%s -f win32 %s -o %s %s\n",\r
+                             "nasm",\r
+                             sourceFilename.c_str (),\r
+                             objectFilename.c_str (),\r
+                             GenerateNasmParameters ( module ).c_str () );\r
+}\r
+\r
+string\r
+MingwModuleHandler::GenerateCommand ( const Module& module,\r
+                                         const string& sourceFilename,\r
+                                         const string& cc ) const\r
+{\r
+       string extension = GetExtension ( sourceFilename );\r
+       if ( extension == ".c" || extension == ".C" )\r
+               return GenerateGccCommand ( module,\r
+                                           sourceFilename,\r
+                                           cc );\r
+       else if ( extension == ".s" || extension == ".S" )\r
+               return GenerateGccAssemblerCommand ( module,\r
+                                                    sourceFilename,\r
+                                                    cc );\r
+       else if ( extension == ".asm" || extension == ".ASM" )\r
+               return GenerateNasmCommand ( module,\r
+                                            sourceFilename );\r
+\r
+       throw InvalidOperationException ( __FILE__,\r
+                                         __LINE__,\r
+                                         "Unsupported filename extension '%s' in file '%s'",\r
+                                         extension.c_str (),\r
+                                         sourceFilename.c_str () );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateObjectFileTargets ( const Module& module,\r
+                                                   const string& cc) const\r
+{\r
+       if ( module.files.size () == 0 )\r
+               return;\r
+       \r
+       GenerateGccModuleIncludeVariable ( module );\r
+\r
+       for ( size_t i = 0; i < module.files.size (); i++ )\r
+       {\r
+               string sourceFilename = module.files[i]->name;\r
+               string objectFilename = GetObjectFilename ( sourceFilename );\r
+               fprintf ( fMakefile,\r
+                         "%s: %s\n",\r
+                         objectFilename.c_str (),\r
+                         sourceFilename.c_str () );\r
+               fprintf ( fMakefile,\r
+                         "\t%s\n",\r
+                         GenerateCommand ( module,\r
+                                           sourceFilename,\r
+                                           cc ).c_str () );\r
+       }\r
+       \r
+       fprintf ( fMakefile, "\n" );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateObjectFileTargetsHost ( const Module& module ) const\r
+{\r
+       GenerateObjectFileTargets ( module,\r
+                                   "${host_gcc}" );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateObjectFileTargetsTarget ( const Module& module ) const\r
+{\r
+       GenerateObjectFileTargets ( module,\r
+                                   "${gcc}" );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateArchiveTarget ( const Module& module,\r
+                                               const string& ar ) const\r
+{\r
+       string archiveFilename = GetModuleArchiveFilename ( module );\r
+       string sourceFilenames = GetSourceFilenames ( module );\r
+       string objectsMacro = GenerateObjectList ( module );\r
+       \r
+       fprintf ( fMakefile,\r
+                 "%s: %s\n",\r
+                 archiveFilename.c_str (),\r
+                 objectsMacro.c_str ());\r
+\r
+       fprintf ( fMakefile,\r
+                 "\t%s -rc %s %s\n\n",\r
+                 ar.c_str (),\r
+                 archiveFilename.c_str (),\r
+                 objectsMacro.c_str ());\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateArchiveTargetHost ( const Module& module ) const\r
+{\r
+       GenerateArchiveTarget ( module,\r
+                               "${host_ar}" );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateArchiveTargetTarget ( const Module& module ) const\r
+{\r
+       GenerateArchiveTarget ( module,\r
+                               "${ar}" );\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetInvocationDependencies ( const Module& module ) const\r
+{\r
+       string dependencies;\r
+       for ( size_t i = 0; i < module.invocations.size (); i++ )\r
+       {\r
+               Invoke& invoke = *module.invocations[i];\r
+               if (invoke.invokeModule == &module)\r
+                       /* Protect against circular dependencies */\r
+                       continue;\r
+               if ( dependencies.length () > 0 )\r
+                       dependencies += " ";\r
+               dependencies += invoke.GetTargets ();\r
+       }\r
+       return dependencies;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetInvocationParameters ( const Invoke& invoke ) const\r
+{\r
+       string parameters ( "" );\r
+       size_t i;\r
+       for (i = 0; i < invoke.output.size (); i++)\r
+       {\r
+               if (parameters.length () > 0)\r
+                       parameters += " ";\r
+               InvokeFile& invokeFile = *invoke.output[i];\r
+               if (invokeFile.switches.length () > 0)\r
+               {\r
+                       parameters += invokeFile.switches;\r
+                       parameters += " ";\r
+               }\r
+               parameters += invokeFile.name;\r
+       }\r
+\r
+       for (i = 0; i < invoke.input.size (); i++)\r
+       {\r
+               if (parameters.length () > 0)\r
+                       parameters += " ";\r
+               InvokeFile& invokeFile = *invoke.input[i];\r
+               if (invokeFile.switches.length () > 0)\r
+               {\r
+                       parameters += invokeFile.switches;\r
+                       parameters += " ";\r
+               }\r
+               parameters += invokeFile.name;\r
+       }\r
+\r
+       return parameters;\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateInvocations ( const Module& module ) const\r
+{\r
+       if ( module.invocations.size () == 0 )\r
+               return;\r
+       \r
+       for ( size_t i = 0; i < module.invocations.size (); i++ )\r
+       {\r
+               const Invoke& invoke = *module.invocations[i];\r
+\r
+               if ( invoke.invokeModule->type != BuildTool )\r
+                       throw InvalidBuildFileException ( module.node.location,\r
+                                                     "Only modules of type buildtool can be invoked." );\r
+\r
+               string invokeTarget = module.GetInvocationTarget ( i );\r
+               fprintf ( fMakefile,\r
+                         "%s: %s\n\n",\r
+                         invoke.GetTargets ().c_str (),\r
+                         invokeTarget.c_str () );\r
+               fprintf ( fMakefile,\r
+                         "%s: %s\n",\r
+                         invokeTarget.c_str (),\r
+                         FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str () );\r
+               fprintf ( fMakefile,\r
+                         "\t%s %s\n\n",\r
+                         FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str (),\r
+                         GetInvocationParameters ( invoke ).c_str () );\r
+               fprintf ( fMakefile,\r
+                         ".PNONY: %s\n\n",\r
+                         invokeTarget.c_str () );\r
+       }\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetPreconditionDependenciesName ( const Module& module ) const\r
+{\r
+       return ssprintf ( "%s_precondition",\r
+                         module.name.c_str () );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GeneratePreconditionDependencies ( const Module& module ) const\r
+{\r
+       string preconditionDependenciesName = GetPreconditionDependenciesName ( module );\r
+       string sourceFilenames = GetSourceFilenames ( module );\r
+       string dependencies = GetModuleDependencies ( module );\r
+       string s = GetInvocationDependencies ( module );\r
+       if ( s.length () > 0 )\r
+       {\r
+               if ( dependencies.length () > 0 )\r
+                       dependencies += " ";\r
+               dependencies += s;\r
+       }\r
+       \r
+       fprintf ( fMakefile,\r
+                 "%s: %s\n\n",\r
+                 preconditionDependenciesName.c_str (),\r
+                 dependencies.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "%s: %s\n\n",\r
+                 sourceFilenames.c_str (),\r
+                 preconditionDependenciesName.c_str ());\r
+       fprintf ( fMakefile,\r
+                 ".PHONY: %s\n\n",\r
+                 preconditionDependenciesName.c_str () );\r
+}\r
+\r
+string MingwModuleHandler::GenerateObjectList ( const Module& module ) const\r
+{\r
+       string macro ( ssprintf("%s_OBJS",module.name.c_str()) );\r
+       fprintf (\r
+               fMakefile,\r
+               "%s = %s\n",\r
+               macro.c_str(),\r
+               GetObjectFilenames(module).c_str() );\r
+       return ssprintf("$(%s)",macro.c_str());\r
+}\r
+\r
+\r
+static MingwBuildToolModuleHandler buildtool_handler;\r
+\r
+MingwBuildToolModuleHandler::MingwBuildToolModuleHandler()\r
+       : MingwModuleHandler ( BuildTool )\r
+{\r
+}\r
+\r
+void\r
+MingwBuildToolModuleHandler::Process ( const Module& module )\r
+{\r
+       GeneratePreconditionDependencies ( module );\r
+       GenerateBuildToolModuleTarget ( module );\r
+       GenerateInvocations ( module );\r
+}\r
+\r
+void\r
+MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module& module )\r
+{\r
+       string target ( FixupTargetFilename ( module.GetPath () ) );\r
+       string archiveFilename = GetModuleArchiveFilename ( module );\r
+       fprintf ( fMakefile, "%s: %s\n",\r
+                 target.c_str (),\r
+                 archiveFilename.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t${host_gcc} -o %s %s\n",\r
+                 target.c_str (),\r
+                 archiveFilename.c_str () );\r
+       GenerateArchiveTargetHost ( module );\r
+       GenerateObjectFileTargetsHost ( module );\r
+}\r
+\r
+static MingwKernelModuleHandler kernelmodule_handler;\r
 \r
 MingwKernelModuleHandler::MingwKernelModuleHandler ()\r
+       : MingwModuleHandler ( Kernel )\r
+{\r
+}\r
+\r
+void\r
+MingwKernelModuleHandler::Process ( const Module& module )\r
 {\r
+       GeneratePreconditionDependencies ( module );\r
+       GenerateKernelModuleTarget ( module );\r
+       GenerateInvocations ( module );\r
 }\r
 \r
-bool MingwKernelModuleHandler::CanHandleModule ( Module& module )\r
+void\r
+MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module )\r
 {\r
-       return true;\r
+       static string ros_junk ( "$(ROS_TEMPORARY)" );\r
+       //static string ros_output ( "$(ROS_INTERMEDIATE)" );\r
+       string target ( FixupTargetFilename(module.GetPath()) );\r
+       string workingDirectory = GetWorkingDirectory ( );\r
+       string archiveFilename = GetModuleArchiveFilename ( module );\r
+       string importLibraryDependencies = GetImportLibraryDependencies ( module );\r
+       string base_tmp = ros_junk + module.name + ".base.tmp";\r
+       string junk_tmp = ros_junk + module.name + ".junk.tmp";\r
+       string temp_exp = ros_junk + module.name + ".temp.exp";\r
+       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",\r
+                                     module.GetBasePath ().c_str () );\r
+       fprintf ( fMakefile, "%s: %s %s\n",\r
+                 target.c_str (),\r
+                 archiveFilename.c_str (),\r
+                 importLibraryDependencies.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t${gcc} %s -Wl,--base-file,%s -o %s %s %s\n",\r
+                 gccOptions.c_str (),\r
+                 base_tmp.c_str (),\r
+                 junk_tmp.c_str (),\r
+                 archiveFilename.c_str (),\r
+                 importLibraryDependencies.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t${rm} %s\n",\r
+                 junk_tmp.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t${dlltool} --dllname %s --base-file %s --output-exp %s --kill-at\n",\r
+                 target.c_str (),\r
+                 base_tmp.c_str (),\r
+                 temp_exp.c_str ());\r
+       fprintf ( fMakefile,\r
+                 "\t${rm} %s\n",\r
+                 base_tmp.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t${gcc} %s -Wl,%s -o %s %s %s\n",\r
+                 gccOptions.c_str (),\r
+                 temp_exp.c_str (),\r
+                 target.c_str (),\r
+                 archiveFilename.c_str (),\r
+                 importLibraryDependencies.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t${rm} %s\n",\r
+                 temp_exp.c_str () );\r
+       \r
+       GenerateArchiveTargetTarget ( module );\r
+       GenerateObjectFileTargetsTarget ( module );\r
 }\r
 \r
-void MingwKernelModuleHandler::Process ( Module& module )\r
+\r
+static MingwStaticLibraryModuleHandler staticlibrary_handler;\r
+\r
+MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()\r
+       : MingwModuleHandler ( StaticLibrary )\r
 {\r
 }\r
+\r
+void\r
+MingwStaticLibraryModuleHandler::Process ( const Module& module )\r
+{\r
+       GeneratePreconditionDependencies ( module );\r
+       GenerateStaticLibraryModuleTarget ( module );\r
+       GenerateInvocations ( module );\r
+}\r
+\r
+void\r
+MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module& module )\r
+{\r
+       GenerateArchiveTargetTarget ( module );\r
+       GenerateObjectFileTargetsTarget ( module );\r
+}\r
+\r
+\r
+static MingwKernelModeDLLModuleHandler kernelmodedll_handler;\r
+\r
+MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler ()\r
+       : MingwModuleHandler ( KernelModeDLL )\r
+{\r
+}\r
+\r
+void\r
+MingwKernelModeDLLModuleHandler::Process ( const Module& module )\r
+{\r
+       GeneratePreconditionDependencies ( module );\r
+       GenerateKernelModeDLLModuleTarget ( module );\r
+       GenerateInvocations ( module );\r
+}\r
+\r
+void\r
+MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Module& module )\r
+{\r
+       static string ros_junk ( "$(ROS_TEMPORARY)" );\r
+       string target ( FixupTargetFilename ( module.GetPath () ) );\r
+       string workingDirectory = GetWorkingDirectory ( );\r
+       string archiveFilename = GetModuleArchiveFilename ( module );\r
+       string importLibraryDependencies = GetImportLibraryDependencies ( module );\r
+\r
+       if (module.importLibrary != NULL)\r
+       {\r
+               fprintf ( fMakefile, "%s:\n",\r
+                         module.GetDependencyPath ().c_str () );\r
+\r
+               fprintf ( fMakefile,\r
+                         "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",\r
+                         module.GetTargetName ().c_str (),\r
+                         FixupTargetFilename ( module.GetBasePath () + SSEP + module.importLibrary->definition ).c_str (),\r
+                         FixupTargetFilename ( module.GetDependencyPath () ).c_str () );\r
+       }\r
+\r
+       if (module.files.size () > 0)\r
+       {\r
+               fprintf ( fMakefile, "%s: %s %s\n",\r
+                         target.c_str (),\r
+                         archiveFilename.c_str (),\r
+                         importLibraryDependencies.c_str () );\r
+       \r
+               fprintf ( fMakefile,\r
+                         "\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",\r
+                         target.c_str (),\r
+                         archiveFilename.c_str (),\r
+                         importLibraryDependencies.c_str () );\r
+               \r
+               GenerateArchiveTargetTarget ( module );\r
+               GenerateObjectFileTargetsTarget ( module );\r
+       }\r
+       else\r
+       {\r
+               fprintf ( fMakefile, "%s:\n\n",\r
+                         target.c_str ());\r
+               fprintf ( fMakefile, ".PHONY: %s\n\n",\r
+                         target.c_str ());\r
+       }\r
+}\r