X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fmingwdlltool.cpp;h=62ef7059a885d7a78d2dd216b2d2612c3eeabd42;hb=1ed833343bc83b83c5f61cbfd74423bbba677a04;hp=582963ea090acea480bd82c01462fa58faf5cf34;hpb=82ae60a647ebb9567f7177c353245f4d72faaf5e;p=builder.git diff --git a/source/mingwdlltool.cpp b/source/mingwdlltool.cpp index 582963e..62ef705 100644 --- a/source/mingwdlltool.cpp +++ b/source/mingwdlltool.cpp @@ -1,7 +1,6 @@ #include #include #include -#include "architecture.h" #include "builder.h" #include "component.h" #include "exportdefinitions.h" @@ -9,6 +8,7 @@ #include "importlibrary.h" #include "installedfile.h" #include "mingwdlltool.h" +#include "objectfile.h" #include "sharedlibrary.h" #include "sourcepackage.h" @@ -18,19 +18,28 @@ using namespace Msp; MingwDllTool::MingwDllTool(Builder &b, const Architecture &a): Tool(b, a, "DLL") { - string command = "dlltool"; - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); + set_command("dlltool", true); + set_run(_run); } -Target *MingwDllTool::create_target(const list &sources, const string &) const +Target *MingwDllTool::create_target(const vector &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()); + + 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; } @@ -38,24 +47,32 @@ Target *MingwDllTool::create_install(Target &target) const { if(ImportLibrary *imp = dynamic_cast(&target)) { - const Tool © = builder.get_toolchain().get_tool("CP"); + 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()); - inst_tgt->set_symlink(link_name); + 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 +Task *MingwDllTool::_run(const Target &target) { - const ImportLibrary &imp = dynamic_cast(target); - const ExportDefinitions &exp = dynamic_cast(*imp.get_dependencies().front()); - const SharedLibrary &shlib = exp.get_library(); + 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(executable->get_path().str()); + argv.push_back(tool.get_executable()->get_path().str()); /* dlltool is stupid and puts temporary files in the working directory by default */ @@ -65,20 +82,37 @@ 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"); - if(shlib.get_install_filename().empty()) - argv.push_back(FS::basename(shlib.get_path())); + 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 - argv.push_back(shlib.get_install_filename()); + { + 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("-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); }