X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=plugins%2Fmsvc%2Fmsvclinker.cpp;fp=plugins%2Fmsvc%2Fmsvclinker.cpp;h=8008791569a37d2c57816d0e68a8199b6124eddf;hb=c8e829c219c65ff8e93b6c7b66212ff0876441c5;hp=0000000000000000000000000000000000000000;hpb=e2c9c3fffcc61a0c102ccf6a7924e2de709092ad;p=builder.git diff --git a/plugins/msvc/msvclinker.cpp b/plugins/msvc/msvclinker.cpp new file mode 100644 index 0000000..8008791 --- /dev/null +++ b/plugins/msvc/msvclinker.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "microsofttools.h" +#include "msvclinker.h" + +using namespace std; +using namespace Msp; + +MsvcLinker::MsvcLinker(Builder &b, const Architecture &a, const MicrosoftTools &m): + Tool(b, &a, "LINK"), + ms_tools(m) +{ + input_suffixes.push_back(".o"); + input_suffixes.push_back(".a"); + + processing_unit = COMPONENT; + + set_command((ms_tools.get_vc_bin_dir()/"link.exe").str(), false); + set_run_external(_run); +} + +Target *MsvcLinker::create_target(const vector &sources, const string &arg) +{ + if(sources.empty()) + throw invalid_argument("MsvcLinker::create_target"); + + vector objs; + objs.reserve(sources.size()); + for(Target *s: sources) + objs.push_back(&dynamic_cast(*s)); + + const Component &comp = *objs.front()->get_component(); + Binary *bin = 0; + if(arg=="shared") + bin = new SharedLibrary(builder, comp, objs); + else + bin = new Executable(builder, comp, objs); + bin->set_tool(*this); + return bin; +} + +string MsvcLinker::create_build_signature(const BuildInfo &binfo) const +{ + string result = Tool::create_build_signature(binfo); + result += ','; + if(binfo.strip) + result += 's'; + if(!binfo.libs.empty()) + { + result += ",l"; + result += join(binfo.libs.begin(), binfo.libs.end(), ",l"); + } + return result; +} + +void MsvcLinker::do_prepare(ToolData &tool) const +{ + const std::string &tool_tag = static_cast(tool).get_tag(); + const Architecture &arch = *static_cast(tool).get_architecture(); + string arch_dir = (arch.get_bits()==64 ? "x64" : "x86"); + + const FS::Path &vc_base_dir = ms_tools.get_vc_base_dir(); + tool.system_path.push_back(vc_base_dir/"lib"/arch_dir); + + const FS::Path &win_sdk_dir = ms_tools.get_windows_sdk_dir(); + const string &win_sdk_ver = ms_tools.get_windows_sdk_version(); + tool.system_path.push_back(win_sdk_dir/"lib"/win_sdk_ver/"ucrt"/arch_dir); + tool.system_path.push_back(win_sdk_dir/"lib"/win_sdk_ver/"um"/arch_dir); + + string path; + for(const FS::Path &p: tool.system_path) + { + append(path, ";", p.str()); + builder.get_logger().log("tools", "Got %s system path: %s", tool_tag, p); + } + + setenv("LIB", path); +} + +ExternalTask::Arguments MsvcLinker::_run(const Binary &bin, FS::Path &work_dir) +{ + const Tool &tool = *bin.get_tool(); + + vector argv; + argv.push_back(tool.get_executable()->get_path().str()); + argv.push_back("/NOLOGO"); + + if(dynamic_cast(&bin)) + argv.push_back("/DLL"); + + BuildInfo binfo; + bin.collect_build_info(binfo); + + /*for(const FS::Path &p: binfo.libpath) + argv.push_back("/LIBPATH:"+p.str());*/ + if(binfo.strip) + argv.push_back("/INCREMENTAL:NO"); + else + argv.push_back("/DEBUG:FULL"); + + argv.push_back("/OUT:"+relative(bin.get_path(), work_dir).str()); + + for(Target *d: bin.get_dependencies()) + { + FileTarget *file = dynamic_cast(d); + Target *tgt = d->get_real_target(); + + if(ObjectFile *obj = dynamic_cast(tgt)) + argv.push_back(relative(obj->get_path(), work_dir).str()); + else if(StaticLibrary *stlib = dynamic_cast(tgt)) + argv.push_back((file?file:stlib)->get_path().str()); + else if(ImportLibrary *imp = dynamic_cast(tgt)) + argv.push_back((file?file:imp)->get_path().str()); + } + + argv.push_back("/SUBSYSTEM:CONSOLE"); + + return argv; +}