From 6613371a07a1a9a8d5dead488092015261a9bf5f Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 16 Nov 2006 22:29:02 +0000 Subject: [PATCH] Support for creating .pc files --- source/builder.cpp | 10 ++++++ source/package.cpp | 53 +++++++++++++++++--------------- source/package.h | 22 ++++++++------ source/pkgconfig.cpp | 15 +++++++++ source/pkgconfig.h | 19 ++++++++++++ source/pkgconfigaction.cpp | 62 ++++++++++++++++++++++++++++++++++++++ source/pkgconfigaction.h | 19 ++++++++++++ 7 files changed, 167 insertions(+), 33 deletions(-) create mode 100644 source/pkgconfig.cpp create mode 100644 source/pkgconfig.h create mode 100644 source/pkgconfigaction.cpp create mode 100644 source/pkgconfigaction.h diff --git a/source/builder.cpp b/source/builder.cpp index 38fbc17..3d8579c 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -18,6 +18,7 @@ #include "misc.h" #include "objectfile.h" #include "package.h" +#include "pkgconfig.h" #include "sharedlibrary.h" #include "staticlibrary.h" #include "systemlibrary.h" @@ -527,6 +528,15 @@ int Builder::create_targets() } } } + + 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 diff --git a/source/package.cpp b/source/package.cpp index 587ce80..5255b86 100644 --- a/source/package.cpp +++ b/source/package.cpp @@ -18,6 +18,7 @@ Package::Package(Builder &b, const string &n, const Path::Path &s): buildable(true), source(s), conf_done(false), + use_pkgconfig(true), need_path(false) { } @@ -30,6 +31,30 @@ void Package::set_path(const Msp::Path::Path &p) 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. */ @@ -99,8 +124,11 @@ Package *Package::create(Builder &b, const string &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"); @@ -116,6 +144,7 @@ Package *Package::create(Builder &b, const string &name) Package *pkg=new Package(b, name, info); pkg->need_path=need_path; + pkg->use_pkgconfig=use_pkgconfig; return pkg; } @@ -239,30 +268,6 @@ void Package::create_build_info() 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) { diff --git a/source/package.h b/source/package.h index b9807e3..52338cc 100644 --- a/source/package.h +++ b/source/package.h @@ -23,6 +23,14 @@ NYI). 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 { @@ -42,6 +50,8 @@ public: 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; } @@ -51,19 +61,13 @@ public: 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; @@ -80,13 +84,13 @@ private: Config config; bool conf_done; + bool use_pkgconfig; bool need_path; Msp::Path::Path path; Package(Builder &, const std::string &, const std::vector &); void init_config(); void create_build_info(); - unsigned get_install_flags(); }; #endif diff --git a/source/pkgconfig.cpp b/source/pkgconfig.cpp new file mode 100644 index 0000000..81dd2aa --- /dev/null +++ b/source/pkgconfig.cpp @@ -0,0 +1,15 @@ +#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)); +} diff --git a/source/pkgconfig.h b/source/pkgconfig.h new file mode 100644 index 0000000..2ddcce8 --- /dev/null +++ b/source/pkgconfig.h @@ -0,0 +1,19 @@ +#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 diff --git a/source/pkgconfigaction.cpp b/source/pkgconfigaction.cpp new file mode 100644 index 0000000..65b0c94 --- /dev/null +++ b/source/pkgconfigaction.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#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="<get_package()->get_use_pkgconfig()) + out<<' '<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 "<