if(!max_depth || depth<max_depth-1)
{
- const list<Target *> &depends=tgt.get_depends();
+ const TargetList &depends=tgt.get_depends();
//depends.sort(target_order);
- for(list<Target *>::const_iterator i=depends.begin(); i!=depends.end(); ++i)
+ for(TargetList::const_iterator i=depends.begin(); i!=depends.end(); ++i)
build_depend_table(**i, depth+1);
}
}
argv.push_back("rc");
argv.push_back(lib.get_name());
- const list<Target *> &deps=lib.get_depends();
- for(list<Target *>::const_iterator i=deps.begin(); i!=deps.end(); ++i)
+ const TargetList &deps=lib.get_depends();
+ for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i)
if(dynamic_cast<ObjectFile *>(*i))
argv.push_back((*i)->get_name());
using namespace Msp;
Builder::Builder(int argc, char **argv):
+ analyzer(0),
+ do_build(true),
verbose(1),
+ chrome(false),
build_file("Build"),
- do_build(true),
- analyzer(0),
- jobs(1),
- chrome(false)
+ jobs(1)
{
GetOpt getopt;
getopt.add_option(GetOpt::Option('a', "analyze", GetOpt::REQUIRED));
return 0;
}
- std::list<std::string> missing;
+ StringList missing;
for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
if(!i->second)
missing.push_back(i->first);
const Config::OptionMap &options=config.get_options();
cout<<"Required packages:\n ";
- const list<PackageRef> &requires=default_pkg->get_requires();
- for(list<PackageRef>::const_iterator i=requires.begin(); i!=requires.end(); ++i)
+ const PkgRefList &requires=default_pkg->get_requires();
+ for(PkgRefList::const_iterator i=requires.begin(); i!=requires.end(); ++i)
{
if(i!=requires.begin())
cout<<", ";
#include <msp/parser/loader.h>
#include <msp/path/path.h>
#include "config.h"
+#include "misc.h"
+#include "target.h"
class Analyzer;
class Package;
-class Target;
class Builder: public Msp::Application
{
bool get_build_all() const { return build_all; }
Package *get_package(const std::string &);
Target *get_target(const std::string &);
- Target *get_header(const std::string &, const std::string &, const std::list<std::string> &);
- Target *get_library(const std::string &, const std::list<std::string> &);
+ Target *get_header(const std::string &, const std::string &, const StringList &);
+ Target *get_library(const std::string &, const StringList &);
const Msp::Path::Path &get_cwd() const { return cwd; }
int main();
~Builder();
public:
Loader(Builder &, const Msp::Path::Path &);
private:
- Builder &bld;
+ Builder &bld;
Msp::Path::Path src;
void package(const std::string &);
};
+ typedef std::list<Package *> PackageList;
typedef std::map<std::string, Package *> PackageMap;
typedef std::map<std::string, Target *> TargetMap;
typedef std::map<std::string, std::string> ToolMap;
- std::list<std::string> cmdline_targets;
+ StringList cmdline_targets;
RawOptionMap cmdline_options;
+ Msp::Path::Path cwd;
- PackageMap packages;
- std::list<Package *> new_pkgs;
- Package *default_pkg;
+ PackageMap packages;
+ PackageList new_pkgs;
+ Package *default_pkg;
- TargetMap targets;
- std::list<Target *> new_tgts;
- TargetMap includes;
- TargetMap libraries;
+ TargetMap targets;
+ TargetList new_tgts;
+ TargetMap includes;
+ TargetMap libraries;
- ToolMap tools;
- unsigned verbose;
- Msp::Path::Path cwd;
+ ToolMap tools; /// Not used yet
+
+ Analyzer *analyzer;
+ bool do_build;
+ bool dry_run;
+ bool help;
+ unsigned verbose;
+ bool chrome;
Msp::Path::Path build_file;
- bool do_build;
- bool dry_run;
- Analyzer *analyzer;
- unsigned jobs;
- std::list<std::string> what_if;
- bool chrome;
- bool conf_all;
- bool build_all;
- bool help;
+ unsigned jobs;
+ StringList what_if;
+ bool conf_all;
+ bool build_all;
- int load_build_file(const Msp::Path::Path &);
- int create_targets();
+ int load_build_file(const Msp::Path::Path &);
+ int create_targets();
Target *check_header(const Msp::Path::Path &);
- void add_target(Target *);
- void update_hash(std::string &, const std::string &);
- int build();
- void package_help();
+ void add_target(Target *);
+ void update_hash(std::string &, const std::string &);
+ int build();
+ void package_help();
static Msp::Application::RegApp<Builder> reg;
};
unique(libs);
}
-void BuildInfo::unique(InfoList &l)
+void BuildInfo::unique(StringList &l)
{
- InfoList l2;
- for(InfoList::iterator i=l.begin(); i!=l.end(); ++i)
+ StringList l2;
+ for(StringList::iterator i=l.begin(); i!=l.end(); ++i)
if(!contains(l2, *i))
l2.push_back(*i);
swap(l, l2);
#include <list>
#include <string>
#include <msp/parser/loader.h>
+#include "misc.h"
class BuildInfo
{
void library(const std::string &s) { binfo.libs.push_back(s); }
};
- typedef std::list<std::string> InfoList;
-
- InfoList cflags;
- InfoList defines;
- InfoList incpath;
- InfoList ldflags;
- InfoList libpath;
- InfoList libs;
+ StringList cflags;
+ StringList defines;
+ StringList incpath;
+ StringList ldflags;
+ StringList libpath;
+ StringList libs;
void add(const BuildInfo &);
void unique();
private:
- void unique(InfoList &);
+ void unique(StringList &);
};
#endif
#include "buildinfo.h"
#include "compile.h"
#include "component.h"
+#include "objectfile.h"
#include "package.h"
using namespace std;
using namespace Msp;
-Compile::Compile(Builder &b, const Path::Path &s, const Path::Path &o, const Component &c):
- ExternalAction(b),
- source(s),
- object(o),
- comp(c)
+Compile::Compile(Builder &b, const ObjectFile &obj):
+ ExternalAction(b)
{
- string ext=Path::splitext(source.str()).ext;
+ const Component &comp=obj.get_component();
+
+ const TargetList &deps=obj.get_depends();
+ Path::Path spath=deps.front()->get_name();
+
+ string ext=Path::splitext(spath.str()).ext;
const char *tool=0;
if(ext==".cpp" || ext==".cc")
{
for(list<string>::const_iterator i=binfo.defines.begin(); i!=binfo.defines.end(); ++i)
argv.push_back("-D"+*i);
+ Path::Path opath=obj.get_name();
argv.push_back("-o");
- argv.push_back(object.str());
- argv.push_back(source.str());
+ argv.push_back(opath.str());
+ argv.push_back(spath.str());
if(!builder.get_dry_run())
- Path::mkpath(object.subpath(0, object.size()-1), 0755);
+ Path::mkpath(opath.subpath(0, opath.size()-1), 0755);
- announce(comp.get_package().get_name(), tool, relative(object.str(), comp.get_package().get_source()).str());
+ announce(comp.get_package().get_name(), tool, relative(opath, comp.get_package().get_source()).str());
launch();
}
#include "externalaction.h"
class Component;
+class ObjectFile;
class Compile: public ExternalAction
{
public:
- Compile(Builder &, const Msp::Path::Path &, const Msp::Path::Path &, const Component &);
-private:
- Msp::Path::Path source;
- Msp::Path::Path object;
- const Component ∁
+ Compile(Builder &, const ObjectFile &);
};
#endif
void Component::resolve_refs()
{
- for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
i->resolve();
}
{
build_info.add(pkg.get_build_info());
- for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
{
if(!i->get_package())
continue;
bool install;
std::string install_headers;
BuildInfo build_info;
- std::list<PackageRef> requires;
+ PkgRefList requires;
};
typedef std::list<Component> ComponentList;
{
public:
Worker(Copy &i): copy(i), done(false), error(false) { launch(); }
- bool get_done() const { return done; }
+ bool get_done() const { return done; }
bool get_error() const { return error; }
private:
Copy ©
{
public:
Executable(Builder &, const Component &, const std::list<ObjectFile *> &);
- const char *get_type() const { return "Executable"; }
+ const char *get_type() const { return "Executable"; }
const Component &get_component() const { return comp; }
- void find_depends();
- Action *build();
+ void find_depends();
+ Action *build();
private:
const Component ∁
{
if(builder.get_verbose()>=2)
{
- for(list<string>::const_iterator i=argv.begin(); i!=argv.end(); ++i)
+ for(StringList::const_iterator i=argv.begin(); i!=argv.end(); ++i)
{
if(i!=argv.begin())
cout<<' ';
if(pid==0)
{
char *argv_[argv.size()+1];
- for(CountingIterator<string, list<string>::iterator> i=argv.begin(); i!=argv.end(); ++i)
+ for(CountingIterator<string, StringList::iterator> i=argv.begin(); i!=argv.end(); ++i)
argv_[i.count()]=strdup(i->c_str());
argv_[argv.size()]=0;
execvp(argv_[0], argv_);
#include <list>
#include <string>
#include "action.h"
+#include "misc.h"
class ExternalAction: public Action
{
public:
int check();
protected:
- std::list<std::string> argv;
- int pid;
- int exit_code;
+ StringList argv;
+ int pid;
+ int exit_code;
ExternalAction(Builder &b): Action(b), pid(0), exit_code(0) { }
void launch();
public:
SystemHeader(Builder &b, const std::string &f): Header(b,0,f) { }
const char *get_type() const { return "SystemHeader"; }
- void find_depends() { deps_ready=true; }
+ void find_depends() { deps_ready=true; }
};
#endif
public:
Install(Builder &, const Package &, Target &, const std::string &);
const char *get_type() const { return "Install"; }
- void check_rebuild();
- Action *build();
+ void check_rebuild();
+ Action *build();
private:
};
{
const Component &comp=exe.get_component();
+ //XXX Determine whether to use g++ or gcc
argv.push_back("g++");
if(comp.get_type()==Component::LIBRARY)
argv.push_back("-o");
argv.push_back(exe.get_name());
- const list<Target *> &deps=exe.get_depends();
- for(list<Target *>::const_iterator i=deps.begin(); i!=deps.end(); ++i)
+ const TargetList &deps=exe.get_depends();
+ for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i)
if(dynamic_cast<ObjectFile *>(*i))
argv.push_back((*i)->get_name());
#include <string>
#include <msp/path/path.h>
+typedef std::list<std::string> StringList;
typedef std::list<Msp::Path::Path> PathList;
-std::string run_command(const std::list<std::string> &);
+std::string run_command(const StringList &);
#endif
void ObjectFile::find_depends()
{
- for(list<Target *>::iterator i=new_deps.begin(); i!=new_deps.end();)
+ for(TargetList::iterator i=new_deps.begin(); i!=new_deps.end();)
{
Target *tgt=*i;
if(tgt->get_depends_ready())
Action *ObjectFile::build()
{
- return Target::build(new Compile(builder, depends.front()->get_name(), name, comp));
+ return Target::build(new Compile(builder, *this));
}
void ObjectFile::find_depends(Target *tgt)
{
public:
ObjectFile(Builder &, const Component &, SourceFile &);
- const char *get_type() const { return "ObjectFile"; }
- void find_depends();
- Action *build();
+ const char *get_type() const { return "ObjectFile"; }
+ const Component &get_component() const { return comp; }
+ void find_depends();
+ Action *build();
private:
const Component ∁
- std::list<Target *> new_deps;
+ TargetList new_deps;
void find_depends(Target *);
void add_depend(Target *);
Package::Package(Builder &b, const string &n, const Path::Path &s):
builder(b),
name(n),
- source(s),
buildable(true),
+ source(s),
build_info_ready(false)
{ }
-Package::Package(Builder &b, const string &n, const vector<string> &info):
- builder(b),
- name(n),
- buildable(false),
- build_info_ready(false)
-{
- for(vector<string>::const_iterator i=info.begin(); i!=info.end(); ++i)
- {
- if(!i->compare(0, 2, "-I"))
- export_binfo.incpath.push_back(i->substr(2));
- else if(!i->compare(0, 2, "-D"))
- export_binfo.defines.push_back(i->substr(2));
- else if(!i->compare(0, 2, "-L"))
- export_binfo.libpath.push_back(i->substr(2));
- else if(!i->compare(0, 2, "-l"))
- export_binfo.libs.push_back(i->substr(2));
- }
-}
-
void Package::set_path(const Msp::Path::Path &p)
{
path=builder.get_cwd()/p;
void Package::resolve_refs()
{
- for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
i->resolve();
for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
i->resolve_refs();
if(buildable)
{
- for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
{
Package *pkg=i->get_package();
if(!pkg)
return pkg;
}
+/*** private ***/
+
+Package::Package(Builder &b, const string &n, const vector<string> &info):
+ builder(b),
+ name(n),
+ buildable(false),
+ build_info_ready(false)
+{
+ for(vector<string>::const_iterator i=info.begin(); i!=info.end(); ++i)
+ {
+ if(!i->compare(0, 2, "-I"))
+ export_binfo.incpath.push_back(i->substr(2));
+ else if(!i->compare(0, 2, "-D"))
+ export_binfo.defines.push_back(i->substr(2));
+ else if(!i->compare(0, 2, "-L"))
+ export_binfo.libpath.push_back(i->substr(2));
+ else if(!i->compare(0, 2, "-l"))
+ export_binfo.libs.push_back(i->substr(2));
+ }
+}
+
void Package::init_buildable()
{
buildable=true;
if(flags&DATA)
config.add_option("includedir", "$prefix/share", "Data installation directory");*/
- for(list<PackageRef>::iterator i=requires.begin(); i!=requires.end(); ++i)
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
config.add_option(i->get_name()+"_path", "", "Path for "+i->get_name());
config.load(source/".options.cache");
};
Package(Builder &, const std::string &, const Msp::Path::Path &);
- Package(Builder &, const std::string &, const std::vector<std::string> &);
void set_path(const Msp::Path::Path &);
- const std::string &get_name() const { return name; }
- const Msp::Path::Path &get_source() const { return source; }
- const ComponentList &get_components() const { return components; }
- bool get_buildable() const { return buildable; }
- const Config &get_config() const { return config; }
- const std::list<PackageRef> &get_requires() const { return requires; }
- const BuildInfo &get_build_info() const { return build_info; }
+ const std::string &get_name() const { return name; }
+ const Msp::Path::Path &get_source() const { return source; }
+ const ComponentList &get_components() const { return components; }
+ bool get_buildable() const { return buildable; }
+ const Config &get_config() const { return config; }
+ const PkgRefList &get_requires() const { return requires; }
+ const BuildInfo &get_build_info() const { return build_info; }
const BuildInfo &get_exported_binfo() const { return export_binfo; }
- Builder &get_builder() const { return builder; }
- bool get_need_path() const { return need_path; }
+ Builder &get_builder() const { return builder; }
+ bool get_need_path() const { return need_path; }
void resolve_refs();
void create_build_info();
void process_options(const RawOptionMap &);
};
Builder &builder;
+
std::string name;
std::string version;
std::string description;
- std::list<PackageRef> requires;
+
+ bool buildable;
+ Msp::Path::Path source;
+ PkgRefList requires;
BuildInfo build_info;
BuildInfo export_binfo;
- Msp::Path::Path source;
- bool buildable;
ComponentList components;
Config config;
bool build_info_ready;
+
bool need_path;
Msp::Path::Path path;
- void init_buildable();
+ Package(Builder &, const std::string &, const std::vector<std::string> &);
+ void init_buildable();
unsigned get_install_flags();
};
#ifndef PACKAGEREF_H_
#define PACKAGEREF_H_
+#include <list>
#include <string>
class Builder;
std::string name;
Package *package;
};
+typedef std::list<PackageRef> PkgRefList;
#endif
{
public:
SourceFile(Builder &, const Component *, const std::string &);
- const std::list<std::string> &get_includes() const { return includes; }
- const char *get_type() const { return "SourceFile"; }
- void find_depends();
- Action *build() { rebuild=false; return 0; }
+ const StringList &get_includes() const { return includes; }
+ const char *get_type() const { return "SourceFile"; }
+ void find_depends();
+ Action *build() { return 0; }
private:
const Component *comp;
- std::list<std::string> includes;
+ StringList includes;
};
#endif
{
public:
StaticLibrary(Builder &, const Component &, const std::list<ObjectFile *> &);
- const char *get_type() const { return "StaticLibrary"; }
+ const char *get_type() const { return "StaticLibrary"; }
const Component &get_component() const { return comp; }
- Action *build();
+ Action *build();
private:
const Component ∁
Target *Target::get_buildable_target()
{
bool self_ok=true;
- for(list<Target *>::iterator i=depends.begin(); i!=depends.end(); ++i)
+ for(TargetList::iterator i=depends.begin(); i!=depends.end(); ++i)
{
Target *tgt=(*i)->get_buildable_target();
if(tgt)
if(prepared)
return;
- for(list<Target *>::iterator i=depends.begin(); i!=depends.end(); ++i)
+ for(TargetList::iterator i=depends.begin(); i!=depends.end(); ++i)
(*i)->prepare();
check_rebuild();
counted=true;
unsigned count=rebuild;
- for(list<Target *>::iterator i=depends.begin(); i!=depends.end(); ++i)
+ for(TargetList::iterator i=depends.begin(); i!=depends.end(); ++i)
count+=(*i)->count_rebuild();
return count;
}
builder(b),
package(p),
name(n),
+ buildable(false),
building(false),
rebuild(false),
deps_ready(false),
prepared(false),
- buildable(false),
counted(false)
{
struct stat st;
mark_rebuild("Does not exist");
else
{
- for(list<Target *>::iterator i=depends.begin(); (i!=depends.end() && !rebuild); ++i)
+ for(TargetList::iterator i=depends.begin(); (i!=depends.end() && !rebuild); ++i)
{
if((*i)->get_mtime()>mtime)
mark_rebuild(Path::basename((*i)->get_name())+" has changed");
class Builder;
class Package;
+class Target;
+typedef std::list<Target *> TargetList;
+
class Target
{
public:
- const std::string &get_name() const { return name; }
- Target *get_buildable_target();
- bool get_rebuild() const { return rebuild; }
- const std::string &get_rebuild_reason() const { return rebuild_reason; }
+ const std::string &get_name() const { return name; }
+ Target *get_buildable_target();
+ bool get_rebuild() const { return rebuild; }
+ const std::string &get_rebuild_reason() const { return rebuild_reason; }
const Msp::Time::TimeStamp &get_mtime() const { return mtime; }
virtual const char *get_type() const=0;
- const std::list<Target *> &get_depends() const { return depends; }
- const Package *get_package() const { return package; }
- bool get_depends_ready() const { return deps_ready; }
- void add_depend(Target *);
- virtual void find_depends() { deps_ready=true; }
- virtual void prepare();
- virtual Action *build()=0;
- void reset_count() { counted=false; }
- virtual unsigned count_rebuild();
- void touch();
+ const TargetList &get_depends() const { return depends; }
+ const Package *get_package() const { return package; }
+ bool get_depends_ready() const { return deps_ready; }
+ void add_depend(Target *);
+ virtual void find_depends() { deps_ready=true; }
+ virtual void prepare();
+ virtual Action *build()=0;
+ void reset_count() { counted=false; }
+ virtual unsigned count_rebuild();
+ void touch();
virtual ~Target() { }
protected:
- Builder &builder;
+ Builder &builder;
const Package *package;
- std::string name;
- bool building;
- bool rebuild;
- std::string rebuild_reason;
+ std::string name;
Msp::Time::TimeStamp mtime;
- std::list<Target *> depends;
- std::list<Target *> rdepends;
- bool deps_ready;
- bool prepared;
- bool buildable;
- bool counted;
+
+ bool buildable;
+ bool building;
+ bool rebuild;
+ std::string rebuild_reason;
+
+ TargetList depends;
+ TargetList rdepends;
+ bool deps_ready;
+
+ bool prepared;
+ bool counted;
Target(Builder &, const Package *, const std::string &);
- void mark_rebuild(const std::string &);
+ void mark_rebuild(const std::string &);
virtual void check_rebuild();
- Action *build(Action *);
+ Action *build(Action *);
virtual void build_done();
};
void VirtualTarget::check_rebuild()
{
- for(list<Target *>::iterator i=depends.begin(); (i!=depends.end() && !rebuild); ++i)
+ for(TargetList::iterator i=depends.begin(); (i!=depends.end() && !rebuild); ++i)
if((*i)->get_rebuild())
mark_rebuild(Msp::Path::basename((*i)->get_name())+" needs rebuilding");
}
public:
VirtualTarget(Builder &b, const std::string &n): Target(b,0,n) { }
const char *get_type() const { return "VirtualTarget"; }
- Action *build() { rebuild=false; return 0; }
- unsigned count_rebuild();
+ Action *build() { rebuild=false; return 0; }
+ unsigned count_rebuild();
private:
void check_rebuild();
};