* Build networking components
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
index 2507b79..3751437 100644 (file)
@@ -70,6 +70,15 @@ MingwModuleHandler::GetExtension ( const string& filename ) const
        return "";\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
+               return filename.substr ( 0, index );\r
+       return "";\r
+}\r
+\r
 string\r
 MingwModuleHandler::ReplaceExtension ( const string& filename,\r
                                           const string& newExtension ) const\r
@@ -80,6 +89,19 @@ MingwModuleHandler::ReplaceExtension ( const string& filename,
        return filename;\r
 }\r
 \r
+string\r
+MingwModuleHandler::GetActualSourceFilename ( const string& filename ) const\r
+{\r
+       string extension = GetExtension ( filename );\r
+       if ( extension == ".spec" || extension == "SPEC" )\r
+       {\r
+               string basename = GetBasename( filename );\r
+               return basename + ".stubs.c";\r
+       }\r
+       else\r
+               return filename;\r
+}\r
+\r
 string\r
 MingwModuleHandler::GetModuleArchiveFilename ( const Module& module ) const\r
 {\r
@@ -120,6 +142,11 @@ MingwModuleHandler::GetModuleDependencies ( const Module& module ) const
                const Module* dependencyModule = dependency->dependencyModule;\r
                dependencies += dependencyModule->GetTargets ();\r
        }\r
+       string definitionDependencies = GetDefinitionDependencies ( module );\r
+       if ( dependencies.length () > 0 && definitionDependencies.length () > 0 )\r
+               dependencies += " " + definitionDependencies;\r
+       else if ( definitionDependencies.length () > 0 )\r
+               dependencies = definitionDependencies;\r
        return dependencies;\r
 }\r
 \r
@@ -143,7 +170,7 @@ MingwModuleHandler::GetSourceFilenames ( const Module& module ) const
 \r
        string sourceFilenames ( "" );\r
        for ( i = 0; i < module.files.size (); i++ )\r
-               sourceFilenames += " " + module.files[i]->name;\r
+               sourceFilenames += " " + GetActualSourceFilename ( module.files[i]->name );\r
        vector<If*> ifs = module.ifs;\r
        for ( i = 0; i < ifs.size(); i++ )\r
        {\r
@@ -152,7 +179,7 @@ MingwModuleHandler::GetSourceFilenames ( const Module& module ) const
                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
-                       sourceFilenames += " " + rIf.files[j]->name;\r
+                       sourceFilenames += " " + GetActualSourceFilename ( rIf.files[j]->name );\r
        }\r
        return sourceFilenames;\r
 }\r
@@ -164,6 +191,8 @@ MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const
        string extension = GetExtension ( sourceFilename );\r
        if ( extension == ".rc" || extension == ".RC" )\r
                newExtension = ".coff";\r
+       else if ( extension == ".spec" || extension == ".SPEC" )\r
+               newExtension = ".stubs.o";\r
        else\r
                newExtension = ".o";\r
        return FixupTargetFilename ( ReplaceExtension ( sourceFilename,\r
@@ -314,7 +343,7 @@ MingwModuleHandler::GenerateMacro ( const char* assignmentOperation,
        }\r
        fprintf ( fMakefile, "\n" );\r
 }\r
-       \r
+\r
 void\r
 MingwModuleHandler::GenerateMacros (\r
        const char* assignmentOperation,\r
@@ -366,11 +395,15 @@ MingwModuleHandler::GenerateMacros (
                        assignmentOperation );\r
                for ( i = 0; i < files.size(); i++ )\r
                {\r
-                       fprintf (\r
-                               fMakefile,\r
-                               "%s%s",\r
-                               ( i%10 == 9 ? "\\\n\t" : " " ),\r
-                               GetObjectFilename(files[i]->name).c_str() );\r
+                       string extension = GetExtension ( files[i]->name );\r
+                       if ( extension != ".spec" && extension != ".SPEC" )\r
+                       {\r
+                               fprintf (\r
+                                       fMakefile,\r
+                                       "%s%s",\r
+                                       ( i%10 == 9 ? "\\\n\t" : " " ),\r
+                                       GetObjectFilename(files[i]->name).c_str() );\r
+                       }\r
                }\r
                fprintf ( fMakefile, "\n" );\r
        }\r
@@ -443,87 +476,155 @@ MingwModuleHandler::GenerateMacros (
                module.name.c_str () );\r
 }\r
 \r
