#include "misc.h"
#include "objectfile.h"
#include "package.h"
+#include "pkgconfig.h"
#include "sharedlibrary.h"
#include "staticlibrary.h"
#include "systemlibrary.h"
}
}
}
+
+ if(i->second->get_install_flags()&(Package::LIB|Package::INCLUDE))
+ {
+ PkgConfig *pc=new PkgConfig(*this, *i->second);
+ add_target(pc);
+ Install *inst=new Install(*this, *i->second, *pc, (inst_base/"lib"/"pkgconfig"/Path::basename(pc->get_name())).str());
+ add_target(inst);
+ install->add_depend(inst);
+ }
}
// Find dependencies until no new targets are created
buildable(true),
source(s),
conf_done(false),
+ use_pkgconfig(true),
need_path(false)
{ }
path=builder.get_cwd()/p;
}
+/**
+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;
+}
+
/**
Tries to resolve all references to dependency packages.
*/
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");
Package *pkg=new Package(b, name, info);
pkg->need_path=need_path;
+ pkg->use_pkgconfig=use_pkgconfig;
return pkg;
}
export_binfo.unique();
}
-/**
-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;
-}
-
Package::Loader::Loader(Package &p):
pkg(p)
{
class Package
{
public:
+ enum InstallFlags
+ {
+ INCLUDE=1,
+ BIN=2,
+ LIB=4,
+ DATA=8
+ };
+
/// Loads a package from a file.
class Loader: public Msp::Parser::Loader
{
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; }
const ComponentList &get_components() const { return components; }
bool get_buildable() const { return buildable; }
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; }
void resolve_refs();
void configure(const RawOptionMap &, unsigned);
static Package *create(Builder &, const std::string &);
private:
- enum InstallFlags
- {
- INCLUDE=1,
- BIN=2,
- LIB=4,
- DATA=8
- };
-
Builder &builder;
std::string name;
Config config;
bool conf_done;
+ 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();
- unsigned get_install_flags();
};
#endif
--- /dev/null
+#include "package.h"
+#include "pkgconfig.h"
+#include "pkgconfigaction.h"
+
+PkgConfig::PkgConfig(Builder &b, const Package &p):
+ Target(b, &p, (p.get_source()/(p.get_name()+".pc")).str()),
+ pkg(p)
+{
+ buildable=true;
+}
+
+Action *PkgConfig::build()
+{
+ return Target::build(new PkgConfigAction(builder, *this));
+}
--- /dev/null
+#ifndef PKGCONFIG_H_
+#define PKGCONFIG_H_
+
+#include "target.h"
+
+/**
+Creates a .pc file to enable other packages fetch build options with pkg-config.
+*/
+class PkgConfig: public Target
+{
+public:
+ PkgConfig(Builder &, const Package &);
+ const char *get_type() const { return "PkgConfig"; }
+ Action *build();
+private:
+ const Package &pkg;
+};
+
+#endif
--- /dev/null
+#include <fstream>
+#include <iostream>
+#include <msp/path/utils.h>
+#include "package.h"
+#include "pkgconfig.h"
+#include "pkgconfigaction.h"
+
+using namespace std;
+
+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());
+
+ ofstream out(p.get_name().c_str());
+ if(out)
+ {
+ // Prefix is already included in the various paths
+ //out<<"prefix="<<pkg.get_config().get_option("prefix").value<<"\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<<"Requires:";
+ const PkgRefList &reqs=pkg.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();
+ out<<"Libs:";
+ for(StringList::const_iterator i=binfo.libpath.begin(); i!=binfo.libpath.end(); ++i)
+ out<<" -L"<<*i;
+ for(StringList::const_iterator i=binfo.libs.begin(); i!=binfo.libs.end(); ++i)
+ out<<" -l"<<*i;
+ for(StringList::const_iterator i=binfo.ldflags.begin(); i!=binfo.ldflags.end(); ++i)
+ out<<' '<<*i;
+ out<<'\n';
+
+ out<<"Cflags:";
+ for(StringList::const_iterator i=binfo.incpath.begin(); i!=binfo.incpath.end(); ++i)
+ out<<" -I"<<*i;
+ for(StringList::const_iterator i=binfo.defines.begin(); i!=binfo.defines.end(); ++i)
+ out<<" -D"<<*i;
+ for(StringList::const_iterator i=binfo.cflags.begin(); i!=binfo.cflags.end(); ++i)
+ out<<' '<<*i;
+ out<<'\n';
+ }
+ else
+ cerr<<"Can't open "<<p.get_name()<<" for writing\n";
+}
+
+int PkgConfigAction::check()
+{
+ signal_done.emit();
+ return 0;
+}
--- /dev/null
+#ifndef PKGCONFIGACTION_H_
+#define PKGCONFIGACTION_H_
+
+#include "action.h"
+
+class PkgConfig;
+
+/**
+Action for building a PkgConfig target. I just couldn't come up with a less
+lame name...
+*/
+class PkgConfigAction: public Action
+{
+public:
+ PkgConfigAction(Builder &, const PkgConfig &);
+ int check();
+};
+
+#endif