Support for non-standard module base addresses
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index fbfa609..54f25a6 100644 (file)
@@ -53,10 +53,10 @@ MingwModuleHandler::~MingwModuleHandler()
 }\r
 \r
 const string &\r
-MingwModuleHandler::PassThruCacheDirectory( const string &file ) const \r
+MingwModuleHandler::PassThruCacheDirectory ( const string &file ) const \r
 {\r
-    directory_set.insert( ReplaceExtension( GetDirectory( file ), "" ) );\r
-    return file;\r
+       directory_set.insert ( GetDirectory ( file ) );\r
+       return file;\r
 }\r
 \r
 void\r
@@ -86,21 +86,11 @@ MingwModuleHandler::GetWorkingDirectory () const
        return ".";\r
 }\r
 \r
-string\r
-MingwModuleHandler::GetDirectory ( const string& filename )\r
-{\r
-       size_t index = filename.find_last_of ( CSEP );\r
-       if (index == string::npos)\r
-               return ".";\r
-       else\r
-               return filename.substr ( 0, index );\r
-}\r
-\r
 string\r
 MingwModuleHandler::GetBasename ( const string& filename ) const\r
 {\r
        size_t index = filename.find_last_of ( '.' );\r
-       if (index != string::npos)\r
+       if ( index != string::npos )\r
                return filename.substr ( 0, index );\r
        return "";\r
 }\r
@@ -111,7 +101,7 @@ MingwModuleHandler::GetActualSourceFilename ( const string& filename ) const
        string extension = GetExtension ( filename );\r
        if ( extension == ".spec" || extension == "SPEC" )\r
        {\r
-               string basename = GetBasename( filename );\r
+               string basename = GetBasename ( filename );\r
                return basename + ".stubs.c";\r
        }\r
        else\r
