From: Mikko Rasa Date: Sat, 6 Apr 2013 22:04:07 +0000 (+0300) Subject: Refactor build graph into its own class X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=373e9bb43c24d38316c5bb0393f4a369563319d3;p=builder.git Refactor build graph into its own class --- diff --git a/source/analyzer.cpp b/source/analyzer.cpp index eaf017b..39cc7e1 100644 --- a/source/analyzer.cpp +++ b/source/analyzer.cpp @@ -2,6 +2,7 @@ #include #include "analyzer.h" #include "builder.h" +#include "buildgraph.h" #include "objectfile.h" #include "sourcefile.h" #include "sourcepackage.h" @@ -23,8 +24,8 @@ void Analyzer::analyze() if(mode==RDEPS) { rdepends.clear(); - const Builder::TargetMap &targets = builder.get_targets(); - for(Builder::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) + const BuildGraph::TargetMap &targets = builder.get_build_graph().get_targets(); + for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) { const Target::Dependencies &depends = i->second->get_dependencies(); for(Target::Dependencies::const_iterator j=depends.begin(); j!=depends.end(); ++j) @@ -42,7 +43,7 @@ void Analyzer::analyze() row.push_back("Rebuild"); table.push_back(row); - Target &cmdline = *builder.get_target("cmdline"); + Target &cmdline = *builder.get_build_graph().get_target("cmdline"); if(mode==RDEPS) { const Target::Dependencies &deps = cmdline.get_dependencies(); diff --git a/source/builder.cpp b/source/builder.cpp index 813f8ed..8b900a4 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -38,6 +38,7 @@ Builder::Builder(int argc, char **argv): native_arch(*this, string()), build_type(0), vfs(*this), + build_graph(*this), analyzer(0), build(false), clean(0), @@ -209,8 +210,6 @@ Builder::Builder(int argc, char **argv): Builder::~Builder() { - for(TargetMap::iterator i=targets.begin(); i!=targets.end(); ++i) - delete i->second; delete analyzer; } @@ -271,7 +270,8 @@ int Builder::main() unsigned count = 0; unsigned to_be_built = 0; - for(TargetMap::iterator j=targets.begin(); j!=targets.end(); ++j) + const BuildGraph::TargetMap &targets = build_graph.get_targets(); + for(BuildGraph::TargetMap::const_iterator j=targets.begin(); j!=targets.end(); ++j) if(j->second->get_package()==i->second) { ++count; @@ -290,7 +290,7 @@ int Builder::main() package_details.push_back(line); } - logger.log("summary", format("%d active packages, %d targets", package_details.size(), targets.size())); + logger.log("summary", format("%d active packages, %d targets", package_details.size(), build_graph.get_targets().size())); for(list::const_iterator i=package_details.begin(); i!=package_details.end(); ++i) logger.log("packages", *i); @@ -315,42 +315,11 @@ int Builder::main() return exit_code; } -Target *Builder::get_target(const string &n) const -{ - TargetMap::const_iterator i = targets.find(n); - if(i!=targets.end()) - return i->second; - return 0; -} - void Builder::problem(const string &p, const string &d) { problems.push_back(Problem(p, d)); } -void Builder::add_target(Target *t) -{ - targets.insert(TargetMap::value_type(t->get_name(), t)); -} - -void Builder::add_primary_target(Target &t) -{ - get_target("world")->add_dependency(t); - - if(t.get_package()==main_pkg && t.get_component() && t.get_component()->is_default()) - get_target("default")->add_dependency(t); -} - -void Builder::add_installed_target(Target &t) -{ - Target *inst_tgt = 0; - if(const Tool *tool = t.get_tool()) - inst_tgt = tool->create_install(t); - if(!inst_tgt) - inst_tgt = toolchain.get_tool("CP").create_target(t); - get_target("install")->add_dependency(*inst_tgt); -} - void Builder::usage(const char *reason, const char *argv0, bool brief) { if(reason) @@ -380,24 +349,13 @@ void Builder::load_build_file(const FS::Path &fn) bool Builder::prepare_build() { - Target *world = new VirtualTarget(*this, "world"); - - Target *def_tgt = new VirtualTarget(*this, "default"); - world->add_dependency(*def_tgt); - - Target *install = new VirtualTarget(*this, "install"); - world->add_dependency(*install); - - Target *tarballs = new VirtualTarget(*this, "tarballs"); - world->add_dependency(*tarballs); - package_manager.get_main_package().prepare(); // Make the cmdline target depend on all targets mentioned on the command line Target *cmdline = new VirtualTarget(*this, "cmdline"); for(NameList::iterator i=cmdline_targets.begin(); i!=cmdline_targets.end(); ++i) { - Target *tgt = get_target(*i); + Target *tgt = build_graph.get_target(*i); if(!tgt) tgt = vfs.get_target(*i); if(!tgt) @@ -444,9 +402,10 @@ bool Builder::prepare_build() int Builder::do_build() { - Target *cmdline = get_target("cmdline"); + Target *cmdline = build_graph.get_target("cmdline"); unsigned total = 0; + const BuildGraph::TargetMap &targets = build_graph.get_targets(); for(map::const_iterator i=targets.begin(); i!=targets.end(); ++i) if(i->second->is_buildable() && i->second->needs_rebuild()) ++total; @@ -550,7 +509,7 @@ int Builder::do_clean() set clean_tgts; list queue; - queue.push_back(get_target("cmdline")); + queue.push_back(build_graph.get_target("cmdline")); while(!queue.empty()) { diff --git a/source/builder.h b/source/builder.h index 283b5fd..40df4ff 100644 --- a/source/builder.h +++ b/source/builder.h @@ -8,6 +8,7 @@ #include #include #include "architecture.h" +#include "buildgraph.h" #include "buildtype.h" #include "config.h" #include "logger.h" @@ -41,9 +42,6 @@ private: void package(const std::string &); }; -public: - typedef std::map TargetMap; - private: typedef std::list NameList; typedef std::map BuildTypeMap; @@ -55,14 +53,13 @@ private: PackageManager package_manager; - TargetMap targets; - Architecture native_arch; Architecture *current_arch; BuildTypeMap build_types; BuildType *build_type; Toolchain toolchain; VirtualFileSystem vfs; + BuildGraph build_graph; Logger logger; ProblemList problems; @@ -93,14 +90,10 @@ public: PackageManager &get_package_manager() { return package_manager; } - /** Looks up a target by name. Returns 0 if no such target exists. */ - Target *get_target(const std::string &) const; - - const TargetMap &get_targets() const { return targets; } - const Msp::FS::Path &get_work_directory() const { return cwd; } const Architecture &get_current_arch() const { return *current_arch; } const Architecture &get_native_arch() const { return native_arch; } + BuildGraph &get_build_graph() { return build_graph; } const Msp::FS::Path &get_prefix() const { return prefix; } const Msp::FS::Path &get_temp_directory() const { return tempdir; } @@ -108,20 +101,6 @@ public: VirtualFileSystem &get_vfs() { return vfs; } const Logger &get_logger() const { return logger; } - /** Adds a target. It can later be retrieved by name. Called from Target - constructor. */ - void add_target(Target *); - - /** Adds a target that is a primary build goal. Such targets will be added - as dependencies of the "world" virtual target. If the target belongs to a - default component of the main package, it's also added to the "default" - virtual target. */ - void add_primary_target(Target &); - - /** Adds a target that will be installed. A new InstalledFile target is - created and added as a dependency to the "install" virtual target. */ - void add_installed_target(Target &); - void problem(const std::string &, const std::string &); static void usage(const char *, const char *, bool); diff --git a/source/buildgraph.cpp b/source/buildgraph.cpp new file mode 100644 index 0000000..8c0ff12 --- /dev/null +++ b/source/buildgraph.cpp @@ -0,0 +1,55 @@ +#include "builder.h" +#include "buildgraph.h" +#include "component.h" +#include "sourcepackage.h" +#include "tool.h" +#include "virtualtarget.h" + +using namespace std; + +BuildGraph::BuildGraph(Builder &b): + builder(b) +{ + Target *world = new VirtualTarget(builder, "world"); + world->add_dependency(*new VirtualTarget(builder, "default")); + world->add_dependency(*new VirtualTarget(builder, "install")); + world->add_dependency(*new VirtualTarget(builder, "tarballs")); +} + +BuildGraph::~BuildGraph() +{ + for(TargetMap::iterator i=targets.begin(); i!=targets.end(); ++i) + delete i->second; +} + +Target *BuildGraph::get_target(const string &n) const +{ + TargetMap::const_iterator i = targets.find(n); + if(i!=targets.end()) + return i->second; + return 0; +} + +void BuildGraph::add_target(Target *t) +{ + targets.insert(TargetMap::value_type(t->get_name(), t)); +} + +void BuildGraph::add_primary_target(Target &t) +{ + get_target("world")->add_dependency(t); + + Package *main_pkg = &builder.get_package_manager().get_main_package(); + if(t.get_package()==main_pkg && t.get_component() && t.get_component()->is_default()) + get_target("default")->add_dependency(t); +} + +void BuildGraph::add_installed_target(Target &t) +{ + Target *inst_tgt = 0; + if(const Tool *tool = t.get_tool()) + inst_tgt = tool->create_install(t); + if(!inst_tgt) + inst_tgt = builder.get_toolchain().get_tool("CP").create_target(t); + get_target("install")->add_dependency(*inst_tgt); +} diff --git a/source/buildgraph.h b/source/buildgraph.h new file mode 100644 index 0000000..54409c0 --- /dev/null +++ b/source/buildgraph.h @@ -0,0 +1,45 @@ +#ifndef BUILDGRAPH_H_ +#define BUILDGRAPH_H_ + +#include "virtualfilesystem.h" + +class Builder; +class Target; + +/** +Manages a graph of targets. +*/ +class BuildGraph +{ +public: + typedef std::map TargetMap; + +private: + Builder &builder; + TargetMap targets; + +public: + BuildGraph(Builder &); + ~BuildGraph(); + + /** Looks up a target by name. Returns 0 if no such target exists. */ + Target *get_target(const std::string &) const; + + const TargetMap &get_targets() const { return targets; } + + /** Adds a target. It can later be retrieved by name. Called from Target + constructor. */ + void add_target(Target *); + + /** Adds a target that is a primary build goal. Such targets will be added + as dependencies of the "world" virtual target. If the target belongs to a + default component of the main package, it's also added to the "default" + virtual target. */ + void add_primary_target(Target &); + + /** Adds a target that will be installed. A new InstalledFile target is + created and added as a dependency to the "install" virtual target. */ + void add_installed_target(Target &); +}; + +#endif diff --git a/source/component.cpp b/source/component.cpp index 68c9b18..d1849f4 100644 --- a/source/component.cpp +++ b/source/component.cpp @@ -104,6 +104,7 @@ void Component::create_build_info() void Component::create_targets() const { Builder &builder = package.get_builder(); + BuildGraph &build_graph = builder.get_build_graph(); const Toolchain &toolchain = builder.get_toolchain(); SourceList source_filenames = collect_source_files(); @@ -128,8 +129,8 @@ void Component::create_targets() const tarname = package.get_name()+"-"+package.get_version(); files.insert(files.begin(), &package.get_build_file()); - const Builder::TargetMap &targets = builder.get_targets(); - for(Builder::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) + const BuildGraph::TargetMap &targets = build_graph.get_targets(); + for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) if(i->second->get_package()==&package && !i->second->is_buildable()) if(find(files.begin(), files.end(), i->second)==files.end()) files.push_back(i->second); @@ -137,13 +138,13 @@ void Component::create_targets() const Target *result = tar.create_target(files, tarname); - builder.get_target("tarballs")->add_dependency(*result); + build_graph.get_target("tarballs")->add_dependency(*result); return; } else if(type==INSTALL) { - Target *inst = builder.get_target("install"); + Target *inst = build_graph.get_target("install"); const Tool © = toolchain.get_tool("CP"); for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) { @@ -166,9 +167,9 @@ void Component::create_targets() const source = new File(builder, package, source_filenames.front()); Target *result = dcomp.create_target(*source); - builder.add_primary_target(*result); + build_graph.add_primary_target(*result); if(install) - builder.add_installed_target(*result); + build_graph.add_installed_target(*result); } if(type==PROGRAM || type==LIBRARY || type==MODULE) @@ -191,7 +192,7 @@ void Component::create_targets() const } if(type==LIBRARY && install && dynamic_cast(src)->is_installable()) - builder.add_installed_target(*src); + build_graph.add_installed_target(*src); } } @@ -211,9 +212,9 @@ void Component::create_targets() const for(list::const_iterator i=results.begin(); i!=results.end(); ++i) { - builder.add_primary_target(**i); + build_graph.add_primary_target(**i); if(install) - builder.add_installed_target(**i); + build_graph.add_installed_target(**i); } } } diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index 7088dfb..21b765b 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -92,7 +92,7 @@ Target *GnuLinker::create_install(Target &target) const const Tool © = builder.get_toolchain().get_tool("CP"); InstalledFile *inst_tgt = dynamic_cast(copy.create_target(target)); if(architecture->get_system()=="windows") - builder.add_installed_target(*shlib->get_import_library()); + builder.get_build_graph().add_installed_target(*shlib->get_import_library()); else { const Pattern &pattern = architecture->get_shared_library_patterns().front(); diff --git a/source/sourcepackage.cpp b/source/sourcepackage.cpp index 9d8a565..8ad12d3 100644 --- a/source/sourcepackage.cpp +++ b/source/sourcepackage.cpp @@ -116,7 +116,7 @@ void SourcePackage::do_prepare() if(pc_needed) { PkgConfigFile *pc = new PkgConfigFile(builder, *this); - builder.get_target("install")->add_dependency(*builder.get_toolchain().get_tool("CP").create_target(*pc)); + builder.get_build_graph().get_target("install")->add_dependency(*builder.get_toolchain().get_tool("CP").create_target(*pc)); } } diff --git a/source/target.cpp b/source/target.cpp index 352b788..691f700 100644 --- a/source/target.cpp +++ b/source/target.cpp @@ -20,7 +20,7 @@ Target::Target(Builder &b, const string &n): state(INIT), primary_target(0) { - builder.add_target(this); + builder.get_build_graph().add_target(this); } void Target::add_dependency(Target &dep)