aboutsummaryrefslogtreecommitdiffstats
path: root/core.lv2/lv2config
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-10-28 02:03:57 +0000
committerDavid Robillard <d@drobilla.net>2010-10-28 02:03:57 +0000
commit0d729e6fa444d193f8e4b3f55117887ef2b9aa8a (patch)
treef01a06640bf0f94706b2823d1394e80658f8cde3 /core.lv2/lv2config
parent9c054a95b02119526ba879805e78b577bd26c68f (diff)
downloadlv2-0d729e6fa444d193f8e4b3f55117887ef2b9aa8a.tar.xz
Move lv2include/lv2include to core.lv2/lv2config and make lv2core build system install it.
Diffstat (limited to 'core.lv2/lv2config')
-rwxr-xr-xcore.lv2/lv2config168
1 files changed, 168 insertions, 0 deletions
diff --git a/core.lv2/lv2config b/core.lv2/lv2config
new file mode 100755
index 0000000..0e4b00f
--- /dev/null
+++ b/core.lv2/lv2config
@@ -0,0 +1,168 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""A program (and Python module) to generate a tree of symlinks to LV2
+extension bundles, where the path of the symlink corresponds to the URI of
+the extension. This allows including extension headers in code without using
+the bundle name. Including extension headers in this way is much better,
+since there is no dependency on the (meaningless and non-persistent) bundle
+name in the code using the header.
+
+For example, after running lv2includegen (and setting the compiler include
+path appropriately), LV2 headers could be included like so:
+
+#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "lv2/lv2plug.in/ns/ext/event/event.h"
+#include "lv2/example.org/foo/foo.h"
+
+Where the initial "lv2" is arbitrary; in this case lv2includegen's output
+directory was "lv2", and that directory's parent was added to the compiler
+include search path. It is a good idea to use such a prefix directory so
+domain names do not conflict with anything else in the include path.
+"""
+
+__authors__ = 'David Robillard'
+__license = 'GNU GPL v3 or later <http://www.gnu.org/licenses/gpl.html>'
+__contact__ = 'devel@lists.lv2plug.in'
+__date__ = '2010-10-05'
+
+import errno
+import glob
+import os
+import stat
+import sys
+
+redland = True
+
+try:
+ import RDF # Attempt to import Redland
+except:
+ try:
+ import rdflib # Attempt to import RDFLib
+ redland = False
+ except:
+ print >> sys.stderr, """Failed to import `RDF' (Redland) or `rdflib'.
+(Please install either package, likely `python-librdf' or `python-rdflib')"""
+ sys.exit(1)
+
+def rdf_namespace(uri):
+ "Create a new RDF namespace"
+ if redland:
+ return RDF.NS(uri)
+ else:
+ return rdflib.Namespace(uri)
+
+def rdf_load(uri):
+ "Load an RDF model"
+ if redland:
+ model = RDF.Model()
+ parser = RDF.Parser(name="turtle")
+ parser.parse_into_model(model, uri)
+ else:
+ model = rdflib.ConjunctiveGraph()
+ model.parse(uri, format="n3")
+ return model
+
+def rdf_find_type(model, rdf_type):
+ "Return a list of the URIs of all resources in model with a given type"
+ if redland:
+ results = model.find_statements(RDF.Statement(None, rdf.type, rdf_type))
+ ret = []
+ for r in results:
+ ret.append(str(r.subject.uri))
+ return ret
+ else:
+ results = model.triples([None, rdf.type, rdf_type])
+ ret = []
+ for r in results:
+ ret.append(r[0])
+ return ret
+
+rdf = rdf_namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
+lv2 = rdf_namespace('http://lv2plug.in/ns/lv2core#')
+
+def lv2_path():
+ "Return the LV2 search path (LV2_PATH in the environment, or a default)."
+ if 'LV2_PATH' in os.environ:
+ return os.environ['LV2_PATH']
+ else:
+ ret = '/usr/lib/lv2' + os.pathsep + '/usr/local/lib/lv2'
+ print 'LV2_PATH unset, using default ' + ret
+ return ret
+
+def __bundles(search_path):
+ "Return a list of all LV2 bundles found in search_path."
+ dirs = search_path.split(os.pathsep)
+ bundles = []
+ for dir in dirs:
+ bundles += glob.glob(os.path.join(dir, '*.lv2'))
+ return bundles
+
+def __usage():
+ script = os.path.basename(sys.argv[0])
+ print """Usage:
+ %s OUTDIR
+
+ OUTDIR : Directory to build include tree
+
+Example:
+ %s /usr/local/include/lv2
+""" % (script, script)
+
+def __mkdir_p(path):
+ "Equivalent of UNIX mkdir -p"
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+
+def build_tree(search_path, outdir):
+ """Build a directory tree under outdir containing symlinks to all LV2
+ extensions found in search_path, such that the symlink paths correspond to
+ the extension URIs."""
+ print "Building LV2 include tree at", outdir, "for", search_path
+ if os.access(outdir, os.F_OK) and not os.access(outdir, os.W_OK):
+ print >> sys.stderr, "lv2include.py: cannot build `%s': Permission denied" % outdir
+ sys.exit(1)
+ for bundle in __bundles(search_path):
+ # Load manifest into model
+ manifest = rdf_load('file://' + os.path.join(bundle, 'manifest.ttl'))
+
+ # Query extension URI
+ specs = rdf_find_type(manifest, lv2.Specification)
+ for ext_uri in specs:
+ ext_scheme = ext_uri[0:ext_uri.find(':')]
+ ext_path = os.path.normpath(ext_uri[ext_uri.find(':') + 1:].lstrip('/'))
+ ext_dir = os.path.join(outdir, ext_scheme, ext_path)
+
+ # Make parent directories
+ __mkdir_p(os.path.dirname(ext_dir))
+
+ # Remove existing symlink if necessary
+ if os.access(ext_dir, os.F_OK):
+ mode = os.lstat(ext_dir)[stat.ST_MODE]
+ if stat.S_ISLNK(mode):
+ os.remove(ext_dir)
+ else:
+ raise Exception(ext_dir + " exists and is not a link")
+
+ # Make symlink to bundle directory
+ os.symlink(bundle, ext_dir)
+
+if __name__ == "__main__":
+ args = sys.argv[1:]
+
+ if len(args) == 0:
+ build_tree('/usr/local/lib/lv2', '/usr/local/include/lv2')
+ build_tree('/usr/lib/lv2', '/usr/include/lv2')
+ sys.exit(0)
+
+ elif len(args) != 1:
+ __usage()
+ sys.exit(1)
+
+ else:
+ build_tree(lv2_path(), args[1])