Bug#951801: User setting of LILYPOND_DATADIR is not honoured

2020-02-23 Thread Simon Tatham
Don Armstrong  wrote:
> Could you try changing /usr/bin/lilypond to be this instead:
> 
> #!/bin/sh
> export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/lilypond/2.18.2/guile"
> exec "lilypond.real" "$@"
> 
> and see if that works better?

No, I'm afraid not. That was the first thing I tried too, in the hope
that Lilypond was just checking for an _absolute_ path in its argv[0],
and might stop trying to be clever if you didn't give it one.

But no: it really does _search_ for its argv[0] value on PATH if it's
not already absolute. So if its argv[0] is just "lilypond.real", that's
just as bad as it being "/usr/bin/lilypond.real".

Demonstration transcript:

$ cat /usr/bin/lilypond
#!/bin/sh
export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/lilypond/2.18.2/guile"
exec "lilypond.real" "$@"
$ export LILYPOND_DATADIR=$HOME/my-datadir
$ lilypond -V demo.ly
Log level set to 287
GNU LilyPond 2.18.2
Relocation: from 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
argv0=lilypond.real
PATH=/usr/bin (prepend)
Setting PATH to 
/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Relocation: compile datadir=, new datadir=/usr/share/lilypond//2.18.2
Relocation: framework_prefix=/usr/bin/..
Setting INSTALLER_PREFIX to /usr/bin/..
Setting LILYPOND_DATADIR to /usr/share/lilypond//2.18.2
[...]

... and then it loads everything from /usr/share/lilypond/2.18.2 as
before.

That's why my actual workaround involved manually setting Lilypond's
argv[0] to something that it _couldn't_ find on PATH.

Now I think about it, an alternative workaround would be to make my own
bin directory alongside my intended datadir, symlink lilypond.real into
there, and ensure it precedes /usr/bin on my path. Then, when
lilypond.real looks for itself on PATH, it finds the version of itself I
wanted. But in order to do that, I still need lilypond.real's argv[0]
not to have an absolute path pointing somewhere else, so the current
/usr/bin/lilypond wrapper still makes that workaround awkward.

