[RBUILD]
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index e43e03b..fe0a268 100644 (file)
@@ -12,9 +12,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 #include "../../pch.h"
 #include <assert.h>
@@ -63,7 +63,6 @@ string
 GetTargetMacro ( const Module& module, bool with_dollar )
 {
        string s ( module.name );
-       strupr ( &s[0] );
        s += "_TARGET";
        if ( with_dollar )
                return ssprintf ( "$(%s)", s.c_str() );
@@ -145,9 +144,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 +186,7 @@ MingwModuleHandler::InstanciateHandler (
                case RpcProxy:
                case MessageHeader:
                case IdlHeader:
+               case IdlInterface:
                case EmbeddedTypeLib:
                case BootSector:
                        handler = new MingwModuleHandler( module );
@@ -219,12 +233,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;
@@ -282,9 +290,7 @@ MingwModuleHandler::GetModuleArchiveFilename () const
 {
        if ( IsStaticLibrary ( module ) )
                return GetTargetFilename ( module, NULL );
-       return new FileLocation ( IntermediateDirectory,
-                                 module.output->relative_path,
-                                 ReplaceExtension ( module.name, ".temp.a" ) );
+       return NULL;
 }
 
 /*static*/ bool
@@ -301,6 +307,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;
@@ -319,9 +327,26 @@ MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
                  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,
+                 "\t${cp} %s %s 1>$(NUL)\n",
+                 backend->GetFullName ( source ).c_str (),
+                 backend->GetFullName ( *PassThruCacheDirectory ( &destination ) ).c_str () );
+}
+
 string
 MingwModuleHandler::GetImportLibraryDependency (
-       const Module& importedModule )
+       const Module& importedModule,
+       bool delayimp )
 {
        string dep;
        if ( ReferenceObjects ( importedModule ) )
@@ -343,7 +368,7 @@ 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;
        }
@@ -355,7 +380,7 @@ MingwModuleHandler::GetImportLibraryDependency (
                for ( size_t i = 0; i < libraries.size (); ++ i )
                {
                        dep += " ";
-                       dep += GetImportLibraryDependency ( *libraries[i]->importedModule );
+                       dep += GetImportLibraryDependency ( *libraries[i]->importedModule, libraries[i]->delayimp );
                }
        }
 
@@ -375,7 +400,7 @@ MingwModuleHandler::GetTargets ( const Module& dependencyModule,
                }
        }
        else
-               targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
+               targets.push_back ( GetImportLibraryDependency ( dependencyModule, false ) );
 }
 
 void
@@ -428,6 +453,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";
        }
@@ -489,6 +516,9 @@ MingwModuleHandler::GenerateCleanTarget () const
        }
        fprintf ( fMakefile, " 2>$(NUL)\n" );
 
+       // Clean files generated by external rules
+       fprintf ( fMakefile, "\t-@${rm} $(%s_CLEANFILES) 2>$(NUL)\n", module.name.c_str() );
+
        if( ProxyMakefile::GenerateProxyMakefile(module) )
        {
                DirectoryLocation root;
@@ -538,6 +568,69 @@ MingwModuleHandler::GenerateDependsTarget () const
                  module.name.c_str () );
 }
 
+static
+const char * const CompilerPrefixTable [ CompilerTypesCount ] =
+{
+       "C",
+       "CXX",
+       "CPP",
+       "AS",
+       "MIDL",
+       "RC",
+       "NASM",
+};
+
+/* static */ void
+MingwModuleHandler::GenerateParameters (
+       const char* prefix,
+       const char* assignmentOperation,
+       const IfableData& data )
+{
+       for ( unsigned type = CompilerTypeCC; type < CompilerTypesCount; ++ type )
+       {
+               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 () );
+               }
+       }
+}
+
 /* static */ string
 MingwModuleHandler::GenerateGccDefineParametersFromVector (
        const vector<Define*>& defines,
@@ -550,24 +643,69 @@ 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;
 }
 
+/* static */ string
+MingwModuleHandler::GenerateDefineParametersFromVector (
+       const std::vector<Define*>& defines,
+       CompilerType compiler )
+{
+       string parameters;
+
+       for ( size_t i = 0; i < defines.size (); i++ )
+       {
+               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;
+}
+
 string
 MingwModuleHandler::ConcatenatePaths (
        const string& path1,
@@ -582,27 +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 );
+               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;
@@ -634,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;
 }
