[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*
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;
}
@ -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
MingwModuleHandler::GenerateImportLibraryTargetIfNeeded ()
{
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 ();
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 --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" : "" );
GenerateImportLibraryTarget(defFilename, library_target, false);
GenerateImportLibraryTarget(defFilename, delayimp_target, true);
if ( defFilename )
delete defFilename;
delete library_target;
delete delayimp_target;
}
}

View 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;

View 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" ));
}

View 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 ();
};