@@ -187,7 +177,7 @@ MingwModuleHandler::GetAllDependencies ( const Module& module ) const
 {\r
        string dependencies = GetImportLibraryDependencies ( module );\r
        string s = GetModuleDependencies ( module );\r
-       if (s.length () > 0)\r
+       if ( s.length () > 0 )\r
        {\r
                dependencies += " ";\r
                dependencies += s;\r
@@ -208,13 +198,13 @@ MingwModuleHandler::GetSourceFilenames ( const Module& module,
                        sourceFilenames += " " + GetActualSourceFilename ( module.files[i]->name );\r
        }\r
        vector<If*> ifs = module.ifs;\r
-       for ( i = 0; i < ifs.size(); i++ )\r
+       for ( i = 0; i < ifs.size (); i++ )\r
        {\r
                size_t j;\r
                If& rIf = *ifs[i];\r
-               for ( j = 0; j < rIf.ifs.size(); j++ )\r
+               for ( j = 0; j < rIf.ifs.size (); j++ )\r
                        ifs.push_back ( rIf.ifs[j] );\r
-               for ( j = 0; j < rIf.files.size(); j++ )\r
+               for ( j = 0; j < rIf.files.size (); j++ )\r
                {\r
                        if ( includeGeneratedFiles || !IsGeneratedFile ( *rIf.files[j] ) )\r
                                sourceFilenames += " " + GetActualSourceFilename ( rIf.files[j]->name );\r
@@ -248,8 +238,7 @@ MingwModuleHandler::GetObjectFilename ( const string& sourceFilename )
                newExtension = ".stubs.o";\r
        else\r
                newExtension = ".o";\r
-       return FixupTargetFilename (\r
-                       ReplaceExtension ( sourceFilename, newExtension ) );\r
+       return FixupTargetFilename ( ReplaceExtension ( sourceFilename, newExtension ) );\r
 }\r
 \r
 string\r
@@ -268,35 +257,54 @@ MingwModuleHandler::GetObjectFilenames ( const Module& module ) const
        return objectFilenames;\r
 }\r
 \r
+bool\r
+MingwModuleHandler::IncludeDirectoryTarget ( const string& directory ) const\r
+{\r
+       if ( directory == "$(ROS_INTERMEDIATE)." SSEP "tools")\r
+               return false;\r
+       else\r
+               return true;\r
+}\r
+\r
 void\r
-MingwModuleHandler::GenerateDirectoryTargets() const \r
+MingwModuleHandler::GenerateDirectoryTargets () const\r
 {\r
+       if ( directory_set.size () == 0 )\r
+               return;\r
+       \r
        set_string::iterator i;\r
-       fprintf( fMakefile, "ifneq ($(ROS_INTERMEDIATE),)\ndirectories::" );\r
+       fprintf ( fMakefile, "directories::" );\r
 \r
-       for ( i = directory_set.begin();\r
-             i != directory_set.end();\r
+       for ( i = directory_set.begin ();\r
+             i != directory_set.end ();\r
              i++ )\r
        {\r
-               fprintf ( fMakefile, " %s", i->c_str() );\r
+               if ( IncludeDirectoryTarget ( *i ) )\r
+               {\r
+                       fprintf ( fMakefile,\r
+                                 " %s",\r
+                                 i->c_str () );\r
+               }\r
        }\r
 \r
-       fprintf( fMakefile, "\n\n" );\r
+       fprintf ( fMakefile, "\n\n" );\r
 \r
-       for ( i = directory_set.begin();\r
-             i != directory_set.end();\r
+       for ( i = directory_set.begin ();\r
+             i != directory_set.end ();\r
              i++ )\r
        {\r
-               fprintf ( fMakefile, "%s ", i->c_str() );\r
+               if ( IncludeDirectoryTarget ( *i ) )\r
+               {\r
+                       fprintf ( fMakefile,\r
+                                 "%s ",\r
+                                 i->c_str () );\r
+               }\r
        }\r
 \r
        fprintf ( fMakefile, \r
-                 "::\n\t${mkdir} $@\n\n"\r
-                 "else\n"\r
-                 "directories::\n\n"\r
-                 "endif\n\n" );\r
+                 "::\n\t${mkdir} $@\n\n" );\r
 \r
-       directory_set.clear();\r
+       directory_set.clear ();\r
 }\r
 \r
 string\r
@@ -351,7 +359,7 @@ MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Includ
        for ( size_t i = 0; i < includes.size (); i++ )\r
        {\r
                Include& include = *includes[i];\r
-               if (parameters.length () > 0)\r
+               if ( parameters.length () > 0 )\r
                        parameters += " ";\r
                parameters += "-I" + include.directory;\r
        }\r
@@ -1080,40 +1088,6 @@ MingwModuleHandler::GetInvocationDependencies ( const Module& module ) const
        return dependencies;\r
 }\r
 \r
-string\r
-MingwModuleHandler::GetInvocationParameters ( const Invoke& invoke ) const\r
-{\r
-       string parameters ( "" );\r
-       size_t i;\r
-       for (i = 0; i < invoke.output.size (); i++)\r
-       {\r
-               if (parameters.length () > 0)\r
-                       parameters += " ";\r
-               InvokeFile& invokeFile = *invoke.output[i];\r
-               if (invokeFile.switches.length () > 0)\r
-               {\r
-                       parameters += invokeFile.switches;\r
-                       parameters += " ";\r
-               }\r
-               parameters += invokeFile.name;\r
-       }\r
-\r
-       for (i = 0; i < invoke.input.size (); i++)\r
-       {\r
-               if (parameters.length () > 0)\r
-                       parameters += " ";\r
-               InvokeFile& invokeFile = *invoke.input[i];\r
-               if (invokeFile.switches.length () > 0)\r
-               {\r
-                       parameters += invokeFile.switches;\r
-                       parameters += " ";\r
-               }\r
-               parameters += invokeFile.name ;\r
-       }\r
-\r
-       return parameters;\r
-}\r
-\r
 void\r
 MingwModuleHandler::GenerateInvocations ( const Module& module ) const\r
 {\r
@@ -1145,7 +1119,7 @@ MingwModuleHandler::GenerateInvocations ( const Module& module ) const
                fprintf ( fMakefile,\r
                          "\t%s %s\n\n",\r
                          FixupTargetFilename ( invoke.invokeModule->GetPath () ).c_str (),\r
-                         GetInvocationParameters ( invoke ).c_str () );\r
+                         invoke.GetParameters ().c_str () );\r
        }\r
 }\r
 \r
@@ -1156,13 +1130,31 @@ MingwModuleHandler::GetPreconditionDependenciesName ( const Module& module ) con
                          module.name.c_str () );\r
 }\r
 \r
