Add new PEFIXUP tool and use it in the build system.
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index c9d6361..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>
 
@@ -220,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,
@@ -270,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
 {
@@ -435,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) )
@@ -615,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;
 }
@@ -647,7 +706,7 @@ MingwModuleHandler::GenerateMacro (
        if ( use_pch && module.pch != NULL )
        {
                fprintf ( fMakefile,
-                         " -I %s",
+                         " -I%s",
                          GetDirectory ( GetPrecompiledHeaderFilename () ).c_str () );
        }
 
@@ -662,10 +721,19 @@ MingwModuleHandler::GenerateMacro (
 
        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++ )
        {
@@ -866,15 +934,20 @@ MingwModuleHandler::GetPrecompiledHeaderFilename () const
 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 += " " + 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 (
@@ -1038,7 +1111,8 @@ MingwModuleHandler::GetWidlFlags ( const File& file )
 string
 MingwModuleHandler::GetRpcServerHeaderFilename ( string basename ) const
 {
-       return basename + "_s.h";
+       return PassThruCacheDirectory ( basename + "_s.h",
+                                       backend->intermediateDirectory );
 }
                
 void
@@ -1051,11 +1125,6 @@ MingwModuleHandler::GenerateWidlCommandsServer (
 
        string basename = GetBasename ( file.name );
 
-       /*string generatedHeaderFilename = PassThruCacheDirectory (
-               basename + ".h",
-               backend->intermediateDirectory );
-       CLEAN_FILE(generatedHeaderFilename);
-       */
        string generatedHeaderFilename = GetRpcServerHeaderFilename ( basename );
        CLEAN_FILE(generatedHeaderFilename);
 
@@ -1084,7 +1153,8 @@ MingwModuleHandler::GenerateWidlCommandsServer (
 string
 MingwModuleHandler::GetRpcClientHeaderFilename ( string basename ) const
 {
-       return basename + "_c.h";
+       return PassThruCacheDirectory ( basename + "_c.h",
+                                       backend->intermediateDirectory );
 }
 
 void
@@ -1097,11 +1167,6 @@ MingwModuleHandler::GenerateWidlCommandsClient (
 
        string basename = GetBasename ( file.name );
 
-       /*string generatedHeaderFilename = PassThruCacheDirectory (
-               basename + ".h",
-               backend->intermediateDirectory );
-       CLEAN_FILE(generatedHeaderFilename);
-       */
        string generatedHeaderFilename = GetRpcClientHeaderFilename ( basename );
        CLEAN_FILE(generatedHeaderFilename);
 
@@ -1154,6 +1219,7 @@ MingwModuleHandler::GenerateCommands (
        if ( extension == ".c" || extension == ".C" )
        {
                GenerateGccCommand ( file.name,
+                                    "",
                                     cc,
                                     cflagsMacro );
                return;
@@ -1163,6 +1229,7 @@ MingwModuleHandler::GenerateCommands (
                  extension == ".cxx" || extension == ".CXX" )
        {
                GenerateGccCommand ( file.name,
+                                    "",
                                     cppc,
                                     cflagsMacro );
                return;
@@ -1190,6 +1257,7 @@ MingwModuleHandler::GenerateCommands (
        {
                GenerateWinebuildCommands ( file.name );
                GenerateGccCommand ( GetActualSourceFilename ( file.name ),
+                                    "",
                                     cc,
                                     cflagsMacro );
                return;
@@ -1199,6 +1267,7 @@ MingwModuleHandler::GenerateCommands (
                GenerateWidlCommands ( file,
                                       widlflagsMacro );
                GenerateGccCommand ( GetActualSourceFilename ( file.name ),
+                                    GetExtraDependencies ( file.name ),
                                     cc,
                                     cflagsMacro );
                return;
@@ -1274,7 +1343,7 @@ MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
 
 void
 MergeStringVector ( const vector<string>& input,
-                       vector<string>& output )
+                    vector<string>& output )
 {
        int wrap_at = 25;
        string s;
@@ -1350,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 (),
@@ -1381,6 +1450,10 @@ 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 () );
@@ -1598,25 +1671,24 @@ MingwModuleHandler::GenerateTargetMacro ()
 
 void
 MingwModuleHandler::GetRpcHeaderDependencies (
-       string_list& dependencies ) const
+       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.imported_module->type == RpcServer ||
-                    library.imported_module->type == RpcClient )
+               if ( library.importedModule->type == RpcServer ||
+                    library.importedModule->type == RpcClient )
                {
-
-                       for ( size_t j = 0; j < library.imported_module->non_if_data.files.size (); j++ )
+                       for ( size_t j = 0; j < library.importedModule->non_if_data.files.size (); j++ )
                        {
-                               File& file = *library.imported_module->non_if_data.files[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.imported_module->type == RpcServer )
+                                       if ( library.importedModule->type == RpcServer )
                                                dependencies.push_back ( GetRpcServerHeaderFilename ( basename ) );
-                                       if ( library.imported_module->type == RpcClient )
+                                       if ( library.importedModule->type == RpcClient )
                                                dependencies.push_back ( GetRpcClientHeaderFilename ( basename ) );
                                }
                        }
@@ -1640,7 +1712,7 @@ MingwModuleHandler::GenerateOtherMacros ()
                module.non_if_data,
                &module.linkerFlags );
 
-       string_list s;
+       vector<string> s;
        if ( module.importLibrary )
        {
                const vector<File*>& files = module.non_if_data.files;
@@ -1652,7 +1724,6 @@ MingwModuleHandler::GenerateOtherMacros ()
                                GetSpecObjectDependencies ( s, file.name );
                }
        }
-       GetRpcHeaderDependencies ( s );
        if ( s.size () > 0 )
        {
                fprintf (
@@ -1986,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
@@ -2086,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 () );
@@ -2173,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,
@@ -2220,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,
@@ -2266,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,
@@ -2364,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,
@@ -2815,12 +2887,13 @@ MingwLiveIsoModuleHandler::OutputModuleCopyCommands ( string& livecdDirectory,
                        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 );
                }
        }
 }
@@ -2995,6 +3068,7 @@ MingwRpcServerModuleHandler::Process ()
        GenerateRules ();
 }
 
+
 MingwRpcClientModuleHandler::MingwRpcClientModuleHandler (
        const Module& module_ )
 
@@ -3007,3 +3081,16 @@ MingwRpcClientModuleHandler::Process ()
 {
        GenerateRules ();
 }
+
+
+MingwAliasModuleHandler::MingwAliasModuleHandler (
+       const Module& module_ )
+
+       : MingwModuleHandler ( module_ )
+{
+}
+
+void
+MingwAliasModuleHandler::Process ()
+{
+}