@@ -645,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,
@@ -750,18 +789,6 @@ MingwModuleHandler::GenerateMacros (
        const vector<LinkerFlag*>* linkerFlags,
        set<const Define *>& used_defs )
 {
-       fprintf ( fMakefile, "# MACROS\n" );
-       GenerateMacro ( assignmentOperation,
-                       commonflagsMacro,
-                       data,
-                       &used_defs,
-                       true );
-       GenerateMacro ( assignmentOperation,
-                       windresflagsMacro,
-                       data,
-                       NULL,
-                       false );
-
        if ( linkerFlags != NULL )
        {
                string linkerParameters = GenerateLinkerParametersFromVector ( *linkerFlags );
@@ -825,7 +852,6 @@ MingwModuleHandler::GenerateSourceMacros (
 {
        size_t i;
 
-       fprintf ( fMakefile, "# SOURCE MACROS\n" );
        const vector<CompilationUnit*>& compilationUnits = data.compilationUnits;
        vector<const FileLocation *> headers;
        if ( compilationUnits.size () > 0 )
@@ -872,7 +898,6 @@ MingwModuleHandler::GenerateObjectMacros (
        vector<const FileLocation *> headers;
        vector<const FileLocation *> mcheaders;
        vector<const FileLocation *> mcresources;
-       fprintf ( fMakefile, "# OBJECT MACROS\n" );
        if ( compilationUnits.size () > 0 )
        {
                for ( i = 0; i < compilationUnits.size (); i++ )
@@ -996,7 +1021,7 @@ MingwModuleHandler::GenerateObjectMacros (
        }
        CleanupCompilationUnitVector ( sourceCompilationUnits );
 
-       if ( IsSpecDefinitionFile() )
+       if ( module.IsSpecDefinitionFile() )
        {
                const FileLocation *stubs_file = new FileLocation(
                        IntermediateDirectory,
@@ -1038,7 +1063,16 @@ MingwModuleHandler::GetDlldataFilename() const
        return new FileLocation( IntermediateDirectory, dlldata_path, module.name + ".dlldata.c" );
 }
 
-/* caller needs to delete the returned object */
+const FileLocation*
+MingwModuleHandler::GetPrecompiledHeaderPath () const
+{
+       if ( !module.pch || !use_pch )
+               return NULL;
+       return new FileLocation ( IntermediateDirectory,
+                                 module.pch->file->relative_path,
+                                 ".gch_" + module.name );
+}
+
 const FileLocation*
 MingwModuleHandler::GetPrecompiledHeaderFilename () const
 {
@@ -1049,153 +1083,97 @@ MingwModuleHandler::GetPrecompiledHeaderFilename () const
                                  module.pch->file->name + ".gch" );
 }
 
-Rule arRule1 ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).a: $($(module_name)_OBJS) $(dependencies) | $(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 winebuildPDefRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec: $(source)$(dependencies) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                         "\t$(ECHO_CPP)\n"
-                         "\t${gcc} -xc -E ${$(module_name)_RCFLAGS} $(source) > $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec\n\n"
-                                                "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.def: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec $(WINEBUILD_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                         "\t$(ECHO_WINEBLD)\n"
-                         "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.def --def -E $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec --filename $(module_dllname)\n\n",
-                         "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec",
-                         "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.def",
-                         "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule winebuildPRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.c: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec $(WINEBUILD_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                      "\t$(ECHO_WINEBLD)\n"
-                      "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $@ --pedll $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).spec --filename $(module_dllname)\n\n"
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.o: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.c | $(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).spec",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.c",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.o",
-                      "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule winebuildDefRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.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)_$(module_name).auto.def --def -E $(source) --filename $(module_dllname)\n\n",
-                        "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).spec",
-                        "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).auto.def",
-                        "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)", NULL );
-Rule winebuildRule ( "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.c: $(source_path)$(SEP)$(source_name_noext).spec $(WINEBUILD_TARGET)\n"
-                     "\t$(ECHO_WINEBLD)\n"
-                     "\t$(Q)$(WINEBUILD_TARGET) $(WINEBUILD_FLAGS) -o $@ --pedll $(source_path)$(SEP)$(source_name_noext).spec --filename $(module_dllname)\n"
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).stubs.o: $(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).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)_$(module_name).stubs.c",
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).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) -fno-unit-at-a-time -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) -fno-unit-at-a-time -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) -fno-unit-at-a-time -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 widlDlldataRule ( "$(source): $(dependencies) ${$(module_name)_precondition} $(WIDL_TARGET) | $(INTERMEDIATE)$(SEP)$(source_dir)\n"
-                     "\t$(ECHO_WIDL)\n"
-                     "\t$(Q)$(WIDL_TARGET) $($(module_name)_WIDLFLAGS) --dlldata-only --dlldata=$(source) $(bare_dependencies)\n"
-                     "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext).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).o", 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_HOSTCC)\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)_CXXFLAGS)$(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_HOSTCC)\n"
-                   "\t${host_gpp} -o $@ $($(module_name)_CXXFLAGS)$(compiler_flags) -c $<\n",
-                   "$(INTERMEDIATE)$(SEP)$(source_dir)$(SEP)$(source_name_noext)_$(module_name).o", NULL );
+
 Rule emptyRule ( "", NULL );
 
 void
@@ -1207,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 );
@@ -1226,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
@@ -1304,6 +1275,7 @@ MingwModuleHandler::GenerateCommands (
                { 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 },
@@ -1319,8 +1291,6 @@ MingwModuleHandler::GenerateCommands (
        size_t i;
        Rule *customRule = NULL;
 
-       fprintf ( fMakefile, "# COMMANDS\n" );
-
        for ( i = 0; i < sizeof ( rules ) / sizeof ( rules[0] ); i++ )
        {
                if ( rules[i].host != HostDontCare && rules[i].host != ModuleHandlerInformations[module.type].DefaultHost )
@@ -1390,25 +1360,6 @@ MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget )
                  "endif\n" );
 }
 
-void
-MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
-{
-       fprintf ( fMakefile, "# BUILD NO STRIP CODE\n" );
-
-       fprintf ( fMakefile,
-                 "ifeq ($(ROS_BUILDNOSTRIP),yes)\n" );
-
-       FileLocation nostripFilename ( OutputDirectory,
-                                      module.output->relative_path,
-                                      GetBasename ( module.output->name ) + ".nostrip" + GetExtension ( *module.output ) );
-       CLEAN_FILE ( nostripFilename );
-
-       OutputCopyCommand ( *module.output, nostripFilename );
-
-       fprintf ( fMakefile,
-                 "endif\n" );
-}
-
 void
 MergeStringVector ( const Backend* backend,
                     const vector<FileLocation>& input,
@@ -1469,158 +1420,61 @@ MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
 }
 
 void
