--- /dev/null
+binary_package "opengl"
+{
+ build_info
+ {
+ library "GL";
+ };
+};
+
+binary_package "pthread"
+{
+ build_info
+ {
+ library "pthread";
+ };
+};
+
+binary_package "gmpxx"
+{
+ build_info
+ {
+ library "gmpxx";
+ };
+};
+
+binary_package "fmod4"
+{
+ build_info
+ {
+ incpath "@/api/inc";
+ libpath "@/api/lib";
+ library "fmodex";
+ };
+ need_path true;
+};
+
+binary_package "xlib"
+{
+ build_info
+ {
+ library "X11";
+ };
+};
+
+architecture "arm" "arm-linux-gnu";
+architecture "win32" "i586-mingw32msvc";
+
+profile "debug"
+{
+ option "debug" "1";
+ option "outdir" "$profile";
+};
+
+profile "release"
+{
+ option "optimize" "3";
+ option "strip" "1";
+ option "outdir" "$profile";
+};
+
+profile "win32"
+{
+ option "arch" "win32";
+ option "prefix" "$HOME/local/$arch";
+ option "outdir" "$profile";
+};
+
+profile "arm"
+{
+ option "arch" "arm";
+ option "prefix" "$HOME/local/$arch";
+ option "outdir" "$profile";
+};
#include "builder.h"
#include "component.h"
#include "objectfile.h"
-#include "package.h"
+#include "sourcepackage.h"
#include "staticlibrary.h"
using namespace std;
{
const Component &comp=lib.get_component();
- argv.push_back(builder.get_tool("AR", lib.get_package()->get_arch()));
+ argv.push_back(builder.get_tool("AR", comp.get_package().get_arch()));
argv.push_back("rc");
argv.push_back(lib.get_name());
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/strings/utils.h>
+#include "binarypackage.h"
+#include "builder.h"
+
+using namespace std;
+using namespace Msp;
+
+BinaryPackage::BinaryPackage(Builder &b, const string &n):
+ Package(b, n),
+ need_path(false)
+{
+ use_pkgconfig=false;
+}
+
+/**
+Sets the path where the package files were installed. This is only useful if
+the package doesn't use pkg-config.
+*/
+void BinaryPackage::set_path(const Msp::Path::Path &p)
+{
+ path=builder.get_cwd()/p;
+}
+
+void BinaryPackage::create_build_info()
+{
+ for(StringList::iterator i=export_binfo.incpath.begin(); i!=export_binfo.incpath.end(); ++i)
+ if((*i)[0]=='@')
+ *i=(path/i->substr(1)).str();
+
+ for(StringList::iterator i=export_binfo.libpath.begin(); i!=export_binfo.libpath.end(); ++i)
+ if((*i)[0]=='@')
+ *i=(path/i->substr(1)).str();
+}
+
+BinaryPackage *BinaryPackage::from_pkgconfig(Builder &builder, const string &name)
+{
+ list<string> argv;
+ argv.push_back("pkg-config");
+ argv.push_back("--silence-errors");
+ argv.push_back("--cflags");
+ argv.push_back("--libs");
+ argv.push_back(name);
+ string info=run_command(argv);
+
+ if(info.empty())
+ return 0;
+
+
+ BinaryPackage *pkg=new BinaryPackage(builder, name);
+ pkg->use_pkgconfig=true;
+ BuildInfo &binfo=pkg->export_binfo;
+
+ vector<string> flags=split(info);
+ for(vector<string>::const_iterator i=flags.begin(); i!=flags.end(); ++i)
+ {
+ if(!i->compare(0, 2, "-I"))
+ binfo.incpath.push_back(i->substr(2));
+ else if(!i->compare(0, 2, "-D"))
+ binfo.defines.push_back(i->substr(2));
+ else if(!i->compare(0, 2, "-L"))
+ binfo.libpath.push_back(i->substr(2));
+ else if(!i->compare(0, 2, "-l"))
+ binfo.libs.push_back(i->substr(2));
+ }
+
+ return pkg;
+}
+
+
+BinaryPackage::Loader::Loader(BinaryPackage &p):
+ Package::Loader(p)
+{
+ add("need_path", &BinaryPackage::need_path);
+ add("build_info", &Loader::build_info);
+}
+
+void BinaryPackage::Loader::build_info()
+{
+ load_sub(static_cast<BinaryPackage &>(pkg).export_binfo);
+}
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef BINARYPACKAGE_H_
+#define BINARYPACKAGE_H_
+
+#include "package.h"
+
+/**
+Represents a package that is installed on the system, but can't be built by
+Builder.
+*/
+class BinaryPackage: public Package
+{
+public:
+ class Loader: public Package::Loader
+ {
+ public:
+ Loader(BinaryPackage &);
+ BinaryPackage &get_object() { return static_cast<BinaryPackage &>(pkg); }
+ private:
+ void build_info();
+ };
+
+ BinaryPackage(Builder &, const std::string &);
+ void set_path(const Msp::Path::Path &);
+ bool get_need_path() const { return need_path; }
+
+ static BinaryPackage *from_pkgconfig(Builder &, const std::string &);
+private:
+ bool need_path;
+ Msp::Path::Path path;
+
+ virtual void create_build_info();
+};
+
+#endif
#include <msp/time/utils.h>
#include "action.h"
#include "analyzer.h"
+#include "binarypackage.h"
#include "builder.h"
#include "header.h"
#include "install.h"
#include "package.h"
#include "pkgconfig.h"
#include "sharedlibrary.h"
+#include "sourcepackage.h"
#include "systemlibrary.h"
#include "tarball.h"
#include "unlink.h"
using namespace Msp;
Builder::Builder(int argc, char **argv):
+ default_pkg(0),
analyzer(0),
build(false),
clean(0),
cwd=Path::getcwd();
archs.insert(StringMap::value_type("native", ""));
- archs.insert(StringMap::value_type("arm", "arm-linux-gnu"));
- archs.insert(StringMap::value_type("win32", "i586-mingw32msvc"));
StringMap &native_tools=tools.insert(ToolMap::value_type("native", StringMap())).first->second;
native_tools.insert(StringMap::value_type("CC", "gcc"));
native_tools.insert(StringMap::value_type("LDXX", "g++"));
native_tools.insert(StringMap::value_type("AR", "ar"));
- StringMap &release_profile=profile_tmpl.insert(ProfileTemplateMap::value_type("release", StringMap())).first->second;
- release_profile.insert(StringMap::value_type("optimize", "3"));
- release_profile.insert(StringMap::value_type("outdir", "$profile"));
-
- StringMap &debug_profile=profile_tmpl.insert(ProfileTemplateMap::value_type("debug", StringMap())).first->second;
- debug_profile.insert(StringMap::value_type("debug", "1"));
- debug_profile.insert(StringMap::value_type("outdir", "$profile"));
-
- for(StringMap::iterator i=archs.begin(); i!=archs.end(); ++i)
- {
- if(i->first=="native")
- continue;
-
- StringMap &arch_profile=profile_tmpl.insert(ProfileTemplateMap::value_type(i->first, StringMap())).first->second;
- arch_profile.insert(StringMap::value_type("arch", i->first));
- arch_profile.insert(StringMap::value_type("prefix", "$HOME/local/$arch"));
- arch_profile.insert(StringMap::value_type("outdir", "$profile"));
- }
+ const char *home=getenv("HOME");
+ if(home)
+ load_build_file((Path::Path(home)/".builderrc").str());
}
/**
}
// Package source not found - create a binary package
- Package *pkg=Package::create(*this, n);
+ Package *pkg=BinaryPackage::from_pkgconfig(*this, n);
+
packages.insert(PackageMap::value_type(n, pkg));
if(pkg)
new_pkgs.push_back(pkg);
return 1;
}
- default_pkg=packages.begin()->second;
-
while(!new_pkgs.empty())
{
Package *pkg=new_pkgs.front();
StringMap problems;
for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
{
+ SourcePackage *spkg=dynamic_cast<SourcePackage *>(i->second);
string prob;
if(!i->second)
prob="missing";
- else if(i->second->get_buildable() && i->second->get_arch()!=default_pkg->get_arch())
- prob="wrong architecture ("+i->second->get_arch()+")";
+ else if(spkg && spkg->get_arch()!=default_pkg->get_arch())
+ prob="wrong architecture ("+spkg->get_arch()+")";
if(!prob.empty())
problems.insert(StringMap::value_type(i->first, prob));
}
for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
{
cout<<' '<<i->second->get_name();
- if(i->second->get_buildable())
+ if(dynamic_cast<SourcePackage *>(i->second))
cout<<'*';
unsigned count=0;
unsigned ood_count=0;
if(!in)
return -1;
+ if(verbose>=3)
+ cout<<"Reading "<<fn<<'\n';
+
DataFile::Parser parser(in, fn.str());
Loader loader(*this, fn.subpath(0, fn.size()-1));
loader.load(parser);
for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
{
- if(!i->second)
- continue;
- if(!i->second->get_buildable())
+ SourcePackage *spkg=dynamic_cast<SourcePackage *>(i->second);
+ if(!spkg)
continue;
- const ComponentList &components=i->second->get_components();
+ const ComponentList &components=spkg->get_components();
for(ComponentList::const_iterator j=components.begin(); j!=components.end(); ++j)
j->create_targets();
- if(i->second->get_install_flags()&(Package::LIB|Package::INCLUDE))
+ if(spkg->get_install_flags()&(SourcePackage::LIB|SourcePackage::INCLUDE))
{
- PkgConfig *pc=new PkgConfig(*this, *i->second);
- install->add_depend(new Install(*this, *i->second, *pc));
+ PkgConfig *pc=new PkgConfig(*this, *spkg);
+ install->add_depend(new Install(*this, *spkg, *pc));
}
- tarballs->add_depend(new TarBall(*this, *i->second));
+ tarballs->add_depend(new TarBall(*this, *spkg));
}
// Find dependencies until no new targets are created
}
for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i)
- i->second->get_deps_cache().save();
+ if(SourcePackage *spkg=dynamic_cast<SourcePackage *>(i->second))
+ spkg->get_deps_cache().save();
return 0;
}
Application::RegApp<Builder> Builder::reg;
+
Builder::Loader::Loader(Builder &b, const Path::Path &s):
bld(b),
src(s)
{
+ add("architecture", &Loader::architecture);
+ add("binary_package", &Loader::binpkg);
+ add("profile", &Loader::profile);
add("package", &Loader::package);
}
+void Builder::Loader::architecture(const string &a, const string &p)
+{
+ bld.archs.insert(StringMap::value_type(a, p));
+}
+
+void Builder::Loader::binpkg(const string &n)
+{
+ BinaryPackage *pkg=new BinaryPackage(bld, n);
+ load_sub(*pkg);
+ bld.packages.insert(PackageMap::value_type(n, pkg));
+ bld.new_pkgs.push_back(pkg);
+}
+
+void Builder::Loader::profile(const string &n)
+{
+ StringMap prf;
+ load_sub<ProfileLoader>(prf);
+ bld.profile_tmpl.insert(ProfileTemplateMap::value_type(n, prf));
+}
+
void Builder::Loader::package(const string &n)
{
- Package *pkg=new Package(bld, n, src);
+ SourcePackage *pkg=new SourcePackage(bld, n, src);
load_sub(*pkg);
bld.packages.insert(PackageMap::value_type(n, pkg));
bld.new_pkgs.push_back(pkg);
+ if(!bld.default_pkg)
+ bld.default_pkg=pkg;
}
+
+Builder::ProfileLoader::ProfileLoader(StringMap &p):
+ profile(p)
+{
+ add("option", &ProfileLoader::option);
+}
+
+void Builder::ProfileLoader::option(const string &o, const string &v)
+{
+ profile.insert(StringMap::value_type(o, v));
+}
class Analyzer;
class Config;
class Package;
+class SourcePackage;
/**
The main application class. Controls and owns everything. Rules the world.
bool get_dry_run() const { return dry_run; }
bool get_build_all() const { return build_all; }
Package *get_package(const std::string &);
- Package *get_default_package() const { return default_pkg; }
+ SourcePackage *get_default_package() const { return default_pkg; }
Target *get_target(const std::string &) const;
const TargetMap &get_targets() const { return targets; }
Target *get_header(const std::string &, const std::string &, const std::string &, const StringList &);
Builder &bld;
Msp::Path::Path src;
+ void architecture(const std::string &, const std::string &);
+ void binpkg(const std::string &);
+ void profile(const std::string &);
void package(const std::string &);
};
+ class ProfileLoader: public Msp::DataFile::Loader
+ {
+ public:
+ ProfileLoader(StringMap &);
+ private:
+ StringMap &profile;
+
+ void option(const std::string &, const std::string &);
+ };
+
typedef std::list<Package *> PackageList;
typedef std::map<std::string, Package *> PackageMap;
typedef std::map<std::string, StringMap> ToolMap;
PackageMap packages;
PackageList new_pkgs;
- Package *default_pkg;
+ SourcePackage *default_pkg;
TargetMap targets;
TargetList new_tgts;
#include "compile.h"
#include "component.h"
#include "objectfile.h"
-#include "package.h"
+#include "sourcepackage.h"
using namespace std;
using namespace Msp;
else
tool="CC";
- argv.push_back(builder.get_tool(tool, obj.get_package()->get_arch()));
+ argv.push_back(builder.get_tool(tool, comp.get_package().get_arch()));
argv.push_back("-c");
const BuildInfo &binfo=comp.get_build_info();
#include <msp/core/error.h>
#include <msp/path/utils.h>
+#include <msp/strings/lexicalcast.h>
#include "builder.h"
#include "component.h"
#include "header.h"
#include "install.h"
#include "objectfile.h"
-#include "package.h"
#include "sharedlibrary.h"
+#include "sourcepackage.h"
#include "staticlibrary.h"
#include "target.h"
using namespace std;
using namespace Msp;
-Component::Component(Package &p, Type t, const string &n):
+Component::Component(SourcePackage &p, Type t, const string &n):
pkg(p),
type(t),
name(n),
build_info.add(i->get_package()->get_exported_binfo());
}
+ if(type==PROGRAM)
+ {
+ string strip=pkg.get_config().get_option("strip").value;
+ if(lexical_cast<bool>(strip))
+ build_info.ldflags.push_back("-s");
+ }
+
if(modular)
{
build_info.ldflags.push_back("-rdynamic");
PathList files=collect_source_files();
- bool build_exe=(type!=Component::HEADERS);
+ bool build_exe=(type!=HEADERS);
list<ObjectFile *> objs;
list<Target *> inst_tgts;
{
Executable *exe=0;
StaticLibrary *slib=0;
- if(type==Component::LIBRARY)
+ if(type==LIBRARY)
{
exe=new SharedLibrary(builder, *this, objs);
slib=new StaticLibrary(builder, *this, objs);
#include "misc.h"
#include "packageref.h"
-class Package;
+class SourcePackage;
/**
Components specify things to be built. Each component may build one binary (it
HEADERS
};
- Component(Package &, Type, const std::string &);
- const Package &get_package() const { return pkg; }
+ Component(SourcePackage &, Type, const std::string &);
+ const SourcePackage &get_package() const { return pkg; }
Type get_type() const { return type; }
const std::string &get_name() const { return name; }
const PathList &get_sources() const { return sources; }
void create_build_info();
void create_targets() const;
protected:
- Package &pkg;
+ SourcePackage &pkg;
Type type;
std::string name;
PathList sources;
#include <msp/strings/utils.h>
#include "condition.h"
-#include "package.h"
+#include "sourcepackage.h"
using namespace std;
using namespace Msp;
-#include <iostream>
-
-Condition::Condition(Package &p, const string &expr):
+Condition::Condition(SourcePackage &p, const string &expr):
pkg(p)
{
vector<string> parts=split(expr);
{
if(*i=="and")
continue;
-
+
unsigned token=i->find_first_of("=!");
if(token==string::npos)
expression.insert(StringMap::value_type(*i, "!0"));
#include "packageref.h"
class Config;
+class SourcePackage;
class Condition
{
void build_info();
};
- Condition(Package &, const std::string &);
+ Condition(SourcePackage &, const std::string &);
const PkgRefList &get_requires() const { return requires; }
const BuildInfo &get_build_info() const { return build_info; }
void resolve_refs();
bool eval();
private:
- Package &pkg;
+ SourcePackage &pkg;
StringMap expression;
PkgRefList requires;
BuildInfo build_info;
#include <msp/time/utils.h>
#include "builder.h"
#include "config.h"
-#include "package.h"
+#include "sourcepackage.h"
using namespace std;
using namespace Msp;
-Config::Config(Package &p):
+Config::Config(SourcePackage &p):
package(p),
freeze_mtime(false)
{ }
#include <msp/time/timestamp.h>
#include "misc.h"
-class Package;
+class SourcePackage;
/**
Manages configuration for a package. A configuration may have an arbitary
};
typedef std::map<std::string, Option> OptionMap;
- Config(Package &);
+ Config(SourcePackage &);
void add_option(const std::string &, const std::string &, const std::string &);
const Option &get_option(const std::string &) const;
const OptionMap &get_options() const { return options; }
Loader(Config &);
private:
Config &conf;
-
+
void option(const std::string &, const std::string &);
};
- Package &package;
+ SourcePackage &package;
OptionMap options;
Msp::Time::TimeStamp mtime;
bool freeze_mtime;
#include <msp/strings/utils.h>
#include "builder.h"
#include "dependencycache.h"
-#include "package.h"
+#include "sourcepackage.h"
using namespace std;
using namespace Msp;
-DependencyCache::DependencyCache(Package &p):
+DependencyCache::DependencyCache(SourcePackage &p):
package(p),
changed(false)
{ }
class DependencyCache
{
public:
- DependencyCache(Package &p);
+ DependencyCache(SourcePackage &p);
void set_deps(const std::string &tgt, const StringList &d);
const StringList &get_deps(const std::string &tgt) const;
const Msp::Time::TimeStamp &get_mtime() const { return mtime; }
private:
typedef std::map<std::string, StringList> DepsMap;
- Package &package;
+ SourcePackage &package;
DepsMap deps;
Msp::Time::TimeStamp mtime;
bool changed;
*/
void Executable::find_depends()
{
- LibMode libmode=package->get_library_mode();
+ LibMode libmode=comp.get_package().get_library_mode();
list<const Component *> queue;
list<Target *> dep_libs;
using namespace std;
using namespace Msp;
-Install::Install(Builder &b, const Package &p, Target &tgt):
+Install::Install(Builder &b, const SourcePackage &p, Target &tgt):
Target(b, &p, generate_target_name(tgt))
{
buildable=true;
string Install::generate_target_name(const Target &tgt)
{
- Path::Path base=tgt.get_package()->get_prefix();
+ const SourcePackage *spkg=dynamic_cast<const SourcePackage *>(tgt.get_package());
+
+ Path::Path base=spkg->get_prefix();
string tgtname=tgt.get_name().substr(tgt.get_name().rfind('/')+1);
string mid;
#ifndef INSTALL_H_
#define INSTALL_H_
+#include "sourcepackage.h"
#include "target.h"
/**
class Install: public Target
{
public:
- Install(Builder &, const Package &, Target &);
+ Install(Builder &, const SourcePackage &, Target &);
const char *get_type() const { return "Install"; }
void check_rebuild();
Action *build();
const Component &comp=exe.get_component();
//XXX Determine whether to use g++ or gcc
- argv.push_back(builder.get_tool("LDXX", exe.get_package()->get_arch()));
+ argv.push_back(builder.get_tool("LDXX", comp.get_package().get_arch()));
if(comp.get_type()==Component::LIBRARY || comp.get_type()==Component::MODULE)
argv.push_back("-shared");
#include "component.h"
#include "install.h"
#include "objectfile.h"
-#include "package.h"
#include "sourcefile.h"
+#include "sourcepackage.h"
using namespace std;
using namespace Msp;
/**
Creates a buildable package.
*/
-Package::Package(Builder &b, const string &n, const Path::Path &s):
+Package::Package(Builder &b, const string &n):
builder(b),
name(n),
- buildable(true),
- source(s),
- config(*this),
conf_done(false),
- deps_cache(*this),
- use_pkgconfig(true),
- need_path(false)
-{
- tar_files.push_back(source/"Build");
-
- if(builder.get_verbose()>=4)
- cout<<"Created buildable package "<<n<<" at "<<s<<'\n';
-}
-
-/**
-Sets the path where the package files were installed. This is only useful for
-non-buildable packages that don't use pkg-config.
-*/
-void Package::set_path(const Msp::Path::Path &p)
-{
- path=builder.get_cwd()/p;
-}
-
-Msp::Path::Path Package::get_temp_dir() const
-{
- return source/config.get_option("tempdir").value/config.get_option("profile").value;
-}
-
-Msp::Path::Path Package::get_out_dir() const
-{
- return source/config.get_option("outdir").value;
-}
-
-/**
-Checks which kinds of things the components of this package install.
-
-@return A bitmask of installed things
-*/
-unsigned Package::get_install_flags()
-{
- unsigned flags=0;
- for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
- {
- if(i->get_install())
- {
- if(i->get_type()==Component::PROGRAM)
- flags|=BIN;
- else if(i->get_type()==Component::LIBRARY || i->get_type()==Component::MODULE)
- flags|=LIB;
- }
- if(!i->get_install_headers().empty())
- flags|=INCLUDE;
- }
-
- return flags;
-}
-
-LibMode Package::get_library_mode() const
-{
- const string &mode=config.get_option("staticlibs").value;
- if(mode=="all")
- return ALL_STATIC;
- else if(mode=="local")
- return LOCAL_STATIC;
- else if(mode=="none")
- return DYNAMIC;
- else
- throw Exception("Unknown library mode");
-}
+ use_pkgconfig(true)
+{ }
/**
Tries to resolve all references to dependency packages.
void Package::resolve_refs()
{
for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
- {
- Package *pkg=i->resolve();
- if(pkg) all_reqs.push_back(pkg);
- }
-
- for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
- {
- i->resolve_refs();
- const PkgRefList &creqs=i->get_requires();
- for(PkgRefList::const_iterator j=creqs.begin(); j!=creqs.end(); ++j)
- if(j->get_package())
- all_reqs.push_back(j->get_package());
- }
-
- for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
- {
- i->resolve_refs();
- const PkgRefList &creqs=i->get_requires();
- for(PkgRefList::const_iterator j=creqs.begin(); j!=creqs.end(); ++j)
- if(j->get_package())
- all_reqs.push_back(j->get_package());
- }
+ i->resolve();
}
/**
if(builder.get_verbose()>=3)
cout<<"Configuring "<<name<<'\n';
- if(buildable)
- {
- init_config();
-
- StringMap::const_iterator prof=opts.find("profile");
- if(prof!=opts.end() && flag)
- config.select_profile(prof->second);
- else
- config.select_last_profile();
-
- if(flag && config.update(opts))
- {
- if(builder.get_verbose()>=2)
- cout<<"Configuration of "<<name<<" changed\n";
- if(!builder.get_dry_run())
- config.save();
- }
-
- config.finish();
-
- for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
- if(i->eval())
- {
- const PkgRefList &reqs=i->get_requires();
- requires.insert(requires.end(), reqs.begin(), reqs.end());
- build_info.add(i->get_build_info());
- }
+ do_configure(opts, flag);
- for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
- {
- if((*i)->get_need_path())
- (*i)->set_path(config.get_option((*i)->get_name()+"_path").value);
- (*i)->configure(opts, flag&2);
- }
-
- deps_cache.load();
- }
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
+ i->get_package()->configure(opts, flag&2);
create_build_info();
conf_done=true;
}
-/**
-Creates a non-buildable package with the given name. Pkg-config is tried first
-to get build information. If it fails, a built-in list of known packages is
-consulted.
-*/
-Package *Package::create(Builder &b, const string &name)
-{
- list<string> argv;
- argv.push_back("pkg-config");
- argv.push_back("--silence-errors");
- argv.push_back("--cflags");
- argv.push_back("--libs");
- argv.push_back(name);
- vector<string> info=split(run_command(argv));
-
- bool need_path=false;
- bool use_pkgconfig=true;
- if(info.empty())
- {
- use_pkgconfig=false;
-
- //XXX Put these in an external file
- if(name=="opengl")
- info.push_back("-lGL");
- else if(name=="pthread")
- info.push_back("-lpthread");
- else if(name=="gmpxx")
- info.push_back("-lgmpxx");
- else if(name=="fmod4")
- need_path=true;
- else if(name=="devil")
- info.push_back("-lIL");
- else if(name=="Xlib")
- info.push_back("-lX11");
- else
- return 0;
- }
-
- Package *pkg=new Package(b, name, info);
- pkg->need_path=need_path;
- pkg->use_pkgconfig=use_pkgconfig;
- return pkg;
-}
-
/*** private ***/
-Package::Package(Builder &b, const string &n, const vector<string> &info):
- builder(b),
- name(n),
- buildable(false),
- config(*this),
- conf_done(false),
- deps_cache(*this)
-{
- 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));
- }
-
- if(builder.get_verbose()>=4)
- {
- cout<<"Created non-buildable package "<<name<<" with";
- for(vector<string>::const_iterator i=info.begin(); i!=info.end(); ++i)
- cout<<' '<<*i;
- cout<<'\n';
- }
-}
-
-/**
-Initializes configuration options and loads cached values.
-*/
-void Package::init_config()
-{
- config.add_option("profile", "default", "Configuration profile");
- config.add_option("tempdir", "temp", "Directory for storing temporary files");
- config.add_option("outdir", ".", "Directory to put build results in");
- config.add_option("optimize", "0", "Apply compiler optimizations");
- config.add_option("debug", "0", "Produce debugging symbols");
- config.add_option("cpu", "auto", "CPU type to optimize for");
- config.add_option("arch", "native", "Architecture for cross-compiling");
- config.add_option("staticlibs", "local", "Use static libraries");
-
- unsigned flags=get_install_flags();
- if(flags)
- config.add_option("prefix", "$HOME/local", "Installation prefix");
- /*if(flags&INCLUDE)
- config.add_option("includedir", "$prefix/include", "Header installation directory");
- if(flags&BIN)
- config.add_option("includedir", "$prefix/bin", "Binary installation directory");
- if(flags&LIB)
- config.add_option("includedir", "$prefix/lib", "Library installation directory");
- if(flags&DATA)
- config.add_option("includedir", "$prefix/share", "Data installation directory");*/
-
- for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
- config.add_option("with_"+i->name, "0", i->descr);
-
- for(PackageList::const_iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
- if((*i)->get_need_path())
- config.add_option((*i)->get_name()+"_path", "", "Path for "+(*i)->get_name());
-}
-
-/**
-Fills in build info based on configuration. All required packages must be
-configured when this is called.
-*/
-void Package::create_build_info()
-{
- if(buildable)
- {
- for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
- {
- Package *pkg=i->get_package();
- if(!pkg)
- continue;
- const BuildInfo &ebi=pkg->get_exported_binfo();
- build_info.add(ebi);
-
- export_binfo.cflags.insert(export_binfo.cflags.end(), ebi.cflags.begin(), ebi.cflags.end());
- export_binfo.incpath.insert(export_binfo.incpath.end(), ebi.incpath.begin(), ebi.incpath.end());
- export_binfo.defines.insert(export_binfo.defines.end(), ebi.defines.begin(), ebi.defines.end());
- }
-
- build_info.cflags.push_back("-Wall");
- build_info.cflags.push_back("-Wshadow");
- build_info.cflags.push_back("-Wextra");
- build_info.cflags.push_back("-Wpointer-arith");
- build_info.cflags.push_back("-Wconversion");
- build_info.cflags.push_back("-Werror");
-
- unsigned flags=get_install_flags();
-
- if(flags&INCLUDE)
- export_binfo.incpath.push_back((Path::Path(config.get_option("prefix").value)/"include").str());
- if(flags&LIB)
- export_binfo.libpath.push_back((Path::Path(config.get_option("prefix").value)/"lib").str());
-
- string optimize=config.get_option("optimize").value;
- if(lexical_cast<unsigned>(optimize))
- {
- build_info.cflags.push_back("-O"+optimize);
- build_info.ldflags.push_back("-O"+optimize);
- string cpu=config.get_option("cpu").value;
- if(cpu!="auto")
- build_info.cflags.push_back("-march="+cpu);
- }
-
- if(lexical_cast<bool>(config.get_option("debug").value))
- {
- build_info.cflags.push_back("-ggdb");
- build_info.defines.push_back("DEBUG");
- }
-
- for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
- if(lexical_cast<bool>(config.get_option("with_"+i->name).value))
- build_info.cflags.push_back("-DWITH_"+toupper(i->name));
-
- build_info.unique();
-
- for(list<Component>::iterator i=components.begin(); i!=components.end(); ++i)
- {
- i->create_build_info();
- if(i->get_type()==Component::LIBRARY)
- export_binfo.libs.push_back(i->get_name());
- }
- }
- else if(name=="fmod4")
- {
- export_binfo.libs.push_back("fmodex");
- if(!path.empty())
- {
- export_binfo.libpath.push_back((path/"api"/"lib").str());
- export_binfo.incpath.push_back((path/"api"/"inc").str());
- }
- }
- export_binfo.unique();
-}
-
-
Package::Loader::Loader(Package &p):
pkg(p)
{
- add("version", &Package::version);
- add("description", &Package::description);
- add("require", &Loader::require);
- add("feature", &Loader::feature);
- add("if", &Loader::condition);
- add("program", &Loader::program);
- add("library", &Loader::library);
- add("module", &Loader::module);
- add("headers", &Loader::headers);
- add("build_info", &Loader::build_info);
- add("tar_file", &Loader::tar_file);
+ add("require", &Loader::require);
}
void Package::Loader::require(const string &n)
{
pkg.requires.push_back(PackageRef(pkg.builder, n));
}
-
-void Package::Loader::feature(const string &n, const string &d)
-{
- pkg.features.push_back(Feature(n, d));
-}
-
-void Package::Loader::condition(const string &c)
-{
- Condition cond(pkg, c);
- load_sub(cond);
- pkg.conditions.push_back(cond);
-}
-
-void Package::Loader::program(const string &n)
-{
- Component prog(pkg, Component::PROGRAM, n);
- load_sub(prog);
- pkg.components.push_back(prog);
-}
-
-void Package::Loader::library(const string &n)
-{
- Component prog(pkg, Component::LIBRARY, n);
- load_sub(prog);
- pkg.components.push_back(prog);
-}
-
-void Package::Loader::module(const string &n)
-{
- Component prog(pkg, Component::MODULE, n);
- load_sub(prog);
- pkg.components.push_back(prog);
-}
-
-void Package::Loader::headers(const string &n)
-{
- Component prog(pkg, Component::HEADERS, n);
- load_sub(prog);
- pkg.components.push_back(prog);
-}
-
-void Package::Loader::build_info()
-{
- load_sub(pkg.build_info);
-}
-
-void Package::Loader::tar_file(const string &f)
-{
- pkg.tar_files.push_back(pkg.source/f);
-}
#include <string>
#include <msp/datafile/loader.h>
#include "buildinfo.h"
-#include "component.h"
-#include "condition.h"
-#include "config.h"
-#include "dependencycache.h"
-#include "feature.h"
#include "packageref.h"
class Builder;
class Package
{
public:
- enum InstallFlags
- {
- INCLUDE=1,
- BIN=2,
- LIB=4,
- DATA=8
- };
-
- /// Loads a package from a file.
class Loader: public Msp::DataFile::Loader
{
public:
Loader(Package &);
Package &get_object() { return pkg; }
- private:
+ protected:
Package &pkg;
-
+
void require(const std::string &);
- void feature(const std::string &, const std::string &);
- void condition(const std::string &);
- void program(const std::string &);
- void library(const std::string &);
- void module(const std::string &);
- void headers(const std::string &);
- void build_info();
- void tar_file(const std::string &);
};
- Package(Builder &, const std::string &, const Msp::Path::Path &);
- void set_path(const Msp::Path::Path &);
const std::string &get_name() const { return name; }
- const std::string &get_version() const { return version; }
- const std::string &get_description() const { return description; }
- const Msp::Path::Path &get_source() const { return source; }
- Msp::Path::Path get_temp_dir() const;
- Msp::Path::Path get_out_dir() const;
- Msp::Path::Path get_prefix() const { return config.get_option("prefix").value; }
- const ComponentList &get_components() const { return components; }
- bool get_buildable() const { return buildable; }
- const Config &get_config() const { return config; }
+ Builder &get_builder() const { return builder; }
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; }
- unsigned get_install_flags();
- bool get_use_pkgconfig() const { return use_pkgconfig; }
- const std::string &get_arch() const { return config.get_option("arch").value; }
- LibMode get_library_mode() const;
- const PathList &get_tar_files() const { return tar_files; }
- DependencyCache &get_deps_cache() const { return deps_cache; }
- void resolve_refs();
- void configure(const StringMap &, unsigned);
- static Package *create(Builder &, const std::string &);
-private:
+ /// Indicates whether or not this package supports pkg-config
+ bool get_use_pkgconfig() const { return use_pkgconfig; }
+
+ virtual void resolve_refs();
+ void configure(const StringMap &, unsigned);
+ virtual ~Package() { }
+protected:
Builder &builder;
-
+
std::string name;
- std::string version;
- std::string description;
-
- bool buildable;
- Msp::Path::Path source;
+
PkgRefList requires;
- PackageList all_reqs;
- FeatureList features;
- BuildInfo build_info;
BuildInfo export_binfo;
- ConditionList conditions;
- ComponentList components;
- Config config;
bool conf_done;
- mutable DependencyCache deps_cache;
- PathList tar_files;
bool use_pkgconfig;
- bool need_path;
- Msp::Path::Path path;
- Package(Builder &, const std::string &, const std::vector<std::string> &);
- void init_config();
- void create_build_info();
+ Package(Builder &, const std::string &);
+ virtual void do_configure(const StringMap &, unsigned) { }
+ virtual void create_build_info() { }
};
#endif
#include "pkgconfig.h"
#include "pkgconfigaction.h"
-PkgConfig::PkgConfig(Builder &b, const Package &p):
+PkgConfig::PkgConfig(Builder &b, const SourcePackage &p):
Target(b, &p, (p.get_source()/(p.get_name()+".pc")).str()),
pkg(p)
{
#ifndef PKGCONFIG_H_
#define PKGCONFIG_H_
+#include "sourcepackage.h"
#include "target.h"
/**
class PkgConfig: public Target
{
public:
- PkgConfig(Builder &, const Package &);
+ PkgConfig(Builder &, const SourcePackage &);
const char *get_type() const { return "PkgConfig"; }
Action *build();
private:
PkgConfigAction::PkgConfigAction(Builder &b, const PkgConfig &p):
Action(b)
{
- const Package &pkg=*p.get_package();
-
- announce(pkg.get_name(), "PC", relative(p.get_name(), pkg.get_source()).str());
-
+ const SourcePackage &spkg=*static_cast<const SourcePackage *>(p.get_package());
+
+ announce(spkg.get_name(), "PC", relative(p.get_name(), spkg.get_source()).str());
+
ofstream out(p.get_name().c_str());
if(out)
{
// Prefix is already included in the various paths
//out<<"prefix="<<pkg.get_prefix()<<"\n\n";
- out<<"source="<<pkg.get_source()<<"\n\n";
-
- out<<"Name: "<<pkg.get_name()<<'\n';
- out<<"Description: "<<pkg.get_description()<<'\n';
- out<<"Version: "<<pkg.get_version()<<'\n';
-
+ out<<"source="<<spkg.get_source()<<"\n\n";
+
+ out<<"Name: "<<spkg.get_name()<<'\n';
+ out<<"Description: "<<spkg.get_description()<<'\n';
+ out<<"Version: "<<spkg.get_version()<<'\n';
+
out<<"Requires:";
- const PkgRefList &reqs=pkg.get_requires();
+ const PkgRefList &reqs=spkg.get_requires();
for(PkgRefList::const_iterator i=reqs.begin(); i!=reqs.end(); ++i)
if(i->get_package()->get_use_pkgconfig())
out<<' '<<i->get_name();
out<<'\n';
- const BuildInfo &binfo=pkg.get_exported_binfo();
+ const BuildInfo &binfo=spkg.get_exported_binfo();
out<<"Libs:";
for(StringList::const_iterator i=binfo.libpath.begin(); i!=binfo.libpath.end(); ++i)
out<<" -L"<<*i;
#include <msp/strings/regex.h>
#include "builder.h"
#include "component.h"
-#include "package.h"
#include "sourcefile.h"
+#include "sourcepackage.h"
using namespace std;
using namespace Msp;
*/
void SourceFile::find_depends()
{
+ if(!comp)
+ return;
+
DependencyCache &deps_cache=comp->get_package().get_deps_cache();
if(mtime>deps_cache.get_mtime())
{
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <iostream>
+#include <msp/strings/lexicalcast.h>
+#include <msp/strings/utils.h>
+#include "binarypackage.h"
+#include "builder.h"
+#include "misc.h"
+#include "sourcepackage.h"
+
+using namespace std;
+using namespace Msp;
+
+/**
+Creates a buildable package.
+*/
+SourcePackage::SourcePackage(Builder &b, const string &n, const Path::Path &s):
+ Package(b, n),
+ source(s),
+ config(*this),
+ deps_cache(*this)
+{
+ tar_files.push_back(source/"Build");
+}
+
+Msp::Path::Path SourcePackage::get_temp_dir() const
+{
+ return source/config.get_option("tempdir").value/config.get_option("profile").value;
+}
+
+Msp::Path::Path SourcePackage::get_out_dir() const
+{
+ return source/config.get_option("outdir").value;
+}
+
+/**
+Checks which kinds of things the components of this package install.
+
+@return A bitmask of installed things
+*/
+unsigned SourcePackage::get_install_flags()
+{
+ unsigned flags=0;
+ for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
+ {
+ if(i->get_install())
+ {
+ if(i->get_type()==Component::PROGRAM)
+ flags|=BIN;
+ else if(i->get_type()==Component::LIBRARY || i->get_type()==Component::MODULE)
+ flags|=LIB;
+ }
+ if(!i->get_install_headers().empty())
+ flags|=INCLUDE;
+ }
+
+ return flags;
+}
+
+LibMode SourcePackage::get_library_mode() const
+{
+ const string &mode=config.get_option("staticlibs").value;
+ if(mode=="all")
+ return ALL_STATIC;
+ else if(mode=="local")
+ return LOCAL_STATIC;
+ else if(mode=="none")
+ return DYNAMIC;
+ else
+ throw Exception("Unknown library mode");
+}
+
+/**
+Tries to resolve all references to dependency packages.
+*/
+void SourcePackage::resolve_refs()
+{
+ Package::resolve_refs();
+
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
+ if(i->get_package())
+ all_reqs.push_back(i->get_package());
+
+ for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i)
+ {
+ i->resolve_refs();
+ const PkgRefList &creqs=i->get_requires();
+ for(PkgRefList::const_iterator j=creqs.begin(); j!=creqs.end(); ++j)
+ if(j->get_package())
+ all_reqs.push_back(j->get_package());
+ }
+
+ for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
+ {
+ i->resolve_refs();
+ const PkgRefList &creqs=i->get_requires();
+ for(PkgRefList::const_iterator j=creqs.begin(); j!=creqs.end(); ++j)
+ if(j->get_package())
+ all_reqs.push_back(j->get_package());
+ }
+}
+
+/*** private ***/
+
+/**
+Processes configuration options that were most likely obtained from the command
+line.
+*/
+void SourcePackage::do_configure(const StringMap &opts, unsigned flag)
+{
+ init_config();
+
+ StringMap::const_iterator prof=opts.find("profile");
+ if(prof!=opts.end() && flag)
+ config.select_profile(prof->second);
+ else
+ config.select_last_profile();
+
+ if(flag && config.update(opts))
+ {
+ if(builder.get_verbose()>=2)
+ cout<<"Configuration of "<<name<<" changed\n";
+ if(!builder.get_dry_run())
+ config.save();
+ }
+
+ config.finish();
+
+ for(ConditionList::iterator i=conditions.begin(); i!=conditions.end(); ++i)
+ if(i->eval())
+ {
+ const PkgRefList &reqs=i->get_requires();
+ requires.insert(requires.end(), reqs.begin(), reqs.end());
+ build_info.add(i->get_build_info());
+ }
+
+ for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
+ {
+ BinaryPackage *bpkg=dynamic_cast<BinaryPackage *>(*i);
+ if(bpkg && bpkg->get_need_path())
+ bpkg->set_path(config.get_option(bpkg->get_name()+"_path").value);
+ }
+
+ deps_cache.load();
+
+ for(PackageList::iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
+ (*i)->configure(opts, flag&2);
+}
+
+/**
+Initializes configuration options.
+*/
+void SourcePackage::init_config()
+{
+ config.add_option("profile", "default", "Configuration profile");
+ config.add_option("tempdir", "temp", "Directory for storing temporary files");
+ config.add_option("outdir", ".", "Directory to put build results in");
+ config.add_option("optimize", "0", "Apply compiler optimizations");
+ config.add_option("strip", "0", "Strip symbols from programs");
+ config.add_option("debug", "0", "Produce debugging symbols");
+ config.add_option("cpu", "auto", "CPU type to optimize for");
+ config.add_option("arch", "native", "Architecture for cross-compiling");
+ config.add_option("staticlibs", "local", "Use static libraries");
+
+ unsigned flags=get_install_flags();
+ if(flags)
+ config.add_option("prefix", "$HOME/local", "Installation prefix");
+ /*if(flags&INCLUDE)
+ config.add_option("includedir", "$prefix/include", "Header installation directory");
+ if(flags&BIN)
+ config.add_option("includedir", "$prefix/bin", "Binary installation directory");
+ if(flags&LIB)
+ config.add_option("includedir", "$prefix/lib", "Library installation directory");
+ if(flags&DATA)
+ config.add_option("includedir", "$prefix/share", "Data installation directory");*/
+
+ for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
+ config.add_option("with_"+i->name, "0", i->descr);
+
+ for(PackageList::const_iterator i=all_reqs.begin(); i!=all_reqs.end(); ++i)
+ {
+ BinaryPackage *bpkg=dynamic_cast<BinaryPackage *>(*i);
+ if(bpkg && bpkg->get_need_path())
+ config.add_option(bpkg->get_name()+"_path", "", "Path for "+bpkg->get_name());
+ }
+}
+
+/**
+Fills in build info based on configuration. All required packages must be
+configured when this is called.
+*/
+void SourcePackage::create_build_info()
+{
+ for(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i)
+ {
+ Package *pkg=i->get_package();
+ if(!pkg)
+ continue;
+ const BuildInfo &ebi=pkg->get_exported_binfo();
+ build_info.add(ebi);
+
+ export_binfo.cflags.insert(export_binfo.cflags.end(), ebi.cflags.begin(), ebi.cflags.end());
+ export_binfo.incpath.insert(export_binfo.incpath.end(), ebi.incpath.begin(), ebi.incpath.end());
+ export_binfo.defines.insert(export_binfo.defines.end(), ebi.defines.begin(), ebi.defines.end());
+ }
+
+ build_info.cflags.push_back("-Wall");
+ build_info.cflags.push_back("-Wshadow");
+ build_info.cflags.push_back("-Wextra");
+ build_info.cflags.push_back("-Wpointer-arith");
+ build_info.cflags.push_back("-Wconversion");
+ build_info.cflags.push_back("-Werror");
+
+ unsigned flags=get_install_flags();
+
+ if(flags&INCLUDE)
+ export_binfo.incpath.push_back((Path::Path(config.get_option("prefix").value)/"include").str());
+ if(flags&LIB)
+ export_binfo.libpath.push_back((Path::Path(config.get_option("prefix").value)/"lib").str());
+
+ string optimize=config.get_option("optimize").value;
+ if(lexical_cast<unsigned>(optimize))
+ {
+ build_info.cflags.push_back("-O"+optimize);
+ build_info.ldflags.push_back("-O"+optimize);
+ string cpu=config.get_option("cpu").value;
+ if(cpu!="auto")
+ build_info.cflags.push_back("-march="+cpu);
+ }
+
+ if(lexical_cast<bool>(config.get_option("debug").value))
+ {
+ build_info.cflags.push_back("-ggdb");
+ build_info.defines.push_back("DEBUG");
+ }
+
+ for(FeatureList::iterator i=features.begin(); i!=features.end(); ++i)
+ if(lexical_cast<bool>(config.get_option("with_"+i->name).value))
+ build_info.cflags.push_back("-DWITH_"+toupper(i->name));
+
+ build_info.unique();
+
+ for(list<Component>::iterator i=components.begin(); i!=components.end(); ++i)
+ {
+ i->create_build_info();
+ if(i->get_type()==Component::LIBRARY)
+ export_binfo.libs.push_back(i->get_name());
+ }
+
+ export_binfo.unique();
+}
+
+
+SourcePackage::Loader::Loader(Package &p):
+ Package::Loader(p)
+{
+ add("version", &SourcePackage::version);
+ add("description", &SourcePackage::description);
+ add("build_info", &Loader::build_info);
+ add("feature", &Loader::feature);
+ add("if", &Loader::condition);
+ add("program", &Loader::program);
+ add("library", &Loader::library);
+ add("module", &Loader::module);
+ add("headers", &Loader::headers);
+ add("tar_file", &Loader::tar_file);
+}
+
+void SourcePackage::Loader::feature(const string &n, const string &d)
+{
+ static_cast<SourcePackage &>(pkg).features.push_back(Feature(n, d));
+}
+
+void SourcePackage::Loader::condition(const string &c)
+{
+ SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
+ Condition cond(spkg, c);
+ load_sub(cond);
+ spkg.conditions.push_back(cond);
+}
+
+void SourcePackage::Loader::program(const string &n)
+{
+ SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
+ Component prog(spkg, Component::PROGRAM, n);
+ load_sub(prog);
+ spkg.components.push_back(prog);
+}
+
+void SourcePackage::Loader::library(const string &n)
+{
+ SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
+ Component prog(spkg, Component::LIBRARY, n);
+ load_sub(prog);
+ spkg.components.push_back(prog);
+}
+
+void SourcePackage::Loader::module(const string &n)
+{
+ SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
+ Component prog(spkg, Component::MODULE, n);
+ load_sub(prog);
+ spkg.components.push_back(prog);
+}
+
+void SourcePackage::Loader::headers(const string &n)
+{
+ SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
+ Component prog(spkg, Component::HEADERS, n);
+ load_sub(prog);
+ spkg.components.push_back(prog);
+}
+
+void SourcePackage::Loader::build_info()
+{
+ load_sub(static_cast<SourcePackage &>(pkg).build_info);
+}
+
+void SourcePackage::Loader::tar_file(const string &f)
+{
+ SourcePackage &spkg=static_cast<SourcePackage &>(pkg);
+ spkg.tar_files.push_back(spkg.source/f);
+}
--- /dev/null
+/* $Id$
+
+This file is part of builder
+Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef SOURCEPACKAGE_H_
+#define SOURCEPACKAGE_H_
+
+#include <string>
+#include "buildinfo.h"
+#include "component.h"
+#include "condition.h"
+#include "config.h"
+#include "dependencycache.h"
+#include "feature.h"
+#include "package.h"
+#include "packageref.h"
+
+class Builder;
+
+/**
+A package that can be built by Builder.
+*/
+class SourcePackage: public Package
+{
+public:
+ enum InstallFlags
+ {
+ INCLUDE=1,
+ BIN=2,
+ LIB=4,
+ DATA=8
+ };
+
+ /// Loads a package from a file.
+ class Loader: public Package::Loader
+ {
+ public:
+ Loader(Package &);
+ SourcePackage &get_object() { return static_cast<SourcePackage &>(pkg); }
+ private:
+ void feature(const std::string &, const std::string &);
+ void condition(const std::string &);
+ void program(const std::string &);
+ void library(const std::string &);
+ void module(const std::string &);
+ void headers(const std::string &);
+ void build_info();
+ void tar_file(const std::string &);
+ };
+
+ SourcePackage(Builder &, const std::string &, const Msp::Path::Path &);
+ void set_path(const Msp::Path::Path &);
+ const std::string &get_name() const { return name; }
+ const std::string &get_version() const { return version; }
+ const std::string &get_description() const { return description; }
+ const Msp::Path::Path &get_source() const { return source; }
+ Msp::Path::Path get_temp_dir() const;
+ Msp::Path::Path get_out_dir() const;
+ Msp::Path::Path get_prefix() const { return config.get_option("prefix").value; }
+ const ComponentList &get_components() const { return components; }
+ const Config &get_config() const { return config; }
+ const BuildInfo &get_build_info() const { return build_info; }
+ const BuildInfo &get_exported_binfo() const { return export_binfo; }
+ Builder &get_builder() const { return builder; }
+ unsigned get_install_flags();
+ const std::string &get_arch() const { return config.get_option("arch").value; }
+ LibMode get_library_mode() const;
+ const PathList &get_tar_files() const { return tar_files; }
+ DependencyCache &get_deps_cache() const { return deps_cache; }
+ virtual void resolve_refs();
+private:
+ std::string version;
+ std::string description;
+
+ Msp::Path::Path source;
+ PackageList all_reqs;
+ FeatureList features;
+ BuildInfo build_info;
+ ConditionList conditions;
+ ComponentList components;
+ Config config;
+ bool conf_done;
+ mutable DependencyCache deps_cache;
+ PathList tar_files;
+
+ //Package(Builder &, const std::string &, const std::vector<std::string> &);
+ virtual void do_configure(const StringMap &, unsigned);
+ void init_config();
+ virtual void create_build_info();
+};
+
+#endif
#include "archive.h"
#include "component.h"
#include "objectfile.h"
-#include "package.h"
+#include "sourcepackage.h"
#include "staticlibrary.h"
using namespace std;
#include <iostream>
#include <msp/path/utils.h>
#include "builder.h"
-#include "package.h"
+#include "sourcepackage.h"
#include "tar.h"
#include "tarball.h"
#include "builder.h"
#include "file.h"
-#include "package.h"
+#include "sourcepackage.h"
#include "tar.h"
#include "tarball.h"
using namespace std;
-TarBall::TarBall(Builder &b, const Package &p, const string &ev):
+TarBall::TarBall(Builder &b, const SourcePackage &p, const string &ev):
Target(b, &p, create_target_name(p, ev))
{
buildable=true;
}
+const SourcePackage *TarBall::get_package() const
+{
+ return static_cast<const SourcePackage *>(package);
+}
+
void TarBall::find_depends()
{
+ const SourcePackage *spkg=dynamic_cast<const SourcePackage *>(package);
+
const TargetMap &targets=builder.get_targets();
for(TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i)
if(i->second->get_package()==package && i->second!=this && !i->second->get_buildable())
add_depend(i->second);
- const PathList &tar_files=package->get_tar_files();
+ const PathList &tar_files=spkg->get_tar_files();
for(PathList::const_iterator i=tar_files.begin(); i!=tar_files.end(); ++i)
{
Target *tgt=builder.get_target(i->str());
return Target::build(new Tar(builder, *this));
}
-string TarBall::create_target_name(const Package &pkg, const string &extra_ver)
+string TarBall::create_target_name(const SourcePackage &pkg, const string &extra_ver)
{
string basename=pkg.get_name()+"-"+pkg.get_version();
if(!extra_ver.empty())
class TarBall: public Target
{
public:
- TarBall(Builder &, const Package &, const std::string & =std::string());
+ TarBall(Builder &, const SourcePackage &, const std::string & =std::string());
virtual const char *get_type() const { return "TarBall"; }
+ const SourcePackage *get_package() const;
virtual void find_depends();
virtual Action *build();
private:
std::string tarname;
- std::string create_target_name(const Package &, const std::string &);
+ std::string create_target_name(const SourcePackage &, const std::string &);
};
#endif
#include "action.h"
#include "builder.h"
#include "package.h"
+#include "sourcepackage.h"
#include "target.h"
using namespace std;
mark_rebuild(Path::basename((*i)->get_name())+" needs rebuilding");
}
}
- if(!rebuild && package && package->get_config().get_mtime()>mtime)
+
+ const SourcePackage *spkg=dynamic_cast<const SourcePackage *>(package);
+ if(!rebuild && spkg && spkg->get_config().get_mtime()>mtime)
mark_rebuild("Package options changed");
}
*/
#include <msp/path/utils.h>
-#include "package.h"
+#include "sourcepackage.h"
#include "target.h"
#include "unlink.h"
Unlink::Unlink(Builder &b, const Target &t):
Action(b)
{
- const Package &pkg=*t.get_package();
+ const SourcePackage &spkg=*static_cast<const SourcePackage *>(t.get_package());
- announce(pkg.get_name(), "RM", relative(t.get_name(), pkg.get_source()).str());
+ announce(spkg.get_name(), "RM", relative(t.get_name(), spkg.get_source()).str());
unlink(t.get_name().c_str());
}