-string\r
+void\r
 MingwModuleHandler::GenerateGccCommand ( const Module& module,\r
                                          const string& sourceFilename,\r
                                          const string& cc,\r
                                          const string& cflagsMacro ) const\r
 {\r
        string objectFilename = GetObjectFilename ( sourceFilename );\r
-       return ssprintf ( "%s -c %s -o %s %s\n",\r
-                             cc.c_str (),\r
-                             sourceFilename.c_str (),\r
-                             objectFilename.c_str (),\r
-                             cflagsMacro.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "%s: %s\n",\r
+                 objectFilename.c_str (),\r
+                 sourceFilename.c_str () );\r
+       fprintf ( fMakefile,\r
+                "\t%s -c %s -o %s %s\n",\r
+                cc.c_str (),\r
+                sourceFilename.c_str (),\r
+                objectFilename.c_str (),\r
+                cflagsMacro.c_str () );\r
 }\r
 \r
-string\r
+void\r
 MingwModuleHandler::GenerateGccAssemblerCommand ( const Module& module,\r
                                                   const string& sourceFilename,\r
                                                   const string& cc,\r
                                                   const string& cflagsMacro ) const\r
 {\r
        string objectFilename = GetObjectFilename ( sourceFilename );\r
-       return ssprintf ( "%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",\r
-                         cc.c_str (),\r
-                         sourceFilename.c_str (),\r
-                         objectFilename.c_str (),\r
-                         cflagsMacro.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "%s: %s\n",\r
+                 objectFilename.c_str (),\r
+                 sourceFilename.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",\r
+                 cc.c_str (),\r
+                 sourceFilename.c_str (),\r
+                 objectFilename.c_str (),\r
+                 cflagsMacro.c_str () );\r
 }\r
 \r
-string\r
+void\r
 MingwModuleHandler::GenerateNasmCommand ( const Module& module,\r
                                           const string& sourceFilename,\r
                                           const string& nasmflagsMacro ) const\r
 {\r
        string objectFilename = GetObjectFilename ( sourceFilename );\r
-       return ssprintf ( "%s -f win32 %s -o %s %s\n",\r
-                             "nasm",\r
-                             sourceFilename.c_str (),\r
-                             objectFilename.c_str (),\r
-                             nasmflagsMacro.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "%s: %s\n",\r
+                 objectFilename.c_str (),\r
+                 sourceFilename.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t%s -f win32 %s -o %s %s\n",\r
+                 "nasm",\r
+                 sourceFilename.c_str (),\r
+                 objectFilename.c_str (),\r
+                 nasmflagsMacro.c_str () );\r
 }\r
 \r
-string\r
+void\r
 MingwModuleHandler::GenerateWindresCommand ( const Module& module,\r
                                              const string& sourceFilename,\r
                                              const string& windresflagsMacro ) const\r
 {\r
        string objectFilename = GetObjectFilename ( sourceFilename );\r
-       return ssprintf ( "%s %s -o %s ${%s}\n",\r
-                             "${windres}",\r
-                             sourceFilename.c_str (),\r
-                             objectFilename.c_str (),\r
-                             windresflagsMacro.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "%s: %s\n",\r
+                 objectFilename.c_str (),\r
+                 sourceFilename.c_str () );\r
+       fprintf ( fMakefile,\r
+                "\t%s %s -o %s ${%s}\n",\r
+                "${windres}",\r
+                sourceFilename.c_str (),\r
+                objectFilename.c_str (),\r
+                windresflagsMacro.c_str () );\r
 }\r
 \r
