X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flib%2Fbuilder.cpp;h=f979d28f38ce35c6f01976cc5109886f83b50ab7;hb=ba5078a4334ef419aeb1949190a743a05037750c;hp=53b9efbae40af0f318f288e0f9c023ead71fd31e;hpb=d3e9e3db18a9fb6024fced0fe506752763c91c7f;p=builder.git diff --git a/source/lib/builder.cpp b/source/lib/builder.cpp index 53b9efb..f979d28 100644 --- a/source/lib/builder.cpp +++ b/source/lib/builder.cpp @@ -5,23 +5,23 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include -#include "android/androidtools.h" #include "binarypackage.h" #include "builder.h" -#include "datafile/datatool.h" #include "installedfile.h" #include "package.h" #include "plugin.h" #include "sharedlibrary.h" -#include "sourcepackage.h" #include "task.h" +#include "tool.h" #include "virtualtarget.h" using namespace std; @@ -48,7 +48,11 @@ void Builder::load_plugins() using CreateFunc = Plugin *(Builder &); FS::Path plugins_dir = FS::get_sys_lib_dir(); + if(!FS::exists(plugins_dir)) + return; + logger->log("files", "Traversing %s", plugins_dir); + vector unordered_plugins; for(const string &f: list_filtered(plugins_dir, "\\.dlm$")) { LoadedPlugin plugin; @@ -71,7 +75,7 @@ void Builder::load_plugins() if(plugin.plugin) { logger->log("plugins", "Loaded plugin %s", f); - plugins.emplace_back(move(plugin)); + unordered_plugins.emplace_back(move(plugin)); continue; } else @@ -81,8 +85,45 @@ void Builder::load_plugins() { logger->log("plugins", "Failed to initialize plugin %s: %s", f, exc.what()); } + } + + add_plugins(unordered_plugins); +} + +void Builder::add_plugins(vector &unordered_plugins) +{ + auto have_plugin = [this](const string &r){ + return any_of(plugins.begin(), plugins.end(), [&r](const LoadedPlugin &p){ return FS::basepart(FS::basename(p.path))==r; }); + }; - delete plugin.module; + while(!unordered_plugins.empty()) + { + bool any_added = false; + for(auto i=unordered_plugins.begin(); i!=unordered_plugins.end(); ) + { + const vector &required = i->plugin->get_required_plugins(); + if(all_of(required.begin(), required.end(), have_plugin)) + { + plugins.push_back(move(*i)); + i = unordered_plugins.erase(i); + any_added = true; + } + else + ++i; + } + + if(!any_added) + break; + } + + for(const LoadedPlugin &p: unordered_plugins) + { + vector missing; + for(const string &r: p.plugin->get_required_plugins()) + if(!have_plugin(r)) + missing.push_back(r); + logger->log("plugins", "Missing required plugins for plugin %s: %s", + FS::basename(p.path), join(missing.begin(), missing.end())); } } @@ -142,9 +183,6 @@ void Builder::update_auto_prefix() void Builder::add_default_tools() { - if(current_arch->get_system()=="android") - toolchain.add_toolchain(new AndroidTools(*this, *current_arch)); - toolchain.add_tool(new DataTool(*this)); for(const LoadedPlugin &p: plugins) p.plugin->add_tools(toolchain, *current_arch); @@ -164,46 +202,71 @@ void Builder::set_logger(const Logger *l) vector Builder::collect_problems() const { + vector target_problems; vector problems; - set broken_packages; - set broken_components; - set broken_tools; + vector broken_packages; + vector broken_components; + vector broken_tools; for(const auto &kvp: build_graph.get_targets()) if(kvp.second->is_broken()) { - for(const string &p: kvp.second->get_problems()) - problems.push_back(format("%s: %s", kvp.second->get_name(), p)); - const Package *package = kvp.second->get_package(); - if(package && !package->get_problems().empty()) - broken_packages.insert(package); + if(package && package->is_broken()) + collect_broken_packages(*package, broken_packages); const Component *component = kvp.second->get_component(); - if(component && !component->get_problems().empty()) - broken_components.insert(component); + if(component && component->is_broken() && !any_equals(broken_components, component)) + { + broken_components.push_back(component); + collect_broken_packages(component->get_package(), broken_packages); + for(const Package *r: component->get_required_packages()) + if(r->is_broken()) + collect_broken_packages(*r, broken_packages); + } const Tool *tool = kvp.second->get_tool(); - if(tool && !tool->get_problems().empty()) - broken_tools.insert(tool); + if(tool && tool->is_broken() && !any_equals(broken_tools, tool)) + { + broken_tools.push_back(tool); + for(const string &p: tool->get_problems()) + problems.push_back(format("%s: %s", tool->get_tag(), p)); + } + + for(const string &p: kvp.second->get_problems()) + target_problems.push_back(format("%s: %s", kvp.second->get_name(), p)); } - // TODO Sort components after their packages, and targets last for(const Package *p: broken_packages) + { for(const string &b: p->get_problems()) problems.push_back(format("%s: %s", p->get_name(), b)); - for(const Component *c: broken_components) - for(const string &b: c->get_problems()) - problems.push_back(format("%s/%s: %s", c->get_package().get_name(), c->get_name(), b)); + for(const Component *c: broken_components) + if(&c->get_package()==p) + { + for(const string &b: c->get_problems()) + problems.push_back(format("%s/%s: %s", p->get_name(), c->get_name(), b)); + } + } - for(const Tool *t: broken_tools) - for(const string &b: t->get_problems()) - problems.push_back(format("%s: %s", t->get_tag(), b)); + problems.insert(problems.end(), make_move_iterator(target_problems.begin()), make_move_iterator(target_problems.end())); return problems; } +void Builder::collect_broken_packages(const Package &pkg, vector &broken) const +{ + if(any_equals(broken, &pkg)) + return; + + broken.push_back(&pkg); + + for(const Package *r: pkg.get_required_packages()) + if(r->is_broken()) + collect_broken_packages(*r, broken); +} + void Builder::load_build_file(const FS::Path &fn, const Config::InputOptions *opts, bool all) { IO::BufferedFile in(fn.str()); @@ -224,6 +287,7 @@ void Builder::save_caches() int Builder::build(unsigned jobs, bool dry_run, bool show_progress) { unsigned total = build_graph.count_rebuild_targets(); + Time::TimeStamp start_time = Time::now(); if(!total) { @@ -235,6 +299,7 @@ int Builder::build(unsigned jobs, bool dry_run, bool show_progress) vector tasks; unsigned count = 0; + Time::TimeDelta sum_time; bool fail = false; bool finish = false; @@ -292,6 +357,13 @@ int Builder::build(unsigned jobs, bool dry_run, bool show_progress) { ++count; + const vector &targets = tasks[i]->get_targets(); + if(!targets.empty()) + { + sum_time += tasks[i]->get_duration(); + get_logger().log("timings", "%s built in %s", targets.front()->get_name(), tasks[i]->get_duration()); + } + delete tasks[i]; tasks.erase(tasks.begin()+i); if(status==Task::ERROR) @@ -312,6 +384,9 @@ int Builder::build(unsigned jobs, bool dry_run, bool show_progress) else if(show_progress) get_logger().log("summary", "Build complete"); + Time::TimeStamp end_time = Time::now(); + get_logger().log("timings", "Build took %s, with a total %s spent on tasks", end_time-start_time, sum_time); + return fail; } @@ -356,6 +431,18 @@ Builder::LoadedPlugin::LoadedPlugin(LoadedPlugin &&other): other.plugin = 0; } +Builder::LoadedPlugin &Builder::LoadedPlugin::operator=(LoadedPlugin &&other) +{ + delete plugin; + delete module; + path = move(other.path); + module = other.module; + plugin = other.plugin; + other.module = 0; + other.plugin = 0; + return *this; +} + Builder::LoadedPlugin::~LoadedPlugin() { delete plugin;