[rbuild] Implement delay import support for gcc in rbuild.

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
This commit is contained in:
Timo Kreuzer 2009-07-26 22:36:55 +00:00
parent 3f10e1dc73
commit 250737d475
4 changed files with 97 additions and 40 deletions

View file

@ -145,9 +145,23 @@ MingwModuleHandler::GetTargetFilename (
const FileLocation* const FileLocation*
MingwModuleHandler::GetImportLibraryFilename ( MingwModuleHandler::GetImportLibraryFilename (
const Module& module, 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 ) if ( pclean_files )
{ {
string_list& clean_files = *pclean_files; string_list& clean_files = *pclean_files;
@ -324,7 +338,8 @@ MingwModuleHandler::OutputCopyCommand ( const FileLocation& source,
string string
MingwModuleHandler::GetImportLibraryDependency ( MingwModuleHandler::GetImportLibraryDependency (
const Module& importedModule ) const Module& importedModule,
bool delayimp )
{ {
string dep; string dep;
if ( ReferenceObjects ( importedModule ) ) if ( ReferenceObjects ( importedModule ) )
@ -346,7 +361,7 @@ MingwModuleHandler::GetImportLibraryDependency (
} }
else else
{ {
const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL ); const FileLocation *library_target = GetImportLibraryFilename ( importedModule, NULL, delayimp );
dep = backend->GetFullName ( *library_target ); dep = backend->GetFullName ( *library_target );
delete library_target; delete library_target;
} }
@ -358,7 +373,7 @@ MingwModuleHandler::GetImportLibraryDependency (
for ( size_t i = 0; i < libraries.size (); ++ i ) for ( size_t i = 0; i < libraries.size (); ++ i )
{ {
dep += " "; dep += " ";
dep += GetImportLibraryDependency ( *libraries[i]->importedModule ); dep += GetImportLibraryDependency ( *libraries[i]->importedModule, libraries[i]->delayimp );
} }
} }
@ -378,7 +393,7 @@ MingwModuleHandler::GetTargets ( const Module& dependencyModule,
} }
} }
else else
targets.push_back ( GetImportLibraryDependency ( dependencyModule ) ); targets.push_back ( GetImportLibraryDependency ( dependencyModule, false ) );
} }
void void
@ -746,7 +761,7 @@ MingwModuleHandler::GenerateImportLibraryDependenciesFromVector (
dependencies += " \\\n\t\t", wrap_count = 0; dependencies += " \\\n\t\t", wrap_count = 0;
else if ( dependencies.size () > 0 ) else if ( dependencies.size () > 0 )
dependencies += " "; dependencies += " ";
dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule ); dependencies += GetImportLibraryDependency ( *libraries[i]->importedModule, libraries[i]->delayimp );
} }
return dependencies; return dependencies;
} }
@ -2134,43 +2149,58 @@ MingwModuleHandler::GetDefinitionFilename () const
} }
} }
void
MingwModuleHandler::GenerateImportLibraryTarget (
const FileLocation *defFilename,
const FileLocation *library_target,
bool delayimp)
{
string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" );
fprintf ( fMakefile, "%s:",
backend->GetFullName ( *library_target ).c_str () );
if ( defFilename )
{
fprintf ( fMakefile, " %s",
backend->GetFullName ( *defFilename ).c_str () );
}
fprintf ( fMakefile, " | %s\n",
backend->GetFullPath ( *library_target ).c_str () );
fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
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 void
MingwModuleHandler::GenerateImportLibraryTargetIfNeeded () MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
{ {
if ( module.importLibrary != NULL ) if ( module.importLibrary != NULL )
{ {
const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files ); const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files, false );
const FileLocation *delayimp_target = GetImportLibraryFilename ( module, &clean_files, true );
const FileLocation *defFilename = GetDefinitionFilename (); const FileLocation *defFilename = GetDefinitionFilename ();
string empty = "tools" + sSep + "rbuild" + sSep + "empty.def";
fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" ); GenerateImportLibraryTarget(defFilename, library_target, false);
GenerateImportLibraryTarget(defFilename, delayimp_target, true);
fprintf ( fMakefile, "%s:",
backend->GetFullName ( *library_target ).c_str () );
if ( defFilename )
{
fprintf ( fMakefile, " %s",
backend->GetFullName ( *defFilename ).c_str () );
}
fprintf ( fMakefile, " | %s\n",
backend->GetFullPath ( *library_target ).c_str () );
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" : "" );
if ( defFilename ) if ( defFilename )
delete defFilename; delete defFilename;
delete library_target; delete library_target;
delete delayimp_target;
} }
} }

View file

