From e0c863681c8a5fad5918bb7730ecbc65fbdfbc64 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 10 Jul 2012 17:23:10 +0300 Subject: [PATCH] Flexible way to specify install locations for components --- source/component.cpp | 6 +++++ source/component.h | 4 ++++ source/installedfile.cpp | 2 ++ source/installmap.cpp | 48 +++++++++++++++++++++++++++++++++++++ source/installmap.h | 52 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+) create mode 100644 source/installmap.cpp create mode 100644 source/installmap.h diff --git a/source/component.cpp b/source/component.cpp index 11d2925..3c5a409 100644 --- a/source/component.cpp +++ b/source/component.cpp @@ -250,6 +250,7 @@ Component::Loader::Loader(Component &c): { add("source", &Loader::source); add("install", &Component::install); + add("install_map", &Loader::install_map); add("build_info", &Loader::build_info); add("require", &Loader::require); add("default", &Component::deflt); @@ -282,3 +283,8 @@ void Component::Loader::build_info() { load_sub(comp.build_info); } + +void Component::Loader::install_map() +{ + load_sub(comp.install_map, comp.pkg.get_source()); +} diff --git a/source/component.h b/source/component.h index 0f9d581..0d67fde 100644 --- a/source/component.h +++ b/source/component.h @@ -5,6 +5,7 @@ #include #include #include "buildinfo.h" +#include "installmap.h" #include "misc.h" #include "package.h" @@ -33,6 +34,7 @@ public: void source(const std::string &); void require(const std::string &); void build_info(); + void install_map(); }; enum Type @@ -55,6 +57,7 @@ protected: BuildInfo build_info; PackageList requires; bool deflt; + InstallMap install_map; public: Component(SourcePackage &, Type, const std::string &); @@ -66,6 +69,7 @@ public: bool get_install() const { return install; } const PackageList &get_requires() const { return requires; } bool is_default() const { return deflt; } + const InstallMap &get_install_map() const { return install_map; } void configure(const StringMap &, unsigned); diff --git a/source/installedfile.cpp b/source/installedfile.cpp index a71bcba..15bd08b 100644 --- a/source/installedfile.cpp +++ b/source/installedfile.cpp @@ -28,6 +28,8 @@ FS::Path InstalledFile::generate_target_path(const FS::Path &prefix, const FileT FS::Path mid; if(!loc.empty()) mid = loc; + else if(const Component *comp = tgt.get_component()) + mid = comp->get_install_map().get_install_location(tgt); else mid = tgt.get_install_location(); diff --git a/source/installmap.cpp b/source/installmap.cpp new file mode 100644 index 0000000..22d92b1 --- /dev/null +++ b/source/installmap.cpp @@ -0,0 +1,48 @@ +#include +#include "filetarget.h" +#include "installmap.h" + +using namespace std; +using namespace Msp; + +void InstallMap::add_mapping(const FS::Path &src, const FS::Path &inst) +{ + Entry e; + e.source = src; + e.install = inst; + entries.push_back(e); +} + +FS::Path InstallMap::get_install_location(const FileTarget &target) const +{ + const FS::Path &source = target.get_path(); + FS::Path install = target.get_install_location(); + for(list::const_iterator i=entries.begin(); i!=entries.end(); ++i) + { + int source_depth = FS::descendant_depth(source, i->source); + if(source_depth>=0) + { + FS::Path install_base = FS::common_ancestor(install, i->install); + if(install_base.size()>1) + { + install = i->install/FS::dirname(source).subpath(i->source.size()); + break; + } + } + } + + return install; +} + + +InstallMap::Loader::Loader(InstallMap &m, const FS::Path &s): + DataFile::ObjectLoader(m), + source_base(s) +{ + add("map", &Loader::map); +} + +void InstallMap::Loader::map(const string &src, const string &inst) +{ + obj.add_mapping(source_base/src, inst); +} diff --git a/source/installmap.h b/source/installmap.h new file mode 100644 index 0000000..955decc --- /dev/null +++ b/source/installmap.h @@ -0,0 +1,52 @@ +#ifndef INSTALLMAP_H_ +#define INSTALLMAP_H_ + +#include +#include +#include + +class FileTarget; + +/** +Maps install locations based on location in the source tree. Mappings are +defined as pairs of source and install locations. Targets within a source +location are mapped if their default install location shares a common prefix +with the mapped install location. The remainder of the source location is +appended to the mapped install location to form the final install location. +*/ +class InstallMap +{ +public: + class Loader: public Msp::DataFile::ObjectLoader + { + private: + Msp::FS::Path source_base; + + public: + Loader(InstallMap &, const Msp::FS::Path &); + + private: + void map(const std::string &, const std::string &); + }; + +private: + struct Entry + { + Msp::FS::Path source; + Msp::FS::Path install; + }; + + std::list entries; + +public: + /** Adds an install mapping. Multiple mappings can be specified for the + same source location, but the first one that matches both that and the + target's default install location will be used. */ + void add_mapping(const Msp::FS::Path &, const Msp::FS::Path &); + + /** Returns the install location for a target. If no defined mappings match + the target, its default install location is returned. */ + Msp::FS::Path get_install_location(const FileTarget &) const; +}; + +#endif -- 2.45.2