X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=plugins%2Fgnu%2Fmingwdlltool.cpp;fp=plugins%2Fgnu%2Fmingwdlltool.cpp;h=c5ffdf5939b9a1b01aeaf88b24a5efd867e055a4;hb=c8e829c219c65ff8e93b6c7b66212ff0876441c5;hp=0000000000000000000000000000000000000000;hpb=e2c9c3fffcc61a0c102ccf6a7924e2de709092ad;p=builder.git diff --git a/plugins/gnu/mingwdlltool.cpp b/plugins/gnu/mingwdlltool.cpp new file mode 100644 index 0000000..c5ffdf5 --- /dev/null +++ b/plugins/gnu/mingwdlltool.cpp @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mingwdlltool.h" + +using namespace std; +using namespace Msp; + +MingwDllTool::MingwDllTool(Builder &b, const Architecture &a): + Tool(b, &a, "DLL") +{ + set_command("dlltool", true); + set_run(_run); +} + +Target *MingwDllTool::create_target(const vector &sources, const string &) +{ + if(sources.size()!=1) + throw invalid_argument("MingwDllTool::create_target"); + SharedLibrary &shlib = dynamic_cast(*sources.front()); + + vector objs; + objs.reserve(shlib.get_dependencies().size()); + for(Target *d: shlib.get_dependencies()) + if(ObjectFile *obj = dynamic_cast(d)) + 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; +} + +Target *MingwDllTool::create_install(Target &target) const +{ + if(ImportLibrary *imp = dynamic_cast(&target)) + { + Tool © = builder.get_toolchain().get_tool("CP"); + InstalledFile *inst_tgt = dynamic_cast(copy.create_target(target)); + string link_name = format("lib%s.dll.a", imp->get_shared_library()->get_libname()); + if(link_name!=FS::basename(inst_tgt->get_path())) + inst_tgt->set_symlink(link_name); + return inst_tgt; + } + else + return 0; +} + +Task *MingwDllTool::_run(const Target &target) +{ + const Tool &tool = *target.get_tool(); + + 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(tool.get_executable()->get_path().str()); + + /* dlltool is stupid and puts temporary files in the working directory by + default */ + argv.push_back("--temp-prefix"); + char random[8]; + for(unsigned i=0; i<8; ++i) + random[i] = 'a'+(rand()%26); + argv.push_back(string("/tmp/")+string(random, 8)); + + const Component &comp = *target.get_component(); + FS::Path work_dir = comp.get_package().get_source_directory(); + + 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("-l"); + argv.push_back(relative(imp->get_path(), work_dir).str()); + } + else + { + for(Target *d: exp->get_dependencies()) + if(ObjectFile *obj = dynamic_cast(d)) + 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("-z"); + argv.push_back(relative(exp->get_path(), work_dir).str()); + } + + return new ExternalTask(argv, work_dir); +}