@ -57,7 +57,8 @@ public:
static const FileLocation* GetImportLibraryFilename ( static const FileLocation* GetImportLibraryFilename (
const Module& module, 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 GenerateGccDefineParametersFromVector ( const std::vector<Define*>& defines, std::set<std::string> &used_defs );
static std::string GenerateDefineParametersFromVector ( const std::vector<Define*>& defines, CompilerType compiler ); 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 GetBasename ( const std::string& filename ) const;
std::string GetCompilationUnitDependencies ( const CompilationUnit& compilationUnit ) const; std::string GetCompilationUnitDependencies ( const CompilationUnit& compilationUnit ) const;
const FileLocation* GetModuleArchiveFilename () const; const FileLocation* GetModuleArchiveFilename () const;
std::string GetImportLibraryDependency ( const Module& importedModule ); std::string GetImportLibraryDependency ( const Module& importedModule, bool delayimp );
void GetTargets ( const Module& dependencyModule, void GetTargets ( const Module& dependencyModule,
string_list& targets ); string_list& targets );
void GetModuleDependencies ( string_list& dependencies ); void GetModuleDependencies ( string_list& dependencies );
@ -118,6 +119,7 @@ protected:
void GeneratePhonyTarget() const; void GeneratePhonyTarget() const;
void GenerateBuildMapCode ( const FileLocation *mapTarget = NULL ); void GenerateBuildMapCode ( const FileLocation *mapTarget = NULL );
void GenerateRules (); void GenerateRules ();
void GenerateImportLibraryTarget (const FileLocation *defFilename, const FileLocation *library_target, bool delayimp);
void GenerateImportLibraryTargetIfNeeded (); void GenerateImportLibraryTargetIfNeeded ();
void GetDefinitionDependencies ( std::vector<FileLocation>& dependencies ) const; void GetDefinitionDependencies ( std::vector<FileLocation>& dependencies ) const;
std::string GetLinkingDependencies () const; std::string GetLinkingDependencies () const;

View file

@ -260,6 +260,7 @@ Module::Module ( const Project& project,
: project (project), : project (project),
node (moduleNode), node (moduleNode),
importLibrary (NULL), importLibrary (NULL),
delayImportLibrary (NULL),
metadata (NULL), metadata (NULL),
bootSector (NULL), bootSector (NULL),
bootstrap (NULL), bootstrap (NULL),
@ -715,7 +716,10 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
} }
else if ( e.name == "library" && e.value.size () ) else if ( e.name == "library" && e.value.size () )
{ {
const XMLAttribute* att = e.GetAttribute ( "delayimport", false );
Library* pLibrary = new Library ( e, *this, e.value ); 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 ); non_if_data.libraries.push_back ( pLibrary );
subs_invalid = true; subs_invalid = true;
} }
@ -780,7 +784,8 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
e.location, e.location,
"Only one <importlibrary> is valid per module" ); "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; subs_invalid = true;
} }
else if ( e.name == "if" || e.name == "ifnot" ) else if ( e.name == "if" || e.name == "ifnot" )
@ -1420,6 +1425,12 @@ Module::SetImportLibrary ( ImportLibrary* importLibrary )
HasImportLibrary () ? "lib" + name + ".a" : output->name ); HasImportLibrary () ? "lib" + name + ".a" : output->name );
} }
void
Module::SetDelayImportLibrary ( ImportLibrary* importLibrary )
{
this->delayImportLibrary = importLibrary;
}
std::string std::string
Module::GetDllName () const Module::GetDllName () const
{ {
@ -1482,7 +1493,8 @@ Library::Library ( const XMLElement& _node,
: node(&_node), : node(&_node),
module(_module), module(_module),
name(_name), name(_name),
importedModule(_module.project.LocateModule(_name)) importedModule(_module.project.LocateModule(_name)),
delayimp(false)
{ {
if ( module.name == name ) if ( module.name == name )
{ {
@ -1506,7 +1518,8 @@ Library::Library ( const Module& _module,
: node(NULL), : node(NULL),
module(_module), module(_module),
name(_name), name(_name),
importedModule(_module.project.LocateModule(_name)) importedModule(_module.project.LocateModule(_name)),
delayimp(false)
{ {
if ( !importedModule ) if ( !importedModule )
{ {
@ -1817,12 +1830,14 @@ Metadata::Metadata ( const XMLElement& _node,
ImportLibrary::~ImportLibrary () ImportLibrary::~ImportLibrary ()
{ {
delete source; delete source;
delete target;
} }
ImportLibrary::ImportLibrary ( const Project& project, ImportLibrary::ImportLibrary ( const Project& project,
const XMLElement& node, const XMLElement& node,
const Module* module ) const Module* module,
bool delayimp )
: XmlNode ( project, node ), : XmlNode ( project, node ),
module (module) module (module)
{ {
@ -1889,6 +1904,11 @@ ImportLibrary::ImportLibrary ( const Project& project,
name, name,
&node ); &node );
} }
target = new FileLocation ( IntermediateDirectory,
base->output->relative_path,
"lib" + module->name + (delayimp ? ".delayimp.a" : ".a" ));
} }

View file

@ -377,6 +377,7 @@ public:
std::string buildtype; std::string buildtype;
ModuleType type; ModuleType type;
ImportLibrary* importLibrary; ImportLibrary* importLibrary;
ImportLibrary* delayImportLibrary;
Metadata* metadata; Metadata* metadata;
Bootsector* bootSector; Bootsector* bootSector;
bool mangledSymbols; bool mangledSymbols;
@ -429,6 +430,7 @@ public:
std::string GetDllName() const; std::string GetDllName() const;
private: private:
void SetImportLibrary ( ImportLibrary* importLibrary ); void SetImportLibrary ( ImportLibrary* importLibrary );
void SetDelayImportLibrary ( ImportLibrary* importLibrary );
DirectoryLocation GetTargetDirectoryTree () const; DirectoryLocation GetTargetDirectoryTree () const;
std::string GetDefaultModuleExtension () const; std::string GetDefaultModuleExtension () const;
std::string GetDefaultModuleEntrypoint () const; std::string GetDefaultModuleEntrypoint () const;
@ -555,6 +557,7 @@ public:
const Module& module; const Module& module;
std::string name; std::string name;
const Module* importedModule; const Module* importedModule;
bool delayimp;
Library ( const XMLElement& _node, Library ( const XMLElement& _node,
const Module& _module, const Module& _module,
@ -655,10 +658,12 @@ public:
const Module* module; const Module* module;
std::string dllname; std::string dllname;
FileLocation *source; FileLocation *source;
FileLocation *target;
ImportLibrary ( const Project& project, ImportLibrary ( const Project& project,
const XMLElement& node, const XMLElement& node,
const Module* module ); const Module* module,
bool delayimp );
~ImportLibrary (); ~ImportLibrary ();
}; };