From 555190f7eafcf3a67750fc63872b23e17371aa98 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 17 Aug 2007 15:55:04 +0000 Subject: [PATCH] Add tarball building --- source/builder.cpp | 6 +++ source/builder.h | 2 +- source/file.cpp | 14 ++++++ source/file.h | 21 ++++++++ source/package.cpp | 8 +++ source/package.h | 3 ++ source/tar.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++ source/tar.h | 45 +++++++++++++++++ source/tarball.cpp | 54 ++++++++++++++++++++ source/tarball.h | 26 ++++++++++ source/target.h | 10 +++- 11 files changed, 310 insertions(+), 2 deletions(-) create mode 100644 source/file.cpp create mode 100644 source/file.h create mode 100644 source/tar.cpp create mode 100644 source/tar.h create mode 100644 source/tarball.cpp create mode 100644 source/tarball.h diff --git a/source/builder.cpp b/source/builder.cpp index 553a3e1..336cc84 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -25,6 +25,7 @@ Distributed under the LGPL #include "pkgconfig.h" #include "sharedlibrary.h" #include "systemlibrary.h" +#include "tarball.h" #include "unlink.h" #include "virtualtarget.h" @@ -508,6 +509,9 @@ int Builder::create_targets() Target *install=new VirtualTarget(*this, "install"); world->add_depend(install); + Target *tarballs=new VirtualTarget(*this, "tarballs"); + world->add_depend(tarballs); + for(PackageMap::iterator i=packages.begin(); i!=packages.end(); ++i) { if(!i->second) @@ -524,6 +528,8 @@ int Builder::create_targets() PkgConfig *pc=new PkgConfig(*this, *i->second); install->add_depend(new Install(*this, *i->second, *pc)); } + + tarballs->add_depend(new TarBall(*this, *i->second)); } // Find dependencies until no new targets are created diff --git a/source/builder.h b/source/builder.h index 291c14b..ba20fe3 100644 --- a/source/builder.h +++ b/source/builder.h @@ -35,6 +35,7 @@ public: Package *get_package(const std::string &); Package *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 &); Target *get_library(const std::string &, const std::string &, const StringList &, LibMode); const Msp::Path::Path &get_cwd() const { return cwd; } @@ -60,7 +61,6 @@ private: typedef std::list PackageList; typedef std::map PackageMap; - typedef std::map TargetMap; typedef std::map ToolMap; typedef std::map ProfileTemplateMap; diff --git a/source/file.cpp b/source/file.cpp new file mode 100644 index 0000000..e2b3c27 --- /dev/null +++ b/source/file.cpp @@ -0,0 +1,14 @@ +/* $Id$ + +This file is part of builder +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "file.h" + +using namespace std; + +File::File(Builder &b, const string &n): + Target(b, 0, n) +{ } diff --git a/source/file.h b/source/file.h new file mode 100644 index 0000000..35c1087 --- /dev/null +++ b/source/file.h @@ -0,0 +1,21 @@ +/* $Id$ + +This file is part of builder +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef FILE_H_ +#define FILE_H_ + +#include "target.h" + +class File: public Target +{ +public: + File(Builder &, const std::string &); + virtual const char *get_type() const { return "File"; } + virtual Action *build() { return 0; } +}; + +#endif diff --git a/source/package.cpp b/source/package.cpp index 949bd8e..372cf28 100644 --- a/source/package.cpp +++ b/source/package.cpp @@ -29,6 +29,8 @@ Package::Package(Builder &b, const string &n, const Path::Path &s): use_pkgconfig(true), need_path(false) { + tar_files.push_back(source/"Build"); + if(builder.get_verbose()>=4) cout<<"Created buildable package "< +#include +#include "builder.h" +#include "package.h" +#include "tar.h" +#include "tarball.h" + +using namespace std; +using namespace Msp; + +Tar::Tar(Builder &b, const TarBall &t): + Action(b), + tarball(t), + worker(0) +{ + string basename=tarball.get_name().substr(tarball.get_name().rfind('/')+1); + announce(tarball.get_package()->get_name(), "TAR ", basename); + if(builder.get_verbose()>=2) + cout<<"Create "<get_done()) + { + signal_done.emit(); + worker->join(); + return worker->get_error()?1:0; + } + + return -1; +} + + +Tar::Worker::Worker(Tar &t): + tar(t), + done(false), + error(false) +{ + launch(); +} + +void Tar::Worker::main() +{ + const Path::Path &pkg_src=tar.tarball.get_package()->get_source(); + Path::Path basedir=Path::splitext(Path::basename(tar.tarball.get_name())).base; + + ofstream out(tar.tarball.get_name().c_str()); + const TargetList &deps=tar.tarball.get_depends(); + for(TargetList::const_iterator i=deps.begin(); i!=deps.end(); ++i) + { + char buf[4096]; + memset(buf, 0, 512); + + string rel_path=(basedir/relative((*i)->get_name(), pkg_src)).str(); + if(rel_path.size()>99) + { + cout<<"Can't store "<get_name(), st); + store_number(buf+100, st.st_mode, 7); + store_number(buf+108, st.st_uid, 7); + store_number(buf+116, st.st_gid, 7); + store_number(buf+124, st.st_size, 11); + store_number(buf+136, st.st_mtime, 11); + buf[156]='0'; + + memset(buf+148, ' ', 8); + unsigned chk=0; + for(unsigned j=0; j<512; ++j) + chk+=static_cast(buf[j]); + store_number(buf+148, chk, 7); + buf[155]=0; + + out.write(buf, 512); + ifstream in((*i)->get_name().c_str()); + for(int j=0; j +#include "action.h" +#include "misc.h" + +class TarBall; + +class Tar: public Action +{ +public: + Tar(Builder &, const TarBall &); + ~Tar(); + + virtual int check(); +private: + class Worker: public Msp::Thread + { + public: + Worker(Tar &); + bool get_done() const { return done; } + bool get_error() const { return error; } + private: + Tar &tar; + bool done; + bool error; + + void main(); + void store_number(char *, unsigned, unsigned); + }; + + const TarBall &tarball; + StringList files; + Worker *worker; +}; + +#endif diff --git a/source/tarball.cpp b/source/tarball.cpp new file mode 100644 index 0000000..348272f --- /dev/null +++ b/source/tarball.cpp @@ -0,0 +1,54 @@ +/* $Id$ + +This file is part of builder +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "builder.h" +#include "file.h" +#include "package.h" +#include "tar.h" +#include "tarball.h" + +using namespace std; + +TarBall::TarBall(Builder &b, const Package &p, const string &ev): + Target(b, &p, create_target_name(p, ev)) +{ + buildable=true; +} + +void TarBall::find_depends() +{ + 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(); + for(PathList::const_iterator i=tar_files.begin(); i!=tar_files.end(); ++i) + { + Target *tgt=builder.get_target(i->str()); + if(!tgt) + tgt=new File(builder, i->str()); + add_depend(tgt); + } + + deps_ready=true; +} + +Action *TarBall::build() +{ + return Target::build(new Tar(builder, *this)); +} + +string TarBall::create_target_name(const Package &pkg, const string &extra_ver) +{ + string basename=pkg.get_name()+"-"+pkg.get_version(); + if(!extra_ver.empty()) + basename+="-"+extra_ver; + basename+=".tar"; + + return (pkg.get_source()/basename).str(); +} diff --git a/source/tarball.h b/source/tarball.h new file mode 100644 index 0000000..6c36237 --- /dev/null +++ b/source/tarball.h @@ -0,0 +1,26 @@ +/* $Id$ + +This file is part of builder +Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef TARBALL_H_ +#define TARBALL_H_ + +#include "target.h" + +class TarBall: public Target +{ +public: + TarBall(Builder &, const Package &, const std::string & =std::string()); + virtual const char *get_type() const { return "TarBall"; } + virtual void find_depends(); + virtual Action *build(); +private: + std::string tarname; + + std::string create_target_name(const Package &, const std::string &); +}; + +#endif diff --git a/source/target.h b/source/target.h index 605b328..cf1d186 100644 --- a/source/target.h +++ b/source/target.h @@ -9,6 +9,7 @@ Distributed under the LGPL #define TARGET_H_ #include +#include #include #include @@ -37,9 +38,14 @@ public: 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(); + /** + Finds dependencies for the target. When all dependencies have been found, + the function should set deps_ready to true. + */ + virtual void find_depends() { deps_ready=true; } + /** Creates and returns an Action suitable for building this target. */ @@ -74,4 +80,6 @@ protected: virtual void build_done(); }; +typedef std::map TargetMap; + #endif -- 2.43.0