[rbuild] Remove distinction between Iso/IsoRegTest, and LiveIso/LiveIsoRegTest module...
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index 531c008..b1c70eb 100644 (file)
@@ -145,9 +145,23 @@ MingwModuleHandler::GetTargetFilename (
 const FileLocation*
 MingwModuleHandler::GetImportLibraryFilename (
        const Module& module,
-       string_list* pclean_files )
+       string_list* pclean_files,
+       bool delayimp )
 {
-       FileLocation *target = new FileLocation ( *module.dependency );
+       FileLocation *target;
+
+       if (module.HasImportLibrary())
+       {
+               if (delayimp)
+               {
+                       target = new FileLocation ( *module.delayImportLibrary->target );
+               }
+               else
+                       target = new FileLocation ( *module.importLibrary->target );
+       }
+       else
+               target = new FileLocation ( *module.dependency );
+
        if ( pclean_files )
        {
                string_list& clean_files = *pclean_files;
@@ -173,6 +187,7 @@ MingwModuleHandler::InstanciateHandler (
                case RpcProxy:
                case MessageHeader:
                case IdlHeader:
+               case IdlInterface:
                case EmbeddedTypeLib:
                case BootSector:
                        handler = new MingwModuleHandler( module );
@@ -219,12 +234,6 @@ MingwModuleHandler::InstanciateHandler (
                case LiveIso:
                        handler = new MingwLiveIsoModuleHandler ( module );
                        break;
-               case IsoRegTest:
-                       handler = new MingwIsoModuleHandler ( module );
-                       break;
-               case LiveIsoRegTest:
-                       handler = new MingwLiveIsoModuleHandler ( module );
-                       break;
                case Test:
                        handler = new MingwTestModuleHandler ( module );
                        break;
@@ -301,6 +310,8 @@ MingwModuleHandler::ReferenceObjects (
                return true;
        if ( module.type == IdlHeader )
                return true;
+       if ( module.type == IdlInterface )
+               return true;
        if ( module.type == MessageHeader)
                return true;
        return false;
@@ -310,6 +321,23 @@ void
 MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
                                         const FileLocation& destination )
 {
+       fprintf ( fMakefile, "# OUTPUT COPY COMMAND\n" );
+       fprintf ( fMakefile,
+                 "\t$(ECHO_CP)\n" );
+       fprintf ( fMakefile,
+                 "\t${cp} %s %s 1>$(NUL)\n",
+                 backend->GetFullName ( source ).c_str (),
+                 backend->GetFullName ( *PassThruCacheDirectory ( &destination ) ).c_str () );
+}
+
+void
+MingwModuleHandler::OutputCopyCommandSingle ( const FileLocation& source,
+                                              const FileLocation& destination )
+{
+       fprintf ( fMakefile,
+                 "%s : %s\n",
+                 backend->GetFullName ( *PassThruCacheDirectory ( &destination ) ).c_str (),
+                 backend->GetFullName ( source ).c_str () );
        fprintf ( fMakefile,
                  "\t$(ECHO_CP)\n" );
        fprintf ( fMakefile,
@@ -320,7 +348,8 @@ MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
 
 string
 MingwModuleHandler::GetImportLibraryDependency (
-       const Module& importedModule )
+       const Module& importedModule,
+       bool delayimp )
 {
        string dep;
        if ( ReferenceObjects ( importedModule ) )
@@ -342,10 +371,22 @@ MingwModuleHandler::GetImportLibraryDependency (
        }
        else
        {
-               const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL );
+               const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL, delayimp );
                dep = backend->GetFullName ( *library_target );
                delete library_target;
        }
+
+       if ( IsStaticLibrary ( importedModule ) || importedModule.type == ObjectLibrary )
+       {
+               const std::vector<Library*>& libraries = importedModule.non_if_data.libraries;
+
+               for ( size_t i = 0; i < libraries.size (); ++ i )
+               {
+                       dep += " ";
+                       dep += GetImportLibraryDependency ( *libraries[i]->importedModule, libraries[i]->delayimp );
+               }
+       }
+
        return dep;
 }
 
@@ -362,7 +403,7 @@ MingwModuleHandler::GetTargets ( const Module& dependencyModule,
                }
        }
        else
-               targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
+               targets.push_back ( GetImportLibraryDependency ( dependencyModule, false ) );
 }
 
 void
@@ -403,13 +444,11 @@ MingwModuleHandler::GetObjectFilename (
 
        if ( module.type == BootSector )
                return new FileLocation ( *module.output );
-       else if ( extension == ".rc" || extension == ".RC" )
+       else if (extension == ".rc")
                newExtension = "_" + module.name + ".coff";
-       else if ( extension == ".mc" || extension == ".MC" )
+       else if (extension == ".mc")
                newExtension = ".rc";
-       else if ( extension == ".spec" || extension == ".SPEC" )
-               newExtension = ".stubs.o";
-       else if ( extension == ".idl" || extension == ".IDL" )
+       else if (extension == ".idl")
        {
                if ( module.type == RpcServer )
                        newExtension = "_s.o";
@@ -417,6 +456,8 @@ MingwModuleHandler::GetObjectFilename (
                        newExtension = "_c.o";
                else if ( module.type == RpcProxy )
                        newExtension = "_p.o";
+               else if ( module.type == IdlInterface )
+                       newExtension = "_i.o";
                else
                        newExtension = ".h";
        }
@@ -460,6 +501,7 @@ MingwModuleHandler::GenerateCleanTarget () const
        if ( module.type == Alias )
                return;
 
+       fprintf ( fMakefile, "# CLEAN TARGET\n" );
        fprintf ( fMakefile,
                  ".PHONY: %s_clean\n",
                  module.name.c_str() );
@@ -501,6 +543,7 @@ MingwModuleHandler::GenerateInstallTarget () const
 {
        if ( !module.install )
                return;
+       fprintf ( fMakefile, "# INSTALL TARGET\n" );
        fprintf ( fMakefile, ".PHONY: %s_install\n", module.name.c_str() );
        fprintf ( fMakefile,
                  "%s_install: %s\n",
@@ -511,6 +554,7 @@ MingwModuleHandler::GenerateInstallTarget () const
 void
 MingwModuleHandler::GenerateDependsTarget () const
 {
+       fprintf ( fMakefile, "# DEPENDS TARGET\n" );
        fprintf ( fMakefile,
                  ".PHONY: %s_depends\n",
                  module.name.c_str() );
@@ -524,24 +568,67 @@ MingwModuleHandler::GenerateDependsTarget () const
                  module.name.c_str () );
 }
 
-string
-MingwModuleHandler::GetObjectFilenames ()
+static
+const char * const CompilerPrefixTable [ CompilerTypesCount ] =
 {
-       const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
-       if ( compilationUnits.size () == 0 )
-               return "";
+       "C",
+       "CXX",
+       "CPP",
+       "AS",
+       "MIDL",
+       "RC",
+       "NASM",
+};
 
-       string objectFilenames ( "" );
-       for ( size_t i = 0; i < compilationUnits.size (); i++ )
+/* static */ void
+MingwModuleHandler::GenerateParameters (
+       const char* prefix,
+       const char* assignmentOperation,
+       const IfableData& data )
+{
+       for ( unsigned type = CompilerTypeCC; type < CompilerTypesCount; ++ type )
        {
-               if ( objectFilenames.size () > 0 )
-                       objectFilenames += " ";
-               const FileLocation& compilationName = compilationUnits[i]->GetFilename ();
-               const FileLocation *object_file = GetObjectFilename ( &compilationName, module );
-               objectFilenames += backend->GetFullName ( *object_file );
-               delete object_file;
+               CompilerType compiler = static_cast < CompilerType > ( type );
+
+               // Includes
+               std::string includes = GenerateIncludeParametersFromVector ( data.includes, compiler );
+
+               if ( includes.size() )
+               {
+                       fprintf ( fMakefile,
+                                         "%s_%sINCLUDES%s%s\n",
+                                         prefix,
+                                         CompilerPrefixTable [ compiler ],
+                                         assignmentOperation,
+                                         includes.c_str () );
+               }
+
+               // Defines
+               std::string defines = GenerateDefineParametersFromVector ( data.defines, compiler );
+
+               if ( defines.size() )
+               {
+                       fprintf ( fMakefile,
+                                         "%s_%sDEFINES%s%s\n",
+                                         prefix,
+                                         CompilerPrefixTable [ compiler ],
+                                         assignmentOperation,
+                                         defines.c_str () );
+               }
+
+               // Flags
+               std::string flags = GenerateCompilerParametersFromVector ( data.compilerFlags, compiler );
+
+               if ( flags.size() )
+               {
+                       fprintf ( fMakefile,
+                                         "%s_%sFLAGS%s%s\n",
+                                         prefix,
+                                         CompilerPrefixTable [ compiler ],
+                                         assignmentOperation,
+                                         flags.c_str () );
+               }
        }
-       return objectFilenames;
 }
 
 /* static */ string
@@ -556,34 +643,65 @@ MingwModuleHandler::GenerateGccDefineParametersFromVector (
                Define& define = *defines[i];
                if (used_defs.find(define.name) != used_defs.end())
                        continue;
+               if (define.redefine)
+               {
+                       if (parameters.length () > 0)
+                               parameters += " ";
+                       parameters += "-U";
+                       parameters += define.name;
+               }
                if (parameters.length () > 0)
                        parameters += " ";
-               if (define.name.find('(') != string::npos)
+               if (define.arguments.length ())
                        parameters += "$(QT)";
                parameters += "-D";
                parameters += define.name;
+               parameters += define.arguments;
                if (define.value.length () > 0)
                {
                        parameters += "=";
                        parameters += define.value;
                }
-               if (define.name.find('(') != string::npos)
+               if (define.arguments.length ())
                        parameters += "$(QT)";
                used_defs.insert(used_defs.begin(),define.name);
        }
        return parameters;
 }
 
-string
-MingwModuleHandler::GenerateGccDefineParameters () const
+/* static */ string
+MingwModuleHandler::GenerateDefineParametersFromVector (
+       const std::vector<Define*>& defines,
+       CompilerType compiler )
 {
-       set<string> used_defs;
-       string parameters = GenerateGccDefineParametersFromVector ( module.project.non_if_data.defines, used_defs );
-       string s = GenerateGccDefineParametersFromVector ( module.non_if_data.defines, used_defs );
-       if ( s.length () > 0 )
+       string parameters;
+
+       for ( size_t i = 0; i < defines.size (); i++ )
        {
-               parameters += " ";
-               parameters += s;
+               Define& define = *defines[i];
+               if (!define.IsCompilerSet (compiler))
+                       continue;
+               if (define.redefine)
+               {
+                       if (parameters.length () > 0)
+                               parameters += " ";
+                       parameters += "-U";
+                       parameters += define.name;
+               }
+               if (parameters.length () > 0)
+                       parameters += " ";
+               if (define.arguments.length ())
+                       parameters += "$(QT)";
+               parameters += "-D";
+               parameters += define.name;
+               parameters += define.arguments;
+               if (define.value.length () > 0)
+               {
+                       parameters += "=";
+                       parameters += define.value;
+               }
+               if (define.arguments.length ())
+                       parameters += "$(QT)";
        }
        return parameters;
 }
@@ -602,40 +720,26 @@ MingwModuleHandler::ConcatenatePaths (
 }
 
 /* static */ string
-MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes )
+MingwModuleHandler::GenerateIncludeParametersFromVector ( const vector<Include*>& includes, const CompilerType type )
 {
        string parameters, path_prefix;
        for ( size_t i = 0; i < includes.size (); i++ )
        {
                Include& include = *includes[i];
-               if ( parameters.length () > 0 )
-                       parameters += " ";
-               parameters += "-I" + backend->GetFullPath ( *include.directory );;
-       }
-       return parameters;
-}
-
-string
-MingwModuleHandler::GenerateGccIncludeParameters () const
-{
-       string parameters = GenerateGccIncludeParametersFromVector ( module.non_if_data.includes );
-       string s = GenerateGccIncludeParametersFromVector ( module.project.non_if_data.includes );
-       if ( s.length () > 0 )
-       {
-               parameters += " ";
-               parameters += s;
+               if ( include.IsCompilerSet( type ) )
+                       parameters += " -I" + backend->GetFullPath ( *include.directory );
        }
        return parameters;
 }
 
-string
-MingwModuleHandler::GenerateCompilerParametersFromVector ( const vector<CompilerFlag*>& compilerFlags, const CompilerType type ) const
+/* static */ string
+MingwModuleHandler::GenerateCompilerParametersFromVector ( const vector<CompilerFlag*>& compilerFlags, const CompilerType type )
 {
        string parameters;
        for ( size_t i = 0; i < compilerFlags.size (); i++ )
        {
                CompilerFlag& compilerFlag = *compilerFlags[i];
-               if ( compilerFlag.compiler == type )
+               if ( compilerFlag.IsCompilerSet( type ) )
                        parameters += " " + compilerFlag.flag;
        }
        return parameters;
@@ -667,7 +771,7 @@ MingwModuleHandler::GenerateImportLibraryDependenciesFromVector (
                        dependencies += " \\\n\t\t", wrap_count = 0;
                else if ( dependencies.size () > 0 )
                        dependencies += " ";
-               dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule );
+               dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule, libraries[i]->delayimp );
        }
        return dependencies;
 }
