From 37ffa892c453a91f06d34068e239e1ba316d7700 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 8 Jul 2012 23:15:50 +0300 Subject: [PATCH] Split GnuLinker into sub-tools and select the appropriate one in create_target --- source/gnulinker.cpp | 51 +++++++++++++++++++++++++++++++++----------- source/gnulinker.h | 17 +++++++++++++++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index 52ae0f3..6eef8b3 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -35,6 +35,15 @@ GnuLinker::GnuLinker(Builder &b): } else system_path.push_back("/usr/"+arch.get_cross_prefix()+"/lib"); + + default_linker = new Linker(*this, "CC"); + cxx_linker = new Linker(*this, "CXX"); +} + +GnuLinker::~GnuLinker() +{ + delete default_linker; + delete cxx_linker; } Target *GnuLinker::create_target(const list &sources, const std::string &arg) const @@ -42,10 +51,15 @@ Target *GnuLinker::create_target(const list &sources, const std::strin if(sources.empty()) throw invalid_argument("GnuLinker::create_target"); list objs; + Linker *linker = default_linker; for(list::const_iterator i=sources.begin(); i!=sources.end(); ++i) { if(ObjectFile *obj = dynamic_cast(*i)) + { objs.push_back(obj); + if(obj->get_tool()->get_tag()=="CXX") + linker = cxx_linker; + } else throw invalid_argument("GnuLinker::create_target"); } @@ -56,24 +70,35 @@ Target *GnuLinker::create_target(const list &sources, const std::strin bin = new SharedLibrary(builder, comp, objs); else bin = new Executable(builder, comp, objs); - bin->set_tool(*this); + bin->set_tool(*linker); return bin; } -Task *GnuLinker::run(const Target &target) const +Task *GnuLinker::run(const Target &) const { - const Binary &bin = dynamic_cast(target); + throw logic_error("GnuLinker should not be run directly"); +} - string command = "gcc"; - const Target::Dependencies &depends = target.get_depends(); - for(Target::Dependencies::const_iterator i=depends.begin(); i!=depends.end(); ++i) - if(ObjectFile *obj = dynamic_cast(*i)) - { - const Tool *tool = obj->get_tool(); - if(tool->get_tag()=="CXX") - command = "g++"; - } +GnuLinker::Linker::Linker(GnuLinker &p, const string &compiler_tag): + SubTool(p) +{ + if(compiler_tag=="CC") + command = "gcc"; + else if(compiler_tag=="CXX") + command = "g++"; + else + throw invalid_argument("GnuLinker::Linker::Linker"); +} + +Target *GnuLinker::Linker::create_target(const list &sources, const string &arg) const +{ + return parent.create_target(sources, arg); +} + +Task *GnuLinker::Linker::run(const Target &target) const +{ + const Binary &bin = dynamic_cast(target); vector argv; argv.push_back(command); @@ -107,6 +132,8 @@ Task *GnuLinker::run(const Target &target) const argv.push_back("-o"); argv.push_back(relative(bin.get_path(), work_dir).str()); + + const Target::Dependencies &depends = target.get_depends(); for(Target::Dependencies::const_iterator i=depends.begin(); i!=depends.end(); ++i) { Target *tgt = (*i)->get_real_target(); diff --git a/source/gnulinker.h b/source/gnulinker.h index 6268944..9f0475a 100644 --- a/source/gnulinker.h +++ b/source/gnulinker.h @@ -5,8 +5,25 @@ class GnuLinker: public Tool { +private: + class Linker: public SubTool + { + private: + std::string command; + + public: + Linker(GnuLinker &, const std::string &); + + virtual Target *create_target(const std::list &, const std::string &) const; + virtual Task *run(const Target &) const; + }; + + Linker *default_linker; + Linker *cxx_linker; + public: GnuLinker(Builder &); + ~GnuLinker(); virtual Target *create_target(const std::list &, const std::string &) const; virtual Task *run(const Target &) const; -- 2.45.2