+string\r
+MingwModuleHandler::GetDefaultDependencies ( const Module& module ) const\r
+{\r
+       /* Avoid circular dependency */\r
+       if ( module.type == BuildTool || module.name == "zlib" )\r
+               return "$(ROS_INTERMEDIATE)." SSEP "tools $(ROS_INTERMEDIATE)." SSEP "lib" SSEP "zlib";\r
+       else\r
+               return "init";\r
+}\r
+\r
 void\r
 MingwModuleHandler::GeneratePreconditionDependencies ( const Module& module ) const\r
 {\r
        string preconditionDependenciesName = GetPreconditionDependenciesName ( module );\r
        string sourceFilenames = GetSourceFilenamesWithoutGeneratedFiles ( module );\r
-       string dependencies = GetModuleDependencies ( module );\r
-       string s = GetInvocationDependencies ( module );\r
+       string dependencies = GetDefaultDependencies ( module );\r
+       string s = GetModuleDependencies ( module );\r
+       if ( s.length () > 0 )\r
+       {\r
+               if ( dependencies.length () > 0 )\r
+                       dependencies += " ";\r
+               dependencies += s;\r
+       }\r
+\r
+       s = GetInvocationDependencies ( module );\r
        if ( s.length () > 0 )\r
        {\r
                if ( dependencies.length () > 0 )\r
@@ -1234,6 +1226,9 @@ string
 MingwModuleHandler::GetDefinitionDependencies ( const Module& module ) const\r
 {\r
        string dependencies;\r
+       string dkNkmLibNoFixup = "dk/nkm/lib";\r
+       dependencies += FixupTargetFilename ( dkNkmLibNoFixup );\r
+       PassThruCacheDirectory ( dkNkmLibNoFixup + SSEP );\r
        for ( size_t i = 0; i < module.files.size (); i++ )\r
        {\r
                File& file = *module.files[i];\r
@@ -1264,6 +1259,8 @@ MingwModuleHandler::GetLinkingDependencies ( const Module& module ) const
 bool\r
 MingwModuleHandler::IsCPlusPlusModule ( const Module& module ) const\r
 {\r
+       if ( module.HasFileWithExtensions ( ".cc", ".CC" ) )\r
+               return true;\r
        if ( module.HasFileWithExtensions ( ".cxx", ".CXX" ) )\r
                return true;\r
        if ( module.HasFileWithExtensions ( ".cpp", ".CPP" ) )\r
@@ -1343,9 +1340,10 @@ MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module )
        string base_tmp = ros_junk + module.name + ".base.tmp";\r
        string junk_tmp = ros_junk + module.name + ".junk.tmp";\r
        string temp_exp = ros_junk + module.name + ".temp.exp";\r
-       string gccOptions = ssprintf ("-Wl,-T,%s" SSEP "ntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0xC0000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",\r
+       string gccOptions = 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",\r
                                      module.GetBasePath ().c_str (),\r
-                                     module.entrypoint.c_str () );\r
+                                     module.entrypoint.c_str (),\r
+                                     module.baseaddress.c_str () );\r
 \r
        GenerateMacrosAndTargetsTarget ( module );\r
 \r
@@ -1469,8 +1467,9 @@ MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Modul
                          archiveFilename.c_str (),\r
                          importLibraryDependencies.c_str () );\r
 \r
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",\r
-                                                    module.entrypoint.c_str () );\r
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",\r
+                                                    module.entrypoint.c_str (),\r
+                                                    module.baseaddress.c_str () );\r
                GenerateLinkerCommand ( module,\r
                                        "${gcc}",\r
                                        linkerParameters,\r
@@ -1526,8 +1525,9 @@ MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ( const
                          archiveFilename.c_str (),\r
                          importLibraryDependencies.c_str () );\r
 \r
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",\r
-                                                    module.entrypoint.c_str () );\r
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",\r
+                                                    module.entrypoint.c_str (),\r
+                                                    module.baseaddress.c_str () );\r
                GenerateLinkerCommand ( module,\r
                                        "${gcc}",\r
                                        linkerParameters,\r
@@ -1579,8 +1579,9 @@ MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ( const Module& modul
                          archiveFilename.c_str (),\r
                          importLibraryDependencies.c_str () );\r
 \r
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll",\r
-                                                    module.entrypoint.c_str () );\r
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll",\r
+                                                    module.entrypoint.c_str (),\r
+                                                    module.baseaddress.c_str () );\r
                GenerateLinkerCommand ( module,\r
                                        "${gcc}",\r
                                        linkerParameters,\r
@@ -1636,8 +1637,9 @@ MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ( const Module& modul
                          archiveFilename.c_str (),\r
                          importLibraryDependencies.c_str () );\r
 \r
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib",\r
-                                                    module.entrypoint.c_str () );\r
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib",\r
+                                                    module.entrypoint.c_str (),\r
+                                                    module.baseaddress.c_str () );\r
                GenerateLinkerCommand ( module,\r
                                        "${gcc}",\r
                                        linkerParameters,\r
@@ -1715,8 +1717,9 @@ MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module
                else\r
                        linker = "${gcc}";\r
 \r
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll",\r
-                                                   module.entrypoint.c_str () );\r
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll",\r
+                                                    module.entrypoint.c_str (),\r
+                                                    module.baseaddress.c_str () );\r
                GenerateLinkerCommand ( module,\r
                                        linker,\r
                                        linkerParameters,\r
@@ -1767,10 +1770,17 @@ MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ( const Module& module
                          objectFilenames.c_str (),\r
                          importLibraryDependencies.c_str () );\r
 \r
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,0x00400000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",\r
-                                                    module.entrypoint.c_str () );\r
+               string linker;\r
+               if ( IsCPlusPlusModule ( module ) )\r
+                       linker = "${gpp}";\r
+               else\r
+                       linker = "${gcc}";\r
+\r
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,console -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",\r
+                                                    module.entrypoint.c_str (),\r
+                                                    module.baseaddress.c_str () );\r
                GenerateLinkerCommand ( module,\r
-                                       "${gcc}",\r
+                                       linker,\r
                                        linkerParameters,\r
                                        objectFilenames );\r
        }\r