-MingwModuleHandler::GenerateRunRsymCode () const
-{
-       fprintf ( fMakefile, "# RUN RSYM CODE\n" );
-       fprintf ( fMakefile,
-             "ifneq ($(ROS_GENERATE_RSYM),no)\n" );
-       fprintf ( fMakefile,
-                 "\t$(ECHO_RSYM)\n" );
-       fprintf ( fMakefile,
-                 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
-       fprintf ( fMakefile,
-             "endif\n" );
-}
-
-void
-MingwModuleHandler::GenerateRunStripCode () const
+MingwModuleHandler::GenerateLinkerCommand () const
 {
-       fprintf ( fMakefile, "# RUN STRIP CODE\n" );
-       fprintf ( fMakefile,
-                 "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
-       fprintf ( fMakefile,
-                 "\t$(ECHO_STRIP)\n" );
-       fprintf ( fMakefile,
-                 "\t${strip} -s -x -X $@\n\n" );
-       fprintf ( fMakefile,
-                 "endif\n" );
-}
+       string definitionFilename;
+       
+       const FileLocation *DefinitionFilename = GetDefinitionFilename ();
 
-void
-MingwModuleHandler::GenerateLinkerCommand (
-       const string& dependencies,
-       const string& linkerParameters,
-       const string& pefixupParameters )
-{
-       const FileLocation *target_file = GetTargetFilename ( module, NULL );
-       const FileLocation *definitionFilename = GetDefinitionFilename ();
-       string linker = "${ld}";
-       string objectsMacro = GetObjectsMacro ( module );
-       string libsMacro = GetLibsMacro ();
-
-       fprintf ( fMakefile, "# LINKER COMMAND\n" );
-
-       string target_macro ( GetTargetMacro ( module ) );
-       string target_folder ( backend->GetFullPath ( *target_file ) );
+       if ( DefinitionFilename ) {
+               definitionFilename = backend->GetFullName (*DefinitionFilename);
+               delete DefinitionFilename;
+       }
 
        string linkerScriptArgument;
-       if ( module.linkerScript != NULL )
-               linkerScriptArgument = ssprintf ( " -T %s", backend->GetFullName ( *module.linkerScript->file ).c_str () );
-       else
-               linkerScriptArgument = "";
-
-       /* check if we need to add default C++ libraries, ie if we have
-        * a C++ user-mode module without the -nostdlib linker flag
-        */
-       bool link_defaultlibs = module.cplusplus &&
-                               linkerParameters.find ("-nostdlib") == string::npos &&
-                               !(module.type == KernelModeDLL || module.type == KernelModeDriver);
-
-       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 (),
-                         linkerParameters.c_str (),
-                         linkerScriptArgument.c_str (),
-                         objectsMacro.c_str (),
-                         link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "",
-                         libsMacro.c_str (),
-                         GetLinkerMacro ().c_str (),
-                         target_macro.c_str () );
+       if ( module.linkerScript != NULL ) {
+               if ( module.project.configuration.Linker == GnuLd )
+                       linkerScriptArgument = ssprintf ( " -T %s", backend->GetFullName ( *module.linkerScript->file ).c_str () );
+               else
+                       fprintf ( stderr,
+                                         "Linker doesn't support linker scripts: linker script %s ignored for module %s\n",
+                                         backend->GetFullName ( *module.linkerScript->file ).c_str (),
+                                         module.name.c_str() );
        }
-       else
-       {
-               FileLocation temp_exp ( IntermediateDirectory,
-                                       module.output->relative_path,
-                                       module.name + ".exp" );
-               CLEAN_FILE ( temp_exp );
 
-               fprintf ( fMakefile,
-                       "%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 () : "",
-                         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",
-
-                         linker.c_str (),
-                         linkerParameters.c_str (),
-                         linkerScriptArgument.c_str (),
-                         backend->GetFullName ( temp_exp ).c_str (),
-                         objectsMacro.c_str (),
-                         link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "",
-                         libsMacro.c_str (),
-                         GetLinkerMacro ().c_str (),
-                         target_macro.c_str () );
+       string extraLibraries;
+       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse ) {
+               if ( module.cplusplus ) {
+                       switch ( module.type )
+                       {
+                       case Win32DLL:
+                       case Win32OCX:
+                       case Win32CUI:
+                       case Win32GUI:
+                       case Win32SCR:
+                               extraLibraries = "$$(PROJECT_CXXLIBS)";
+                               break;
 
-               fprintf ( fMakefile,
-                         "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n",
-                         target_macro.c_str (),
-                         pefixupParameters.c_str() );
+                       default:
+                               extraLibraries = "$$(PROJECT_CCLIBS)";
+                               break;
+                       }
+               } else
+                       extraLibraries = "$$(PROJECT_CCLIBS)";
        }
 
-       GenerateBuildMapCode ();
-       GenerateBuildNonSymbolStrippedCode ();
-       GenerateRunRsymCode ();
-       GenerateRunStripCode ();
-       GenerateCleanObjectsAsYouGoCode ();
-
-       if ( definitionFilename )
-               delete definitionFilename;
-       delete target_file;
-}
-
-void
-MingwModuleHandler::GeneratePhonyTarget() const
-{
-       string targetMacro ( GetTargetMacro ( module ) );
-       const FileLocation *target_file = GetTargetFilename ( module, NULL );
+       delete PassThruCacheDirectory ( new FileLocation ( module.output->directory, module.output->relative_path, "" ) );
+       delete PassThruCacheDirectory ( new FileLocation ( IntermediateDirectory, module.output->relative_path, "" ) );
 
-       fprintf ( fMakefile, "# PHONY TARGET\n" );
        fprintf ( fMakefile,
-                 ".PHONY: %s\n\n",
-                 targetMacro.c_str ());
-       fprintf ( fMakefile, "%s: | %s\n",
-                 targetMacro.c_str (),
-                 backend->GetFullPath ( *target_file ).c_str () );
-
-       delete target_file;
+                         "$(eval $(call RBUILD_LINK_RULE,%s,%s,%s,%s,%s,%s,%s))\n",
+                         module.name.c_str(),
+                         definitionFilename.c_str(),
+                         module.xmlbuildFile.c_str(),
+                         linkerScriptArgument.c_str(),
+                         extraLibraries.c_str(),
+                         module.GetEntryPoint().c_str(),
+                         module.baseaddress.c_str() );
 }
 
 void