Incidentally, this seems to have been fixed upstream: if I check out
Lilypond master from git, it honours LILYPOND_DATADIR. I think the
commit that changed things was this one:
https://sourceforge.net/p/testlilyissues/issues/5481/
but it's a full rewrite of the relocation algorithm, so probably not the
kind of thing it would be easy or desirable to cherry-pick into the 2.18
series :-(

Cheers,
Simon

-- 
for k in [pow(x,37,0x1a1298d262b49c895d47f) for x in [0x50deb914257022de7fff,
0x213558f2215127d5a2d1, 0x90c99e86d08b91218630, 0x109f3d0cfbf640c0beee7,
0xc83e01379a5fbec5fdd1, 0x19d3d70a8d567e388600e, 0x534e2f6e8a4a33155123]]:
 print("".join([chr(32+3*((k>>x)&1))for x in range(79)])) # 



Bug#951801: User setting of LILYPOND_DATADIR is not honoured

2020-02-22 Thread Don Armstrong
On Fri, 21 Feb 2020, Simon Tatham wrote:
> However, the override doesn't actually work! 

[...]

> In order to work around this, I tried to 'exec' the Lilypond binary
> with an argv[0] that does not appear on PATH at all, which inhibits
> the initial 'relocate' operation and causes the input value of
> LILYPOND_DATADIR not to be overwritten.

Hrm; that's really surprising. I have to admit that I haven't ever
tested LILYPOND_DATADIR.

Could you try changing /usr/bin/lilypond to be this instead:

#!/bin/sh
export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/lilypond/2.18.2/guile"
exec "lilypond.real" "$@"

and see if that works better?

-- 
Don Armstrong  https://www.donarmstrong.com

Vimes hated and despised the privileges of rank, but they had this to
be said for them: At least they meant that you could hate and despise
them in comfort.
 -- Terry Pratchett _The Fifth Elephant_ p111



Bug#951801: User setting of LILYPOND_DATADIR is not honoured

2020-02-21 Thread Simon Tatham
Package: lilypond
Version: 2.19.81+really-2.18.2-13

The Lilypond documentation says that if you set the environment
variable LILYPOND_DATADIR to point at a directory, then Lilypond will
look for its data files (fonts, startup files etc) in that directory
instead of /usr/share/lilypond/. In particular, in the
2.18 series, this is the only way to substitute a different musical
notation font.

However, the override doesn't actually work! Under normal conditions,
Lilypond overwrites that variable itself during startup, with a value
derived from searching PATH for its own binary. Using the -V option
you can see this happening in the startup messages, and then
subsequent messages show fonts and other resources being loaded from
the standard location:

$ export LILYPOND_DATADIR=$HOME/my-datadir
$ lilypond.real -V demo.ly
Log level set to 287
GNU LilyPond 2.18.2
Relocation: is absolute: argv0=/usr/bin/lilypond.real
PATH=/usr/bin (prepend)
Setting PATH to 
/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Relocation: compile datadir=, new datadir=/usr/share/lilypond//2.18.2
Relocation: framework_prefix=/usr/bin/..
Setting INSTALLER_PREFIX to /usr/bin/..
Setting LILYPOND_DATADIR to /usr/share/lilypond//2.18.2
[...]
Interpreting music...
[/usr/share/lilypond/2.18.2/fonts/otf/emmentaler-20.otf]
elapsed time: 0.01 seconds
[...]

In order to work around this, I tried to 'exec' the Lilypond binary
with an argv[0] that does not appear on PATH at all, which inhibits
the initial 'relocate' operation and causes the input value of
LILYPOND_DATADIR not to be overwritten.

That works OK, provided I take account of the fact that
/usr/bin/lilypond is a wrapper script that sets up LD_LIBRARY_PATH. If
I manually repeat that setting, and then exec the real binary
directly, then I have more luck:

$ export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/lilypond/2.18.2/guile"
$ export LILYPOND_DATADIR=$HOME/my-datadir
$ (exec -a sdfsdfsdf lilypond.real -V demo.ly)
Log level set to 287
GNU LilyPond 2.18.2
Relocation: from 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
argv0=sdfsdfsdf
programming error: cannot find absolute argv0
continuing, cross fingers
[...]
LILYPOND_DATADIR="/usr/share/lilypond/2.18.2"
LILYPOND_DATADIR="/root/my-datadir"
LOCALEDIR="/usr/share/locale"
[...]
Interpreting music...
[/root/my-datadir/fonts/otf/emmentaler-20.otf]
elapsed time: 0.01 seconds

... and now it's loading fonts from where I told it to.

But the intervening wrapper script at /usr/bin/lilypond makes it very
awkward to automate this! The best way I've managed to find, which
arranges to use the correct LD_LIBRARY_PATH setup from
/usr/bin/lilypond and then pass a custom argv[0] to the real binary,
is to write a wrapper bash script which covers the 'exec' builtin with
an alias, and then sources /usr/bin/lilypond:

#!/bin/bash
shopt -s expand_aliases
alias exec='exec -a sdfsdfsdf'
export LILYPOND_DATADIR=$HOME/my-datadir
source /usr/bin/lilypond

With that wrapper script, I can get Lilypond to behave as I want:

$ ./wrapper.sh -V demo.ly
[...]
LILYPOND_DATADIR="/root/my-datadir"
[...]

But it would be really nice not to have to recommend this procedure to
people who want to use a different music font!

Cheers,
Simon

-- 
for k in [pow(x,37,0x1a1298d262b49c895d47f) for x in [0x50deb914257022de7fff,
0x213558f2215127d5a2d1, 0x90c99e86d08b91218630, 0x109f3d0cfbf640c0beee7,
0xc83e01379a5fbec5fdd1, 0x19d3d70a8d567e388600e, 0x534e2f6e8a4a33155123]]:
 print("".join([chr(32+3*((k>>x)&1))for x in range(79)])) #