@@ -678,104 +782,6 @@ MingwModuleHandler::GenerateLinkerParameters () const
        return GenerateLinkerParametersFromVector ( module.linkerFlags );
 }
 
-void
-MingwModuleHandler::GenerateMacro (
-       const char* assignmentOperation,
-       const string& macro,
-       const IfableData& data,
-       set<const Define *> *used_defs,
-       bool generatingCompilerMacro )
-{
-       size_t i;
-       bool generateAssignment;
-
-       generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0;
-       if ( generatingCompilerMacro )
-               generateAssignment |= data.compilerFlags.size () > 0;
-       if ( generateAssignment )
-       {
-               fprintf ( fMakefile,
-                         "%s %s",
-                         macro.c_str(),
-                         assignmentOperation );
-       }
-
-       const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
-       if ( pchFilename )
-       {
-               fprintf ( fMakefile,
-                         " -I%s",
-                         backend->GetFullPath ( *pchFilename ).c_str () );
-               delete pchFilename;
-       }
-
-       if ( generatingCompilerMacro )
-       {
-               string compilerParameters = GenerateCompilerParametersFromVector ( data.compilerFlags, CompilerTypeDontCare );
-               if ( compilerParameters.size () > 0 )
-               {
-                       fprintf (
-                               fMakefile,
-                               "%s",
-                               compilerParameters.c_str () );
-               }
-       }
-       for ( i = 0; i < data.includes.size(); i++ )
-       {
-               const Include& include = *data.includes[i];
-               const FileLocation* includeDirectory = include.directory;
-               fprintf (
-                       fMakefile,
-                       " -I%s",
-                       backend->GetFullPath ( *includeDirectory ).c_str() );
-       }
-       for ( i = 0; i < data.defines.size(); i++ )
-       {
-               const Define& define = *data.defines[i];
-               if ( used_defs )
-               {
-                       set<const Define *>::const_iterator last_define;
-                       for (last_define = used_defs->begin ();
-                            last_define != used_defs->end ();
-                            last_define++)
-                       {
-                               if ( (*last_define)->name != define.name )
-                                       continue;
-                               if ( !define.overridable )
-                               {
-                                       throw InvalidOperationException ( (*last_define)->node->location.c_str (),
-                                                                         0,
-                                                                         "Invalid override of define '%s', already defined at %s",
-                                                                         define.name.c_str (),
-                                                                         define.node->location.c_str () );
-                               }
-                               if ( backend->configuration.Verbose )
-                                       printf("%s: Overriding '%s' already defined at %s\n",
-                                               (*last_define)->node->location.c_str (), define.name.c_str (),
-                                               define.node->location.c_str () );
-                               break;
-                       }
-                       if ( last_define != used_defs->end () )
-                               continue;
-               }
-               fprintf (
-                       fMakefile,
-                       " -D%s",
-                       define.name.c_str() );
-               if (define.value.length () > 0)
-                       fprintf (
-                               fMakefile,
-                               "=%s",
-                               define.value.c_str() );
-               if ( used_defs )
-                       used_defs->insert( used_defs->begin (), &define );
-       }
-       if ( generateAssignment )
-       {
-               fprintf ( fMakefile, "\n" );
-       }
-}
-
 void
 MingwModuleHandler::GenerateMacros (
        const char* assignmentOperation,
@@ -783,17 +789,6 @@ MingwModuleHandler::GenerateMacros (
        const vector<LinkerFlag*>* linkerFlags,
        set<const Define *>& used_defs )
 {
-       GenerateMacro ( assignmentOperation,
-                       cflagsMacro,
-                       data,
-                       &used_defs,
-                       true );
-       GenerateMacro ( assignmentOperation,
-                       windresflagsMacro,
-                       data,
-                       NULL,
-                       false );
-
        if ( linkerFlags != NULL )
        {
                string linkerParameters = GenerateLinkerParametersFromVector ( *linkerFlags );
@@ -810,6 +805,22 @@ MingwModuleHandler::GenerateMacros (
 
        if ( data.libraries.size () > 0 )
        {
+               // Check if host and target modules are not mixed up
+               HostType current = ModuleHandlerInformations[module.type].DefaultHost;
+               std::vector<Library*>::const_iterator it;
+               for ( it = data.libraries.begin(); it != data.libraries.end(); ++it )
+               {
+                       HostType imported = ModuleHandlerInformations[(*it)->importedModule->type].DefaultHost;
+                       if (current != imported)
+                       {
+                               throw InvalidOperationException ( __FILE__,
+                                                                 __LINE__,
+                                                                 "Module '%s' imports module '%s', which is not of the right type",
+                                                                 module.name.c_str (),
+                                                                 (*it)->importedModule->name.c_str () );
+                       }
+               }
+
                string deps = GenerateImportLibraryDependenciesFromVector ( data.libraries );
                if ( deps.size () > 0 )
                {
@@ -1009,9 +1020,59 @@ MingwModuleHandler::GenerateObjectMacros (
                delete object_file;
        }
        CleanupCompilationUnitVector ( sourceCompilationUnits );
+
+       if ( IsSpecDefinitionFile() )
+       {
+               const FileLocation *stubs_file = new FileLocation(
+                       IntermediateDirectory,
+                       module.importLibrary->source->relative_path,
+                       ReplaceExtension ( module.importLibrary->source->name, "_" + module.name + ".stubs.o" ) );
+
+               fprintf (
+                       fMakefile,
+                       "%s += %s\n",
+                       objectsMacro.c_str(),
+                       backend->GetFullName ( *stubs_file ).c_str () );
+
+               delete stubs_file;
+       }
+
+       if ( module.type == RpcProxy )
+       {
+               const FileLocation *dlldata_file = GetDlldataFilename();
+
+               fprintf (
+                       fMakefile,
+                       "%s += %s\n",
+                       objectsMacro.c_str(),
+                       ReplaceExtension ( backend->GetFullName ( *dlldata_file ), ".o" ).c_str() );
+
+               delete dlldata_file;
+       }
+}
+
+const FileLocation*
+MingwModuleHandler::GetDlldataFilename() const
+{
+       std::string dlldata_path = "";
+       size_t dlldata_path_len = module.xmlbuildFile.find_last_of(cSep);
+
+       if ( dlldata_path_len != std::string::npos && dlldata_path_len != 0 )
+               dlldata_path = module.xmlbuildFile.substr(0, dlldata_path_len);
+
+       return new FileLocation( IntermediateDirectory, dlldata_path, module.name + ".dlldata.c" );
+}
+
+const FileLocation*
+MingwModuleHandler::GetPrecompiledHeaderPath () const
+{
+       if ( !module.pch || !use_pch )
+               return NULL;
+       return new FileLocation ( IntermediateDirectory,
+                                 module.pch->file->relative_path,
+                                 ".gch_" + module.name );
 }
 
-/* caller needs to delete the returned object */
 const FileLocation*
 MingwModuleHandler::GetPrecompiledHeaderFilename () const
 {
@@ -1022,139 +1083,97 @@ MingwModuleHandler::GetPrecompiledHeaderFilename () const
                                  module.pch->file->name + ".gch" );
 }
 
-Rule arRule1 ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).a: $($(module_name)_OBJS) | $(INTERMEDIATE)$(SEP)$(source_dir)\n",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).a",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
+Rule windresRule ( "$(eval $(call RBUILD_WRC_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                   "$(intermediate_path_unique).coff",
+                   "$(intermediate_path_unique).res",
+                   "$(intermediate_path_unique).res.d",
+                   "$(intermediate_dir)$(SEP)", NULL );
+Rule winebuildPRule ( "$(eval $(call RBUILD_WINEBUILD_WITH_CPP_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags),$(module_dllname)))\n",
+                      "$(intermediate_path_unique).spec",
+                      "$(intermediate_path_unique).spec.d",
+                      "$(intermediate_path_unique).auto.def",
+                      "$(intermediate_path_unique).stubs.c",
+                      "$(intermediate_path_unique).stubs.o",
+                      "$(intermediate_path_unique).stubs.o.d",
+                      "$(intermediate_dir)$(SEP)", NULL );
+Rule winebuildRule ( "$(eval $(call RBUILD_WINEBUILD_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags),$(module_dllname)))\n",
+                     "$(intermediate_path_unique).auto.def",
+                     "$(intermediate_path_unique).stubs.c",
+                     "$(intermediate_path_unique).stubs.o",
+                     "$(intermediate_path_unique).stubs.o.d",
+                     "$(intermediate_dir)$(SEP)", NULL );
+Rule gasRule ( "$(eval $(call RBUILD_GAS_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+               "$(intermediate_path_unique).o",
+               "$(intermediate_path_unique).o.d", NULL );
+Rule gccRule ( "$(eval $(call RBUILD_CC_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+               "$(intermediate_path_unique).o",
+               "$(intermediate_path_unique).o.d", NULL );
+Rule gccHostRule ( "$(eval $(call RBUILD_HOST_GCC_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                   "$(intermediate_path_unique).o", NULL );
+Rule gppRule ( "$(eval $(call RBUILD_CXX_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+               "$(intermediate_path_unique).o",
+               "$(intermediate_path_unique).o.d", NULL );
+Rule gppHostRule ( "$(eval $(call RBUILD_HOST_GPP_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                   "$(intermediate_path_unique).o", NULL );
+Rule widlHeaderRule ( "$(eval $(call RBUILD_WIDL_HEADER_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                      "$(intermediate_path_noext).h",
+                      "$(intermediate_dir)$(SEP)", NULL );
+Rule widlServerRule ( "$(eval $(call RBUILD_WIDL_SERVER_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                      "$(intermediate_path_noext)_s.h",
+                      "$(intermediate_path_noext)_s.c",
+                      "$(intermediate_path_noext)_s.o",
+                      "$(intermediate_dir)$(SEP)", NULL );
+Rule widlClientRule ( "$(eval $(call RBUILD_WIDL_CLIENT_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                      "$(intermediate_path_noext)_c.h",
+                      "$(intermediate_path_noext)_c.c",
+                      "$(intermediate_path_noext)_c.o",
+                      "$(intermediate_dir)$(SEP)", NULL );
+Rule widlProxyRule ( "$(eval $(call RBUILD_WIDL_PROXY_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                     "$(intermediate_path_noext)_p.h",
+                     "$(intermediate_path_noext)_p.c",
+                     "$(intermediate_path_noext)_p.o",
+                     "$(intermediate_dir)$(SEP)", NULL );
+Rule widlInterfaceRule ( "$(eval $(call RBUILD_WIDL_INTERFACE_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                       "$(intermediate_path_noext)_i.c",
+                       "$(intermediate_path_noext)_i.o",
+                       "$(intermediate_dir)$(SEP)", NULL );
+Rule widlDlldataRule ( "$(eval $(call RBUILD_WIDL_DLLDATA_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags),$(bare_dependencies)))\n",
+                       "$(intermediate_path_noext).o", NULL );
+Rule widlTlbRule ( "$(eval $(call RBUILD_WIDL_TLB_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                   "$(intermediate_dir)$(SEP)", NULL );
+Rule pchRule ( "$(eval $(call RBUILD_CC_PCH_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                          "$(intermediate_dir)$(SEP).gch_$(module_name)$(SEP)$(source_name).gch",
+                          "$(intermediate_dir)$(SEP).gch_$(module_name)$(SEP)$(source_name).gch.d",
+                          "$(intermediate_dir)$(SEP).gch_$(module_name)$(SEP)", NULL );
+Rule pchCxxRule ( "$(eval $(call RBUILD_CXX_PCH_RULE,$(module_name),$(source),$(dependencies),$(compiler_flags)))\n",
+                             "$(intermediate_dir)$(SEP).gch_$(module_name)$(SEP)$(source_name).gch",
+                             "$(intermediate_dir)$(SEP).gch_$(module_name)$(SEP)$(source_name).gch.d",
+                             "$(intermediate_dir)$(SEP).gch_$(module_name)$(SEP)", NULL );
+Rule bootRule ( "$(eval $(call RBUILD_NASM,$(module_name),$(source),$(dependencies),,$(module_output)))\n",
+                "$(module_output)",
+                "$(OUTPUT)$(SEP)$(source_dir)$(SEP)", NULL );
+Rule nasmRule ( "$(eval $(call RBUILD_NASM,$(module_name),$(source),$(dependencies),,$(intermediate_path_unique).o))\n",
+                "$(intermediate_path_unique).o",
+                "$(intermediate_dir)$(SEP)", NULL );
+
+/* TODO: move these to rules.mak */
+Rule wmcRule ( "$(intermediate_path_noext).rc $(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h: $(WMC_TARGET) $(source) | $(intermediate_dir)\n"
+               "\t$(ECHO_WMC)\n"
+               "\t$(Q)$(WMC_TARGET) -i -H $(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h -o $(intermediate_path_noext).rc $(source)\n",
+               "$(intermediate_path_noext).rc",
+               "$(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h",
+               "$(intermediate_dir)$(SEP)", NULL );
+/* TODO: if possible, move these to rules.mak */
+Rule arRule1 ( "$(intermediate_path_noext).a: $($(module_name)_OBJS)  $(dependencies) | $(intermediate_dir)\n",
+               "$(intermediate_path_noext).a",
+               "$(intermediate_dir)$(SEP)", NULL );
 Rule arRule2 ( "\t$(ECHO_AR)\n"
               "\t${ar} -rc $@ $($(module_name)_OBJS)\n",
               NULL );
-Rule arHostRule2 ( "\t$(ECHO_AR)\n"
+Rule arHostRule2 ( "\t$(ECHO_HOSTAR)\n"
                    "\t${host_ar} -rc $@ $($(module_name)_OBJS)\n",
                    NULL );
-Rule gasRule ( "$(source): ${$(module_name)_precondition}\n"
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-               "\t$(ECHO_GAS)\n"
-               "\t${gcc} -x assembler-with-cpp -o $@ -D__ASM__ $($(module_name)_CFLAGS) -c $<\n",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule bootRule ( "$(source): ${$(module_name)_precondition}\n"
-                "$(module_output): $(source)$(dependencies) | $(OUTPUT)$(SEP)$(source_dir)\n"
-                "\t$(ECHO_NASM)\n"
-                "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
-                "$(OUTPUT)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule nasmRule ( "$(source): ${$(module_name)_precondition}\n"
-                "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                "\t$(ECHO_NASM)\n"
-                "\t$(Q)${nasm} -f win32 $< -o $@ $($(module_name)_NASMFLAGS)\n",
-                "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o",
-                "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule windresRule ( "$(source): ${$(module_name)_precondition}\n"
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff: $(source)$(dependencies) $(WRC_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir) $(TEMPORARY)\n"
-                   "\t$(ECHO_WRC)\n"
-                   "\t${gcc} -xc -E -DRC_INVOKED ${$(module_name)_RCFLAGS} $(source) > $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp\n"
-                   "\t$(Q)$(WRC_TARGET) ${$(module_name)_RCFLAGS} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp\n"
-                   "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).rci.tmp 2>$(NUL)\n"
-                   "\t${windres} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp -o $@\n"
-                   "\t-@${rm} $(TEMPORARY)$(SEP)$(module_name).$(source_name_noext).res.tmp 2>$(NUL)\n",
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).coff",
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule wmcRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc $(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h: $(WMC_TARGET) $(source) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-               "\t$(ECHO_WMC)\n"
-               "\t$(Q)$(WMC_TARGET) -i -H $(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h -o $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc $(source)\n",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).rc",
-               "$(INTERMEDIATE)$(SEP)include$(SEP)reactos$(SEP)$(source_name_noext).h",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule winebuildKMRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def: $(source)$(dependencies) $(WINEBUILD_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                       "\t$(ECHO_WINEBLD)\n"
-                       "\t${gcc} -xc -E $(source) -I. > $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec\n"
-                       "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).spec.def --def -E $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec\n"
-                       "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.c:\n"
-                       "\t${cp} $(NUL) $@ 1>$(NUL)\n"
-                       "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.o: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.c$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                       "\t$(ECHO_CC)\n"
-                       "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-                       "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec",
-                       "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def",
-                       "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.c",
-                       "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.o",
-                       "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule winebuildRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def: $(source)$(dependencies) $(WINEBUILD_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                     "\t$(ECHO_WINEBLD)\n"
-                     "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).spec.def --def -E $(source)\n"
-                     "$(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).stubs.c: $(source_path)$(SEP)$(source_name_noext).spec $(WINEBUILD_TARGET)\n"
-                     "\t$(ECHO_WINEBLD)\n"
-                     "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $(INTERMEDIATE)$(SEP)$(source_path)$(SEP)$(source_name_noext).stubs.c --pedll $(source_path)$(SEP)$(source_name_noext).spec\n"
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.o: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.c$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                     "\t$(ECHO_CC)\n"
-                     "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec.def",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.c",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).stubs.o",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule widlHeaderRule ( "$(source): ${$(module_name)_precondition}\n"
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                      "\t$(ECHO_WIDL)\n"
-                      "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h $(source)\n",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).h",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule widlServerRule ( "$(source): ${$(module_name)_precondition}\n"
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                      "\t$(ECHO_WIDL)\n"
-                      "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h -s -S $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c $(source)\n"
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.o: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                      "\t$(ECHO_CC)\n"
-                      "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.h",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.c",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_s.o",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule widlClientRule ( "$(source): ${$(module_name)_precondition}\n"
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                      "\t$(ECHO_WIDL)\n"
-                      "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h -c -C $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c $(source)\n"
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.o: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                      "\t$(ECHO_CC)\n"
-                      "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.h",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.c",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_c.o",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule widlProxyRule ( "$(source): ${$(module_name)_precondition}\n"
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                     "\t$(ECHO_WIDL)\n"
-                     "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -h -H $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h -p -P $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c $(source)\n"
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.o: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                      "\t$(ECHO_CC)\n"
-                      "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.h",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.c",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_p.o",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule widlTlbRule ( "$(source): ${$(module_name)_precondition}\n"
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(module_name).tlb: $(source)$(dependencies) $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                   "\t$(ECHO_WIDL)\n"
-                   "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) -t -T $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).tlb $(source)\n",
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule gccRule ( "$(source): ${$(module_name)_precondition}\n"
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-               "\t$(ECHO_CC)\n"
-               "\t${gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
-Rule gccHostRule ( "$(source): ${$(module_name)_precondition}\n"
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                   "\t$(ECHO_CC)\n"
-                   "\t${host_gcc} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
-Rule gppRule ( "$(source): ${$(module_name)_precondition}\n"
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-               "\t$(ECHO_CC)\n"
-               "\t${gpp} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-               "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
-Rule gppHostRule ( "$(source): ${$(module_name)_precondition}\n"
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                   "\t$(ECHO_CC)\n"
-                   "\t${host_gpp} -o $@ $($(module_name)_CFLAGS)$(compiler_flags) -c $<\n",
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
+
 Rule emptyRule ( "", NULL );
 
 void
@@ -1166,13 +1185,6 @@ MingwModuleHandler::GenerateGccCommand (
        const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
        string dependencies = extraDependencies;
 
-       string flags;
-       string extension = GetExtension ( *sourceFile );
-       if ( extension == ".cc" || extension == ".cpp" || extension == ".cxx" )
-               flags = GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, CompilerTypeCPP );
-       else
-               flags = GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, CompilerTypeCC );
-
        if ( pchFilename )
        {
                dependencies += " " + backend->GetFullName ( *pchFilename );
@@ -1185,7 +1197,7 @@ MingwModuleHandler::GenerateGccCommand (
        if ( rpcDependencies.size () > 0 )
                dependencies += " " + v2s ( backend, rpcDependencies, 5 );
 
-       rule->Execute ( fMakefile, backend, module, sourceFile, clean_files, dependencies, flags );
+       rule->Execute ( fMakefile, backend, module, sourceFile, clean_files, dependencies );
 }
 
 string
@@ -1260,12 +1272,10 @@ MingwModuleHandler::GenerateCommands (
                { HostDontCare, TypeDontCare, ".asm", &nasmRule },
                { HostDontCare, TypeDontCare, ".rc", &windresRule },
                { HostDontCare, TypeDontCare, ".mc", &wmcRule },
-               { HostFalse, Kernel, ".spec", &winebuildKMRule },
-               { HostFalse, KernelModeDLL, ".spec", &winebuildKMRule },
-               { HostDontCare, TypeDontCare, ".spec", &winebuildRule },
                { HostDontCare, RpcServer, ".idl", &widlServerRule },
                { HostDontCare, RpcClient, ".idl", &widlClientRule },
                { HostDontCare, RpcProxy, ".idl", &widlProxyRule },
+               { HostDontCare, IdlInterface, ".idl", &widlInterfaceRule },
                { HostDontCare, EmbeddedTypeLib, ".idl", &widlTlbRule },
                { HostDontCare, TypeDontCare, ".idl", &widlHeaderRule },
                { HostTrue, TypeDontCare, ".c", &gccHostRule },
@@ -1314,6 +1324,8 @@ MingwModuleHandler::GenerateCommands (
 void
 MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget )
 {
+       fprintf ( fMakefile, "# BUILD MAP CODE\n" );
+
        fprintf ( fMakefile,
                  "ifeq ($(ROS_BUILDMAP),full)\n" );
 
@@ -1351,6 +1363,8 @@ MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget )
 void
 MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
 {
+       fprintf ( fMakefile, "# BUILD NO STRIP CODE\n" );
+
        fprintf ( fMakefile,
                  "ifeq ($(ROS_BUILDNOSTRIP),yes)\n" );
 
@@ -1427,6 +1441,7 @@ MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
 void
 MingwModuleHandler::GenerateRunRsymCode () const
 {
+       fprintf ( fMakefile, "# RUN RSYM CODE\n" );
        fprintf ( fMakefile,
              "ifneq ($(ROS_GENERATE_RSYM),no)\n" );
        fprintf ( fMakefile,
@@ -1440,6 +1455,7 @@ MingwModuleHandler::GenerateRunRsymCode () const
 void
 MingwModuleHandler::GenerateRunStripCode () const
 {
+       fprintf ( fMakefile, "# RUN STRIP CODE\n" );
        fprintf ( fMakefile,
                  "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
        fprintf ( fMakefile,
@@ -1462,6 +1478,8 @@ MingwModuleHandler::GenerateLinkerCommand (
        string objectsMacro = GetObjectsMacro ( module );
        string libsMacro = GetLibsMacro ();
 
+       fprintf ( fMakefile, "# LINKER COMMAND\n" );
+
        string target_macro ( GetTargetMacro ( module ) );
        string target_folder ( backend->GetFullPath ( *target_file ) );
 
@@ -1471,15 +1489,6 @@ MingwModuleHandler::GenerateLinkerCommand (
        else
                linkerScriptArgument = "";
 
-       fprintf ( fMakefile,
-               "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
-               target_macro.c_str (),
-               definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
-               dependencies.c_str (),
-               target_folder.c_str () );
-       fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
-       string targetName ( module.output->name );
-
        /* check if we need to add default C++ libraries, ie if we have
         * a C++ user-mode module without the -nostdlib linker flag
         */
@@ -1489,6 +1498,14 @@ MingwModuleHandler::GenerateLinkerCommand (
 
        if ( !module.HasImportLibrary() )
        {
+               fprintf ( fMakefile,
+                       "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
+                       target_macro.c_str (),
+                       definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
+                       dependencies.c_str (),
+                       target_folder.c_str () );
+               fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
+
                fprintf ( fMakefile,
                          "\t%s %s%s %s %s %s %s -o %s\n",
                          linker.c_str (),
@@ -1502,19 +1519,33 @@ MingwModuleHandler::GenerateLinkerCommand (
        }
        else
        {
-               FileLocation temp_exp ( TemporaryDirectory,
-                                       "",
-                                       module.name + ".temp.exp" );
+               FileLocation temp_exp ( IntermediateDirectory,
+                                       module.output->relative_path,
+                                       module.name + ".exp" );
                CLEAN_FILE ( temp_exp );
 
                fprintf ( fMakefile,
-                         "\t${dlltool} --dllname %s --def %s --output-exp %s%s%s\n",
-                         targetName.c_str (),
+                       "%s: %s | %s\n",
+                       backend->GetFullName ( temp_exp ).c_str (),
+                       definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
+                       backend->GetFullPath ( temp_exp ).c_str () );
+               fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
+
+               fprintf ( fMakefile,
+                         "\t${dlltool} --dllname %s --def %s --output-exp $@%s%s\n",
+                         module.GetDllName ().c_str (),
                          definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
-                         backend->GetFullName ( temp_exp ).c_str (),
                          module.mangledSymbols ? "" : " --kill-at",
                          module.underscoreSymbols ? " --add-underscore" : "" );
 
+               fprintf ( fMakefile,
+                       "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
+                       target_macro.c_str (),
+                       backend->GetFullName ( temp_exp ).c_str (),
+                       dependencies.c_str (),
+                       target_folder.c_str () );
+               fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
+
                fprintf ( fMakefile,
                          "\t%s %s%s %s %s %s %s %s -o %s\n",
 
@@ -1532,10 +1563,6 @@ MingwModuleHandler::GenerateLinkerCommand (
                          "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n",
                          target_macro.c_str (),
                          pefixupParameters.c_str() );
-
-               fprintf ( fMakefile,
-                         "\t-@${rm} %s 2>$(NUL)\n",
-                         backend->GetFullName ( temp_exp ).c_str () );
        }
 
        GenerateBuildMapCode ();
@@ -1555,6 +1582,7 @@ MingwModuleHandler::GeneratePhonyTarget() const
        string targetMacro ( GetTargetMacro ( module ) );
        const FileLocation *target_file = GetTargetFilename ( module, NULL );
 
+       fprintf ( fMakefile, "# PHONY TARGET\n" );
        fprintf ( fMakefile,
                  ".PHONY: %s\n\n",
                  targetMacro.c_str ());
@@ -1571,6 +1599,8 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
        size_t i;
        string moduleDependencies;
 
+       fprintf ( fMakefile, "# OBJECT FILE TARGETS\n" );
+
        const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
        for ( i = 0; i < compilationUnits.size (); i++ )
        {
@@ -1588,8 +1618,6 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
        {
                GenerateCommands ( *compilationUnits[i],
                                   moduleDependencies );
-               fprintf ( fMakefile,
-                         "\n" );
        }
 
        vector<CompilationUnit*> sourceCompilationUnits;
@@ -1600,39 +1628,41 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
                                   moduleDependencies );
        }
        CleanupCompilationUnitVector ( sourceCompilationUnits );
+
+       if ( module.type == RpcProxy )
+       {
+               widlDlldataRule.Execute ( fMakefile,
+                                                                 backend,
+                                                                 module,
+                                                                 GetDlldataFilename(),
+                                                                 clean_files,
+                                                                 ssprintf ( "$(%s_SOURCES)", module.name.c_str ()) );
+       }
 }
 
 void
 MingwModuleHandler::GenerateObjectFileTargets ()
 {
-       const FileLocation *pchFilename = GetPrecompiledHeaderFilename ();
+       fprintf ( fMakefile, "# OBJECT FILE TARGETS\n" );
 
-       if ( pchFilename )
+       if ( module.pch && use_pch )
        {
-               string cc = ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue ? "${host_gcc}" : "${gcc}" );
-               string cppc = ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue ? "${host_gpp}" : "${gpp}" );
 
-               const FileLocation& baseHeaderFile = *module.pch->file;
-               CLEAN_FILE ( *pchFilename );
-               string dependencies = backend->GetFullName ( baseHeaderFile );
+               std::map<string, string> vars;
+
                /* WIDL generated headers may be used */
+               string dependencies;
                vector<FileLocation> rpcDependencies;
                GetRpcHeaderDependencies ( rpcDependencies );
                if ( rpcDependencies.size () > 0 )
-                       dependencies += " " + v2s ( backend, rpcDependencies, 5 );
-               fprintf ( fMakefile,
-                         "%s: %s | %s\n",
-                         backend->GetFullName ( *pchFilename ).c_str(),
-                         dependencies.c_str(),
-                         backend->GetFullPath ( *pchFilename ).c_str() );
-               fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
-               fprintf ( fMakefile,
-                         "\t%s -o %s %s -g %s\n\n",
-                         module.cplusplus ? cppc.c_str() : cc.c_str(),
-                         backend->GetFullName ( *pchFilename ).c_str(),
-                         cflagsMacro.c_str(),
-                         backend->GetFullName ( baseHeaderFile ).c_str() );
-               delete pchFilename;
+                       dependencies = " " + v2s ( backend, rpcDependencies, 5 );
+
+               if ( module.cplusplus )
+                       pchCxxRule.Execute ( fMakefile, backend, module, module.pch->file, clean_files, dependencies );
+               else
+                       pchRule.Execute ( fMakefile, backend, module, module.pch->file, clean_files, dependencies );
+
+               fprintf ( fMakefile, "\n" );
        }
 
        GenerateObjectFileTargets ( module.non_if_data );
@@ -1646,17 +1676,26 @@ MingwModuleHandler::GenerateArchiveTarget ()
        const FileLocation *archiveFilename = GetModuleArchiveFilename ();
        const FileLocation *definitionFilename = GetDefinitionFilename ();
 
-       arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
+       fprintf ( fMakefile, "# ARCHIVE TARGET\n" );
 
        if ( IsStaticLibrary ( module ) && definitionFilename )
        {
+               arRule1.Execute ( fMakefile,
+                                                 backend,
+                                                 module,
+                                                 archiveFilename,
+                                                 clean_files,
+                                                 backend->GetFullName ( *definitionFilename ).c_str () );
+
                fprintf ( fMakefile,
                          "\t${dlltool} --dllname %s --def %s --output-lib $@%s%s\n",
-                         module.importLibrary->dllname.c_str (),
+                         module.GetDllName ().c_str (),
                          backend->GetFullName ( *definitionFilename ).c_str (),
                          module.mangledSymbols ? "" : " --kill-at",
                          module.underscoreSymbols ? " --add-underscore" : "" );
        }
+       else
+               arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
 
        if ( definitionFilename )
                delete definitionFilename;
@@ -1673,13 +1712,6 @@ MingwModuleHandler::GenerateArchiveTarget ()
        return archiveFilename;
 }
 
-string
-MingwModuleHandler::GetCFlagsMacro () const
-{
-       return ssprintf ( "$(%s_CFLAGS)",
-                         module.name.c_str () );
-}
-
 /*static*/ string
 MingwModuleHandler::GetObjectsMacro ( const Module& module )
 {
@@ -1687,12 +1719,6 @@ MingwModuleHandler::GetObjectsMacro ( const Module& module )
                          module.name.c_str () );
 }
 
-string
-MingwModuleHandler::GetLinkingDependenciesMacro () const
-{
-       return ssprintf ( "$(%s_LINKDEPS)", module.name.c_str () );
-}
-
 string
 MingwModuleHandler::GetLibsMacro () const
 {
@@ -1706,6 +1732,16 @@ MingwModuleHandler::GetLinkerMacro () const
                          module.name.c_str () );
 }
 
+string
+MingwModuleHandler::GetDebugFormat ()
+{
+    if (Environment::GetArch() == "amd64")
+    {
+        return "dwarf-2";
+    }
+    return "stabs+";
+}
+
 string
 MingwModuleHandler::GetModuleTargets ( const Module& module )
 {
@@ -1725,7 +1761,8 @@ MingwModuleHandler::GenerateSourceMacro ()
 {
        sourcesMacro = ssprintf ( "%s_SOURCES", module.name.c_str ());
 
-       GenerateSourceMacros ( module.non_if_data );
+       if ( module.type == RpcProxy || module.type == Cabinet )
+               GenerateSourceMacros ( module.non_if_data );
 
        // future references to the macro will be to get its values
        sourcesMacro = ssprintf ("$(%s)", sourcesMacro.c_str ());
@@ -1806,143 +1843,60 @@ MingwModuleHandler::GenerateOtherMacros ()
 {
        set<const Define *> used_defs;
 
-       cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
-       nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());
-       windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());
-       widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());
        linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());
        libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
-       linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());
 
-       GenerateMacros (
-               "=",
-               module.non_if_data,
-               &module.linkerFlags,
-               used_defs );
+       const FileLocation * pchPath = GetPrecompiledHeaderPath ();
 
-       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
+       if ( pchPath )
        {
-               GenerateMacros (
-                       "+=",
-                       module.project.non_if_data,
-                       NULL,
-                       used_defs );
-       }
+               string pchPathStr = backend->GetFullName ( *pchPath );
+               delete pchPath;
 
-       vector<FileLocation> s;
-       if ( module.importLibrary )
-       {
-               const vector<CompilationUnit*>& compilationUnits = module.non_if_data.compilationUnits;
-               for ( size_t i = 0; i < compilationUnits.size (); i++ )
-               {
-                       CompilationUnit& compilationUnit = *compilationUnits[i];
-                       const FileLocation& sourceFile = compilationUnit.GetFilename ();
-                       string extension = GetExtension ( sourceFile );
-                       if ( extension == ".spec" || extension == ".SPEC" )
-                               GetSpecObjectDependencies ( s, &sourceFile );
-               }
-       }
-       if ( s.size () > 0 )
-       {
-               fprintf (
-                       fMakefile,
-                       "%s +=",
-                       linkDepsMacro.c_str() );
-               for ( size_t i = 0; i < s.size(); i++ )
-                       fprintf ( fMakefile,
-                                 " %s",
-                                 backend->GetFullName ( s[i] ).c_str () );
-               fprintf ( fMakefile, "\n" );
-       }
+               fprintf ( fMakefile,
+                                 "%s_%sINCLUDES+= -I%s\n",
+                                 module.name.c_str(),
+                                 CompilerPrefixTable[CompilerTypeCC],
+                                 pchPathStr.c_str() );
 
-       string globalCflags = "";
-       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
-               globalCflags += " $(PROJECT_CFLAGS)";
-       else
-               globalCflags += " -Wall -Wpointer-arith -D__REACTOS__";
-       globalCflags += " -g";
-       if ( backend->usePipe )
-               globalCflags += " -pipe";
-       if ( !module.allowWarnings )
-               globalCflags += " -Werror";
-       if ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue )
-       {
-               if ( module.cplusplus )
-                       globalCflags += " $(HOST_CPPFLAGS)";
-               else
-                       globalCflags += " -Wno-strict-aliasing $(HOST_CFLAGS)";
-       }
-       else
-       {
-               if ( module.cplusplus )
-               {
-                       // HACK: use host headers when building C++
-                       globalCflags += " $(HOST_CPPFLAGS)";
-               }
-               else
-                       globalCflags += " -nostdinc";
+               fprintf ( fMakefile,
+                                 "%s_%sINCLUDES+= -I%s\n",
+                                 module.name.c_str(),
+                                 CompilerPrefixTable[CompilerTypeCXX],
+                                 pchPathStr.c_str() );
        }
 
-       // Always force disabling of sibling calls optimisation for GCC
-       // (TODO: Move to version-specific once this bug is fixed in GCC)
-       globalCflags += " -fno-optimize-sibling-calls";
+       const char * toolPrefix = "";
 
-       fprintf (
-               fMakefile,
-               "%s +=%s\n",
-               cflagsMacro.c_str (),
-               globalCflags.c_str () );
+       if ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue )
+               toolPrefix = "HOST_";
 
-       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
+       // FIXME: this is very ugly and generates lots of useless entries
+       for ( unsigned type = CompilerTypeCC; type < CompilerTypesCount; ++ type )
        {
-               fprintf (
-                       fMakefile,
-                       "%s += $(PROJECT_RCFLAGS)\n",
-                       windresflagsMacro.c_str () );
+               string flags;
 
-               fprintf (
-                       fMakefile,
-                       "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
-                       widlflagsMacro.c_str (),
-                       module.output->relative_path.c_str () );
+               if ( module.dynamicCRT )
+                       flags += ssprintf ( " $(%s%sFLAG_CRTDLL)", toolPrefix, CompilerPrefixTable[type] );
 
-               fprintf (
-                       fMakefile,
-                       "%s_LFLAGS := $(PROJECT_LFLAGS) -g $(%s_LFLAGS)\n",
-                       module.name.c_str (),
-                       module.name.c_str () );
-       }
-       else
-       {
-               fprintf (
-                       fMakefile,
-                       "%s_LFLAGS += $(HOST_LFLAGS)\n",
-                       module.name.c_str () );
-       }
+               // FIXME: this duplicates the flag for CPP and C/CXX
+               if ( !module.allowWarnings )
+                       flags += ssprintf ( " $(%s%sFLAG_WERROR)", toolPrefix, CompilerPrefixTable[type] );
 
-       fprintf (
-               fMakefile,
-               "%s += $(%s)\n",
-               linkDepsMacro.c_str (),
-               libsMacro.c_str () );
+               if ( module.isUnicode )
+                       flags += ssprintf ( " $(%s%sFLAG_UNICODE)", toolPrefix, CompilerPrefixTable[type] );
 
-       const char *cflags = ModuleHandlerInformations[module.type].cflags;
-       if ( strlen( cflags ) > 0 )
-       {
-               fprintf ( fMakefile,
-                         "%s += %s\n\n",
-                         cflagsMacro.c_str (),
-                         cflags );
+               if ( flags.size() )
+               {
+                       fprintf ( fMakefile,
+                                         "%s_%sFLAGS+=%s\n",
+                                         module.name.c_str(),
+                                         CompilerPrefixTable[type],
+                                         flags.c_str() );
+               }
        }
 
-       const char* nasmflags = ModuleHandlerInformations[module.type].nasmflags;
-       if ( strlen( nasmflags ) > 0 )
-       {
-               fprintf ( fMakefile,
-                         "%s += %s\n\n",
-                         nasmflagsMacro.c_str (),
-                         nasmflags );
-       }
+       GenerateParameters ( module.name.c_str(), "+=", module.non_if_data );
 
        const char *linkerflags = ModuleHandlerInformations[module.type].linkerflags;
        if ( strlen( linkerflags ) > 0 )
@@ -1953,24 +1907,34 @@ MingwModuleHandler::GenerateOtherMacros ()
                          linkerflags );
        }
 
-       if ( IsStaticLibrary ( module ) && module.isStartupLib )
+       // FIXME: make rules for linker, move standard flags there
+       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
        {
-               fprintf ( fMakefile,
-                         "%s += -Wno-main\n\n",
-                         cflagsMacro.c_str () );
+               if ( module.cplusplus )
+                       fprintf ( fMakefile,
+                                         "%s+= $(PROJECT_LPPFLAGS)\n\n",
+                                         linkerflagsMacro.c_str () );
+               else
+                       fprintf ( fMakefile,
+                                         "%s+= $(PROJECT_LFLAGS)\n\n",
+                                         linkerflagsMacro.c_str () );
        }
 
-       fprintf ( fMakefile, "\n\n" );
+       GenerateMacros (
+               "+=",
+               module.non_if_data,
+               &module.linkerFlags,
+               used_defs );
 
-       // future references to the macros will be to get their values
-       cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
-       nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
-       widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
+       fprintf ( fMakefile, "\n\n" );
 }
 
 void
 MingwModuleHandler::GenerateRules ()
 {
+    SpecFileType spec;
+
+       fprintf ( fMakefile, "# RULES\n" );
        string targetMacro = GetTargetMacro ( module );
        //CLEAN_FILE ( targetMacro );
        CLEAN_FILE ( FileLocation ( SourceDirectory, "", targetMacro ) );
@@ -1997,6 +1961,21 @@ MingwModuleHandler::GenerateRules ()
                delete ar_target;
        }
 
+
+    spec = IsSpecDefinitionFile();
+
+    if(spec)
+       {
+               Rule * defRule;
+
+               if (spec == PSpec)
+                       defRule = &winebuildPRule;
+               else
+                       defRule = &winebuildRule;
+
+               defRule->Execute ( fMakefile, backend, module, module.importLibrary->source, clean_files );
+       }
+
        GenerateObjectFileTargets ();
 }
 
@@ -2021,6 +2000,8 @@ MingwModuleHandler::GenerateInvocations () const
        if ( module.invocations.size () == 0 )
                return;
 
+       fprintf ( fMakefile, "# INVOCATIONS\n" );
+
        size_t iend = module.invocations.size ();
        for ( size_t i = 0; i < iend; i++ )
        {
@@ -2117,6 +2098,7 @@ MingwModuleHandler::GetDefaultDependencies (
 void
 MingwModuleHandler::GeneratePreconditionDependencies ()
 {
+       fprintf ( fMakefile, "# PRECONDITION DEPENDENCIES\n" );
        string preconditionDependenciesName = GetPreconditionDependenciesName ();
        string_list dependencies;
        GetDefaultDependencies ( dependencies );
@@ -2139,14 +2121,21 @@ MingwModuleHandler::GeneratePreconditionDependencies ()
        fprintf ( fMakefile, "\n" );
 }
 
-bool
-MingwModuleHandler::IsWineModule () const
+SpecFileType
+MingwModuleHandler::IsSpecDefinitionFile () const
 {
-       if ( module.importLibrary == NULL)
-               return false;
+    if(!module.importLibrary)
+        return None;
+
+       std::string ext = GetExtension ( *module.importLibrary->source );
 
-       size_t index = module.importLibrary->source->name.rfind ( ".spec.def" );
-       return ( index != string::npos );
+    if ( ext == ".spec" )
+        return Spec;
+
+    if ( ext == ".pspec" )
+        return PSpec;
+
+    return None;
 }
 
 /* caller needs to delete the returned object */
@@ -2156,62 +2145,72 @@ MingwModuleHandler::GetDefinitionFilename () const
        if ( module.importLibrary == NULL )
                return NULL;
 
-       DirectoryLocation directory;
-       if ( IsWineModule () )
-               directory = IntermediateDirectory;
+       if ( IsSpecDefinitionFile () )
+       {
+               return new FileLocation ( IntermediateDirectory,
+                                                                 module.importLibrary->source->relative_path,
+                                                                 GetBasename ( module.importLibrary->source->name ) + "_" + module.name + ".auto.def" );
+       }
        else
-               directory = SourceDirectory;
-
-       return new FileLocation ( directory,
-                                 module.importLibrary->source->relative_path,
-                                 module.importLibrary->source->name );
+       {
+               return new FileLocation ( SourceDirectory,
+                                                                 module.importLibrary->source->relative_path,
+                                                                 module.importLibrary->source->name );
+       }
 }
 
 void
-MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
+MingwModuleHandler::GenerateImportLibraryTarget (
+       const FileLocation *defFilename,
+       const FileLocation *library_target,
+       bool delayimp)
 {
-       if ( module.importLibrary != NULL )
-       {
-               const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
-               const FileLocation *defFilename = GetDefinitionFilename ();
-               string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
+       string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
 
-               vector<FileLocation> deps;
-               GetDefinitionDependencies ( deps );
+       fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" );
 
-               fprintf ( fMakefile, "# IMPORT LIBRARY RULE:\n" );
+       fprintf ( fMakefile, "%s:",
+                 backend->GetFullName ( *library_target ).c_str () );
 
-               fprintf ( fMakefile, "%s:",
-                         backend->GetFullName ( *library_target ).c_str () );
+       if ( defFilename )
+       {
+               fprintf ( fMakefile, " %s",
+                         backend->GetFullName ( *defFilename ).c_str () );
+       }
 
-               if ( defFilename )
-               {
-                       fprintf ( fMakefile, " %s",
-                                 backend->GetFullName ( *defFilename ).c_str () );
-               }
+       fprintf ( fMakefile, " | %s\n",
+                 backend->GetFullPath ( *library_target ).c_str () );
 
-               size_t i, iend = deps.size();
-               for ( i = 0; i < iend; i++ )
-                       fprintf ( fMakefile, " %s",
-                                 backend->GetFullName ( deps[i] ).c_str () );
+       fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
 
-               fprintf ( fMakefile, " | %s\n",
-                         backend->GetFullPath ( *library_target ).c_str () );
+       fprintf ( fMakefile,
+                 "\t${dlltool} --dllname %s --def %s %s %s%s%s\n\n",
+                 module.GetDllName ().c_str (),
+                 defFilename ? backend->GetFullName ( *defFilename ).c_str ()
+                             : empty.c_str (),
+                 delayimp ? "--output-delaylib" : "--output-lib",
+                 backend->GetFullName ( *library_target ).c_str (),
+                 module.mangledSymbols ? "" : " --kill-at",
+                 module.underscoreSymbols ? " --add-underscore" : "" );
+}
 
-               fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
+void
+MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
+{
+       if ( module.importLibrary != NULL )
+       {
+               const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files, false );
+               const FileLocation *delayimp_target = GetImportLibraryFilename ( module, &clean_files, true );
+               const FileLocation *defFilename = GetDefinitionFilename ();
 
-               fprintf ( fMakefile,
-                         "\t${dlltool} --dllname %s --def %s --output-lib %s%s%s\n\n",
-                         module.output->name.c_str (),
-                         defFilename ? backend->GetFullName ( *defFilename ).c_str ()
-                                     : empty.c_str (),
-                         backend->GetFullName ( *library_target ).c_str (),
-                         module.mangledSymbols ? "" : " --kill-at",
-                         module.underscoreSymbols ? " --add-underscore" : "" );
+               GenerateImportLibraryTarget(defFilename, library_target, false);
+               GenerateImportLibraryTarget(defFilename, delayimp_target, true);
 
                if ( defFilename )
                        delete defFilename;
                delete library_target;
+               delete delayimp_target;
+
        }
 }
 
@@ -2220,17 +2219,9 @@ MingwModuleHandler::GetSpecObjectDependencies (
        vector<FileLocation>& dependencies,
        const FileLocation *file ) const
 {
-       string basename = GetBasename ( file->name );
-
-       FileLocation defDependency ( IntermediateDirectory,
-                                    file->relative_path,
-                                    basename + ".spec.def" );
-       dependencies.push_back ( defDependency );
-
-       FileLocation stubsDependency ( IntermediateDirectory,
-                                      file->relative_path,
-                                    basename + ".stubs.c" );
-       dependencies.push_back ( stubsDependency );
+       dependencies.push_back ( FileLocation ( IntermediateDirectory,
+                                                                                       file->relative_path,
+                                                                                       GetBasename ( file->name ) + "_" + module.name + ".stubs.c" ) );
 }
 
 void
@@ -2278,9 +2269,11 @@ MingwModuleHandler::GetDefinitionDependencies (
                const CompilationUnit& compilationUnit = *compilationUnits[i];
                const FileLocation& sourceFile = compilationUnit.GetFilename ();
                string extension = GetExtension ( sourceFile );
-               if ( extension == ".spec" || extension == ".SPEC" )
+
+               if (extension == ".spec" || extension == ".pspec")
                        GetSpecObjectDependencies ( dependencies, &sourceFile );
-               if ( extension == ".idl" || extension == ".IDL" )
+
+               if (extension == ".idl")
                {
                        if ( ( module.type == RpcServer ) || ( module.type == RpcClient ) || ( module.type == RpcProxy ) )
                                GetWidlObjectDependencies ( dependencies, &sourceFile );
@@ -2316,6 +2309,38 @@ MingwAddDebugSupportLibraries ( Module& module, DebugSupportType type )
        module.non_if_data.libraries.push_back(pLibrary);
 }
 
+static void
+MingwAddCRTLibrary( Module &module )
+{
+       const char * crtAttr = module.CRT.c_str ();
+       const char * crtLib = NULL;
+
+       if ( stricmp ( crtAttr, "libc" ) == 0 )
+               crtLib = "crt";
+       else if ( stricmp ( crtAttr, "msvcrt" ) == 0 )
+               crtLib = "msvcrt";
+       else if ( stricmp ( crtAttr, "libcntpr" ) == 0 )
+               crtLib = "libcntpr";
+       else if ( stricmp ( crtAttr, "ntdll" ) == 0 )
+               crtLib = "ntdll";
+
+       if ( crtLib )
+       {
+               Library* pLibrary = new Library ( module, std::string ( crtLib ) );
+
+               if ( pLibrary->importedModule == NULL)
+               {
+                       throw XMLInvalidBuildFileException (
+                               module.node.location,
+                               "module '%s' trying to import non-existant C runtime module '%s'",
+                               module.name.c_str(),
+                               crtLib );
+               }
+
+               module.non_if_data.libraries.push_back ( pLibrary );
+       }
+}
+
 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler ( const Module& module_ )
        : MingwModuleHandler ( module_ )
 {
@@ -2332,11 +2357,12 @@ MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string objectsMacro = GetObjectsMacro ( module );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
        string libsMacro = GetLibsMacro ();
 
        GenerateRules ();
 
+       fprintf ( fMakefile, "# BUILD TOOL MODULE TARGET\n" );
+
        string linker;
        if ( module.cplusplus )
                linker = "${host_gpp}";
@@ -2347,9 +2373,9 @@ MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
        fprintf ( fMakefile, "%s: %s %s | %s\n",
                  targetMacro.c_str (),
                  objectsMacro.c_str (),
-                 linkDepsMacro.c_str (),
+                 libsMacro.c_str (),
                  backend->GetFullPath ( *target_file ).c_str () );
-       fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
+       fprintf ( fMakefile, "\t$(ECHO_HOSTLD)\n" );
        fprintf ( fMakefile,
                  "\t%s %s -o $@ %s %s\n\n",
                  linker.c_str (),
@@ -2379,7 +2405,7 @@ MingwKernelModuleHandler::GenerateKernelModuleTarget ()
 {
        string targetMacro ( GetTargetMacro ( module ) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2387,7 +2413,7 @@ MingwKernelModuleHandler::GenerateKernelModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2415,6 +2441,7 @@ MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
 void
 MingwKernelModeDLLModuleHandler::AddImplicitLibraries ( Module& module )
 {
+       MingwAddCRTLibrary ( module );
        MingwAddDebugSupportLibraries ( module, DebugKernelMode );
 }
 
@@ -2429,7 +2456,7 @@ MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
 {
        string targetMacro ( GetTargetMacro ( module ) );
        string workingDirectory = GetWorkingDirectory ();
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2437,7 +2464,7 @@ MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2463,6 +2490,7 @@ MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler (
 void
 MingwNativeDLLModuleHandler::AddImplicitLibraries ( Module& module )
 {
+       MingwAddCRTLibrary ( module );
        MingwAddDebugSupportLibraries ( module, DebugUserMode );
 }
 
@@ -2477,7 +2505,7 @@ MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2485,7 +2513,7 @@ MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2511,6 +2539,7 @@ MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler (
 void
 MingwNativeCUIModuleHandler::AddImplicitLibraries ( Module& module )
 {
+       MingwAddCRTLibrary ( module );
        MingwAddDebugSupportLibraries ( module, DebugUserMode );
 }
 
@@ -2525,7 +2554,7 @@ MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2533,7 +2562,7 @@ MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2563,23 +2592,10 @@ MingwWin32OCXModuleHandler::MingwWin32OCXModuleHandler (
 {
 }
 
-static bool
-LinksToCrt( Module &module )
-{
-       for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
-       {
-               Library& library = *module.non_if_data.libraries[i];
-               if ( library.name == "libcntpr" || library.name == "crt" )
-                       return true;
-       }
-       return false;
-}
-
 static void
 MingwAddImplicitLibraries( Module &module )
 {
        Library* pLibrary;
-       bool links_to_crt;
 
        if ( module.type != Win32DLL
          && module.type != Win32OCX
@@ -2587,54 +2603,28 @@ MingwAddImplicitLibraries( Module &module )
          && module.type != Win32GUI
          && module.type != Win32SCR)
        {
-               // no implicit libraries
                return;
        }
 
-       links_to_crt = LinksToCrt ( module );
-
-       if ( !module.isDefaultEntryPoint )
+       if ( module.isDefaultEntryPoint )
        {
-               if ( module.GetEntryPoint(false) == "0" )
+               if ( module.IsDLL () )
                {
-                       if ( !links_to_crt )
-                       {
-                               pLibrary = new Library ( module, "mingw_common" );
-                               module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin() , pLibrary );
-
-                               pLibrary = new Library ( module, "msvcrt" );
-                               module.non_if_data.libraries.push_back ( pLibrary );
-                               links_to_crt = true;
-                       }
+                       //pLibrary = new Library ( module, "__mingw_dllmain" );
+                       //module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
+               }
+               else
+               {
+                       pLibrary = new Library ( module, module.isUnicode ? "mingw_wmain" : "mingw_main" );
+                       module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
                }
-               pLibrary = new Library ( module, "debugsup_ntdll" );
-               module.non_if_data.libraries.push_back(pLibrary);
-               return;
-       }
-
-       if ( module.IsDLL () )
-       {
-               //pLibrary = new Library ( module, "__mingw_dllmain" );
-               //module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
-       }
-       else
-       {
-               pLibrary = new Library ( module, module.isUnicode ? "mingw_wmain" : "mingw_main" );
-               module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
        }
 
        pLibrary = new Library ( module, "mingw_common" );
-       module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin() + 1, pLibrary );
+       module.non_if_data.libraries.push_back ( pLibrary );
 
-       if ( !links_to_crt )
-       {
-               // always link in msvcrt to get the basic routines
-               pLibrary = new Library ( module, "msvcrt" );
-               module.non_if_data.libraries.push_back ( pLibrary );
-       }
-
-       pLibrary = new Library ( module, "debugsup_ntdll" );
-       module.non_if_data.libraries.push_back(pLibrary);
+       MingwAddCRTLibrary ( module );
+       MingwAddDebugSupportLibraries ( module, DebugUserMode );
 }
 
 void
@@ -2654,7 +2644,7 @@ MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2662,7 +2652,7 @@ MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2695,7 +2685,7 @@ MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2703,7 +2693,7 @@ MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2743,7 +2733,7 @@ MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2751,7 +2741,7 @@ MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2791,7 +2781,7 @@ MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -2799,7 +2789,7 @@ MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=windows -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -2831,6 +2821,7 @@ MingwBootLoaderModuleHandler::Process ()
 void
 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
 {
+       fprintf ( fMakefile, "# BOOT LOADER MODULE TARGET\n" );
        string targetName ( module.output->name );
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ();
@@ -2839,7 +2830,6 @@ MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
                                module.name + ".junk.tmp" );
        CLEAN_FILE ( junk_tmp );
        string objectsMacro = GetObjectsMacro ( module );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
        string libsMacro = GetLibsMacro ();
 
        GenerateRules ();
@@ -2848,7 +2838,7 @@ MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
        fprintf ( fMakefile, "%s: %s %s | %s\n",
                  targetMacro.c_str (),
                  objectsMacro.c_str (),
-                 linkDepsMacro.c_str (),
+                 libsMacro.c_str (),
                  backend->GetFullPath ( *target_file ).c_str () );
 
        fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
@@ -2856,10 +2846,10 @@ MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
        if (Environment::GetArch() == "arm")
        {
                fprintf ( fMakefile,
-                        "\t${gcc} -Wl,--subsystem,native -Wl,--section-start,startup=0x8000 -o %s %s %s %s\n",
+                        "\t${gcc} -Wl,--subsystem,native -o %s %s %s %s\n",
                         backend->GetFullName ( junk_tmp ).c_str (),
                         objectsMacro.c_str (),
-                        linkDepsMacro.c_str (),
+                        libsMacro.c_str (),
                         GetLinkerMacro ().c_str ());
        }
        else
@@ -2868,7 +2858,7 @@ MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
                         "\t${gcc} -Wl,--subsystem,native -Wl,-Ttext,0x8000 -o %s %s %s %s\n",
                         backend->GetFullName ( junk_tmp ).c_str (),
                         objectsMacro.c_str (),
-                        linkDepsMacro.c_str (),
+                        libsMacro.c_str (),
                         GetLinkerMacro ().c_str ());
        }
        fprintf ( fMakefile,
@@ -2898,6 +2888,8 @@ MingwBootProgramModuleHandler::Process ()
 void
 MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
 {
+       fprintf ( fMakefile, "# BOOT PROGRAM MODULE TARGET\n" );
+
        string targetName ( module.output->name );
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ();
@@ -2914,7 +2906,6 @@ MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
        CLEAN_FILE ( junk_elf );
        CLEAN_FILE ( junk_cpy );
        string objectsMacro = GetObjectsMacro ( module );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
        string libsMacro = GetLibsMacro ();
        const Module *payload = module.project.LocateModule ( module.payload );
 
@@ -2924,7 +2915,7 @@ MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
        fprintf ( fMakefile, "%s: %s %s %s | %s\n",
                  targetMacro.c_str (),
                  objectsMacro.c_str (),
-                 linkDepsMacro.c_str (),
+                 libsMacro.c_str (),
                  payload->name.c_str (),
                  backend->GetFullPath ( *target_file ).c_str () );
 
@@ -2940,9 +2931,9 @@ MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
                backend->GetFullName ( junk_cpy ).c_str (),
                backend->GetFullName ( junk_tmp ).c_str () );
 
-       fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -g -o %s\n",
+       fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -o %s\n",
                module.buildtype.c_str (),
-               linkDepsMacro.c_str (),
+               libsMacro.c_str (),
                backend->GetFullName ( junk_tmp ).c_str (),
                backend->GetFullName ( junk_elf ).c_str () );
 
@@ -2976,7 +2967,8 @@ MingwIsoModuleHandler::Process ()
 
 void
 MingwIsoModuleHandler::OutputBootstrapfileCopyCommands (
-       const string& bootcdDirectory )
+       const string& bootcdDirectory,
+       vector<FileLocation>& destinations )
 {
        for ( std::map<std::string, Module*>::const_iterator p = module.project.modules.begin (); p != module.project.modules.end (); ++ p )
        {
@@ -2990,14 +2982,16 @@ MingwIsoModuleHandler::OutputBootstrapfileCopyCommands (
                                                           ? bootcdDirectory + sSep + m.bootstrap->base
                                                           : bootcdDirectory,
                                                  m.bootstrap->nameoncd );
-                       OutputCopyCommand ( *m.output, targetFile );
+                       OutputCopyCommandSingle ( *m.output, targetFile );
+                       destinations.push_back ( targetFile );
                }
        }
 }
 
 void
 MingwIsoModuleHandler::OutputCdfileCopyCommands (
-       const string& bootcdDirectory )
+       const string& bootcdDirectory,
+       std::vector<FileLocation>& destinations )
 {
        for ( size_t i = 0; i < module.project.cdfiles.size (); i++ )
        {
@@ -3007,7 +3001,19 @@ MingwIsoModuleHandler::OutputCdfileCopyCommands (
                                              ? bootcdDirectory + sSep + cdfile.target->relative_path
                                              : bootcdDirectory,
                                          cdfile.target->name );
-               OutputCopyCommand ( *cdfile.source, targetFile );
+               OutputCopyCommandSingle ( *cdfile.source, targetFile );
+               destinations.push_back ( targetFile );
+       }
+       for ( size_t i = 0; i < module.cdfiles.size (); i++ )
+       {
+               const CDFile& cdfile = *module.cdfiles[i];
+               FileLocation targetFile ( OutputDirectory,
+                                         cdfile.target->relative_path.length () > 0
+                                             ? bootcdDirectory + sSep + cdfile.target->relative_path
+                                             : bootcdDirectory,
+                                         cdfile.target->name );
+               OutputCopyCommandSingle ( *cdfile.source, targetFile );
+               destinations.push_back ( targetFile );
        }
 }
 
@@ -3094,25 +3100,14 @@ MingwIsoModuleHandler::GetCdFiles (
 void
 MingwIsoModuleHandler::GenerateIsoModuleTarget ()
 {
-       string bootcdDirectory = "cd";
+       fprintf ( fMakefile, "# ISO MODULE TARGET\n" );
+       string bootcdDirectory = module.name;
        FileLocation bootcd ( OutputDirectory,
                              bootcdDirectory,
                              "" );
        FileLocation bootcdReactos ( OutputDirectory,
                                     bootcdDirectory + sSep + Environment::GetCdOutputPath (),
                                     "" );
-       vector<FileLocation> vSourceFiles, vCdFiles;
-       vector<FileLocation> vCdDirectories;
-
-       // unattend.inf
-       FileLocation srcunattend ( SourceDirectory,
-                                  "boot" + sSep + "bootdata" + sSep + "bootcdregtest",
-                                  "unattend.inf" );
-       FileLocation tarunattend ( bootcdReactos.directory,
-                                  bootcdReactos.relative_path,
-                                  "unattend.inf" );
-       if (module.type == IsoRegTest)
-               vSourceFiles.push_back ( srcunattend );
 
        // bootsector
        const Module* bootModule = module.bootSector->bootSectorModule;
@@ -3126,7 +3121,6 @@ MingwIsoModuleHandler::GenerateIsoModuleTarget ()
        }
 
        const FileLocation *isoboot = bootModule->output;
-       vSourceFiles.push_back ( *isoboot );
 
        // prepare reactos.dff and reactos.inf
        FileLocation reactosDff ( SourceDirectory,
@@ -3136,31 +3130,18 @@ MingwIsoModuleHandler::GenerateIsoModuleTarget ()
                                  bootcdReactos.relative_path,
                                  "reactos.inf" );
 
-       vSourceFiles.push_back ( reactosDff );
-
        /*
                We use only the name and not full FileLocation(ouput) because Iso/LiveIso are an exception to the general rule.
                Iso/LiveIso outputs are generated in code base root
        */
        string IsoName = module.output->name;
 
-       string sourceFiles = v2s ( backend, vSourceFiles, 5 );
-
-       // fill cdrom
-       GetCdDirectories ( vCdDirectories, bootcdDirectory );
-       GetCdFiles ( vCdFiles );
-       string cdDirectories = "";//v2s ( vCdDirectories, 5 );
-       string cdFiles = v2s ( backend, vCdFiles, 5 );
-
-       fprintf ( fMakefile, ".PHONY: %s\n\n",
-                 module.name.c_str ());
-       fprintf ( fMakefile,
-                 "%s: all %s %s %s $(CABMAN_TARGET) $(CDMAKE_TARGET) %s\n",
+       fprintf ( fMakefile, ".PHONY: %s_CABINET\n\n",
+                 module.name.c_str () );
+       fprintf ( fMakefile, "%s_CABINET: all $(CABMAN_TARGET) %s | %s\n",
                  module.name.c_str (),
-                 backend->GetFullName ( *isoboot ).c_str (),
-                 sourceFiles.c_str (),
-                 cdFiles.c_str (),
-                 cdDirectories.c_str () );
+                 backend->GetFullName ( reactosDff ).c_str (),
+                 backend->GetFullPath ( bootcdReactos ).c_str () );
        fprintf ( fMakefile,
                  "\t$(Q)$(CABMAN_TARGET) -C %s -L %s -I -P $(OUTPUT)\n",
                  backend->GetFullName ( reactosDff ).c_str (),
@@ -3171,13 +3152,29 @@ MingwIsoModuleHandler::GenerateIsoModuleTarget ()
                  backend->GetFullName ( reactosInf ).c_str (),
                  backend->GetFullPath ( bootcdReactos ).c_str ());
        fprintf ( fMakefile,
-                 "\t-@${rm} %s 2>$(NUL)\n",
+                 "\t-@${rm} %s 2>$(NUL)\n\n",
                  backend->GetFullName ( reactosInf ).c_str () );
-       OutputBootstrapfileCopyCommands ( bootcdDirectory );
-       OutputCdfileCopyCommands ( bootcdDirectory );
 
-       if (module.type == IsoRegTest)
-               OutputCopyCommand ( srcunattend, tarunattend );
+       std::vector<FileLocation> sourceFiles;
+       OutputBootstrapfileCopyCommands ( bootcdDirectory, sourceFiles );
+       OutputCdfileCopyCommands ( bootcdDirectory, sourceFiles );
+
+       fprintf( fMakefile,
+                "\n%s_OBJS := %s\n\n",
+                module.name.c_str (),
+                v2s ( backend, sourceFiles, 5 ).c_str () );
+
+       fprintf ( fMakefile, ".PHONY: %s\n\n",
+                 module.name.c_str ());
+       fprintf ( fMakefile,
+                 "%s: $(%s_OBJS) %s_CABINET %s $(CDMAKE_TARGET) | %s\n",
+                 module.name.c_str (),
+                 module.name.c_str (),
+                 module.name.c_str (),
+                 backend->GetFullName ( *isoboot ).c_str (),
+                 backend->GetFullPath ( FileLocation ( OutputDirectory,
+                                                       bootcdDirectory,
+                                                       "" ) ).c_str () );
 
        fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
        fprintf ( fMakefile,
@@ -3214,7 +3211,8 @@ MingwLiveIsoModuleHandler::CreateDirectory ( const string& directory )
 
 void
 MingwLiveIsoModuleHandler::OutputModuleCopyCommands ( string& livecdDirectory,
-                                                      string& reactosDirectory )
+                                                      string& reactosDirectory,
+                                                      std::vector<FileLocation>& destinations )
 {
        for ( std::map<std::string, Module*>::const_iterator p = module.project.modules.begin (); p != module.project.modules.end (); ++ p )
        {
@@ -3229,15 +3227,17 @@ MingwLiveIsoModuleHandler::OutputModuleCopyCommands ( string& livecdDirectory,
                                                       ? livecdDirectory + sSep + reactosDirectory + sSep + m.install->relative_path
                                                       : livecdDirectory + sSep + reactosDirectory,
                                                   m.install->name );
-                       OutputCopyCommand ( *aliasedModule.output,
-                                           destination);
+                       OutputCopyCommandSingle ( *aliasedModule.output,
+                                                 destination);
+                       destinations.push_back ( destination );
                }
        }
 }
 
 void
 MingwLiveIsoModuleHandler::OutputNonModuleCopyCommands ( string& livecdDirectory,
-                                                         string& reactosDirectory )
+                                                         string& reactosDirectory,
+                                                         std::vector<FileLocation>& destinations )
 {
        for ( size_t i = 0; i < module.project.installfiles.size (); i++ )
        {
@@ -3247,12 +3247,14 @@ MingwLiveIsoModuleHandler::OutputNonModuleCopyCommands ( string& livecdDirectory
                                          ? livecdDirectory + sSep + reactosDirectory + sSep + installfile.target->relative_path
                                          : livecdDirectory + sSep + reactosDirectory,
                                      installfile.target->name );
-               OutputCopyCommand ( *installfile.source, target );
+               OutputCopyCommandSingle ( *installfile.source, target );
+               destinations.push_back ( target );
        }
 }
 
 void
-MingwLiveIsoModuleHandler::OutputProfilesDirectoryCommands ( string& livecdDirectory )
+MingwLiveIsoModuleHandler::OutputProfilesDirectoryCommands ( string& livecdDirectory,
+                                                             vector<FileLocation>& destinations )
 {
        CreateDirectory ( livecdDirectory + sSep + "Profiles" );
        CreateDirectory ( livecdDirectory + sSep + "Profiles" + sSep + "All Users") ;
@@ -3267,12 +3269,14 @@ MingwLiveIsoModuleHandler::OutputProfilesDirectoryCommands ( string& livecdDirec
        FileLocation destination ( OutputDirectory,
                                   livecdDirectory,
                                   "freeldr.ini" );
-       OutputCopyCommand ( livecdIni,
-                           destination );
+       OutputCopyCommandSingle ( livecdIni,
+                                 destination );
+       destinations.push_back ( destination );
 }
 
 void
-MingwLiveIsoModuleHandler::OutputLoaderCommands ( string& livecdDirectory )
+MingwLiveIsoModuleHandler::OutputLoaderCommands ( string& livecdDirectory,
+                                                  std::vector<FileLocation>& destinations )
 {
        FileLocation freeldr ( OutputDirectory,
                               "boot" + sSep + "freeldr" + sSep + "freeldr",
@@ -3280,13 +3284,15 @@ MingwLiveIsoModuleHandler::OutputLoaderCommands ( string& livecdDirectory )
        FileLocation destination ( OutputDirectory,
                                   livecdDirectory + sSep + "loader",
                                   "setupldr.sys" );
-       OutputCopyCommand ( freeldr,
-                           destination );
+       OutputCopyCommandSingle ( freeldr,
+                                 destination );
+       destinations.push_back ( destination );
 }
 
 void
 MingwLiveIsoModuleHandler::OutputRegistryCommands ( string& livecdDirectory )
 {
+       fprintf ( fMakefile, "# REGISTRY COMMANDS\n" );
        FileLocation reactosSystem32ConfigDirectory ( OutputDirectory,
                                                      livecdDirectory + sSep + "reactos" + sSep + "system32" + sSep + "config",
                                                      "" );
@@ -3301,6 +3307,7 @@ MingwLiveIsoModuleHandler::OutputRegistryCommands ( string& livecdDirectory )
 void
 MingwLiveIsoModuleHandler::GenerateLiveIsoModuleTarget ()
 {
+       fprintf ( fMakefile, "# LIVE ISO MODULE TARGET\n" );
        string livecdDirectory = module.name;
        FileLocation livecd ( OutputDirectory, livecdDirectory, "" );
 
@@ -3332,19 +3339,31 @@ MingwLiveIsoModuleHandler::GenerateLiveIsoModuleTarget ()
                                     "" );
        CLEAN_FILE ( livecdReactos );
 
+       std::vector<FileLocation> sourceFiles;
+       OutputModuleCopyCommands ( livecdDirectory,
+                                  reactosDirectory,
+                                  sourceFiles );
+       OutputNonModuleCopyCommands ( livecdDirectory,
+                                     reactosDirectory,
+                                     sourceFiles );
+       OutputProfilesDirectoryCommands ( livecdDirectory, sourceFiles );
+       OutputLoaderCommands ( livecdDirectory, sourceFiles );
+
+       fprintf( fMakefile,
+                "\n%s_OBJS := %s\n\n",
+                module.name.c_str (),
+                v2s ( backend, sourceFiles, 5 ).c_str () );
+
        fprintf ( fMakefile, ".PHONY: %s\n\n",
                  module.name.c_str ());
        fprintf ( fMakefile,
-                 "%s: all %s %s $(MKHIVE_TARGET) $(CDMAKE_TARGET)\n",
+                 "%s : $(%s_OBJS) %s %s $(MKHIVE_TARGET) $(CDMAKE_TARGET)\n",
+                 module.name.c_str (),
                  module.name.c_str (),
                  backend->GetFullName ( *isoboot) .c_str (),
-                 backend->GetFullPath ( livecdReactos ).c_str () );
-       OutputModuleCopyCommands ( livecdDirectory,
-                                  reactosDirectory );
-       OutputNonModuleCopyCommands ( livecdDirectory,
-                                     reactosDirectory );
-       OutputProfilesDirectoryCommands ( livecdDirectory );
-       OutputLoaderCommands ( livecdDirectory );
+                 backend->GetFullPath ( FileLocation ( OutputDirectory,
+                                                       livecdDirectory,
+                                                       "" ) ).c_str () );
        OutputRegistryCommands ( livecdDirectory );
        fprintf ( fMakefile, "\t$(ECHO_CDMAKE)\n" );
        fprintf ( fMakefile,
@@ -3384,7 +3403,7 @@ MingwTestModuleHandler::GenerateTestModuleTarget ()
 {
        string targetMacro ( GetTargetMacro ( module ) );
        string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateImportLibraryTargetIfNeeded ();
 
@@ -3392,7 +3411,7 @@ MingwTestModuleHandler::GenerateTestModuleTarget ()
        {
                GenerateRules ();
 
-               string dependencies = linkDepsMacro + " " + objectsMacro;
+               string dependencies = libsMacro + " " + objectsMacro;
 
                string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
                                                     module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
@@ -3431,6 +3450,7 @@ MingwCabinetModuleHandler::MingwCabinetModuleHandler (
 void
 MingwCabinetModuleHandler::Process ()
 {
+       fprintf ( fMakefile, "# CABINET MODULE TARGET\n" );
        string targetMacro ( GetTargetMacro (module) );
 
        GenerateRules ();
@@ -3461,25 +3481,28 @@ MingwElfExecutableModuleHandler::Process ()
        string targetMacro ( GetTargetMacro (module) );
        string workingDirectory = GetWorkingDirectory ();
        string objectsMacro = GetObjectsMacro ( module );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
        string libsMacro = GetLibsMacro ();
+       string debugFormat = GetDebugFormat ();
 
+       fprintf ( fMakefile, "# ELF EXECUTABLE TARGET\n" );
        GenerateRules ();
 
        const FileLocation *target_file = GetTargetFilename ( module, NULL );
        fprintf ( fMakefile, "%s: %s %s | %s\n",
                  targetMacro.c_str (),
                  objectsMacro.c_str (),
-                 linkDepsMacro.c_str (),
+                 libsMacro.c_str (),
                  backend->GetFullPath ( *target_file ).c_str () );
 
        fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
 
-       fprintf ( fMakefile, "\t${gcc} $(%s_LINKFORMAT) %s %s -g -o %s\n",
+       fprintf ( fMakefile, "\t${gcc} $(%s_LINKFORMAT) %s %s -g%s -o %s\n",
                  module.buildtype.c_str(),
                  objectsMacro.c_str(),
                  libsMacro.c_str(),
+                 debugFormat.c_str(),
                  targetMacro.c_str () );
 
        delete target_file;
+       fprintf ( fMakefile, "#/ELF EXECUTABLE TARGET\n" );
 }