@@ -1629,8 +1483,6 @@ 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++ )
        {
@@ -1648,8 +1500,6 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
        {
                GenerateCommands ( *compilationUnits[i],
                                   moduleDependencies );
-               fprintf ( fMakefile,
-                         "\n" );
        }
 
        vector<CompilationUnit*> sourceCompilationUnits;
@@ -1661,20 +1511,6 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
        }
        CleanupCompilationUnitVector ( sourceCompilationUnits );
 
-       SpecFileType spec = IsSpecDefinitionFile ();
-
-       if ( spec )
-       {
-               Rule * defRule;
-
-               if (spec == PSpec)
-                       defRule = &winebuildPRule;
-               else
-                       defRule = &winebuildRule;
-
-               defRule->Execute ( fMakefile, backend, module, module.importLibrary->source, clean_files );
-       }
-
        if ( module.type == RpcProxy )
        {
                widlDlldataRule.Execute ( fMakefile,
@@ -1689,42 +1525,25 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
 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 %s -gstabs+ -x %s %s\n\n",
-                         cc.c_str(),
-                         backend->GetFullName ( *pchFilename ).c_str(),
-                         module.cplusplus ? cxxflagsMacro.c_str() : cflagsMacro.c_str(),
-                                 GenerateCompilerParametersFromVector ( module.non_if_data.compilerFlags, module.cplusplus ? CompilerTypeCPP : CompilerTypeCC ).c_str(),
-                                 module.cplusplus ? "c++-header" : "c-header",
-                         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 );
        }
 
        GenerateObjectFileTargets ( module.non_if_data );
-       fprintf ( fMakefile, "\n" );
 }
 
 /* caller needs to delete the returned object */
@@ -1732,6 +1551,10 @@ const FileLocation*
 MingwModuleHandler::GenerateArchiveTarget ()
 {
        const FileLocation *archiveFilename = GetModuleArchiveFilename ();
+
+       if ( archiveFilename == NULL )
+               return NULL;
+
        const FileLocation *definitionFilename = GetDefinitionFilename ();
 
        fprintf ( fMakefile, "# ARCHIVE TARGET\n" );
@@ -1746,11 +1569,8 @@ MingwModuleHandler::GenerateArchiveTarget ()
                                                  backend->GetFullName ( *definitionFilename ).c_str () );
 
                fprintf ( fMakefile,
-                         "\t${dlltool} --dllname %s --def %s --output-lib $@%s%s\n",
-                         module.GetDllName ().c_str (),
-                         backend->GetFullName ( *definitionFilename ).c_str (),
-                         module.mangledSymbols ? "" : " --kill-at",
-                         module.underscoreSymbols ? " --add-underscore" : "" );
+                         "\t${dlltool} --def %s --kill-at --output-lib $@\n",
+                         backend->GetFullName ( *definitionFilename ).c_str () );
        }
        else
                arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files );
@@ -1777,12 +1597,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
 {
@@ -1792,10 +1606,20 @@ MingwModuleHandler::GetLibsMacro () const
 string
 MingwModuleHandler::GetLinkerMacro () const
 {
-       return ssprintf ( "$(%s_LFLAGS)",
+       return ssprintf ( "$(%s_LDFLAGS)",
                          module.name.c_str () );
 }
 
+string
+MingwModuleHandler::GetDebugFormat ()
+{
+    if (Environment::GetArch() == "amd64")
+    {
+        return "dwarf-2";
+    }
+    return "stabs+";
+}
+
 string
 MingwModuleHandler::GetModuleTargets ( const Module& module )
 {
@@ -1815,7 +1639,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 ());
@@ -1835,7 +1660,6 @@ MingwModuleHandler::GenerateObjectMacro ()
 void
 MingwModuleHandler::GenerateTargetMacro ()
 {
-       fprintf ( fMakefile, "# TARGET MACRO\n" );
        fprintf ( fMakefile,
                "%s := %s\n",
                GetTargetMacro ( module, false ).c_str (),
@@ -1882,199 +1706,83 @@ MingwModuleHandler::GetRpcHeaderDependencies (
                                        }
                                        if ( library.importedModule->type == IdlHeader )
                                        {
-                                               const FileLocation *header = GetIdlHeaderFilename ( &sourceFile );
-                                               dependencies.push_back ( *header );
-                                               delete header;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-void
-MingwModuleHandler::GenerateOtherMacros ()
-{
-       set<const Define *> used_defs;
-
-       fprintf ( fMakefile, "# OTHER MACROS\n" );
-
-       commonflagsMacro = ssprintf ("%s_COMMONFLAGS", module.name.c_str ());
-       cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());
-       cxxflagsMacro = ssprintf ("%s_CXXFLAGS", 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 );
-
-       if ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue )
-       {
-               GenerateMacros("+=", module.project.host_non_if_data, NULL, used_defs);
-       }
-       else
-       {
-               GenerateMacros (
-                       "+=",
-                       module.project.non_if_data,
-                       NULL,
-                       used_defs );
-       }
-
-       if ( IsSpecDefinitionFile() )
-       {
-               vector<FileLocation> s;
-               GetSpecImplibDependencies ( s, module.importLibrary->source );
-
-               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" );
-       }
-
-       string globalCflags = " ";
-       globalCflags += ssprintf ("$(%s)", commonflagsMacro.c_str ());
-       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
-       {
-               if ( module.dynamicCRT )
-                       globalCflags += " -D_DLL -D__USE_CRTIMP";
-       }
-       else
-               globalCflags += " -Wall -Wpointer-arith";
-       globalCflags += " -gstabs+";
-       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 )
-               {
-                       globalCflags += " $(TARGET_CPPFLAGS)";
+                                               const FileLocation *header = GetIdlHeaderFilename ( &sourceFile );
+                                               dependencies.push_back ( *header );
+                                               delete header;
+                                       }
+                               }
+                       }
                }
