#include <msp/io/print.h>
#include "analyzer.h"
#include "builder.h"
+#include "buildgraph.h"
#include "objectfile.h"
#include "sourcefile.h"
#include "sourcepackage.h"
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)
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();
native_arch(*this, string()),
build_type(0),
vfs(*this),
+ build_graph(*this),
analyzer(0),
build(false),
clean(0),
Builder::~Builder()
{
- for(TargetMap::iterator i=targets.begin(); i!=targets.end(); ++i)
- delete i->second;
delete analyzer;
}
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;
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<string>::const_iterator i=package_details.begin(); i!=package_details.end(); ++i)
logger.log("packages", *i);
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)
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)
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<string, Target *>::const_iterator i=targets.begin(); i!=targets.end(); ++i)
if(i->second->is_buildable() && i->second->needs_rebuild())
++total;
set<Target *> clean_tgts;
list<Target *> queue;
- queue.push_back(get_target("cmdline"));
+ queue.push_back(build_graph.get_target("cmdline"));
while(!queue.empty())
{
#include <msp/datafile/loader.h>
#include <msp/fs/path.h>
#include "architecture.h"
+#include "buildgraph.h"
#include "buildtype.h"
#include "config.h"
#include "logger.h"
void package(const std::string &);
};
-public:
- typedef std::map<std::string, Target *> TargetMap;
-
private:
typedef std::list<std::string> NameList;
typedef std::map<std::string, BuildType> BuildTypeMap;
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;
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; }
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);
--- /dev/null
+#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);
+}
--- /dev/null
+#ifndef BUILDGRAPH_H_
+#define BUILDGRAPH_H_
+
+#include "virtualfilesystem.h"
+
+class Builder;
+class Target;
+
+/**
+Manages a graph of targets.
+*/
+class BuildGraph
+{
+public:
+ typedef std::map<std::string, Target *> 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
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();
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);
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)
{
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)
}
if(type==LIBRARY && install && dynamic_cast<FileTarget *>(src)->is_installable())
- builder.add_installed_target(*src);
+ build_graph.add_installed_target(*src);
}
}
for(list<Target *>::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);
}
}
}
const Tool © = builder.get_toolchain().get_tool("CP");
InstalledFile *inst_tgt = dynamic_cast<InstalledFile *>(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();
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));
}
}
state(INIT),
primary_target(0)
{
- builder.add_target(this);
+ builder.get_build_graph().add_target(this);
}
void Target::add_dependency(Target &dep)