2 # -*- coding: utf-8 -*-
4 """A program (and Python module) to generate a tree of symlinks to LV2
5 extension bundles, where the path of the symlink corresponds to the URI of
6 the extension. This allows including extension headers in code without using
7 the bundle name. Including extension headers in this way is much better,
8 since there is no dependency on the (meaningless and non-persistent) bundle
9 name in the code using the header.
11 For example, after running lv2includegen (and setting the compiler include
12 path appropriately), LV2 headers could be included like so:
14 #include "lv2/lv2plug.in/ns/lv2core/lv2.h"
15 #include "lv2/lv2plug.in/ns/ext/event/event.h"
16 #include "lv2/example.org/foo/foo.h"
18 Where the initial "lv2" is arbitrary; in this case lv2includegen's output
19 directory was "lv2", and that directory's parent was added to the compiler
20 include search path. It is a good idea to use such a prefix directory so
21 domain names do not conflict with anything else in the include path.
24 __authors__
= 'David Robillard'
25 __license
= 'GNU GPL v3 or later <http://www.gnu.org/licenses/gpl.html>'
26 __contact__
= 'devel@lists.lv2plug.in'
27 __date__
= '2010-10-05'
39 parser
= RDF
.Parser(name
="guess")
40 parser
.parse_into_model(model
, uri
)
43 def rdf_find(model
, s
, p
, o
):
44 return model
.find_statements(RDF
.Statement(s
, p
, o
))
46 def rdf_namespace(uri
):
49 rdf
= rdf_namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
50 lv2
= rdf_namespace('http://lv2plug.in/ns/lv2core#')
53 "Return the LV2 search path (LV2_PATH in the environment, or a default)."
54 if 'LV2_PATH' in os
.environ
:
55 return os
.environ
['LV2_PATH']
57 ret
= '/usr/lib/lv2' + os
.pathsep
+ '/usr/local/lib/lv2'
58 print 'LV2_PATH unset, using default ' + ret
61 def __bundles(search_path
):
62 "Return a list of all LV2 bundles found in search_path."
63 dirs
= search_path
.split(os
.pathsep
)
66 bundles
+= glob
.glob(os
.path
.join(dir, '*.lv2'))
70 script
= os
.path
.basename(sys
.argv
[0])
74 OUTDIR : Directory to build include tree
77 %s /usr/local/include/lv2
78 """ % (script
, script
)
81 "Equivalent of UNIX mkdir -p"
85 if e
.errno
== errno
.EEXIST
:
90 def build_tree(search_path
, outdir
):
91 """Build a directory tree under outdir containing symlinks to all LV2
92 extensions found in search_path, such that the symlink paths correspond to
93 the extension URIs."""
94 for bundle
in __bundles(search_path
):
95 # Load manifest into model
96 manifest
= rdf_load('file://' + os
.path
.join(bundle
, 'manifest.ttl'))
99 results
= rdf_find(manifest
, None, rdf
.type, lv2
.Specification
)
101 ext_uri
= str(r
.subject
.uri
)
102 ext_scheme
= ext_uri
[0:ext_uri
.find(':')]
103 ext_path
= os
.path
.normpath(ext_uri
[ext_uri
.find(':') + 1:].lstrip('/'))
104 ext_dir
= os
.path
.join(outdir
, ext_scheme
, ext_path
)
106 # Make parent directories
107 __mkdir_p(os
.path
.dirname(ext_dir
))
109 # Remove existing symlink if necessary
110 if os
.access(ext_dir
, os
.F_OK
):
111 mode
= os
.lstat(ext_dir
)[stat
.ST_MODE
]
112 if stat
.S_ISLNK(mode
):
115 raise Exception(ext_dir
+ " exists and is not a link")
117 # Make symlink to bundle directory
118 os
.symlink(bundle
, ext_dir
)
120 if __name__
== "__main__":
127 print "Building LV2 include tree at", outdir
129 build_tree(lv2_path(), outdir
)