-               else
-                       globalCflags += " -nostdinc";
        }
+}
 
-       // 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";
+void
+MingwModuleHandler::GenerateOtherMacros ()
+{
+       set<const Define *> used_defs;
 
-       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse )
-       {
-               fprintf (
-                       fMakefile,
-                       "%s +=%s\n",
-                       cflagsMacro.c_str (),
-                       (" $(PROJECT_CFLAGS)" + globalCflags).c_str () );
+       linkerflagsMacro = ssprintf ("%s_LDFLAGS", module.name.c_str ());
+       libsMacro = ssprintf("%s_LIBS", module.name.c_str ());
 
-               fprintf (
-                       fMakefile,
-                       "%s +=%s\n",
-                       cxxflagsMacro.c_str (),
-                       (" $(PROJECT_CXXFLAGS)" + globalCflags).c_str () );
+       const FileLocation * pchPath = GetPrecompiledHeaderPath ();
 
-               fprintf (
-                       fMakefile,
-                       "%s += $(PROJECT_RCFLAGS)\n",
-                       windresflagsMacro.c_str () );
+       if ( pchPath )
+       {
+               string pchPathStr = backend->GetFullName ( *pchPath );
+               delete pchPath;
 
-               fprintf (
-                       fMakefile,
-                       "%s += $(PROJECT_WIDLFLAGS) -I%s\n",
-                       widlflagsMacro.c_str (),
-                       module.output->relative_path.c_str () );
+               fprintf ( fMakefile,
+                                 "%s_%sINCLUDES+= -I%s\n",
+                                 module.name.c_str(),
+                                 CompilerPrefixTable[CompilerTypeCC],
+                                 pchPathStr.c_str() );
 
-               fprintf (
-                       fMakefile,
-                       "%s_LFLAGS := $(PROJECT_LFLAGS) $(%s_LFLAGS)\n",
-                       module.name.c_str (),
-                       module.name.c_str () );
+               fprintf ( fMakefile,
+                                 "%s_%sINCLUDES+= -I%s\n",
+                                 module.name.c_str(),
+                                 CompilerPrefixTable[CompilerTypeCXX],
+                                 pchPathStr.c_str() );
        }
-       else
+
+       const char * toolPrefix = "";
+
+       if ( ModuleHandlerInformations[module.type].DefaultHost == HostTrue )
+               toolPrefix = "HOST_";
+
+       // FIXME: this is very ugly and generates lots of useless entries
+       for ( unsigned type = CompilerTypeCC; type < CompilerTypesCount; ++ type )
        {
-               fprintf (
-                       fMakefile,
-                       "%s +=%s\n",
-                       cflagsMacro.c_str (),
-                       globalCflags.c_str () );
+               string flags;
 
-               fprintf (
-                       fMakefile,
-                       "%s +=%s\n",
-                       cxxflagsMacro.c_str (),
-                       globalCflags.c_str () );
+               if ( module.dynamicCRT )
+                       flags += ssprintf ( " $(%s%sFLAG_CRTDLL)", toolPrefix, CompilerPrefixTable[type] );
 
-               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 );
-               fprintf ( fMakefile,
-                         "%s += %s\n\n",
-                         cxxflagsMacro.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 )
-       {
-               fprintf ( fMakefile,
-                         "%s += %s\n\n",
-                         linkerflagsMacro.c_str (),
-                         linkerflags );
-       }
+       GenerateMacros (
+               "+=",
+               module.non_if_data,
+               &module.linkerFlags,
+               used_defs );
 
        fprintf ( fMakefile, "\n\n" );
-
-       // future references to the macros will be to get their values
-       commonflagsMacro = ssprintf ("$(%s)", commonflagsMacro.c_str ());
-       cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());
-       cxxflagsMacro = ssprintf ("$(%s)", cxxflagsMacro.c_str ());
-       nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());
-       widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());
 }
 
 void
@@ -2092,7 +1800,7 @@ MingwModuleHandler::GenerateRules ()
                module.name.c_str () );
        string dependencies = GetTargetMacro ( module );
        if ( module.type == Test )
-               dependencies += " $(REGTESTS_RUN_TARGET)";
+               dependencies += " $(regtests_run_TARGET)";
        fprintf ( fMakefile, "%s: %s\n\n",
                module.name.c_str (),
                dependencies.c_str () );
@@ -2106,20 +1814,22 @@ MingwModuleHandler::GenerateRules ()
        if ( !ReferenceObjects ( module ) )
        {
                const FileLocation* ar_target = GenerateArchiveTarget ();
-               delete ar_target;
+
+               if ( ar_target )
+                       delete ar_target;
        }
 
 
-    spec = IsSpecDefinitionFile();
+    spec = module.IsSpecDefinitionFile();
 
     if(spec)
        {
                Rule * defRule;
 
                if (spec == PSpec)
-                       defRule = &winebuildPDefRule;
+                       defRule = &winebuildPRule;
                else
-                       defRule = &winebuildDefRule;
+                       defRule = &winebuildRule;
 
                defRule->Execute ( fMakefile, backend, module, module.importLibrary->source, clean_files );
        }
