From: Mikko Rasa Date: Fri, 28 Sep 2012 12:36:43 +0000 (+0300) Subject: Generate export definitions with dlltool X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=a957405689fafa1afc233182a3756e36ea34281c;p=builder.git Generate export definitions with dlltool Having it as a side effect was causing trouble with rebuild check, and it's cleaner to build each file separately anyway. --- diff --git a/source/exportdefinitions.cpp b/source/exportdefinitions.cpp index cc50e16..8fbf76e 100644 --- a/source/exportdefinitions.cpp +++ b/source/exportdefinitions.cpp @@ -1,14 +1,17 @@ #include "component.h" #include "exportdefinitions.h" +#include "objectfile.h" #include "sourcepackage.h" +using namespace std; using namespace Msp; -ExportDefinitions::ExportDefinitions(Builder &b, const Component &c, SharedLibrary &l): - FileTarget(b, c.get_package(), generate_target_path(c)), - lib(l) +ExportDefinitions::ExportDefinitions(Builder &b, const Component &c, const list &objs): + FileTarget(b, c.get_package(), generate_target_path(c)) { component = &c; + for(list::const_iterator i=objs.begin(); i!=objs.end(); ++i) + add_dependency(**i); } FS::Path ExportDefinitions::generate_target_path(const Component &comp) diff --git a/source/exportdefinitions.h b/source/exportdefinitions.h index 73d6f0f..22ba94b 100644 --- a/source/exportdefinitions.h +++ b/source/exportdefinitions.h @@ -3,25 +3,20 @@ #include "filetarget.h" -class SharedLibrary; +class ObjectFile; /** An export definition file for a shared library. Only used on Windows. */ class ExportDefinitions: public FileTarget { -private: - SharedLibrary &lib; - public: - ExportDefinitions(Builder &, const Component &, SharedLibrary &); + ExportDefinitions(Builder &, const Component &, const std::list &); private: static Msp::FS::Path generate_target_path(const Component &); public: virtual const char *get_type() const { return "ExportDefinitions"; } - - SharedLibrary &get_library() const { return lib; } }; #endif diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index cd40a85..ede0119 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -74,11 +74,8 @@ Target *GnuLinker::create_target(const list &sources, const string &ar SharedLibrary *shlib = new SharedLibrary(builder, comp, objs); if(architecture->get_system()=="windows") { - ExportDefinitions *exp = new ExportDefinitions(builder, comp, *shlib); - shlib->add_side_effect(*exp); const Tool &dlltool = builder.get_toolchain().get_tool("DLL"); - ImportLibrary *imp = dynamic_cast(dlltool.create_target(*exp)); - shlib->set_import_library(imp); + dlltool.create_target(*shlib); } bin = shlib; } @@ -176,12 +173,6 @@ Task *GnuLinker::Linker::run(const Target &target) const { argv.push_back("-shared"); argv.push_back("-fPIC"); - const Target::Dependencies &side_eff = target.get_side_effects(); - for(Target::Dependencies::const_iterator i=side_eff.begin(); i!=side_eff.end(); ++i) - { - if(ExportDefinitions *exp = dynamic_cast(*i)) - argv.push_back("-Wl,--output-def,"+relative(exp->get_path(), work_dir).str()); - } if(architecture->get_system()!="windows" && !shlib->get_soname().empty()) argv.push_back("-Wl,-soname,"+shlib->get_soname()); } diff --git a/source/importlibrary.cpp b/source/importlibrary.cpp index 9ac441f..0fb5f72 100644 --- a/source/importlibrary.cpp +++ b/source/importlibrary.cpp @@ -2,6 +2,7 @@ #include "component.h" #include "exportdefinitions.h" #include "importlibrary.h" +#include "sharedlibrary.h" #include "sourcepackage.h" using namespace std; @@ -12,16 +13,17 @@ ImportLibrary::ImportLibrary(Builder &b, const FS::Path &p): shared_lib(0) { } -ImportLibrary::ImportLibrary(Builder &b, const Component &c, ExportDefinitions &exp): - FileTarget(b, c.get_package(), c.get_package().get_out_dir()/format("lib%s.dll.a", c.get_name())), - shared_lib(&exp.get_library()) +ImportLibrary::ImportLibrary(Builder &b, const Component &c, SharedLibrary &sl, ExportDefinitions &exp): + FileTarget(b, c.get_package(), c.get_package().get_out_dir()/format("lib%s.dll.a", sl.get_libname())), + shared_lib(&sl) { component = &c; add_dependency(exp); + shared_lib->set_import_library(this); install_location = "lib"; const string &version = component->get_package().get_interface_version(); if(!version.empty()) - install_filename = format("lib%s-%s.dll.a", c.get_name(), version); + install_filename = format("lib%s-%s.dll.a", sl.get_libname(), version); } diff --git a/source/importlibrary.h b/source/importlibrary.h index 99db24d..aac11f9 100644 --- a/source/importlibrary.h +++ b/source/importlibrary.h @@ -17,7 +17,7 @@ private: public: ImportLibrary(Builder &, const Msp::FS::Path &); - ImportLibrary(Builder &, const Component &, ExportDefinitions &); + ImportLibrary(Builder &, const Component &, SharedLibrary &, ExportDefinitions &); virtual const char *get_type() const { return "ImportLibrary"; } diff --git a/source/mingwdlltool.cpp b/source/mingwdlltool.cpp index f76fb1c..5f62a02 100644 --- a/source/mingwdlltool.cpp +++ b/source/mingwdlltool.cpp @@ -9,6 +9,7 @@ #include "importlibrary.h" #include "installedfile.h" #include "mingwdlltool.h" +#include "objectfile.h" #include "sharedlibrary.h" #include "sourcepackage.h" @@ -28,9 +29,20 @@ Target *MingwDllTool::create_target(const list &sources, const string { if(sources.size()!=1) throw invalid_argument("MingwDllTool::create_target"); - ExportDefinitions &def = dynamic_cast(*sources.front()); - ImportLibrary *imp = new ImportLibrary(builder, *def.get_component(), def); + SharedLibrary &shlib = dynamic_cast(*sources.front()); + + list objs; + const Target::Dependencies &depends = shlib.get_dependencies(); + for(Target::Dependencies::const_iterator i=depends.begin(); i!=depends.end(); ++i) + if(ObjectFile *obj = dynamic_cast(*i)) + objs.push_back(obj); + + ExportDefinitions *exp = new ExportDefinitions(builder, *shlib.get_component(), objs); + exp->set_tool(*this); + + ImportLibrary *imp = new ImportLibrary(builder, *shlib.get_component(), shlib, *exp); imp->set_tool(*this); + return imp; } @@ -51,9 +63,14 @@ Target *MingwDllTool::create_install(Target &target) const Task *MingwDllTool::run(const Target &target) const { - const ImportLibrary &imp = dynamic_cast(target); - const ExportDefinitions &exp = dynamic_cast(*imp.get_dependencies().front()); - const SharedLibrary &shlib = exp.get_library(); + const ImportLibrary *imp = dynamic_cast(&target); + const ExportDefinitions *exp = 0; + if(imp) + exp = &dynamic_cast(*imp->get_dependencies().front()); + else + exp = dynamic_cast(&target); + if(!imp && !exp) + throw invalid_argument("MingwDllTool::run"); vector argv; argv.push_back(executable->get_path().str()); @@ -66,20 +83,40 @@ Task *MingwDllTool::run(const Target &target) const random[i] = 'a'+(rand()%26); argv.push_back(string("/tmp/")+string(random, 8)); - const Component &comp = *imp.get_component(); + const Component &comp = *target.get_component(); FS::Path work_dir = comp.get_package().get_source_directory(); - argv.push_back("-d"); - argv.push_back(relative(exp.get_path(), work_dir).str()); + if(imp) + { + const SharedLibrary &shlib = *imp->get_shared_library(); + + argv.push_back("-d"); + argv.push_back(relative(exp->get_path(), work_dir).str()); + + argv.push_back("-D"); + if(shlib.get_install_filename().empty()) + argv.push_back(FS::basename(shlib.get_path())); + else + argv.push_back(shlib.get_install_filename()); - argv.push_back("-D"); - if(shlib.get_install_filename().empty()) - argv.push_back(FS::basename(shlib.get_path())); + argv.push_back("-l"); + argv.push_back(relative(imp->get_path(), work_dir).str()); + } else - argv.push_back(shlib.get_install_filename()); + { + const Target::Dependencies &depends = exp->get_dependencies(); + for(Target::Dependencies::const_iterator i=depends.begin(); i!=depends.end(); ++i) + { + if(ObjectFile *obj = dynamic_cast(*i)) + argv.push_back(relative(obj->get_path(), work_dir).str()); + } + + // XXX Should use dllexport, but that has some other problems to solve + argv.push_back("--export-all-symbols"); - argv.push_back("-l"); - argv.push_back(relative(imp.get_path(), work_dir).str()); + argv.push_back("-z"); + argv.push_back(relative(exp->get_path(), work_dir).str()); + } return new ExternalTask(argv, work_dir); }