From 35f2979869bff43706f3163ec0979c7084aaa3c4 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 6 Oct 2014 03:13:37 +0300 Subject: [PATCH] Split Component into several subclasses The create_targets function in particular was rather unwieldy and contained four completely separate branches. Having distinct component types in different classes will also enhance modularity. --- source/binarycomponent.cpp | 137 ++++++++++++++++++++++++ source/binarycomponent.h | 40 +++++++ source/component.cpp | 201 +---------------------------------- source/component.h | 25 ++--- source/datapackcomponent.cpp | 42 ++++++++ source/datapackcomponent.h | 14 +++ source/installcomponent.cpp | 29 +++++ source/installcomponent.h | 14 +++ source/sharedlibrary.cpp | 8 +- source/sourcepackage.cpp | 97 +++++++++-------- source/sourcepackage.h | 12 ++- source/tarballcomponent.cpp | 46 ++++++++ source/tarballcomponent.h | 14 +++ 13 files changed, 410 insertions(+), 269 deletions(-) create mode 100644 source/binarycomponent.cpp create mode 100644 source/binarycomponent.h create mode 100644 source/datapackcomponent.cpp create mode 100644 source/datapackcomponent.h create mode 100644 source/installcomponent.cpp create mode 100644 source/installcomponent.h create mode 100644 source/tarballcomponent.cpp create mode 100644 source/tarballcomponent.h diff --git a/source/binarycomponent.cpp b/source/binarycomponent.cpp new file mode 100644 index 0000000..0d3e253 --- /dev/null +++ b/source/binarycomponent.cpp @@ -0,0 +1,137 @@ +#include +#include "binarycomponent.h" +#include "builder.h" +#include "filetarget.h" +#include "sourcepackage.h" +#include "tool.h" + +using namespace std; +using namespace Msp; + +BinaryComponent::BinaryComponent(SourcePackage &p, const string &n, Type t): + Component(p, n), + type(t) +{ } + +void BinaryComponent::create_build_info() +{ + Component::create_build_info(); + + for(UseList::const_iterator i=uses.begin(); i!=uses.end(); ++i) + { + /* Select an include path that contains all the sources for this and the + used component. This should produce a sensible result in most cases. */ + FS::Path base; + for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j) + base = base.empty() ? *j : FS::common_ancestor(base, *j); + const SourceList &use_sources = (*i)->get_sources(); + for(SourceList::const_iterator j=use_sources.begin(); j!=use_sources.end(); ++j) + base = FS::common_ancestor(base, *j); + build_info.incpath.push_back(base); + build_info.libs.push_back((*i)->get_name()); + if(!(*i)->get_install()) + { + build_info.libmodes[(*i)->get_name()] = BuildInfo::STATIC; + build_info.libpath.push_back((*i)->get_package().get_source_directory()); + } + } + + if(type==LIBRARY || type==MODULE) + if(build_info.libmode objs; + SourceList source_filenames = collect_source_files(); + for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) + { + string ext = FS::extpart(FS::basename(*i)); + Target *src = 0; + + Tool *gen = pkg_tools.get_tool_for_suffix(ext); + if(gen) + { + Target *tmpl = gen->create_source(*this, *i); + if(tmpl) + { + src = gen->create_target(*tmpl); + ext = FS::extpart(FS::basename(dynamic_cast(*src).get_path())); + } + } + + Tool *tool = toolchain.get_tool_for_suffix(ext, true); + if(tool) + { + if(!src) + src = tool->create_source(*this, *i); + if(!src) + continue; + + if(tool->accepts_suffix(ext)) + { + Target *obj = tool->create_target(*src); + objs.push_back(obj); + } + + if(type==LIBRARY && install) + { + if(dynamic_cast(src)->is_installable()) + build_graph.add_installed_target(*src); + + const Target::Dependencies &side_effects = src->get_side_effects(); + for(Target::Dependencies::const_iterator j=side_effects.begin(); j!=side_effects.end(); ++j) + if(dynamic_cast(*j)->is_installable()) + build_graph.add_installed_target(**j); + } + } + } + + Tool &linker = toolchain.get_tool("LINK"); + + list results; + if(type==LIBRARY) + { + Tool &archiver = toolchain.get_tool("AR"); + results.push_back(linker.create_target(objs, "shared")); + results.push_back(archiver.create_target(objs)); + } + else if(type==MODULE) + results.push_back(linker.create_target(objs, "shared")); + else + results.push_back(linker.create_target(objs)); + + for(list::const_iterator i=results.begin(); i!=results.end(); ++i) + { + build_graph.add_primary_target(**i); + if(install) + build_graph.add_installed_target(**i); + } +} + +BinaryComponent::Loader::Loader(BinaryComponent &c): + DerivedObjectLoader(c) +{ + add("use", &Loader::use); +} + +void BinaryComponent::Loader::use(const string &n) +{ + const BinaryComponent *comp = dynamic_cast(&obj.package.get_component(n)); + if(!comp || comp->type!=LIBRARY) + throw logic_error(n+" is not a library"); + + obj.uses.push_back(comp); +} diff --git a/source/binarycomponent.h b/source/binarycomponent.h new file mode 100644 index 0000000..3a6affd --- /dev/null +++ b/source/binarycomponent.h @@ -0,0 +1,40 @@ +#ifndef BINARYCOMPONENT_H_ +#define BINARYCOMPONENT_H_ + +#include "component.h" + +class BinaryComponent: public Component +{ +public: + class Loader: public Msp::DataFile::DerivedObjectLoader + { + public: + Loader(BinaryComponent &); + private: + void use(const std::string &); + }; + + enum Type + { + LIBRARY, + PROGRAM, + MODULE + }; + +private: + typedef std::list UseList; + + Type type; + UseList uses; + +public: + BinaryComponent(SourcePackage &, const std::string &, Type); + + Type get_type() const { return type; } + + virtual void create_build_info(); + virtual void update_exported_build_info(BuildInfo &) const; + virtual void create_targets() const; +}; + +#endif diff --git a/source/component.cpp b/source/component.cpp index 4e7f547..833a0ed 100644 --- a/source/component.cpp +++ b/source/component.cpp @@ -7,25 +7,13 @@ #include "booleanevaluator.h" #include "builder.h" #include "component.h" -#include "csourcefile.h" -#include "datapack.h" -#include "executable.h" -#include "file.h" -#include "objectfile.h" -#include "sharedlibrary.h" #include "sourcepackage.h" -#include "staticlibrary.h" -#include "tarball.h" -#include "target.h" -#include "tool.h" -#include "toolchain.h" using namespace std; using namespace Msp; -Component::Component(SourcePackage &p, Type t, const string &n): +Component::Component(SourcePackage &p, const string &n): package(p), - type(t), name(n), install(false), deflt(true) @@ -67,29 +55,6 @@ void Component::create_build_info() *i = (package.get_source_directory() / *i).str(); for(BuildInfo::PathList::iterator i=build_info.libpath.begin(); i!=build_info.libpath.end(); ++i) *i = (package.get_source_directory() / *i).str(); - - for(UseList::const_iterator i=uses.begin(); i!=uses.end(); ++i) - { - /* Select an include path that contains all the sources for this and the - used component. This should produce a sensible result in most cases. */ - FS::Path base; - for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j) - base = base.empty() ? *j : FS::common_ancestor(base, *j); - const SourceList &use_sources = (*i)->get_sources(); - for(SourceList::const_iterator j=use_sources.begin(); j!=use_sources.end(); ++j) - base = FS::common_ancestor(base, *j); - build_info.incpath.push_back(base); - build_info.libs.push_back((*i)->get_name()); - if(!(*i)->get_install()) - { - build_info.libmodes[(*i)->get_name()] = BuildInfo::STATIC; - build_info.libpath.push_back((*i)->get_package().get_source_directory()); - } - } - - if(type==LIBRARY || type==MODULE) - if(build_info.libmode files; - for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) - { - FileTarget *file = builder.get_vfs().get_target(*i); - if(!file) - file = new File(builder, package, *i); - files.push_back(file); - } - - string tarname = name; - if(name=="@src") - { - tarname = package.get_name()+"-"+package.get_version(); - files.insert(files.begin(), &package.get_build_file()); - - const BuildGraph::TargetMap &targets = build_graph.get_targets(); - for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) - if(i->second->get_package()==&package && !i->second->is_buildable()) - if(find(files.begin(), files.end(), i->second)==files.end()) - files.push_back(i->second); - } - - Target *result = tar.create_target(files, tarname); - - build_graph.get_target("tarballs")->add_dependency(*result); - - return; - } - else if(type==INSTALL) - { - Target *inst = build_graph.get_target("install"); - Tool © = toolchain.get_tool("CP"); - for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) - { - FileTarget *ft; - if(Target *tgt = builder.get_vfs().get_target(*i)) - ft = dynamic_cast(tgt); - else - ft = new File(builder, package, *i); - inst->add_dependency(*copy.create_target(*ft, name)); - } - } - else if(type==DATAPACK) - { - Tool &dcomp = toolchain.get_tool("DATA"); - - list files; - for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) - { - string ext = FS::extpart(FS::basename(*i)); - if(ext==".mdt") - { - Target *src = dcomp.create_source(*this, *i); - files.push_back(dcomp.create_target(*src, "collection")); - } - else if(Target *tgt = builder.get_vfs().get_target(*i)) - files.push_back(tgt); - else - files.push_back(new File(builder, package, *i)); - } - - Target *result = dcomp.create_target(files, "pack"); - - build_graph.add_primary_target(*result); - if(install) - build_graph.add_installed_target(*result); - } - - if(type==PROGRAM || type==LIBRARY || type==MODULE) - { - list objs; - const Toolchain &pkg_tools = package.get_toolchain(); - for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) - { - string ext = FS::extpart(FS::basename(*i)); - Target *src = 0; - - Tool *gen = pkg_tools.get_tool_for_suffix(ext); - if(gen) - { - Target *tmpl = gen->create_source(*this, *i); - if(tmpl) - { - src = gen->create_target(*tmpl); - ext = FS::extpart(FS::basename(dynamic_cast(*src).get_path())); - } - } - - Tool *tool = toolchain.get_tool_for_suffix(ext, true); - if(tool) - { - if(!src) - src = tool->create_source(*this, *i); - if(!src) - continue; - - if(tool->accepts_suffix(ext)) - { - Target *obj = tool->create_target(*src); - objs.push_back(obj); - } - - if(type==LIBRARY && install) - { - if(dynamic_cast(src)->is_installable()) - build_graph.add_installed_target(*src); - - const Target::Dependencies &side_effects = src->get_side_effects(); - for(Target::Dependencies::const_iterator j=side_effects.begin(); j!=side_effects.end(); ++j) - if(dynamic_cast(*j)->is_installable()) - build_graph.add_installed_target(**j); - } - } - } - - Tool &linker = toolchain.get_tool("LINK"); - - list results; - if(type==LIBRARY) - { - Tool &archiver = toolchain.get_tool("AR"); - results.push_back(linker.create_target(objs, "shared")); - results.push_back(archiver.create_target(objs)); - } - else if(type==MODULE) - results.push_back(linker.create_target(objs, "shared")); - else - results.push_back(linker.create_target(objs)); - - for(list::const_iterator i=results.begin(); i!=results.end(); ++i) - { - build_graph.add_primary_target(**i); - if(install) - build_graph.add_installed_target(**i); - } - } -} - Component::SourceList Component::collect_source_files() const { SourceList files; @@ -321,7 +135,6 @@ Component::Loader::Loader(Component &c): add("build_info", &Loader::build_info); add("require", &Loader::require); add("default", &Component::deflt); - add("use", &Loader::use); } void Component::Loader::build_info() @@ -372,15 +185,3 @@ void Component::Loader::source(const string &s) { obj.sources.push_back((obj.package.get_source_directory()/s).str()); } - -void Component::Loader::use(const string &n) -{ - const SourcePackage::ComponentList &components = obj.package.get_components(); - for(SourcePackage::ComponentList::const_iterator i=components.begin(); i!=components.end(); ++i) - if(i->get_name()==n && i->get_type()==LIBRARY) - { - obj.uses.push_back(&*i); - return; - } - throw invalid_argument("Component::Loader::use"); -} diff --git a/source/component.h b/source/component.h index 7cbd1e1..d33ca25 100644 --- a/source/component.h +++ b/source/component.h @@ -31,42 +31,28 @@ public: void overlay(const std::string &); void require(const std::string &); void source(const std::string &); - void use(const std::string &); - }; - - enum Type - { - LIBRARY, - PROGRAM, - MODULE, - DATAPACK, - INSTALL, - TARBALL }; typedef std::list SourceList; typedef std::list OverlayList; - typedef std::list UseList; protected: SourcePackage &package; - Type type; std::string name; SourceList sources; OverlayList overlays; bool install; BuildInfo build_info; Package::Requirements requires; - UseList uses; bool deflt; InstallMap install_map; std::list problems; public: - Component(SourcePackage &, Type, const std::string &); + Component(SourcePackage &, const std::string &); + virtual ~Component() { } const SourcePackage &get_package() const { return package; } - Type get_type() const { return type; } const std::string &get_name() const { return name; } /** Returns a list of sources for the component. They may refer to @@ -83,7 +69,6 @@ public: bool get_install() const { return install; } const InstallMap &get_install_map() const { return install_map; } const Package::Requirements &get_required_packages() const { return requires; } - const UseList &get_used_components() const { return uses; } bool is_default() const { return deflt; } const std::list &get_problems() const { return problems; } @@ -92,13 +77,15 @@ public: /** Prepares the build information for building. Pulls build info from the parent and dependency packages, and adds any component-specific flags. */ - void create_build_info(); + virtual void create_build_info(); + + virtual void update_exported_build_info(BuildInfo &) const { } const BuildInfo &get_build_info() const { return build_info; } BuildInfo get_build_info_for_path(const Msp::FS::Path &) const; - void create_targets() const; + virtual void create_targets() const = 0; }; #endif diff --git a/source/datapackcomponent.cpp b/source/datapackcomponent.cpp new file mode 100644 index 0000000..f936e91 --- /dev/null +++ b/source/datapackcomponent.cpp @@ -0,0 +1,42 @@ +#include +#include "builder.h" +#include "datapackcomponent.h" +#include "file.h" +#include "sourcepackage.h" +#include "tool.h" + +using namespace std; +using namespace Msp; + +DataPackComponent::DataPackComponent(SourcePackage &p, const string &n): + Component(p, n) +{ } + +void DataPackComponent::create_targets() const +{ + Builder &builder = package.get_builder(); + Tool &dcomp = builder.get_toolchain().get_tool("DATA"); + + list files; + SourceList source_filenames = collect_source_files(); + for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) + { + string ext = FS::extpart(FS::basename(*i)); + if(ext==".mdt") + { + Target *src = dcomp.create_source(*this, *i); + files.push_back(dcomp.create_target(*src, "collection")); + } + else if(Target *tgt = builder.get_vfs().get_target(*i)) + files.push_back(tgt); + else + files.push_back(new File(builder, package, *i)); + } + + Target *result = dcomp.create_target(files, "pack"); + + BuildGraph &build_graph = builder.get_build_graph(); + build_graph.add_primary_target(*result); + if(install) + build_graph.add_installed_target(*result); +} diff --git a/source/datapackcomponent.h b/source/datapackcomponent.h new file mode 100644 index 0000000..75b99a6 --- /dev/null +++ b/source/datapackcomponent.h @@ -0,0 +1,14 @@ +#ifndef DATAPACKCOMPONENT_H_ +#define DATAPACKCOMPONENT_H_ + +#include "component.h" + +class DataPackComponent: public Component +{ +public: + DataPackComponent(SourcePackage &, const std::string &); + + virtual void create_targets() const; +}; + +#endif diff --git a/source/installcomponent.cpp b/source/installcomponent.cpp new file mode 100644 index 0000000..9584a51 --- /dev/null +++ b/source/installcomponent.cpp @@ -0,0 +1,29 @@ +#include "installcomponent.h" +#include "builder.h" +#include "file.h" +#include "sourcepackage.h" +#include "tool.h" + +using namespace std; + +InstallComponent::InstallComponent(SourcePackage &p, const string &n): + Component(p, n) +{ } + +void InstallComponent::create_targets() const +{ + Builder &builder = package.get_builder(); + Target *inst = builder.get_build_graph().get_target("install"); + Tool © = builder.get_toolchain().get_tool("CP"); + + SourceList source_filenames = collect_source_files(); + for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) + { + FileTarget *ft; + if(Target *tgt = builder.get_vfs().get_target(*i)) + ft = dynamic_cast(tgt); + else + ft = new File(builder, package, *i); + inst->add_dependency(*copy.create_target(*ft, name)); + } +} diff --git a/source/installcomponent.h b/source/installcomponent.h new file mode 100644 index 0000000..43dae71 --- /dev/null +++ b/source/installcomponent.h @@ -0,0 +1,14 @@ +#ifndef INSTALLCOMPONENT_H_ +#define INSTALLCOMPONENT_H_ + +#include "component.h" + +class InstallComponent: public Component +{ +public: + InstallComponent(SourcePackage &, const std::string &); + + virtual void create_targets() const; +}; + +#endif diff --git a/source/sharedlibrary.cpp b/source/sharedlibrary.cpp index 6600b74..6c816bd 100644 --- a/source/sharedlibrary.cpp +++ b/source/sharedlibrary.cpp @@ -1,7 +1,7 @@ #include #include +#include "binarycomponent.h" #include "builder.h" -#include "component.h" #include "objectfile.h" #include "sharedlibrary.h" #include "sourcepackage.h" @@ -28,7 +28,8 @@ SharedLibrary::SharedLibrary(Builder &b, const Component &c, const listget_type()==Component::MODULE) + const BinaryComponent &bcomp = dynamic_cast(*component); + if(bcomp.get_type()==BinaryComponent::MODULE) install_location /= package->get_name(); else { @@ -59,7 +60,8 @@ SharedLibrary::SharedLibrary(Builder &b, const Component &c, const list(comp); + if(bcomp.get_type()==BinaryComponent::MODULE) return comp.get_name()+".m"; else { diff --git a/source/sourcepackage.cpp b/source/sourcepackage.cpp index ddfa00f..1dd7dbd 100644 --- a/source/sourcepackage.cpp +++ b/source/sourcepackage.cpp @@ -1,13 +1,19 @@ +#include #include +#include #include #include #include #include +#include "binarycomponent.h" #include "binarypackage.h" #include "booleanevaluator.h" #include "builder.h" +#include "datapackcomponent.h" #include "file.h" +#include "installcomponent.h" #include "pkgconfigfile.h" +#include "tarballcomponent.h" #include "tool.h" #include "sourcegenerator.h" #include "sourcepackage.h" @@ -15,14 +21,6 @@ using namespace std; using namespace Msp; -namespace { - -bool component_sort(const Component &c1, const Component &c2) -{ return c1.get_type()get_name()==n) + return **i; + throw key_error(n); +} + bool SourcePackage::match_feature(const string &feat, const string *comp) const { string value = config.get_option("with_"+feat).value; @@ -101,37 +113,24 @@ void SourcePackage::do_prepare() build_info.defines[ident] = "1"; } - bool export_paths = false; - for(list::iterator i=components.begin(); i!=components.end(); ++i) + for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i) { - i->prepare(); - i->create_build_info(); - - if(i->get_type()==Component::LIBRARY) - { - export_binfo.libs.push_back(i->get_name()); - export_paths = true; - } - } + (*i)->prepare(); + (*i)->create_build_info(); - if(export_paths) - { - export_binfo.incpath.push_back((builder.get_prefix()/"include").str()); - export_binfo.libpath.push_back((builder.get_prefix()/"lib").str()); + (*i)->update_exported_build_info(export_binfo); } cache.load(); - bool pc_needed = false; - for(ComponentList::const_iterator i=components.begin(); i!=components.end(); ++i) - { - i->create_targets(); - if(i->get_type()==Component::LIBRARY) - pc_needed = true; - } + for(ComponentList::iterator i=components.begin(); i!=components.end(); ++i) + (*i)->create_targets(); - if(pc_needed) + if(!export_binfo.libs.empty()) { + export_binfo.incpath.push_back((builder.get_prefix()/"include").str()); + export_binfo.libpath.push_back((builder.get_prefix()/"lib").str()); + PkgConfigFile *pc = new PkgConfigFile(builder, *this); builder.get_build_graph().get_target("install")->add_dependency(*builder.get_toolchain().get_tool("CP").create_target(*pc)); } @@ -164,12 +163,12 @@ void SourcePackage::Loader::init(const Config::InputOptions *o) add("feature", &Loader::feature); add("generate", &Loader::generate); add("if_feature", &Loader::if_feature); - add("program", &Loader::component); - add("library", &Loader::component); - add("module", &Loader::component); - add("install", &Loader::component); + add("program", &Loader::component_arg); + add("library", &Loader::component_arg); + add("module", &Loader::component_arg); + add("install", &Loader::component); add("interface_version", &Loader::interface_version); - add("datapack", &Loader::component); + add("datapack", &Loader::component); add("source_tarball", &Loader::source_tarball); add("tarball", &Loader::tarball); add("version", &Loader::version); @@ -177,7 +176,11 @@ void SourcePackage::Loader::init(const Config::InputOptions *o) void SourcePackage::Loader::finish() { - obj.components.sort(component_sort); + /* Make sure the source tarball is last in the list so targets from all + other components wil be created first */ + ComponentList::iterator i = find(obj.components.begin(), obj.components.end(), obj.source_tarball); + if(i!=obj.components.end()) + obj.components.splice(obj.components.end(), obj.components, i); } void SourcePackage::Loader::feature(const string &n, const string &d) @@ -196,11 +199,19 @@ void SourcePackage::Loader::feature(const string &n, const string &d) } } -template +template void SourcePackage::Loader::component(const string &n) { - Component comp(obj, t, n); - load_sub(comp); + C *comp = new C(obj, n); + load_sub(*comp); + obj.components.push_back(comp); +} + +template +void SourcePackage::Loader::component_arg(const string &n) +{ + C *comp = new C(obj, n, a); + load_sub(*comp); obj.components.push_back(comp); } @@ -239,7 +250,7 @@ void SourcePackage::Loader::source_tarball() void SourcePackage::Loader::tarball(const string &n) { - Component trbl(obj, Component::TARBALL, n); + TarballComponent trbl(obj, n); load_sub(trbl); } diff --git a/source/sourcepackage.h b/source/sourcepackage.h index 3d86863..6629600 100644 --- a/source/sourcepackage.h +++ b/source/sourcepackage.h @@ -14,6 +14,7 @@ class Builder; class BuildType; class FileTarget; +class TarballComponent; /** A package that can be built by Builder. @@ -33,8 +34,10 @@ public: void init(const Config::InputOptions *); virtual void finish(); void feature(const std::string &, const std::string &); - template + template void component(const std::string &); + template + void component_arg(const std::string &); void build_info(); void generate(const std::string &); void if_feature(const std::string &); @@ -44,7 +47,7 @@ public: void version(const std::string &); }; - typedef std::list ComponentList; + typedef std::list ComponentList; private: typedef std::list FeatureList; @@ -60,12 +63,13 @@ private: FeatureList features; BuildInfo build_info; ComponentList components; - Component *source_tarball; + TarballComponent *source_tarball; Config config; mutable Cache cache; public: SourcePackage(Builder &, const std::string &, const Msp::FS::Path &); + ~SourcePackage(); const std::string &get_version() const { return version; } const std::string &get_interface_version() const { return interface_version; } @@ -77,7 +81,7 @@ public: Msp::FS::Path get_output_directory() const; const Toolchain &get_toolchain() const { return local_tools; } - const ComponentList &get_components() const { return components; } + const Component &get_component(const std::string &) const; const Config &get_config() const { return config; } bool match_feature(const std::string &, const std::string *) const; void set_build_type(const BuildType &); diff --git a/source/tarballcomponent.cpp b/source/tarballcomponent.cpp new file mode 100644 index 0000000..c94103c --- /dev/null +++ b/source/tarballcomponent.cpp @@ -0,0 +1,46 @@ +#include +#include "builder.h" +#include "file.h" +#include "sourcepackage.h" +#include "tarballcomponent.h" +#include "tool.h" + +using namespace std; + +TarballComponent::TarballComponent(SourcePackage &p, const string &n): + Component(p, n) +{ } + +void TarballComponent::create_targets() const +{ + Builder &builder = package.get_builder(); + + list files; + SourceList source_filenames = collect_source_files(); + for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) + { + FileTarget *file = builder.get_vfs().get_target(*i); + if(!file) + file = new File(builder, package, *i); + files.push_back(file); + } + + BuildGraph &build_graph = builder.get_build_graph(); + + string tarname = name; + if(name=="@src") + { + tarname = package.get_name()+"-"+package.get_version(); + files.insert(files.begin(), &package.get_build_file()); + + const BuildGraph::TargetMap &targets = build_graph.get_targets(); + for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) + if(i->second->get_package()==&package && !i->second->is_buildable()) + if(find(files.begin(), files.end(), i->second)==files.end()) + files.push_back(i->second); + } + + const Toolchain &toolchain = builder.get_toolchain(); + Target *result = toolchain.get_tool("TAR").create_target(files, tarname); + build_graph.get_target("tarballs")->add_dependency(*result); +} diff --git a/source/tarballcomponent.h b/source/tarballcomponent.h new file mode 100644 index 0000000..d54f95e --- /dev/null +++ b/source/tarballcomponent.h @@ -0,0 +1,14 @@ +#ifndef TARBALLCOMPONENT_H_ +#define TARBALLCOMPONENT_H_ + +#include "component.h" + +class TarballComponent: public Component +{ +public: + TarballComponent(SourcePackage &, const std::string &); + + virtual void create_targets() const; +}; + +#endif -- 2.45.2