@@ -2212,17 +1922,17 @@ MingwModuleHandler::GetDefaultDependencies (
        if (module.name != "psdk" &&
                module.name != "dxsdk")
        {
-               dependencies.push_back ( "$(PSDK_TARGET) $(psdk_HEADERS)" );
-               dependencies.push_back ( "$(DXSDK_TARGET) $(dxsdk_HEADERS)" );
+               dependencies.push_back ( "$(psdk_TARGET) $(psdk_HEADERS)" );
+               dependencies.push_back ( "$(dxsdk_TARGET) $(dxsdk_HEADERS)" );
        }
 
        if (module.name != "errcodes" &&
                module.name != "bugcodes" &&
                module.name != "ntstatus")
        {
-               dependencies.push_back ( "$(ERRCODES_TARGET) $(ERRCODES_MCHEADERS)" );
-               dependencies.push_back ( "$(BUGCODES_TARGET) $(BUGCODES_MCHEADERS)" );
-               dependencies.push_back ( "$(NTSTATUS_TARGET) $(NTSTATUS_MCHEADERS)" );
+               dependencies.push_back ( "$(errcodes_TARGET) $(ERRCODES_MCHEADERS)" );
+               dependencies.push_back ( "$(bugcodes_TARGET) $(BUGCODES_MCHEADERS)" );
+               dependencies.push_back ( "$(ntstatus_TARGET) $(NTSTATUS_MCHEADERS)" );
        }
 
        ///* Check if any dependent library relies on the generated headers */
@@ -2269,23 +1979,6 @@ MingwModuleHandler::GeneratePreconditionDependencies ()
        fprintf ( fMakefile, "\n" );
 }
 
-SpecFileType
-MingwModuleHandler::IsSpecDefinitionFile () const
-{
-    if(!module.importLibrary)
-        return None;
-
-       std::string ext = GetExtension ( *module.importLibrary->source );
-
-    if ( ext == ".spec" )
-        return Spec;
-
-    if ( ext == ".pspec" )
-        return PSpec;
-
-    return None;
-}
-
 /* caller needs to delete the returned object */
 const FileLocation*
 MingwModuleHandler::GetDefinitionFilename () const
@@ -2293,7 +1986,7 @@ MingwModuleHandler::GetDefinitionFilename () const
        if ( module.importLibrary == NULL )
                return NULL;
 
-       if ( IsSpecDefinitionFile () )
+       if ( module.IsSpecDefinitionFile () )
        {
                return new FileLocation ( IntermediateDirectory,
                                                                  module.importLibrary->source->relative_path,
@@ -2307,46 +2000,6 @@ MingwModuleHandler::GetDefinitionFilename () const
        }
 }
 
-void
-MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
-{
-       if ( module.importLibrary != NULL )
-       {
-               const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
-               const FileLocation *defFilename = GetDefinitionFilename ();
-               string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
-
-               fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" );
-
-               fprintf ( fMakefile, "%s:",
-                         backend->GetFullName ( *library_target ).c_str () );
-
-               if ( defFilename )
-               {
-                       fprintf ( fMakefile, " %s",
-                                 backend->GetFullName ( *defFilename ).c_str () );
-               }
-
-               fprintf ( fMakefile, " | %s\n",
-                         backend->GetFullPath ( *library_target ).c_str () );
-
-               fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
-
-               fprintf ( fMakefile,
-                         "\t${dlltool} --dllname %s --def %s --output-lib %s%s%s\n\n",
-                         module.GetDllName ().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" : "" );
-
-               if ( defFilename )
-                       delete defFilename;
-               delete library_target;
-       }
-}
-
 void
 MingwModuleHandler::GetSpecObjectDependencies (
        vector<FileLocation>& dependencies,
@@ -2357,16 +2010,6 @@ MingwModuleHandler::GetSpecObjectDependencies (
                                                                                        GetBasename ( file->name ) + "_" + module.name + ".stubs.c" ) );
 }
 
