X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fmsvclinker.cpp;fp=source%2Fmsvclinker.cpp;h=46d89f7194a5565692b0a1c032f0d2a206180cc2;hb=c0e0728ff439ddb364cee26f164e46705beac822;hp=0000000000000000000000000000000000000000;hpb=650560b14cac4bb35589b5b8db99197c5e1345cc;p=builder.git diff --git a/source/msvclinker.cpp b/source/msvclinker.cpp new file mode 100644 index 0000000..46d89f7 --- /dev/null +++ b/source/msvclinker.cpp @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include "builder.h" +#include "component.h" +#include "executable.h" +#include "externaltask.h" +#include "importlibrary.h" +#include "microsofttools.h" +#include "msvclinker.h" +#include "objectfile.h" +#include "sharedlibrary.h" +#include "sourcepackage.h" +#include "staticlibrary.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); +} + +Target *MsvcLinker::create_target(const list &sources, const string &arg) +{ + if(sources.empty()) + throw invalid_argument("MsvcLinker::create_target"); + + list objs; + for(list::const_iterator i=sources.begin(); i!=sources.end(); ++i) + { + if(ObjectFile *obj = dynamic_cast(*i)) + objs.push_back(obj); + else + throw invalid_argument("MsvcLinker::create_target"); + } + + 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 = FS::basename(executable->get_path()); + 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() +{ + string arch_dir = (architecture->get_bits()==64 ? "x64" : "x86"); + + const FS::Path &vc_base_dir = ms_tools.get_vc_base_dir(); + 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(); + system_path.push_back(win_sdk_dir/"lib"/win_sdk_ver/"ucrt"/arch_dir); + system_path.push_back(win_sdk_dir/"lib"/win_sdk_ver/"um"/arch_dir); + + string path; + for(SearchPath::const_iterator i=system_path.begin(); i!=system_path.end(); ++i) + { + append(path, ";", i->str()); + builder.get_logger().log("tools", format("Got %s system path: %s", tag, *i)); + } + + setenv("LIB", path); +} + +Task *MsvcLinker::run(const Target &target) const +{ + const Binary &bin = dynamic_cast(target); + + vector argv; + argv.push_back(executable->get_path().str()); + argv.push_back("/NOLOGO"); + + FS::Path work_dir = bin.get_component()->get_package().get_source_directory(); + + if(dynamic_cast(&bin)) + argv.push_back("/DLL"); + + BuildInfo binfo; + target.collect_build_info(binfo); + + /*for(BuildInfo::PathList::const_iterator i=binfo.libpath.begin(); i!=binfo.libpath.end(); ++i) + argv.push_back("/LIBPATH:"+i->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()); + + const Target::Dependencies &depends = target.get_dependencies(); + for(Target::Dependencies::const_iterator i=depends.begin(); i!=depends.end(); ++i) + { + FileTarget *file = dynamic_cast(*i); + Target *tgt = (*i)->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 new ExternalTask(argv, work_dir); +}