]> git.tdb.fi Git - builder.git/commitdiff
Flexible way to specify install locations for components
authorMikko Rasa <tdb@tdb.fi>
Tue, 10 Jul 2012 14:23:10 +0000 (17:23 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 10 Jul 2012 20:55:52 +0000 (23:55 +0300)
source/component.cpp
source/component.h
source/installedfile.cpp
source/installmap.cpp [new file with mode: 0644]
source/installmap.h [new file with mode: 0644]

index 11d2925d83514ce4849f08fcff0bf6a9d92c8f9e..3c5a40945ed56184e4776edd7cb74b0ec3ee5b91 100644 (file)
@@ -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());
+}
index 0f9d581bcfb1695805036437edb73ed5bf2eea39..0d67fdeb874deaa60c1438f01764bbb1c697bf9c 100644 (file)
@@ -5,6 +5,7 @@
 #include <msp/datafile/loader.h>
 #include <msp/fs/path.h>
 #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);
 
index a71bcba3c29adae803f357c1455ad3dc76bae2d5..15bd08b06f7b507b16109c8f08f7933306d1e092 100644 (file)
@@ -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 (file)
index 0000000..22d92b1
--- /dev/null
@@ -0,0 +1,48 @@
+#include <msp/fs/utils.h>
+#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<Entry>::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<InstallMap>(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 (file)
index 0000000..955decc
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef INSTALLMAP_H_
+#define INSTALLMAP_H_
+
+#include <list>
+#include <msp/datafile/objectloader.h>
+#include <msp/fs/path.h>
+
+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<InstallMap>
+       {
+       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<Entry> 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