-void
-MingwModuleHandler::GetSpecImplibDependencies (
-       vector<FileLocation>& dependencies,
-       const FileLocation *file ) const
-{
-       dependencies.push_back ( FileLocation ( IntermediateDirectory,
-                                                                                       file->relative_path,
-                                                                                       GetBasename ( file->name ) + "_" + module.name + ".auto.def" ) );
-}
-
 void
 MingwModuleHandler::GetMcObjectDependencies (
        vector<FileLocation>& dependencies,
@@ -2500,7 +2143,6 @@ MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ()
 {
        string targetMacro ( GetTargetMacro (module) );
        string objectsMacro = GetObjectsMacro ( module );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
        string libsMacro = GetLibsMacro ();
 
        GenerateRules ();
@@ -2517,9 +2159,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 (),
@@ -2547,30 +2189,8 @@ MingwKernelModuleHandler::Process ()
 void
 MingwKernelModuleHandler::GenerateKernelModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro ( module ) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + objectsMacro;
-
-               string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters + " $(NTOSKRNL_SHARED)",
-                                       " -sections" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2598,29 +2218,8 @@ MingwKernelModeDLLModuleHandler::Process ()
 void
 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro ( module ) );
-       string workingDirectory = GetWorkingDirectory ();
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + 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 (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       " -sections" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2647,29 +2246,8 @@ MingwNativeDLLModuleHandler::Process ()
 void
 MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + 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 (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2696,29 +2274,8 @@ MingwNativeCUIModuleHandler::Process ()
 void
 MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + objectsMacro;
-
-               string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2786,29 +2343,8 @@ MingwWin32DLLModuleHandler::Process ()
 void
 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + 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 (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2827,29 +2363,8 @@ MingwWin32OCXModuleHandler::Process ()
 void
 MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + 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 (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2875,29 +2390,8 @@ MingwWin32CUIModuleHandler::Process ()
 void
 MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + objectsMacro;
-
-               string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2923,29 +2417,8 @@ MingwWin32GUIModuleHandler::Process ()
 void
 MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + objectsMacro;
-
-               string linkerParameters = ssprintf ( "-subsystem=windows -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -2965,56 +2438,63 @@ MingwBootLoaderModuleHandler::Process ()
 void
 MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget ()
 {
-       string targetName ( module.output->name );
+       fprintf ( fMakefile, "# BOOT LOADER MODULE TARGET\n" );
        string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ();
-       FileLocation junk_tmp ( TemporaryDirectory,
-                               "",
-                               module.name + ".junk.tmp" );
-       CLEAN_FILE ( junk_tmp );
        string objectsMacro = GetObjectsMacro ( module );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
+       string libsMacro = GetLibsMacro ();
 
        GenerateRules ();
-
-       fprintf ( fMakefile, "# BOOT LOADER MODULE TARGET\n" );
+       
+       string objectsDir = "${call RBUILD_intermediate_dir,$(" + module.name + "_TARGET)}";
+       string rspFile = objectsDir + "$(SEP)" + module.name + "_objs.rsp";
+
+       /* Generate the rsp rule */
+       fprintf(fMakefile, "%s: $(%s_OBJS) %s | %s\n"
+               "\t$(ECHO_RSP)\n"
+               "\t-@${rm} $@ 2>$(NUL)\n"
+               "\t${cp} $(NUL) $@ >$(NUL)\n"
+               "\t$(foreach obj,$(%s_LIBS),$(Q)echo $(QUOTE)$(subst \\,\\\\,$(obj))$(QUOTE)>>$@$(NL))\n\n",
+               rspFile.c_str(),
+               module.name.c_str(),
+               module.xmlbuildFile.c_str(),
+               objectsDir.c_str(),
+               module.name.c_str());
 
        const FileLocation *target_file = GetTargetFilename ( module, NULL );
        fprintf ( fMakefile, "%s: %s %s | %s\n",
                  targetMacro.c_str (),
-                 objectsMacro.c_str (),
-                 linkDepsMacro.c_str (),
+                 rspFile.c_str(),
+                 libsMacro.c_str (),
                  backend->GetFullPath ( *target_file ).c_str () );
 
        fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
 
-       if (Environment::GetArch() == "arm")
-       {
-               fprintf ( fMakefile,
-                        "\t${gcc} -Wl,--subsystem,native -Wl,--section-start,startup=0x8000 -o %s %s %s %s\n",
-                        backend->GetFullName ( junk_tmp ).c_str (),
-                        objectsMacro.c_str (),
-                        linkDepsMacro.c_str (),
-                        GetLinkerMacro ().c_str ());
-       }
-       else
-       {
-               fprintf ( fMakefile,
-                        "\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 (),
-                        GetLinkerMacro ().c_str ());
-       }
-       fprintf ( fMakefile,
-                 "\t${objcopy} -O binary %s $@\n",
-                 backend->GetFullName ( junk_tmp ).c_str () );
-       GenerateBuildMapCode ( &junk_tmp );
-       fprintf ( fMakefile,
-                 "\t-@${rm} %s 2>$(NUL)\n",
-                 backend->GetFullName ( junk_tmp ).c_str () );
-
-       delete target_file;
+       string linkerScriptArgument;
+       if ( module.linkerScript != NULL ) {
+        linkerScriptArgument = ssprintf(" -T %s", backend->GetFullName(*module.linkerScript->file).c_str());
+       }
+
+    /* Link the stripped booloader */
+    fprintf(fMakefile,
+            "\t${ld} --strip-all --subsystem native --entry=%s --image-base=%s @%s $(PROJECT_CCLIBS) "
+            "$(BUILTIN_LDFLAGS) $(PROJECT_LDFLAGS) $(LDFLAG_DRIVER) %s -o $@\n",
+            module.GetEntryPoint().c_str(),
+            module.baseaddress.c_str(),
+            rspFile.c_str(),
+            linkerScriptArgument.c_str() );
+
+    /* Link an unstripped version */
+       fprintf(fMakefile,
+               "ifeq ($(ROS_BUILDNOSTRIP),yes)\n"
+               "\t${ld} --subsystem native --entry=%s --image-base=%s @%s $(PROJECT_CCLIBS) "
+               "$(BUILTIN_LDFLAGS) $(PROJECT_LDFLAGS) $(LDFLAG_DRIVER) %s -o %s$(SEP)%s.nostrip.sys\n"
+               "endif\n",
+               module.GetEntryPoint().c_str(),
+               module.baseaddress.c_str(),
+            rspFile.c_str(),
+               linkerScriptArgument.c_str(),
+               backend->GetFullPath(*target_file).c_str(),
+               module.name.c_str());
 }
 
 
@@ -3033,6 +2513,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 ();
@@ -3049,18 +2531,16 @@ 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 );
 
        GenerateRules ();
 
-       fprintf ( fMakefile, "# BOOT PROGRAM MODULE TARGET\n" );
-
        const FileLocation *target_file = GetTargetFilename ( module, NULL );
        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 () );
 
@@ -3078,7 +2558,7 @@ MingwBootProgramModuleHandler::GenerateBootProgramModuleTarget ()
 
        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 () );
 
@@ -3112,7 +2592,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 )
        {
@@ -3126,14 +2607,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++ )
        {
@@ -3143,7 +2626,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 );
        }
 }
 
