X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fpackage.cpp;h=5f25f1a90eb053705092d75b13f565109ffbf2a4;hb=62106ed7cef9b8ef6f07aaf491f8250f7e8d9398;hp=2e7932c1c57a93dbed709797eb14a05b5a9572ea;hpb=0fd98b61eb112fe397c67b7735627b7bbdd01e41;p=builder.git diff --git a/source/package.cpp b/source/package.cpp index 2e7932c..5f25f1a 100644 --- a/source/package.cpp +++ b/source/package.cpp @@ -1,359 +1,58 @@ +#include #include #include +#include "booleanevaluator.h" #include "builder.h" -#include "misc.h" #include "package.h" using namespace std; using namespace Msp; -#include - -/** -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), - conf_done(false), - use_pkgconfig(true), - need_path(false) -{ } - -/** -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 + label(string(1, toupper(n[0]))+n.substr(1)), + prepared(false), + use_pkgconfig(true) { - return source/config.get_option("outdir").value; + builder.get_package_manager().add_package(this); } -/** -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 +void Package::prepare() { - 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 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()); - } -} - -/** -Processes configuration options that were most likely obtained from the command -line. -*/ -void Package::configure(const RawOptionMap &opts, unsigned flag) -{ - if(conf_done) + if(prepared) return; - if(builder.get_verbose()>=3) - cout<<"Configuring "<second); - else - config.select_last_profile(); - - if(flag && config.update(opts)) - { - if(builder.get_verbose()>=2) - cout<<"Configuration of "<get_need_path()) - (*i)->set_path(config.get_option((*i)->get_name()+"_path").value); - (*i)->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 argv; - argv.push_back("pkg-config"); - argv.push_back("--silence-errors"); - argv.push_back("--cflags"); - argv.push_back("--libs"); - argv.push_back(name); - vector 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 - 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 &info): - builder(b), - name(n), - buildable(false), - conf_done(false) -{ - for(vector::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)); - } -} - -/** -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"); - - const char *home=getenv("HOME"); - unsigned flags=get_install_flags(); - if(flags) - config.add_option("prefix", string(home)+"/local"/*"/usr"*/, "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(PkgRefList::iterator i=requires.begin(); i!=requires.end(); ++i) - if(i->get_package() && i->get_package()->get_need_path()) - config.add_option(i->get_name()+"_path", "", "Path for "+i->get_name()); + for(Requirements::const_iterator i=requires.begin(); i!=requires.end(); ++i) + (*i)->prepare(); - config.set_source(source); + do_prepare(); + prepared = true; } -/** -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; - build_info.add(pkg->get_exported_binfo()); - //XXX We probably really only want to pass cflags and defines through - export_binfo.add(pkg->get_exported_binfo()); - } - - 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(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(config.get_option("debug").value)) - { - build_info.cflags.push_back("-ggdb"); - build_info.defines.push_back("DEBUG"); - } - - build_info.unique(); - - for(list::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) + DataFile::ObjectLoader(p) { - add("version", &Package::version); - add("description", &Package::description); - add("require", &Loader::require); - add("program", &Loader::program); - add("library", &Loader::library); - add("module", &Loader::module); - add("headers", &Loader::headers); - add("build_info", &Loader::build_info); + add("if_arch", &Loader::if_arch); + add("label", &Package::label); + add("require", &Loader::require); } -void Package::Loader::require(const string &n) -{ - pkg.requires.push_back(PackageRef(pkg.builder, n)); -} - -void Package::Loader::program(const string &n) +void Package::Loader::if_arch(const string &cond) { - Component prog(pkg, Component::PROGRAM, n); - load_sub(prog); - pkg.components.push_back(prog); + BooleanEvaluator eval(sigc::hide<1>(sigc::mem_fun(&obj.builder.get_current_arch(), &Architecture::match_name)), false); + bool match = eval.evaluate(cond); + obj.builder.get_logger().log("configure", format("%s: arch %s %smatched", obj.name, cond, (match ? "" : "not "))); + if(match) + load_sub_with(*this); } -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() +void Package::Loader::require(const string &n) { - load_sub(pkg.build_info); + Package *req = obj.builder.get_package_manager().find_package(n); + if(req) + obj.requires.push_back(req); + else + obj.problems.push_back(format("Required package %s not found", n)); }