-string\r
-MingwModuleHandler::GenerateCommand ( const Module& module,\r
-                                      const string& sourceFilename,\r
-                                      const string& cc,\r
-                                      const string& cflagsMacro,\r
-                                      const string& nasmflagsMacro,\r
-                                      const string& windresflagsMacro ) const\r
+void\r
+MingwModuleHandler::GenerateWinebuildCommands ( const Module& module,\r
+                                                const string& sourceFilename ) const\r
+{\r
+       string basename = GetBasename ( sourceFilename );\r
+       fprintf ( fMakefile,\r
+                 "%s.def: %s\n",\r
+                 basename.c_str (),\r
+                 sourceFilename.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t%s --def=%s -o %s.def\n",\r
+                 "${winebuild}",\r
+                 sourceFilename.c_str (),\r
+                 basename.c_str () );\r
+\r
+       fprintf ( fMakefile,\r
+                 "%s.stubs.c: %s\n",\r
+                 basename.c_str (),\r
+                 sourceFilename.c_str () );\r
+       fprintf ( fMakefile,\r
+                 "\t%s --pedll=%s -o %s.stubs.c\n",\r
+                 "${winebuild}",\r
+                 sourceFilename.c_str (),\r
+                 basename.c_str () );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateCommands ( const Module& module,\r
+                                       const string& sourceFilename,\r
+                                       const string& cc,\r
+                                       const string& cflagsMacro,\r
+                                       const string& nasmflagsMacro,\r
+                                       const string& windresflagsMacro ) const\r
 {\r
        string extension = GetExtension ( sourceFilename );\r
        if ( extension == ".c" || extension == ".C" )\r
-               return GenerateGccCommand ( module,\r
-                                           sourceFilename,\r
-                                           cc,\r
-                                           cflagsMacro );\r
+       {\r
+               GenerateGccCommand ( module,\r
+                                    sourceFilename,\r
+                                    cc,\r
+                                    cflagsMacro );\r
+               return;\r
+       }\r
        else if ( extension == ".s" || extension == ".S" )\r
-               return GenerateGccAssemblerCommand ( module,\r
-                                                    sourceFilename,\r
-                                                    cc,\r
-                                                    cflagsMacro );\r
+       {\r
+               GenerateGccAssemblerCommand ( module,\r
+                                             sourceFilename,\r
+                                             cc,\r
+                                             cflagsMacro );\r
+               return;\r
+       }\r
        else if ( extension == ".asm" || extension == ".ASM" )\r
-               return GenerateNasmCommand ( module,\r
-                                            sourceFilename,\r
-                                            nasmflagsMacro );\r
+       {\r
+               GenerateNasmCommand ( module,\r
+                                     sourceFilename,\r
+                                     nasmflagsMacro );\r
+               return;\r
+       }\r
        else if ( extension == ".rc" || extension == ".RC" )\r
-               return GenerateWindresCommand ( module,\r
-                                               sourceFilename,\r
-                                               windresflagsMacro );\r
+       {\r
+               GenerateWindresCommand ( module,\r
+                                        sourceFilename,\r
+                                        windresflagsMacro );\r
+               return;\r
+       }\r
+       else if ( extension == ".spec" || extension == ".SPEC" )\r
+       {\r
+               GenerateWinebuildCommands ( module,\r
+                                           sourceFilename );\r
+               GenerateGccCommand ( module,\r
+                                    GetActualSourceFilename ( sourceFilename ),\r
+                                    cc,\r
+                                    cflagsMacro );\r
+               return;\r
+       }\r
 \r
        throw InvalidOperationException ( __FILE__,\r
                                          __LINE__,\r
@@ -614,19 +715,14 @@ MingwModuleHandler::GenerateObjectFileTargets ( const Module& module,
        for ( i = 0; i < files.size (); i++ )\r
        {\r
                string sourceFilename = files[i]->name;\r
-               string objectFilename = GetObjectFilename ( sourceFilename );\r
-               fprintf ( fMakefile,\r
-                         "%s: %s\n",\r
-                         objectFilename.c_str (),\r
-                         sourceFilename.c_str () );\r
+               GenerateCommands ( module,\r
+                                  sourceFilename,\r
+                                  cc,\r
+                                  cflagsMacro,\r
+                                  nasmflagsMacro,\r
+                                  windresflagsMacro );\r
                fprintf ( fMakefile,\r
-                         "\t%s\n",\r
-                         GenerateCommand ( module,\r
-                                           sourceFilename,\r
-                                           cc,\r
-                                           cflagsMacro,\r
-                                           nasmflagsMacro,\r
-                                           windresflagsMacro ).c_str () );\r
+                         "\n" );\r
        }\r
 \r
        for ( i = 0; i < ifs.size(); i++ )\r
@@ -937,8 +1033,10 @@ MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ( const Module& module )
 {\r
        if ( module.importLibrary != NULL )\r
        {\r
-               fprintf ( fMakefile, "%s:\n",\r
-                         module.GetDependencyPath ().c_str () );\r
+               string definitionDependencies = GetDefinitionDependencies ( module );\r
+               fprintf ( fMakefile, "%s: %s\n",\r
+                         module.GetDependencyPath ().c_str (),\r
+                         definitionDependencies.c_str () );\r
 \r
                fprintf ( fMakefile,\r
                          "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",\r
@@ -948,6 +1046,44 @@ MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ( const Module& module )
        }\r
 }\r
 \r
+string\r
+MingwModuleHandler::GetSpecObjectDependencies ( const string& filename ) const\r
+{\r
+       string basename = GetBasename ( filename );\r
+       return basename + ".def" + " " + basename + ".stubs.c";\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetDefinitionDependencies ( const Module& module ) const\r
+{\r
+       string dependencies;\r
+       for ( size_t i = 0; i < module.files.size (); i++ )\r
+       {\r
+               File& file = *module.files[i];\r
+               string extension = GetExtension ( file.name );\r
+               if ( extension == ".spec" || extension == ".SPEC" )\r
+               {\r
+                       if ( dependencies.length () > 0 )\r
+                               dependencies += " ";\r
+                       dependencies += GetSpecObjectDependencies ( file.name );\r
+               }\r
+       }\r
+       return dependencies;\r
+}\r
+\r
+string\r
+MingwModuleHandler::GetLinkingDependencies ( const Module& module ) const\r
+{\r
+       string dependencies = GetImportLibraryDependencies ( module );\r
+       string s = GetDefinitionDependencies ( module );\r
+       if ( s.length () > 0 )\r
+       {\r
+               dependencies += " ";\r
+               dependencies += s;\r
+       }\r
+       return dependencies;\r
+}\r
+\r
 \r
 static MingwBuildToolModuleHandler buildtool_handler;\r
 \r
@@ -1141,6 +1277,7 @@ MingwKernelModeDriverModuleHandler::Process ( const Module& module )
        GenerateInvocations ( module );\r
 }\r
 \r
+\r
 void\r
 MingwKernelModeDriverModuleHandler::GenerateKernelModeDriverModuleTarget ( const Module& module )\r
 {\r
@@ -1253,8 +1390,8 @@ MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module
        static string ros_junk ( "$(ROS_TEMPORARY)" );\r
        string target ( FixupTargetFilename ( module.GetPath () ) );\r
        string workingDirectory = GetWorkingDirectory ( );\r
-       string archiveFilename = GetModuleArchiveFilename ( module );\r
-       string importLibraryDependencies = GetImportLibraryDependencies ( module );\r
+       string objectFilenames = GetObjectFilenames ( module );\r
+       string linkingDependencies = GetLinkingDependencies ( module );\r
 \r
        GenerateImportLibraryTargetIfNeeded ( module );\r
 \r
@@ -1264,14 +1401,14 @@ MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module
 \r
                fprintf ( fMakefile, "%s: %s %s\n",\r
                          target.c_str (),\r
-                         archiveFilename.c_str (),\r
-                         importLibraryDependencies.c_str () );\r
+                         objectFilenames.c_str (),\r
+                         linkingDependencies.c_str () );\r
 \r
                string linkerParameters ( "-Wl,--subsystem,console -Wl,--entry,_DllMain@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll" );\r
                GenerateLinkerCommand ( module,\r
                                 "${gcc}",\r
                                 linkerParameters,\r
-                                archiveFilename );\r
+                                objectFilenames );\r
        }\r
        else\r
        {\r