@@ -3231,25 +2726,13 @@ void
 MingwIsoModuleHandler::GenerateIsoModuleTarget ()
 {
        fprintf ( fMakefile, "# ISO MODULE TARGET\n" );
-       string bootcdDirectory = "cd";
+       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;
@@ -3263,7 +2746,6 @@ MingwIsoModuleHandler::GenerateIsoModuleTarget ()
        }
 
        const FileLocation *isoboot = bootModule->output;
-       vSourceFiles.push_back ( *isoboot );
 
        // prepare reactos.dff and reactos.inf
        FileLocation reactosDff ( SourceDirectory,
@@ -3273,52 +2755,55 @@ 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",
+                 "\t$(Q)$(cabman_TARGET) -C %s -L %s -I -P $(OUTPUT)\n",
                  backend->GetFullName ( reactosDff ).c_str (),
                  backend->GetFullPath ( bootcdReactos ).c_str () );
        fprintf ( fMakefile,
-                 "\t$(Q)$(CABMAN_TARGET) -C %s -RC %s -L %s -N -P $(OUTPUT)\n",
+                 "\t$(Q)$(cabman_TARGET) -C %s -RC %s -L %s -N -P $(OUTPUT)\n",
                  backend->GetFullName ( reactosDff ).c_str (),
                  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,
-                 "\t$(Q)$(CDMAKE_TARGET) -v -j -m -b %s %s REACTOS %s\n",
+                 "\t$(Q)$(cdmake_TARGET) -v -j -m -b %s %s REACTOS %s\n",
                  backend->GetFullName ( *isoboot ).c_str (),
                  backend->GetFullPath ( bootcd ).c_str (),
                  IsoName.c_str() );
@@ -3351,7 +2836,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 )
        {
@@ -3366,15 +2852,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++ )
        {
@@ -3384,12 +2872,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") ;
@@ -3404,12 +2894,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",
@@ -3417,8 +2909,9 @@ MingwLiveIsoModuleHandler::OutputLoaderCommands ( string& livecdDirectory )
        FileLocation destination ( OutputDirectory,
                                   livecdDirectory + sSep + "loader",
                                   "setupldr.sys" );
-       OutputCopyCommand ( freeldr,
-                           destination );
+       OutputCopyCommandSingle ( freeldr,
+                                 destination );
+       destinations.push_back ( destination );
 }
 
 void
@@ -3431,7 +2924,7 @@ MingwLiveIsoModuleHandler::OutputRegistryCommands ( string& livecdDirectory )
        fprintf ( fMakefile,
                  "\t$(ECHO_MKHIVE)\n" );
        fprintf ( fMakefile,
-                 "\t$(MKHIVE_TARGET) boot%cbootdata %s $(ARCH) boot%cbootdata%clivecd.inf boot%cbootdata%chiveinst_$(ARCH).inf\n",
+                 "\t$(mkhive_TARGET) boot%cbootdata %s $(ARCH) boot%cbootdata%clivecd.inf boot%cbootdata%chiveinst_$(ARCH).inf\n",
                  cSep, backend->GetFullPath ( reactosSystem32ConfigDirectory ).c_str (),
                  cSep, cSep, cSep, cSep );
 }
@@ -3471,23 +2964,35 @@ 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,
-                 "\t$(Q)$(CDMAKE_TARGET) -v -m -j -b %s %s REACTOS %s\n",
+                 "\t$(Q)$(cdmake_TARGET) -v -m -j -b %s %s REACTOS %s\n",
                  backend->GetFullName( *isoboot ).c_str (),
                  backend->GetFullPath ( livecd ).c_str (),
                  IsoName.c_str() );
@@ -3521,29 +3026,8 @@ MingwTestModuleHandler::GetModuleSpecificCompilationUnits ( vector<CompilationUn
 void
 MingwTestModuleHandler::GenerateTestModuleTarget ()
 {
-       string targetMacro ( GetTargetMacro ( module ) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string linkDepsMacro = GetLinkingDependenciesMacro ();
-
-       GenerateImportLibraryTargetIfNeeded ();
-
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
-               GenerateRules ();
-
-               string dependencies = linkDepsMacro + " " + objectsMacro;
-
-               string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
-       }
+       GenerateRules ();
+       GenerateLinkerCommand ();
 }
 
 
@@ -3570,19 +3054,19 @@ MingwCabinetModuleHandler::MingwCabinetModuleHandler (
 void
 MingwCabinetModuleHandler::Process ()
 {
+       fprintf ( fMakefile, "# CABINET MODULE TARGET\n" );
        string targetMacro ( GetTargetMacro (module) );
 
        GenerateRules ();
 
-       fprintf ( fMakefile, "# CABINET MODULE TARGET\n" );
        const FileLocation *target_file = GetTargetFilename ( module, NULL );
-       fprintf ( fMakefile, "%s: $(CABMAN_TARGET) | %s\n",
+       fprintf ( fMakefile, "%s: $(cabman_TARGET) | %s\n",
                  targetMacro.c_str (),
                  backend->GetFullPath ( *target_file ).c_str () );
 
        fprintf ( fMakefile, "\t$(ECHO_CABMAN)\n" );
        fprintf ( fMakefile,
-                 "\t$(Q)$(CABMAN_TARGET) -M raw -S %s $(%s_SOURCES)\n",      // Escape the asterisk for Make
+                 "\t$(Q)$(cabman_TARGET) -M raw -S %s $(%s_SOURCES)\n",      // Escape the asterisk for Make
                  targetMacro.c_str (),
                          module.name.c_str());
 }
@@ -3601,26 +3085,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 ();
 
-       fprintf ( fMakefile, "# ELF EXECUTABLE TARGET\n" );
        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 -gstabs+ -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" );
 }