Add new PEFIXUP tool and use it in the build system.
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index f0663aa..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;
 }
@@ -633,13 +692,24 @@ MingwModuleHandler::GenerateMacro (
        const IfableData& data )
 {
        size_t i;
+       bool generateAssignment;
+
+       generateAssignment = (use_pch && module.pch != NULL ) || data.includes.size () > 0 || data.defines.size () > 0 || data.compilerFlags.size () > 0;
+       if ( generateAssignment )
+       {
+               fprintf ( fMakefile,
+                         "%s %s",
+                         macro.c_str(),
+                         assignmentOperation );
+       }
+
+       if ( use_pch && module.pch != NULL )
+       {
+               fprintf ( fMakefile,
+                         " -I%s",
+                         GetDirectory ( GetPrecompiledHeaderFilename () ).c_str () );
+       }
 
-       fprintf (
-               fMakefile,
-               "%s %s",
-               macro.c_str(),
-               assignmentOperation );
-       
        string compilerParameters = GenerateCompilerParametersFromVector ( data.compilerFlags );
        if ( compilerParameters.size () > 0 )
        {
@@ -651,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++ )
        {
@@ -669,7 +748,10 @@ MingwModuleHandler::GenerateMacro (
                                "=%s",
                                d.value.c_str() );
        }
-       fprintf ( fMakefile, "\n" );
+       if ( generateAssignment )
+       {
+               fprintf ( fMakefile, "\n" );
+       }
 }
 
 void
@@ -680,15 +762,12 @@ MingwModuleHandler::GenerateMacros (
 {
        size_t i;
 
-       if ( data.includes.size () > 0 || data.defines.size () > 0 || data.compilerFlags.size () > 0 )
-       {
-               GenerateMacro ( assignmentOperation,
-                               cflagsMacro,
-                               data );
-               GenerateMacro ( assignmentOperation,
-                               windresflagsMacro,
-                               data );
-       }
+       GenerateMacro ( assignmentOperation,
+                       cflagsMacro,
+                       data );
+       GenerateMacro ( assignmentOperation,
+                       windresflagsMacro,
+                       data );
        
        if ( linkerFlags != NULL )
        {
@@ -844,18 +923,31 @@ MingwModuleHandler::GenerateObjectMacros (
        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->file.name + ".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 (
@@ -1019,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
@@ -1032,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);
 
@@ -1065,7 +1153,8 @@ MingwModuleHandler::GenerateWidlCommandsServer (
 string
 MingwModuleHandler::GetRpcClientHeaderFilename ( string basename ) const
 {
-       return basename + "_c.h";
+       return PassThruCacheDirectory ( basename + "_c.h",
+                                       backend->intermediateDirectory );
 }
 
 void
@@ -1078,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);
 
@@ -1135,6 +1219,7 @@ MingwModuleHandler::GenerateCommands (
        if ( extension == ".c" || extension == ".C" )
        {
                GenerateGccCommand ( file.name,
+                                    "",
                                     cc,
                                     cflagsMacro );
                return;
@@ -1144,6 +1229,7 @@ MingwModuleHandler::GenerateCommands (
                  extension == ".cxx" || extension == ".CXX" )
        {
                GenerateGccCommand ( file.name,
+                                    "",
                                     cppc,
                                     cflagsMacro );
                return;
@@ -1171,6 +1257,7 @@ MingwModuleHandler::GenerateCommands (
        {
                GenerateWinebuildCommands ( file.name );
                GenerateGccCommand ( GetActualSourceFilename ( file.name ),
+                                    "",
                                     cc,
                                     cflagsMacro );
                return;
@@ -1180,6 +1267,7 @@ MingwModuleHandler::GenerateCommands (
                GenerateWidlCommands ( file,
                                       widlflagsMacro );
                GenerateGccCommand ( GetActualSourceFilename ( file.name ),
+                                    GetExtraDependencies ( file.name ),
                                     cc,
                                     cflagsMacro );
                return;
@@ -1255,7 +1343,7 @@ MingwModuleHandler::GenerateBuildNonSymbolStrippedCode ()
 
 void
 MergeStringVector ( const vector<string>& input,
-                       vector<string>& output )
+                    vector<string>& output )
 {
        int wrap_at = 25;
        string s;
@@ -1331,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 (),
@@ -1362,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 () );
@@ -1458,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->file.name;
-               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,
@@ -1584,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 ) );
                                }
                        }
@@ -1626,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;
@@ -1638,7 +1724,6 @@ MingwModuleHandler::GenerateOtherMacros ()
                                GetSpecObjectDependencies ( s, file.name );
                }
        }
-       GetRpcHeaderDependencies ( s );
        if ( s.size () > 0 )
        {
                fprintf (
@@ -1972,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
@@ -2072,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 () );
@@ -2159,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,
@@ -2206,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,
@@ -2252,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,
@@ -2350,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,
@@ -2801,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 );
                }
        }
 }
@@ -2981,6 +3068,7 @@ MingwRpcServerModuleHandler::Process ()
        GenerateRules ();
 }
 
+
 MingwRpcClientModuleHandler::MingwRpcClientModuleHandler (
        const Module& module_ )
 
@@ -2993,3 +3081,16 @@ MingwRpcClientModuleHandler::Process ()
 {
        GenerateRules ();
 }
+
+
+MingwAliasModuleHandler::MingwAliasModuleHandler (
+       const Module& module_ )
+
+       : MingwModuleHandler ( module_ )
+{
+}
+
+void
+MingwAliasModuleHandler::Process ()
+{
+}