[rbuild] Implement delay import support for gcc in rbuild.
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 26 Jul 2009 22:36:55 +0000 (22:36 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 26 Jul 2009 22:36:55 +0000 (22:36 +0000)
As soon as you declare a library import with
<library delayimport="true"> you will link to the autogenerated delayimportlib. This will currenlty not work without a patched version of dlltool.

svn path=/trunk/; revision=42242

reactos/tools/rbuild/backend/mingw/modulehandler.cpp
reactos/tools/rbuild/backend/mingw/modulehandler.h
reactos/tools/rbuild/module.cpp
reactos/tools/rbuild/rbuild.h

index 0fe2105..f5b608d 100644 (file)
@@ -145,9 +145,23 @@ MingwModuleHandler::GetTargetFilename (
 const FileLocation*
 MingwModuleHandler::GetImportLibraryFilename (
        const Module& module,
-       string_list* pclean_files )
+       string_list* pclean_files,
+       bool delayimp )
 {
-       FileLocation *target = new FileLocation ( *module.dependency );
+       FileLocation *target;
+
+       if (module.HasImportLibrary())
+       {
+               if (delayimp)
+               {
+                       target = new FileLocation ( *module.delayImportLibrary->target );
+               }
+               else
+                       target = new FileLocation ( *module.importLibrary->target );
+       }
+       else
+               target = new FileLocation ( *module.dependency );
+
        if ( pclean_files )
        {
                string_list& clean_files = *pclean_files;
@@ -324,7 +338,8 @@ MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
 
 string
 MingwModuleHandler::GetImportLibraryDependency (
-       const Module& importedModule )
+       const Module& importedModule,
+       bool delayimp )
 {
        string dep;
        if ( ReferenceObjects ( importedModule ) )
@@ -346,7 +361,7 @@ MingwModuleHandler::GetImportLibraryDependency (
        }
        else
        {
-               const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL );
+               const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL, delayimp );
                dep = backend->GetFullName ( *library_target );
                delete library_target;
        }
@@ -358,7 +373,7 @@ MingwModuleHandler::GetImportLibraryDependency (
                for ( size_t i = 0; i < libraries.size (); ++ i )
                {
                        dep += " ";
-                       dep += GetImportLibraryDependency ( *libraries[i]->importedModule );
+                       dep += GetImportLibraryDependency ( *libraries[i]->importedModule, libraries[i]->delayimp );
                }
        }
 
@@ -378,7 +393,7 @@ MingwModuleHandler::GetTargets ( const Module& dependencyModule,
                }
        }
        else
-               targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
+               targets.push_back ( GetImportLibraryDependency ( dependencyModule, false ) );
 }
 
 void
@@ -746,7 +761,7 @@ MingwModuleHandler::GenerateImportLibraryDependenciesFromVector (
                        dependencies += " \\\n\t\t", wrap_count = 0;
                else if ( dependencies.size () > 0 )
                        dependencies += " ";
-               dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule );
+               dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule, libraries[i]->delayimp );
        }
        return dependencies;
 }
@@ -2135,42 +2150,57 @@ MingwModuleHandler::GetDefinitionFilename () const
 }
 
 void
-MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
+MingwModuleHandler::GenerateImportLibraryTarget (
+       const FileLocation *defFilename,
+       const FileLocation *library_target,
+       bool delayimp)
 {
-       if ( module.importLibrary != NULL )
-       {
-               const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files );
-               const FileLocation *defFilename = GetDefinitionFilename ();
-               string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
+       string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
 
-               fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" );
+       fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" );
 
-               fprintf ( fMakefile, "%s:",
-                         backend->GetFullName ( *library_target ).c_str () );
+       fprintf ( fMakefile, "%s:",
+                 backend->GetFullName ( *library_target ).c_str () );
 
-               if ( defFilename )
-               {
-                       fprintf ( fMakefile, " %s",
-                                 backend->GetFullName ( *defFilename ).c_str () );
-               }
+       if ( defFilename )
+       {
+               fprintf ( fMakefile, " %s",
+                         backend->GetFullName ( *defFilename ).c_str () );
+       }
 
-               fprintf ( fMakefile, " | %s\n",
-                         backend->GetFullPath ( *library_target ).c_str () );
+       fprintf ( fMakefile, " | %s\n",
+                 backend->GetFullPath ( *library_target ).c_str () );
 
-               fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
+       fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
 
-               fprintf ( fMakefile,
-                         "\t${dlltool} --dllname %s --def %s --output-lib %s%s%s\n\n",
-                         module.GetDllName ().c_str (),
-                         defFilename ? backend->GetFullName ( *defFilename ).c_str ()
-                                     : empty.c_str (),
-                         backend->GetFullName ( *library_target ).c_str (),
-                         module.mangledSymbols ? "" : " --kill-at",
-                         module.underscoreSymbols ? " --add-underscore" : "" );
+       fprintf ( fMakefile,
+                 "\t${dlltool} --dllname %s --def %s %s %s%s%s\n\n",
+                 module.GetDllName ().c_str (),
+                 defFilename ? backend->GetFullName ( *defFilename ).c_str ()
+                             : empty.c_str (),
+                 delayimp ? "--output-delaylib" : "--output-lib",
+                 backend->GetFullName ( *library_target ).c_str (),
+                 module.mangledSymbols ? "" : " --kill-at",
+                 module.underscoreSymbols ? " --add-underscore" : "" );
+}
+
+void
+MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
+{
+       if ( module.importLibrary != NULL )
+       {
+               const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files, false );
+               const FileLocation *delayimp_target = GetImportLibraryFilename ( module, &clean_files, true );
+               const FileLocation *defFilename = GetDefinitionFilename ();
+
+               GenerateImportLibraryTarget(defFilename, library_target, false);
+               GenerateImportLibraryTarget(defFilename, delayimp_target, true);
 
                if ( defFilename )
                        delete defFilename;
                delete library_target;
+               delete delayimp_target;
+
        }
 }
 
index 5b02cb9..de93eeb 100644 (file)
@@ -57,7 +57,8 @@ public:
 
        static const FileLocation* GetImportLibraryFilename (
                const Module& module,
-               string_list* pclean_files );
+               string_list* pclean_files,
+               bool delayimp );
 
        static std::string GenerateGccDefineParametersFromVector ( const std::vector<Define*>& defines, std::set<std::string> &used_defs );
        static std::string GenerateDefineParametersFromVector ( const std::vector<Define*>& defines, CompilerType compiler );
@@ -95,7 +96,7 @@ protected:
        std::string GetBasename ( const std::string& filename ) const;
        std::string GetCompilationUnitDependencies ( const CompilationUnit& compilationUnit ) const;
        const FileLocation* GetModuleArchiveFilename () const;
-       std::string GetImportLibraryDependency ( const Module& importedModule );
+       std::string GetImportLibraryDependency ( const Module& importedModule, bool delayimp );
        void GetTargets ( const Module& dependencyModule,
                          string_list& targets );
        void GetModuleDependencies ( string_list& dependencies );
@@ -118,6 +119,7 @@ protected:
        void GeneratePhonyTarget() const;
        void GenerateBuildMapCode ( const FileLocation *mapTarget = NULL );
        void GenerateRules ();
+       void GenerateImportLibraryTarget (const FileLocation *defFilename, const FileLocation *library_target, bool delayimp);
        void GenerateImportLibraryTargetIfNeeded ();
        void GetDefinitionDependencies ( std::vector<FileLocation>& dependencies ) const;
        std::string GetLinkingDependencies () const;
index 0078952..af4b253 100644 (file)
@@ -260,6 +260,7 @@ Module::Module ( const Project& project,
        : project (project),
          node (moduleNode),
          importLibrary (NULL),
+         delayImportLibrary (NULL),
          metadata (NULL),
          bootSector (NULL),
          bootstrap (NULL),
@@ -715,7 +716,10 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
        }
        else if ( e.name == "library" && e.value.size () )
        {
+               const XMLAttribute* att = e.GetAttribute ( "delayimport", false );
                Library* pLibrary = new Library ( e, *this, e.value );
+               if ( att && !stricmp ( att->value.c_str(), "true" ) )
+                       pLibrary->delayimp = true;
                non_if_data.libraries.push_back ( pLibrary );
                subs_invalid = true;
        }
