X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbuilder.cpp;h=6eeaa2fa3ca3b39e05298b3bd780ff5401cccbaa;hb=HEAD;hp=e501f69e0513631d8611830ae2c2b1f7cd75a963;hpb=6e02286dcbd62b8f5ef56987c2298d54b689ad9c;p=builder.git diff --git a/source/builder.cpp b/source/builder.cpp deleted file mode 100644 index e501f69..0000000 --- a/source/builder.cpp +++ /dev/null @@ -1,339 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "binarypackage.h" -#include "builder.h" -#include "builtintools.h" -#include "clangtools.h" -#include "datatool.h" -#include "gnutools.h" -#include "installedfile.h" -#include "package.h" -#include "sharedlibrary.h" -#include "sourcepackage.h" -#include "task.h" -#include "virtualtarget.h" - -using namespace std; -using namespace Msp; - -Builder::Builder(): - package_manager(*this), - native_arch(*this, string()), - current_arch(0), - build_type(0), - vfs(*this), - build_graph(*this), - logger(&default_logger), - tempdir("temp"), - top_loader(0) -{ - set_architecture(string()); -} - -Builder::~Builder() -{ - if(current_arch!=&native_arch) - delete current_arch; -} - -void Builder::set_architecture(const string &name) -{ - if(name.empty()) - { - current_arch = &native_arch; - prefix = FS::get_home_dir()/"local"; - } - else - { - current_arch = new Architecture(*this, name); - prefix = FS::get_home_dir()/"local"/current_arch->get_name(); - } -} - -void Builder::set_build_type(const string &name) -{ - build_type = &get_item(build_types, name); -} - -void Builder::set_prefix(const FS::Path &p) -{ - prefix = p; -} - -void Builder::set_temp_directory(const FS::Path &p) -{ - tempdir = p; -} - -void Builder::add_default_tools() -{ - if(current_arch->get_system()=="darwin") - toolchain.add_toolchain(new ClangTools(*this, *current_arch)); - toolchain.add_toolchain(new GnuTools(*this, *current_arch)); - toolchain.add_toolchain(new BuiltinTools(*this)); - toolchain.add_tool(new DataTool(*this)); -} - -void Builder::set_logger(const Logger *l) -{ - logger = (l ? l : &default_logger); -} - -list Builder::collect_problems() const -{ - list problems; - set broken_packages; - set broken_components; - set broken_tools; - - const BuildGraph::TargetMap &targets = build_graph.get_targets(); - for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) - if(i->second->is_broken()) - { - const list &tgt_problems = i->second->get_problems(); - for(list::const_iterator j=tgt_problems.begin(); j!=tgt_problems.end(); ++j) - problems.push_back(format("%s: %s", i->second->get_name(), *j)); - - const Package *package = i->second->get_package(); - if(package && !package->get_problems().empty()) - broken_packages.insert(package); - - const Component *component = i->second->get_component(); - if(component && !component->get_problems().empty()) - broken_components.insert(component); - - const Tool *tool = i->second->get_tool(); - if(tool && !tool->get_problems().empty()) - broken_tools.insert(tool); - } - - // TODO Sort components after their packages, and targets last - for(set::const_iterator i=broken_packages.begin(); i!=broken_packages.end(); ++i) - { - const list &pkg_problems = (*i)->get_problems(); - for(list::const_iterator j=pkg_problems.begin(); j!=pkg_problems.end(); ++j) - problems.push_back(format("%s: %s", (*i)->get_name(), *j)); - } - - for(set::const_iterator i=broken_components.begin(); i!=broken_components.end(); ++i) - { - const list &comp_problems = (*i)->get_problems(); - for(list::const_iterator j=comp_problems.begin(); j!=comp_problems.end(); ++j) - problems.push_back(format("%s/%s: %s", (*i)->get_package().get_name(), (*i)->get_name(), *j)); - } - - for(set::const_iterator i=broken_tools.begin(); i!=broken_tools.end(); ++i) - { - const list &tool_problems = (*i)->get_problems(); - for(list::const_iterator j=tool_problems.begin(); j!=tool_problems.end(); ++j) - problems.push_back(format("%s: %s", (*i)->get_tag(), *j)); - } - - return problems; -} - -void Builder::load_build_file(const FS::Path &fn, const Config::InputOptions *opts, bool all) -{ - IO::BufferedFile in(fn.str()); - - get_logger().log("files", format("Reading %s", fn)); - - DataFile::Parser parser(in, fn.str()); - Loader loader(*this, opts, all); - loader.load(parser); -} - -int Builder::build(unsigned jobs, bool dry_run, bool show_progress) -{ - unsigned total = build_graph.count_rebuild_targets(); - - if(!total) - { - get_logger().log("summary", "Already up to date"); - return 0; - } - get_logger().log("summary", format("Will build %d target%s", total, (total!=1 ? "s" : ""))); - - vector tasks; - - unsigned count = 0; - - bool fail = false; - bool finish = false; - bool starved = false; - - while(!finish) - { - if(tasks.size()get_tool()) - get_logger().log("tasks", format("%-4s %s", tgt->get_tool()->get_tag(), tgt->get_name())); - Task *task = tgt->build(); - if(task) - { - get_logger().log("commands", format("%s", task->get_command())); - if(dry_run) - { - task->signal_finished.emit(true); - delete task; - } - else - { - task->start(); - tasks.push_back(task); - } - } - - if(show_progress) - IO::print("%d of %d target%s built\033[1G", count, total, (total!=1 ? "s" : "")); - } - else if(tasks.empty()) - finish = true; - else - starved = true; - } - else - Time::sleep(10*Time::msec); - - for(unsigned i=0; iwait(); - else - status = tasks[i]->check(); - - if(status!=Task::RUNNING) - { - ++count; - - delete tasks[i]; - tasks.erase(tasks.begin()+i); - if(status==Task::ERROR) - fail = true; - if(tasks.empty() && fail) - finish = true; - starved = false; - } - else - ++i; - } - } - - if(show_progress) - IO::print("\033[K"); - if(fail) - get_logger().log("summary", "Build failed"); - else if(show_progress) - get_logger().log("summary", "Build complete"); - - if(!dry_run) - { - const PackageManager::PackageMap &packages = package_manager.get_packages(); - for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) - i->second->save_caches(); - } - - return fail; -} - -int Builder::clean(bool all, bool dry_run) -{ - // Cleaning doesn't care about ordering, so a simpler method can be used - - set clean_tgts; - list queue; - queue.push_back(build_graph.get_target("cmdline")); - - while(!queue.empty()) - { - Target *tgt = queue.front(); - queue.erase(queue.begin()); - - if(tgt->is_buildable() && (tgt->get_package()==&package_manager.get_main_package() || all)) - clean_tgts.insert(tgt); - - const Target::Dependencies &deps = tgt->get_dependencies(); - for(list::const_iterator i=deps.begin(); i!=deps.end(); ++i) - if(!clean_tgts.count(*i)) - queue.push_back(*i); - } - - for(set::iterator i=clean_tgts.begin(); i!=clean_tgts.end(); ++i) - { - get_logger().log("tasks", format("RM %s", (*i)->get_name())); - if(!dry_run) - (*i)->clean(); - } - - return 0; -} - - -Builder::Loader::Loader(Builder &b, const Config::InputOptions *o, bool a): - DataFile::ObjectLoader(b), - options(o), - conf_all(a) -{ - add("architecture", &Loader::architecture); - add("binary_package", &Loader::binpkg); - add("build_type", &Loader::build_type); - add("package", &Loader::package); - - if(!obj.top_loader) - obj.top_loader = this; - else if(!options && obj.top_loader!=this && obj.top_loader->conf_all) - options = obj.top_loader->options; -} - -Builder::Loader::~Loader() -{ - if(obj.top_loader==this) - obj.top_loader = 0; -} - -void Builder::Loader::architecture(const string &n) -{ - if(obj.current_arch->match_name(n)) - load_sub(*obj.current_arch); -} - -void Builder::Loader::binpkg(const string &n) -{ - BinaryPackage *pkg = new BinaryPackage(obj, n); - load_sub(*pkg); -} - -void Builder::Loader::build_type(const string &n) -{ - BuildType btype(n); - load_sub(btype); - BuildTypeMap::iterator i = obj.build_types.insert(BuildTypeMap::value_type(n, btype)).first; - if(!obj.build_type) - obj.build_type = &i->second; -} - -void Builder::Loader::package(const string &n) -{ - SourcePackage *pkg = new SourcePackage(obj, n, get_source()); - - if(options) - load_sub(*pkg, *options); - else - load_sub(*pkg); - - if(obj.build_type) - pkg->set_build_type(*obj.build_type); -}