[erlang-questions] How about make the erl to be relocatable ? for multiple erlang versions installed on a same host

Michael Truog mjtruog@REDACTED
Tue Jun 6 05:17:45 CEST 2017


What I find useful to handle multiple Erlang versions, is to move the installation directory in lib to separate name, and use a symbolic link when switching between versions.  The installation is has been setup for awhile in a way where this doesn't break, which is nice.  So, PREFIX=="/usr/local" if installing from source, but whatever it is:
cd PREFIX/lib/
mv erlang erlang_VERSION
ln -s erlang_VERSION erlang

In the future, to switch versions, you only need to change the symbolic link target.

I don't see a good reason to change the erl executable to handle testing separate versions, because your concerns seem focused on troubles dealing with packages.  That would likely be an issue with packages, where the package manager wants to enforce having 1 version of something.  If the packages were built to have the version number in the path, then the problem could be avoided (and the solution is similar to the info above), but it would remain a package problem.

On 06/05/2017 07:38 PM, derek wrote:
>
> the default erl is a shell script, like this:
>
> #!/bin/sh
> [...]
> # %CopyrightEnd%
> #
> ROOTDIR="/usr/lib/erlang"
> ...
>
>
> Where the ROOTDIR is set to a hard code string at installation time, and it makes the erl script not relocatable,
>
> sometimes we want to install multiple erlang versions for testing features, like this following is my way to test install esl packaged erlang-20.0-rc2, all just extract "install" to my $HOME/opt/... without sysadmin permission:
>
> # download the deb or rpm package
> $ wget -P ./Downloads -m https://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~debian~jessie_amd64.deb <https://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1%7Edebian%7Ejessie_amd64.deb>
>
> # the deb is an ar format, you can use standard ar/tar tools to extract to local ./usr/lib/erlang/
> $ ar p ./Downloads/packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~debian~jessie_amd64.deb <http://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1%7Edebian%7Ejessie_amd64.deb> data.tar.xz | tar --xz -xvv ./usr/lib/erlang/
>
> # or to extract the rpm, it is cpio format:
> # rpm2cpio ./Downloads/packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1~centos~6_amd64.rpm <http://packages.erlang-solutions.com/erlang/esl-erlang/FLAVOUR_1_general/esl-erlang_20.0-rc2-1%7Ecentos%7E6_amd64.rpm> | cpio -vid './usr/lib/erlang/*'
>
> Once I get ./usr/lib/erlang/ I usually renamed to ./opt/ ...
>
> $ mv -v ./usr/lib/erlang/ ./opt/esl-erlang_20.0-rc2-1~debian~jessie
>
> Then a problem is this erl doesn't run, because it tries to access the hard coded ROOTDIR from /usr/lib/erlang (does not exist)
>
> (the "bash -xe" is only to show how does the shell script run, but not necessary)
>
> $ bash -xe ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl
> + ROOTDIR=/usr/lib/erlang
> + BINDIR=/usr/lib/erlang/erts-9.0/bin
> + EMU=beam
> ++ echo ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl
> ++ sed 's/.*\///'
> + PROGNAME=erl
> + export EMU
> + export ROOTDIR
> + export BINDIR
> + export PROGNAME
> + exec /usr/lib/erlang/erts-9.0/bin/erlexec
> ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl: line 29: /usr/lib/erlang/erts-9.0/bin/erlexec: No such file or directory
>
> So I back it up and make little changes to make it read path from where it's installed:
>
> $ \cp -va ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl{,.orig}
> `./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl' -> `./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl.orig'
>
> $ vim ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl
>
> Diff is here:
>
> $ diff -u ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl{.orig,}
> --- ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl.orig2017-06-06 01:57:50.796140791 +0000
> +++ ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl2017-06-06 01:59:15.713988348 +0000
> @@ -18,10 +18,12 @@
>  #
>  # %CopyrightEnd%
>  #
> -ROOTDIR="/usr/lib/erlang"
> +# ROOTDIR="/usr/lib/erlang"
> +ROOTDIR="$(readlink -f ${0%/*}/..)"
>  BINDIR=$ROOTDIR/erts-9.0/bin
>  EMU=beam
> -PROGNAME=`echo $0 | sed 's/.*\///'`
> +# PROGNAME=`echo $0 | sed 's/.*\///'`
> +PROGNAME="${0##*/}"
>  export EMU
>  export ROOTDIR
>  export BINDIR
>
> Then it runs:
>
> $ bash -xe ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl
> ++ readlink -f ./opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/..
> + ROOTDIR=/home/username/opt/esl-erlang_20.0-rc2-1~debian~jessie
> + BINDIR=/home/username/opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin
> + EMU=beam
> + PROGNAME=erl
> + export EMU
> + export ROOTDIR
> + export BINDIR
> + export PROGNAME
> + exec /home/username/opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin/erlexec
> Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:24:24] [ds:24:24:10] [async-threads:10] [hipe] [kernel-poll:false]
>
> Eshell V9.0  (abort with ^G)
> 1>
>
> I am aware of there is a "Install" script can be used to install itself to another location, but the problem remains: it's still hard coded of new install path:
> ./opt/esl-erlang_20.0-rc2-1~debian~jessie/Install
>
>
> The problem need to be solved, especially when used with docker's bind mount feature, it can be mounted to a complete different path, I hope the erl can still run without any change:
>
> Here it shows my changed erl escript can still run when bind mounted to the container's "/opt/esl-erlang_20.0-rc2-1~debian~jessie"
>
> $ docker run -it --rm -v $PWD/opt:/opt:ro ubuntu bash -xe /opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/erl
> ++ readlink -f /opt/esl-erlang_20.0-rc2-1~debian~jessie/bin/..
> + ROOTDIR=/opt/esl-erlang_20.0-rc2-1~debian~jessie
> + BINDIR=/opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin
> + EMU=beam
> + PROGNAME=erl
> + export EMU
> + export ROOTDIR
> + export BINDIR
> + export PROGNAME
> + exec /opt/esl-erlang_20.0-rc2-1~debian~jessie/erts-9.0/bin/erlexec
> Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:24:24] [ds:24:24:10] [async-threads:10] [hipe] [kernel-poll:false]
>
> Eshell V9.0  (abort with ^G)
> 1>
> User switch command
>  --> q
>
> Or add to PATH:
>
> $ docker run -it --rm -v $PWD/opt:/opt:ro -e PATH=/opt/esl-erlang_20.0-rc2-1~debian~jessie/bin:$PATH -e LANG=C.UTF-8 ubuntu erl +pc unicode
> Erlang/OTP 20 [RELEASE CANDIDATE 2] [erts-9.0] [source] [64-bit] [smp:24:24] [ds:24:24:10] [async-threads:10] [hipe] [kernel-poll:false]
>
> Eshell V9.0  (abort with ^G)
> 1> io:format("~tp~n", [{'hello_юникод_世界', <<"Hello, 世界; юникод"/utf8>>, "Hello, 世界; юникод"}]).
> {'hello_юникод_世界',<<"Hello, 世界; юникод"/utf8>>,"Hello, 世界; юникод"}
> ok
> 2>
> User switch command
>  --> q
>
>
> Hopefully this entertains; I can make a PR to https://github.com/erlang/otp if somebody like.
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170605/3678d861/attachment.htm>


More information about the erlang-questions mailing list