Add new PEFIXUP tool and use it in the build system.
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index 12257cc..7b6a9e6 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2005 Casper S. Hornstrup
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * 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.
+ */
 #include "../../pch.h"
 #include <assert.h>
 
@@ -110,7 +127,20 @@ MingwModuleHandler::PassThruCacheDirectory (
                /* This path already includes the generated files directory variable */
                return file;
        else
+       {
+               if ( file == "" )
+                       return generatedFilesDirectory;
                return generatedFilesDirectory + SSEP + file;
+       }
+}
+
+/*static*/ Directory*
+MingwModuleHandler::GetTargetDirectoryTree (
+       const Module& module )
+{
+       if ( module.type == StaticLibrary )
+               return backend->intermediateDirectory;
+       return backend->outputDirectory;
 }
 
 /*static*/ string
@@ -120,7 +150,7 @@ MingwModuleHandler::GetTargetFilename (
 {
        string target = PassThruCacheDirectory (
                NormalizeFilename ( module.GetPath () ),
-               backend->outputDirectory );
+               GetTargetDirectoryTree ( module ) );
        if ( pclean_files )
        {
                string_list& clean_files = *pclean_files;
@@ -136,7 +166,7 @@ MingwModuleHandler::GetImportLibraryFilename (
 {
        string target = PassThruCacheDirectory (
                NormalizeFilename ( module.GetDependencyPath () ),
-               backend->outputDirectory );
+               backend->intermediateDirectory );
        if ( pclean_files )
        {
                string_list& clean_files = *pclean_files;
@@ -207,6 +237,9 @@ MingwModuleHandler::InstanciateHandler (
                case RpcClient:
                        handler = new MingwRpcClientModuleHandler ( module );
                        break;
+               case Alias:
+                       handler = new MingwAliasModuleHandler ( module );
+                       break;
                default:
                        throw UnknownModuleTypeException (
                                module.node.location,
@@ -257,6 +290,20 @@ MingwModuleHandler::GetActualSourceFilename (
                return filename;
 }
 
+string
+MingwModuleHandler::GetExtraDependencies (
+       const string& filename ) const
+{
+       string extension = GetExtension ( filename );
+       if ( extension == ".idl" || extension == ".IDL" )
+       {
+               string basename = GetBasename ( filename );
+               return GetRpcServerHeaderFilename ( basename ) + " " + GetRpcClientHeaderFilename ( basename );
+       }
+       else
+               return "";
+}
+
 string
 MingwModuleHandler::GetModuleArchiveFilename () const
 {
@@ -336,16 +383,15 @@ MingwModuleHandler::GetModuleDependencies (
 }
 
 void
-MingwModuleHandler::GetSourceFilenames (
-       string_list& list,
-       bool includeGeneratedFiles ) const
+MingwModuleHandler::GetSourceFilenames ( string_list& list,
+                                         bool includeGeneratedFiles ) const
 {
        size_t i;
 
        const vector<File*>& files = module.non_if_data.files;
        for ( i = 0; i < files.size (); i++ )
        {
-               if ( includeGeneratedFiles || !IsGeneratedFile ( *files[i] ) )
+               if ( includeGeneratedFiles || !files[i]->IsGeneratedFile () )
                {
                        list.push_back (
                                GetActualSourceFilename ( files[i]->name ) );
@@ -366,7 +412,7 @@ MingwModuleHandler::GetSourceFilenames (
                for ( j = 0; j < files.size (); j++ )
                {
                        File& file = *files[j];
-                       if ( includeGeneratedFiles || !IsGeneratedFile ( file ) )
+                       if ( includeGeneratedFiles || !file.IsGeneratedFile () )
                        {
                                list.push_back (
                                        GetActualSourceFilename ( file.name ) );
@@ -423,13 +469,38 @@ MingwModuleHandler::GetObjectFilename (
        return obj_file;
 }
 
+string
+MingwModuleHandler::GetModuleCleanTarget ( const Module& module ) const
+{
+       return module.name + "_clean";
+}
+
+void
+MingwModuleHandler::GetReferencedObjectLibraryModuleCleanTargets ( vector<string>& moduleNames ) const
+{
+       for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
+       {
+               Library& library = *module.non_if_data.libraries[i];
+               if ( library.importedModule->type == ObjectLibrary )
+                       moduleNames.push_back ( GetModuleCleanTarget ( *library.importedModule ) );
+       }
+}
+
 void
 MingwModuleHandler::GenerateCleanTarget () const
 {
-       if ( 0 == clean_files.size() )
+       if ( module.type == Alias )
                return;
-       fprintf ( fMakefile, ".PHONY: %s_clean\n", module.name.c_str() );
-       fprintf ( fMakefile, "%s_clean:\n\t-@${rm}", module.name.c_str() );
+       
+       fprintf ( fMakefile,
+                 ".PHONY: %s_clean\n",
+                  module.name.c_str() );
+       vector<string> referencedModuleNames;
+       GetReferencedObjectLibraryModuleCleanTargets ( referencedModuleNames );
+       fprintf ( fMakefile,
+                 "%s: %s\n\t-@${rm}",
+                 GetModuleCleanTarget ( module ).c_str(),
+                 v2s ( referencedModuleNames, 10 ).c_str () );
        for ( size_t i = 0; i < clean_files.size(); i++ )
        {
                if ( 9==((i+1)%10) )
@@ -446,19 +517,29 @@ MingwModuleHandler::GenerateInstallTarget () const
        if ( module.installName.length () == 0 )
                return;
        fprintf ( fMakefile, ".PHONY: %s_install\n", module.name.c_str() );
-       fprintf ( fMakefile, "%s_install:\n", module.name.c_str() );
-       string sourceFilename = MingwModuleHandler::PassThruCacheDirectory (
-               NormalizeFilename ( module.GetPath () ),
-               backend->outputDirectory );
        string normalizedTargetFilename = MingwModuleHandler::PassThruCacheDirectory (
                NormalizeFilename ( module.installBase + SSEP + module.installName ),
                backend->installDirectory );
        fprintf ( fMakefile,
-                 "\t$(ECHO_CP)\n" );
+                 "%s_install: %s\n",
+                 module.name.c_str (),
+                 normalizedTargetFilename.c_str() );
+}
+
+void
+MingwModuleHandler::GenerateDependsTarget () const
+{
        fprintf ( fMakefile,
-                 "\t${cp} %s %s 1>$(NUL)\n",
-                 sourceFilename.c_str (),
-                 normalizedTargetFilename.c_str () );
+                 ".PHONY: %s_depends\n",
+                 module.name.c_str() );
+       fprintf ( fMakefile,
+                 "%s_depends: $(RBUILD_TARGET)\n",
+                 module.name.c_str () );
+       fprintf ( fMakefile,
+                 "\t$(ECHO_RBUILD)\n" );
+       fprintf ( fMakefile,
+                 "\t$(Q)$(RBUILD_TARGET) -dm%s mingw\n",
+                 module.name.c_str () );
 }
 
 string
@@ -479,9 +560,9 @@ MingwModuleHandler::GetObjectFilenames ()
        return objectFilenames;
 }
 
-string
+/* static */ string
 MingwModuleHandler::GenerateGccDefineParametersFromVector (
-       const vector<Define*>& defines ) const
+       const vector<Define*>& defines )
 {
        string parameters;
        for ( size_t i = 0; i < defines.size (); i++ )
@@ -526,8 +607,8 @@ MingwModuleHandler::ConcatenatePaths (
                return path1 + CSEP + path2;
 }
 
-string
-MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes ) const
+/* static */ string
+MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes )
 {
        string parameters;
        for ( size_t i = 0; i < includes.size (); i++ )
@@ -553,7 +634,6 @@ MingwModuleHandler::GenerateGccIncludeParameters () const
        return parameters;
 }
 
-
 string
 MingwModuleHandler::GenerateCompilerParametersFromVector ( const vector<CompilerFlag*>& compilerFlags ) const
 {
@@ -594,7 +674,7 @@ MingwModuleHandler::GenerateImportLibraryDependenciesFromVector (
                        dependencies += " \\\n\t\t", wrap_count = 0;
                else if ( dependencies.size () > 0 )
                        dependencies += " ";
-               dependencies += GetImportLibraryDependency ( *libraries[i]->imported_module );
+               dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule );
        }
        return dependencies;
 }
@@ -609,35 +689,51 @@ void
 MingwModuleHandler::GenerateMacro (
        const char* assignmentOperation,
        const string& macro,
-       const IfableData& data,
-       const vector<CompilerFlag*>* compilerFlags )
+       const IfableData& data )
 {
        size_t i;
+       bool generateAssignment;
 
-       fprintf (
-               fMakefile,
-               "%s %s",
-               macro.c_str(),
-               assignmentOperation );
-       
-       if ( compilerFlags != NULL )
+       generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0 || data.compilerFlags.size () > 0;
+       if ( generateAssignment )
        {
-               string compilerParameters = GenerateCompilerParametersFromVector ( *compilerFlags );
-               if ( compilerParameters.size () > 0 )
-               {
-                       fprintf (
-                               fMakefile,
-                               " %s",
-                               compilerParameters.c_str () );
-               }
+               fprintf ( fMakefile,
+                         "%s %s",
+                         macro.c_str(),
+                         assignmentOperation );
+       }
+
+       if ( use_pch && module.pch != NULL )
+       {
+               fprintf ( fMakefile,
+                         " -I%s",
+                         GetDirectory ( GetPrecompiledHeaderFilename () ).c_str () );
+       }
+
+       string compilerParameters = GenerateCompilerParametersFromVector ( data.compilerFlags );
+       if ( compilerParameters.size () > 0 )
+       {
+               fprintf (
+                       fMakefile,
+                       " %s",
+                       compilerParameters.c_str () );
        }
 
        for ( i = 0; i < data.includes.size(); i++ )
        {
+               const Include& include = *data.includes[i];
+               string includeDirectory;
+               if ( include.baseModule != NULL &&
+                    ( include.baseModule->type == RpcServer ||
+                      include.baseModule->type == RpcClient ) )
+                       includeDirectory = PassThruCacheDirectory ( NormalizeFilename ( include.directory ),
+                                                                   backend->intermediateDirectory );
+               else
+                       includeDirectory = include.directory;
                fprintf (
                        fMakefile,
                        " -I%s",
-                       data.includes[i]->directory.c_str() );
+                       includeDirectory.c_str() );
        }
        for ( i = 0; i < data.defines.size(); i++ )
        {
@@ -652,29 +748,26 @@ MingwModuleHandler::GenerateMacro (
                                "=%s",
                                d.value.c_str() );
        }
-       fprintf ( fMakefile, "\n" );
+       if ( generateAssignment )
+       {
+               fprintf ( fMakefile, "\n" );
+       }
 }
 
 void
 MingwModuleHandler::GenerateMacros (
        const char* assignmentOperation,
        const IfableData& data,
-       const vector<CompilerFlag*>* compilerFlags,
        const vector<LinkerFlag*>* linkerFlags )
 {
        size_t i;
 
-       if ( data.includes.size () > 0 || data.defines.size () > 0 )
-       {
-               GenerateMacro ( assignmentOperation,
-                               cflagsMacro,
-                               data,
-                               compilerFlags );
-               GenerateMacro ( assignmentOperation,
-                               windresflagsMacro,
-                               data,
-                               compilerFlags );
-       }
+       GenerateMacro ( assignmentOperation,
+                       cflagsMacro,
+                       data );
+       GenerateMacro ( assignmentOperation,
+                       windresflagsMacro,
+                       data );
        
        if ( linkerFlags != NULL )
        {
@@ -712,17 +805,18 @@ MingwModuleHandler::GenerateMacros (
                        || rIf.data.includes.size()
                        || rIf.data.libraries.size()
                        || rIf.data.files.size()
+                       || rIf.data.compilerFlags.size()
                        || rIf.data.ifs.size() )
                {
                        fprintf (
                                fMakefile,
-                               "ifeq (\"$(%s)\",\"%s\")\n",
+                               "%s (\"$(%s)\",\"%s\")\n",
+                               rIf.negated ? "ifneq" : "ifeq",
                                rIf.property.c_str(),
                                rIf.value.c_str() );
                        GenerateMacros (
                                "+=",
                                rIf.data,
-                               NULL,
                                NULL );
                        fprintf ( 
                                fMakefile,
@@ -731,11 +825,22 @@ MingwModuleHandler::GenerateMacros (
        }
 }
 
+void
+MingwModuleHandler::CleanupFileVector ( vector<File*>& sourceFiles )
+{
+       for (size_t i = 0; i < sourceFiles.size (); i++)
+               delete sourceFiles[i];
+}
+
+void
+MingwModuleHandler::GetModuleSpecificSourceFiles ( vector<File*>& sourceFiles )
+{
+}
+
 void
 MingwModuleHandler::GenerateObjectMacros (
        const char* assignmentOperation,
        const IfableData& data,
-       const vector<CompilerFlag*>* compilerFlags,
        const vector<LinkerFlag*>* linkerFlags )
 {
        size_t i;
@@ -785,37 +890,64 @@ MingwModuleHandler::GenerateObjectMacros (
                        || rIf.data.includes.size()
                        || rIf.data.libraries.size()
                        || rIf.data.files.size()
+                       || rIf.data.compilerFlags.size()
                        || rIf.data.ifs.size() )
                {
                        fprintf (
                                fMakefile,
-                               "ifeq (\"$(%s)\",\"%s\")\n",
+                               "%s (\"$(%s)\",\"%s\")\n",
+                               rIf.negated ? "ifneq" : "ifeq",
                                rIf.property.c_str(),
                                rIf.value.c_str() );
                        GenerateObjectMacros (
                                "+=",
                                rIf.data,
-                               NULL,
                                NULL );
                        fprintf ( 
                                fMakefile,
                                "endif\n\n" );
                }
        }
+
+       vector<File*> sourceFiles;
+       GetModuleSpecificSourceFiles ( sourceFiles );
+       for ( i = 0; i < sourceFiles.size (); i++ )
+       {
+               fprintf (
+                       fMakefile,
+                       "%s += %s\n",
+                       objectsMacro.c_str(),
+                       GetObjectFilename (
+                               sourceFiles[i]->name, NULL ).c_str () );
+       }
+       CleanupFileVector ( sourceFiles );
+}
+
+string
+MingwModuleHandler::GetPrecompiledHeaderFilename () const
+{
+       const string& basePchFilename = module.pch->file.name + ".gch";
+       return PassThruCacheDirectory ( NormalizeFilename ( basePchFilename ),
+                                       backend->intermediateDirectory );
 }
 
 void
 MingwModuleHandler::GenerateGccCommand (
        const string& sourceFilename,
+       const string& extraDependencies,
        const string& cc,
        const string& cflagsMacro )
 {
        string dependencies = sourceFilename;
+       if ( extraDependencies != "" )
+               dependencies += " " + extraDependencies;
        if ( module.pch && use_pch )
-               dependencies += " " + module.pch->header + ".gch";
+               dependencies += " " + GetPrecompiledHeaderFilename ();
        
        /* WIDL generated headers may be used */
-       dependencies += " " + GetLinkingDependenciesMacro ();
+       vector<string> rpcDependencies;
+       GetRpcHeaderDependencies ( rpcDependencies );
+       dependencies += " " + v2s ( rpcDependencies, 5 );
        dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
 
        string objectFilename = GetObjectFilename (
@@ -871,7 +1003,7 @@ MingwModuleHandler::GenerateNasmCommand (
        fprintf ( fMakefile, "\t$(ECHO_NASM)\n" );
        fprintf ( fMakefile,
                  "\t%s -f win32 $< -o $@ %s\n",
-                 "$(Q)nasm",
+                 "$(Q)${nasm}",
                  nasmflagsMacro.c_str () );
 }
 
@@ -884,8 +1016,9 @@ MingwModuleHandler::GenerateWindresCommand (
        dependencies += " " + NormalizeFilename ( module.xmlbuildFile );
        string objectFilename =
                GetObjectFilename ( sourceFilename, &clean_files );
-       string rciFilename = ros_temp + module.name + ".rci.tmp";
-       string resFilename = ros_temp + module.name + ".res.tmp";
+       string sourceFilenamePart = ReplaceExtension ( GetFilename ( sourceFilename ), "" );
+       string rciFilename = ros_temp + module.name + "." + sourceFilenamePart + ".rci.tmp";
+       string resFilename = ros_temp + module.name + "." + sourceFilenamePart + ".res.tmp";
        if ( module.useWRC )
        {
                fprintf ( fMakefile,
@@ -953,21 +1086,20 @@ MingwModuleHandler::GenerateWinebuildCommands (
                  dependencies.c_str () );
        fprintf ( fMakefile, "\t$(ECHO_WINEBLD)\n" );
        fprintf ( fMakefile,
-                 "\t%s --def=%s -o %s\n",
+                 "\t%s -o %s --def -E %s\n",
                  "$(Q)$(WINEBUILD_TARGET)",
-                 sourceFilename.c_str (),
-                 def_file.c_str () );
-
+                 def_file.c_str (),
+                 sourceFilename.c_str () );
        fprintf ( fMakefile,
                  "%s: %s $(WINEBUILD_TARGET)\n",
                  stub_file.c_str (),
                  sourceFilename.c_str () );
        fprintf ( fMakefile, "\t$(ECHO_WINEBLD)\n" );
        fprintf ( fMakefile,
-                 "\t%s --pedll=%s -o %s\n",
+                 "\t%s -o %s --pedll %s\n",
                  "$(Q)$(WINEBUILD_TARGET)",
-                 sourceFilename.c_str (),
-                 stub_file.c_str () );
+                 stub_file.c_str (),
+                 sourceFilename.c_str () );
 }
 
 string
@@ -975,6 +1107,13 @@ MingwModuleHandler::GetWidlFlags ( const File& file )
 {
        return file.switches;
 }
+
+string
+MingwModuleHandler::GetRpcServerHeaderFilename ( string basename ) const
+{
+       return PassThruCacheDirectory ( basename + "_s.h",
+                                       backend->intermediateDirectory );
+}
                
 void
 MingwModuleHandler::GenerateWidlCommandsServer (
@@ -986,12 +1125,7 @@ MingwModuleHandler::GenerateWidlCommandsServer (
 
        string basename = GetBasename ( file.name );
 
-       /*string generatedHeaderFilename = PassThruCacheDirectory (
-               basename + ".h",
-               backend->intermediateDirectory );
-       CLEAN_FILE(generatedHeaderFilename);
-       */
-       string generatedHeaderFilename = basename + "_s.h";
+       string generatedHeaderFilename = GetRpcServerHeaderFilename ( basename );
        CLEAN_FILE(generatedHeaderFilename);
 
        string generatedServerFilename = PassThruCacheDirectory (
@@ -1016,6 +1150,13 @@ MingwModuleHandler::GenerateWidlCommandsServer (
                  file.name.c_str () );
 }
 
+string
+MingwModuleHandler::GetRpcClientHeaderFilename ( string basename ) const
+{
+       return PassThruCacheDirectory ( basename + "_c.h",
+                                       backend->intermediateDirectory );
+}
+
 void
 MingwModuleHandler::GenerateWidlCommandsClient (
        const File& file,
@@ -1026,12 +1167,7 @@ MingwModuleHandler::GenerateWidlCommandsClient (
 
        string basename = GetBasename ( file.name );
 
-       /*string generatedHeaderFilename = PassThruCacheDirectory (
-               basename + ".h",
-               backend->intermediateDirectory );
-       CLEAN_FILE(generatedHeaderFilename);
-       */
-       string generatedHeaderFilename = basename + "_c.h";
+       string generatedHeaderFilename = GetRpcClientHeaderFilename ( basename );
        CLEAN_FILE(generatedHeaderFilename);
 
        string generatedClientFilename = PassThruCacheDirectory (
@@ -1083,6 +1219,7 @@ MingwModuleHandler::GenerateCommands (
        if ( extension == ".c" || extension == ".C" )
        {
                GenerateGccCommand ( file.name,
+                                    "",
                                     cc,
                                     cflagsMacro );
                return;
@@ -1092,6 +1229,7 @@ MingwModuleHandler::GenerateCommands (
                  extension == ".cxx" || extension == ".CXX" )
        {
                GenerateGccCommand ( file.name,
+                                    "",
                                     cppc,
                                     cflagsMacro );
                return;
@@ -1119,6 +1257,7 @@ MingwModuleHandler::GenerateCommands (
        {
                GenerateWinebuildCommands ( file.name );
                GenerateGccCommand ( GetActualSourceFilename ( file.name ),
+                                    "",
                                     cc,
                                     cflagsMacro );
                return;
@@ -1128,6 +1267,7 @@ MingwModuleHandler::GenerateCommands (
                GenerateWidlCommands ( file,
                                       widlflagsMacro );
                GenerateGccCommand ( GetActualSourceFilename ( file.name ),
+                                    GetExtraDependencies ( file.name ),
                                     cc,
                                     cflagsMacro );
                return;
@@ -1203,7 +1343,7 @@ MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
 
 void
 MergeStringVector ( const vector<string>& input,
-                       vector<string>& output )
+                    vector<string>& output )
 {
        int wrap_at = 25;
        string s;
@@ -1240,7 +1380,7 @@ MingwModuleHandler::GetObjectsVector ( const IfableData& data,
 void
 MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
 {
-       if ( backend->cleanAsYouGo )
+       if ( backend->configuration.CleanAsYouGo )
        {
                vector<string> objectFiles;
                GetObjectsVector ( module.non_if_data,
@@ -1257,6 +1397,15 @@ MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const
        }
 }
 
+void
+MingwModuleHandler::GenerateRunRsymCode () const
+{
+       fprintf ( fMakefile,
+                 "\t$(ECHO_RSYM)\n" );
+       fprintf ( fMakefile,
+                 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
+}
+
 void
 MingwModuleHandler::GenerateLinkerCommand (
        const string& dependencies,
@@ -1270,7 +1419,7 @@ MingwModuleHandler::GenerateLinkerCommand (
        string def_file = GetDefinitionFilename ();
 
        fprintf ( fMakefile,
-               "%s: %s %s $(RSYM_TARGET) | %s\n",
+               "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
                target.c_str (),
                def_file.c_str (),
                dependencies.c_str (),
@@ -1280,40 +1429,17 @@ MingwModuleHandler::GenerateLinkerCommand (
 
        if ( module.IsDLL () )
        {
-               string base_tmp = ros_temp + module.name + ".base.tmp";
-               CLEAN_FILE ( base_tmp );
-               string junk_tmp = ros_temp + module.name + ".junk.tmp";
-               CLEAN_FILE ( junk_tmp );
                string temp_exp = ros_temp + module.name + ".temp.exp";
                CLEAN_FILE ( temp_exp );
        
-               fprintf ( fMakefile,
-                         "\t%s %s -Wl,--base-file,%s -o %s %s %s %s\n",
-                         linker.c_str (),
-                         linkerParameters.c_str (),
-                         base_tmp.c_str (),
-                         junk_tmp.c_str (),
-                         objectsMacro.c_str (),
-                         libsMacro.c_str (),
-                         GetLinkerMacro ().c_str () );
-       
-               fprintf ( fMakefile,
-                         "\t-@${rm} %s 2>$(NUL)\n",
-                         junk_tmp.c_str () );
-       
                string killAt = module.mangledSymbols ? "" : "--kill-at";
                fprintf ( fMakefile,
-                         "\t${dlltool} --dllname %s --base-file %s --def %s --output-exp %s %s\n",
+                         "\t${dlltool} --dllname %s --def %s --output-exp %s %s\n",
                          targetName.c_str (),
-                         base_tmp.c_str (),
                          def_file.c_str (),
                          temp_exp.c_str (),
                          killAt.c_str () );
        
-               fprintf ( fMakefile,
-                         "\t-@${rm} %s 2>$(NUL)\n",
-                         base_tmp.c_str () );
-       
                fprintf ( fMakefile,
                          "\t%s %s %s -o %s %s %s %s\n",
                          linker.c_str (),
@@ -1324,20 +1450,13 @@ MingwModuleHandler::GenerateLinkerCommand (
                          libsMacro.c_str (),
                          GetLinkerMacro ().c_str () );
        
+               fprintf ( fMakefile,
+                         "\t$(Q)$(PEFIXUP_TARGET) %s -exports\n",
+                         target.c_str () );
+
                fprintf ( fMakefile,
                          "\t-@${rm} %s 2>$(NUL)\n",
                          temp_exp.c_str () );
-               
-               GenerateCleanObjectsAsYouGoCode ();
-       
-               GenerateBuildMapCode ();
-       
-               GenerateBuildNonSymbolStrippedCode ();
-       
-               fprintf ( fMakefile,
-                         "\t$(ECHO_RSYM)\n" );
-               fprintf ( fMakefile,
-                         "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
        }
        else
        {
@@ -1349,20 +1468,24 @@ MingwModuleHandler::GenerateLinkerCommand (
                          objectsMacro.c_str (),
                          libsMacro.c_str (),
                          GetLinkerMacro ().c_str () );
-
-               GenerateCleanObjectsAsYouGoCode ();
        }
+
+       GenerateBuildMapCode ();
+       GenerateBuildNonSymbolStrippedCode ();
+       GenerateRunRsymCode ();
+       GenerateCleanObjectsAsYouGoCode ();
 }
 
 void
 MingwModuleHandler::GeneratePhonyTarget() const
 {
-       string targetMacro ( GetTargetMacro(module) );
-       fprintf ( fMakefile, ".PHONY: %s\n\n",
+       string targetMacro ( GetTargetMacro ( module ) );
+       fprintf ( fMakefile,
+                 ".PHONY: %s\n\n",
                  targetMacro.c_str ());
        fprintf ( fMakefile, "%s: | %s\n",
                  targetMacro.c_str (),
-                 GetDirectory(GetTargetFilename(module,NULL)).c_str () );
+                 GetDirectory ( GetTargetFilename ( module, NULL ) ).c_str () );
 }
 
 void
@@ -1402,6 +1525,20 @@ MingwModuleHandler::GenerateObjectFileTargets (
                                            windresflagsMacro,
                                            widlflagsMacro );
        }
+
+       vector<File*> sourceFiles;
+       GetModuleSpecificSourceFiles ( sourceFiles );
+       for ( i = 0; i < sourceFiles.size (); i++ )
+       {
+               GenerateCommands ( *sourceFiles[i],
+                                  cc,
+                                  cppc,
+                                  cflagsMacro,
+                                  nasmflagsMacro,
+                                  windresflagsMacro,
+                                  widlflagsMacro );
+       }
+       CleanupFileVector ( sourceFiles );
 }
 
 void
@@ -1413,27 +1550,22 @@ MingwModuleHandler::GenerateObjectFileTargets (
        const string& windresflagsMacro,
        const string& widlflagsMacro )
 {
-       if ( module.pch )
+       if ( module.pch && use_pch )
        {
-               const string& pch_file = module.pch->header;
-               string gch_file = pch_file + ".gch";
-               CLEAN_FILE(gch_file);
-               if ( use_pch )
-               {
-                       fprintf (
-                               fMakefile,
-                               "%s: %s\n",
-                               gch_file.c_str(),
-                               pch_file.c_str() );
-                       fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
-                       fprintf (
-                               fMakefile,
-                               "\t%s -o %s %s -g %s\n\n",
-                               ( module.cplusplus ? cppc.c_str() : cc.c_str() ),
-                               gch_file.c_str(),
-                               cflagsMacro.c_str(),
-                               pch_file.c_str() );
-               }
+               const string& baseHeaderFilename = module.pch->file.name;
+               const string& pchFilename = GetPrecompiledHeaderFilename ();
+               CLEAN_FILE(pchFilename);
+               fprintf ( fMakefile,
+                         "%s: %s\n",
+                         pchFilename.c_str(),
+                         baseHeaderFilename.c_str() );
+               fprintf ( fMakefile, "\t$(ECHO_PCH)\n" );
+               fprintf ( fMakefile,
+                         "\t%s -o %s %s -g %s\n\n",
+                         module.cplusplus ? cppc.c_str() : cc.c_str(),
+                         pchFilename.c_str(),
+                         cflagsMacro.c_str(),
+                         baseHeaderFilename.c_str() );
        }
 
        GenerateObjectFileTargets ( module.non_if_data,
@@ -1522,7 +1654,6 @@ MingwModuleHandler::GenerateObjectMacro ()
        GenerateObjectMacros (
                "=",
                module.non_if_data,
-               &module.compilerFlags,
                &module.linkerFlags );
 
        // future references to the macro will be to get its values
@@ -1538,6 +1669,33 @@ MingwModuleHandler::GenerateTargetMacro ()
                GetModuleTargets ( module ).c_str () );
 }
 
+void
+MingwModuleHandler::GetRpcHeaderDependencies (
+       vector<string>& dependencies ) const
+{
+       for ( size_t i = 0; i < module.non_if_data.libraries.size (); i++ )
+       {
+               Library& library = *module.non_if_data.libraries[i];
+               if ( library.importedModule->type == RpcServer ||
+                    library.importedModule->type == RpcClient )
+               {
+                       for ( size_t j = 0; j < library.importedModule->non_if_data.files.size (); j++ )
+                       {
+                               File& file = *library.importedModule->non_if_data.files[j];
+                               string extension = GetExtension ( file.name );
+                               if ( extension == ".idl" || extension == ".IDL" )
+                               {
+                                       string basename = GetBasename ( file.name );
+                                       if ( library.importedModule->type == RpcServer )
+                                               dependencies.push_back ( GetRpcServerHeaderFilename ( basename ) );
+                                       if ( library.importedModule->type == RpcClient )
+                                               dependencies.push_back ( GetRpcClientHeaderFilename ( basename ) );
+                               }
+                       }
+               }
+       }
+}
+
 void
 MingwModuleHandler::GenerateOtherMacros ()
 {
@@ -1552,12 +1710,11 @@ MingwModuleHandler::GenerateOtherMacros ()
        GenerateMacros (
                "=",
                module.non_if_data,
-               &module.compilerFlags,
                &module.linkerFlags );
 
+       vector<string> s;
        if ( module.importLibrary )
        {
-               string_list s;
                const vector<File*>& files = module.non_if_data.files;
                for ( size_t i = 0; i < files.size (); i++ )
                {
@@ -1566,18 +1723,18 @@ MingwModuleHandler::GenerateOtherMacros ()
                        if ( extension == ".spec" || extension == ".SPEC" )
                                GetSpecObjectDependencies ( s, file.name );
                }
-               if ( s.size () > 0 )
-               {
-                       fprintf (
-                               fMakefile,
-                               "%s +=",
-                               linkDepsMacro.c_str() );
-                       for ( size_t i = 0; i < s.size(); i++ )
-                               fprintf ( fMakefile,
-                                         " %s",
-                                         s[i].c_str () );
-                       fprintf ( fMakefile, "\n" );
-               }
+       }
+       if ( s.size () > 0 )
+       {
+               fprintf (
+                       fMakefile,
+                       "%s +=",
+                       linkDepsMacro.c_str() );
+               for ( size_t i = 0; i < s.size(); i++ )
+                       fprintf ( fMakefile,
+                                 " %s",
+                                 s[i].c_str () );
+               fprintf ( fMakefile, "\n" );
        }
 
        string globalCflags = "-g";
@@ -1655,32 +1812,46 @@ MingwModuleHandler::GenerateRules ()
        string cppc = ( module.host == HostTrue ? "${host_gpp}" : "${gpp}" );
        string ar = ( module.host == HostTrue ? "${host_ar}" : "${ar}" );
 
-       string targetMacro = GetTargetMacro ( module );
+       if ( module.name != "zlib" ) /* Avoid make warning */
+       {
+               string proxyMakefile = PassThruCacheDirectory (
+                       NormalizeFilename ( module.GetBasePath () + SSEP + "makefile" ),
+                       backend->outputDirectory );
+               CLEAN_FILE ( proxyMakefile );
+       }
 
+       string targetMacro = GetTargetMacro ( module );
        CLEAN_FILE ( targetMacro );
 
        // generate phony target for module name
        fprintf ( fMakefile, ".PHONY: %s\n",
                module.name.c_str () );
+       string dependencies = GetTargetMacro ( module );
+       if ( module.type == Test )
+               dependencies += " $(REGTESTS_RUN_TARGET)";
        fprintf ( fMakefile, "%s: %s\n\n",
                module.name.c_str (),
-               GetTargetMacro ( module ).c_str () );
+               dependencies.c_str () );
+       if ( module.type == Test )
+       {
+               fprintf ( fMakefile,
+                         "\t@%s\n",
+                         targetMacro.c_str ());
+       }
 
        if ( !ReferenceObjects ( module ) )
        {
                string ar_target ( GenerateArchiveTarget ( ar, objectsMacro ) );
                if ( targetMacro != ar_target )
-               {
                        CLEAN_FILE ( ar_target );
-               }
        }
 
        GenerateObjectFileTargets ( cc,
-                                                               cppc,
-                                                               cflagsMacro,
-                                                               nasmflagsMacro,
-                                                               windresflagsMacro,
-                                                           widlflagsMacro );
+                                   cppc,
+                                   cflagsMacro,
+                                   nasmflagsMacro,
+                                   windresflagsMacro,
+                                   widlflagsMacro );
 }
 
 void
@@ -1850,7 +2021,7 @@ MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
                                  deps[i].c_str () );
 
                fprintf ( fMakefile, " | %s\n",
-                         GetDirectory ( GetTargetFilename ( module, NULL ) ).c_str () );
+                         GetDirectory ( GetImportLibraryFilename ( module, NULL ) ).c_str () );
 
                fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
 
@@ -1886,10 +2057,11 @@ MingwModuleHandler::GetWidlObjectDependencies (
        const string& filename ) const
 {
        string basename = GetBasename ( filename );
-       string serverDependency = PassThruCacheDirectory (
+       string serverSourceDependency = PassThruCacheDirectory (
                NormalizeFilename ( basename + "_s.c" ),
                backend->intermediateDirectory );
-       dependencies.push_back ( serverDependency );
+       dependencies.push_back ( serverSourceDependency );
+       dependencies.push_back ( GetRpcServerHeaderFilename ( basename ) );
 }
 
 void
@@ -1986,7 +2158,7 @@ MingwKernelModuleHandler::GenerateKernelModuleTarget ()
 
                string dependencies = linkDepsMacro + " " + objectsMacro;
 
-               string linkerParameters = ssprintf ( "-Wl,-T,%s" SSEP "ntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll --dll",
+               string linkerParameters = ssprintf ( "-Wl,-T,%s" SSEP "ntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
                                                     module.GetBasePath ().c_str (),
                                                     module.entrypoint.c_str (),
                                                     module.baseaddress.c_str () );
@@ -2073,7 +2245,7 @@ MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
 
                string dependencies = linkDepsMacro + " " + objectsMacro;
 
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll --dll",
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
                                                     module.entrypoint.c_str (),
                                                     module.baseaddress.c_str () );
                GenerateLinkerCommand ( dependencies,
@@ -2120,7 +2292,7 @@ MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ()
 
                string dependencies = linkDepsMacro + " " + objectsMacro;
 
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll --dll",
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
                                                     module.entrypoint.c_str (),
                                                     module.baseaddress.c_str () );
                GenerateLinkerCommand ( dependencies,
@@ -2166,7 +2338,7 @@ MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
 
                string dependencies = linkDepsMacro + " " + objectsMacro;
 
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll --dll",
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -shared",
                                                     module.entrypoint.c_str (),
                                                     module.baseaddress.c_str () );
                GenerateLinkerCommand ( dependencies,
@@ -2238,33 +2410,9 @@ MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler (
 void
 MingwWin32DLLModuleHandler::Process ()
 {
-       GenerateExtractWineDLLResourcesTarget ();
        GenerateWin32DLLModuleTarget ();
 }
 
-void
-MingwWin32DLLModuleHandler::GenerateExtractWineDLLResourcesTarget ()
-{
-       fprintf ( fMakefile, ".PHONY: %s_extractresources\n\n",
-                 module.name.c_str () );
-       fprintf ( fMakefile, "%s_extractresources: $(BIN2RES_TARGET)\n",
-                 module.name.c_str () );
-       const vector<File*>& files = module.non_if_data.files;
-       for ( size_t i = 0; i < files.size (); i++ )
-       {
-               File& file = *files[i];
-               string extension = GetExtension ( file.name );
-               if ( extension == ".rc" || extension == ".RC" )
-               {
-                       string resource = NormalizeFilename ( file.name );
-                       fprintf ( fMakefile, "\t$(ECHO_BIN2RES)\n" );
-                       fprintf ( fMakefile, "\t@:echo ${bin2res} -f -x %s\n",
-                                 resource.c_str () );
-               }
-       }
-       fprintf ( fMakefile, "\n");
-}
-
 void
 MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
 {
@@ -2288,7 +2436,7 @@ MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
                else
                        linker = "${gcc}";
 
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll --dll",
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -shared",
                                                     module.entrypoint.c_str (),
                                                     module.baseaddress.c_str () );
                GenerateLinkerCommand ( dependencies,
@@ -2507,6 +2655,8 @@ MingwIsoModuleHandler::OutputBootstrapfileCopyCommands (
        for ( size_t i = 0; i < module.project.modules.size (); i++ )
        {
                const Module& m = *module.project.modules[i];
+               if ( !m.enabled )
+                       continue;
                if ( m.bootstrap != NULL )
                {
                        string sourceFilename = PassThruCacheDirectory (
@@ -2553,6 +2703,8 @@ MingwIsoModuleHandler::GetBootstrapCdDirectories ( const string& bootcdDirectory
        for ( size_t i = 0; i < module.project.modules.size (); i++ )
        {
                const Module& m = *module.project.modules[i];
+               if ( !m.enabled )
+                       continue;
                if ( m.bootstrap != NULL )
                {
                        string targetDirectory ( bootcdDirectory + SSEP + m.bootstrap->base );
@@ -2598,6 +2750,8 @@ MingwIsoModuleHandler::GetBootstrapCdFiles (
        for ( size_t i = 0; i < module.project.modules.size (); i++ )
        {
                const Module& m = *module.project.modules[i];
+               if ( !m.enabled )
+                       continue;
                if ( m.bootstrap != NULL )
                {
                        string filename = PassThruCacheDirectory (
@@ -2708,8 +2862,8 @@ MingwLiveIsoModuleHandler::CreateDirectory ( const string& directory )
 
 void
 MingwLiveIsoModuleHandler::OutputCopyCommand ( const string& sourceFilename,
-                                                  const string& targetFilename,
-                                                  const string& targetDirectory )
+                                               const string& targetFilename,
+                                               const string& targetDirectory )
 {
        string normalizedTargetFilename = MingwModuleHandler::PassThruCacheDirectory (
                NormalizeFilename ( targetDirectory + SSEP + targetFilename ),
@@ -2724,26 +2878,29 @@ MingwLiveIsoModuleHandler::OutputCopyCommand ( const string& sourceFilename,
 
 void
 MingwLiveIsoModuleHandler::OutputModuleCopyCommands ( string& livecdDirectory,
-                                                         string& reactosDirectory )
+                                                      string& reactosDirectory )
 {
        for ( size_t i = 0; i < module.project.modules.size (); i++ )
        {
                const Module& m = *module.project.modules[i];
+               if ( !m.enabled )
+                       continue;
                if ( m.installName.length () > 0 )
                {
+                       const Module& aliasedModule = backend->GetAliasedModuleOrModule ( m  );
                        string sourceFilename = MingwModuleHandler::PassThruCacheDirectory (
-                               NormalizeFilename ( m.GetPath () ),
+                               NormalizeFilename ( aliasedModule.GetPath () ),
                                backend->outputDirectory );
                        OutputCopyCommand ( sourceFilename,
-                                       m.installName,
-                                       livecdDirectory + SSEP + reactosDirectory + SSEP + m.installBase );
+                                           m.installName,
+                                           livecdDirectory + SSEP + reactosDirectory + SSEP + m.installBase );
                }
        }
 }
 
 void
 MingwLiveIsoModuleHandler::OutputNonModuleCopyCommands ( string& livecdDirectory,
-                                                            string& reactosDirectory )
+                                                         string& reactosDirectory )
 {
        for ( size_t i = 0; i < module.project.installfiles.size (); i++ )
        {
@@ -2850,6 +3007,15 @@ MingwTestModuleHandler::Process ()
        GenerateTestModuleTarget ();
 }
 
+void
+MingwTestModuleHandler::GetModuleSpecificSourceFiles ( vector<File*>& sourceFiles )
+{
+       string basePath = "$(INTERMEDIATE)" SSEP + module.GetBasePath ();
+       sourceFiles.push_back ( new File ( basePath + SSEP "_hooks.c", false, "", false ) );
+       sourceFiles.push_back ( new File ( basePath + SSEP "_stubs.S", false, "", false ) );
+       sourceFiles.push_back ( new File ( basePath + SSEP "_startup.c", false, "", false ) );
+}
+
 void
 MingwTestModuleHandler::GenerateTestModuleTarget ()
 {
@@ -2902,6 +3068,7 @@ MingwRpcServerModuleHandler::Process ()
        GenerateRules ();
 }
 
+
 MingwRpcClientModuleHandler::MingwRpcClientModuleHandler (
        const Module& module_ )
 
@@ -2914,3 +3081,16 @@ MingwRpcClientModuleHandler::Process ()
 {
        GenerateRules ();
 }
+
+
+MingwAliasModuleHandler::MingwAliasModuleHandler (
+       const Module& module_ )
+
+       : MingwModuleHandler ( module_ )
+{
+}
+
+void
+MingwAliasModuleHandler::Process ()
+{
+}