@@ -1825,8 +1835,9 @@ MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ( const Module& module
                else\r
                        linker = "${gcc}";\r
 \r
-               string linkerParameters = ssprintf ( "-Wl,--subsystem,windows -Wl,--entry,%s -Wl,--image-base,0x00400000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",\r
-                                                    module.entrypoint.c_str () );\r
+               string linkerParameters = ssprintf ( "-Wl,--subsystem,windows -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000",\r
+                                                    module.entrypoint.c_str (),\r
+                                                    module.baseaddress.c_str () );\r
                GenerateLinkerCommand ( module,\r
                                        linker,\r
                                        linkerParameters,\r
@@ -1943,28 +1954,37 @@ MingwIsoModuleHandler::Process ( const Module& module )
 void\r
 MingwIsoModuleHandler::GenerateIsoModuleTarget ( const Module& module )\r
 {\r
-       string isoboot = "$(ROS_INTERMEDIATE)" + FixupTargetFilename ( "boot/freeldr/bootsect/isoboot.o" );\r
+       string bootcdDirectory = "cd";\r
+       string isoboot = FixupTargetFilename ( "boot/freeldr/bootsect/isoboot.o" );\r
+       string bootcdReactosNoFixup = bootcdDirectory + "/reactos";\r
+       string bootcdReactos = FixupTargetFilename ( bootcdReactosNoFixup );\r
+       PassThruCacheDirectory ( bootcdReactos + SSEP );\r
+       string reactosInf = FixupTargetFilename ( bootcdReactosNoFixup + "/reactos.inf" );\r
+       string reactosDff = NormalizeFilename ( "bootdata/packages/reactos.dff" );\r
 \r
        fprintf ( fMakefile, ".PHONY: %s\n\n",\r
                      module.name.c_str ());\r
        fprintf ( fMakefile,\r
-                 "%s: all %s\n",\r
+                 "%s: all %s %s\n",\r
                  module.name.c_str (),\r
-                 isoboot.c_str () );\r
+                 isoboot.c_str (),\r
+                 bootcdReactos.c_str () );\r
        fprintf ( fMakefile,\r
-                 "\t${cabman} /C %s /L $(ROS_INTERMEDIATE)%s /I\n",\r
-                 FixupTargetFilename ( "bootdata/packages/reactos.dff" ).c_str (),\r
-                 FixupTargetFilename ( "bootcd/reactos" ).c_str () );\r
+                 "\t${cabman} /C %s /L %s /I\n",\r
+                 reactosDff.c_str (),\r
+                 bootcdReactos.c_str () );\r
        fprintf ( fMakefile,\r
-                 "\t${cabman} /C %s /RC $(ROS_INTERMEDIATE)%s /L $(BOOTCD_DIR)reactos /N\n",\r
-                 FixupTargetFilename ( "bootdata/packages/reactos.dff" ).c_str (),\r
-                 FixupTargetFilename ( "bootcd/reactos/reactos.inf" ).c_str () );\r
+                 "\t${cabman} /C %s /RC %s /L %s /N\n",\r
+                 reactosDff.c_str (),\r
+                 reactosInf.c_str (),\r
+                 bootcdReactos.c_str () );\r
        fprintf ( fMakefile,\r
-                 "\t- ${rm} $(ROS_INTERMEDIATE)%s\n",\r
-                 FixupTargetFilename ( "bootcd/reactos/reactos.inf" ).c_str () );\r
+                 "\t- ${rm} %s\n",\r
+                 reactosInf.c_str () );\r
        fprintf ( fMakefile,\r
-                 "\t${cdmake} -v -m -b %s $(ROS_INTERMEDIATE)bootcd REACTOS ReactOS.iso\n",\r
-                 isoboot.c_str () );\r
+                 "\t${cdmake} -v -m -b %s %s REACTOS ReactOS.iso\n",\r
+                 isoboot.c_str (),\r
+                 bootcdDirectory.c_str () );\r
        fprintf ( fMakefile,\r
                  "\n" );\r
 }\r