@@ -780,7 +784,8 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                                e.location,
                                "Only one <importlibrary> is valid per module" );
                }
-               SetImportLibrary ( new ImportLibrary ( project, e, this ) );
+               SetImportLibrary ( new ImportLibrary ( project, e, this, false ) );
+               SetDelayImportLibrary ( new ImportLibrary ( project, e, this, true ) );
                subs_invalid = true;
        }
        else if ( e.name == "if" || e.name == "ifnot" )
@@ -1420,6 +1425,12 @@ Module::SetImportLibrary ( ImportLibrary* importLibrary )
                                        HasImportLibrary () ? "lib" + name + ".a" : output->name );
 }
 
+void
+Module::SetDelayImportLibrary ( ImportLibrary* importLibrary )
+{
+       this->delayImportLibrary = importLibrary;
+}
+
 std::string
 Module::GetDllName () const
 {
@@ -1482,7 +1493,8 @@ Library::Library ( const XMLElement& _node,
        : node(&_node),
          module(_module),
          name(_name),
-         importedModule(_module.project.LocateModule(_name))
+         importedModule(_module.project.LocateModule(_name)),
+         delayimp(false)
 {
        if ( module.name == name )
        {
@@ -1506,7 +1518,8 @@ Library::Library ( const Module& _module,
        : node(NULL),
          module(_module),
          name(_name),
-         importedModule(_module.project.LocateModule(_name))
+         importedModule(_module.project.LocateModule(_name)),
+         delayimp(false)
 {
        if ( !importedModule )
        {
@@ -1817,12 +1830,14 @@ Metadata::Metadata ( const XMLElement& _node,
 ImportLibrary::~ImportLibrary ()
 {
        delete source;
+       delete target;
 }
 
 
 ImportLibrary::ImportLibrary ( const Project& project,
                                const XMLElement& node,
-                               const Module* module )
+                               const Module* module,
+                               bool delayimp )
        : XmlNode ( project, node ),
          module (module)
 {
@@ -1889,6 +1904,11 @@ ImportLibrary::ImportLibrary ( const Project& project,
                                            name,
                                            &node );
        }
+
+       target = new FileLocation ( IntermediateDirectory,
+                                   base->output->relative_path,
+                                   "lib" + module->name + (delayimp ? ".delayimp.a" :  ".a" ));
+
 }
 
 
index 6b43e79..13baa2e 100644 (file)
@@ -377,6 +377,7 @@ public:
        std::string buildtype;
        ModuleType type;
        ImportLibrary* importLibrary;
+       ImportLibrary* delayImportLibrary;
        Metadata* metadata;
        Bootsector* bootSector;
        bool mangledSymbols;
@@ -429,6 +430,7 @@ public:
        std::string GetDllName() const;
 private:
        void SetImportLibrary ( ImportLibrary* importLibrary );
+       void SetDelayImportLibrary ( ImportLibrary* importLibrary );
        DirectoryLocation GetTargetDirectoryTree () const;
        std::string GetDefaultModuleExtension () const;
        std::string GetDefaultModuleEntrypoint () const;
@@ -555,6 +557,7 @@ public:
        const Module& module;
        std::string name;
        const Module* importedModule;
+       bool delayimp;
 
        Library ( const XMLElement& _node,
                  const Module& _module,
@@ -655,10 +658,12 @@ public:
        const Module* module;
        std::string dllname;
        FileLocation *source;
+       FileLocation *target;
 
        ImportLibrary ( const Project& project,
                        const XMLElement& node,
-                       const Module* module );
+                       const Module* module,
+                       bool delayimp );
        ~ImportLibrary ();
 };