372 lines
12 KiB
Bash
Executable File
372 lines
12 KiB
Bash
Executable File
#!/bin/sh
|
|
# vi: ft=bash
|
|
|
|
set -eu
|
|
|
|
stringContain() { case $2 in *$1* ) return 0;; *) return 1;; esac ;}
|
|
|
|
supported_rnrs="r6rs r7rs"
|
|
supported_implementations="capyscheme chezscheme chibi chicken cyclone foment \
|
|
gambit gauche guile ikarus ironscheme kawa larceny loko meevax mosh \
|
|
mit-scheme racket sagittarius skint stklos tr7 ypsilon"
|
|
|
|
## Make sure all arguments are right
|
|
if [ "${1}" = "" ]; then
|
|
echo "Give implementation name as first argument"
|
|
echo "${supported_implementations}"
|
|
exit 1
|
|
fi
|
|
|
|
if stringContain "${1}" "${supported_implementations}"; then
|
|
sleep 0
|
|
else
|
|
echo "Unsupported implementation: ${1}"
|
|
echo "${supported_implementations}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${2}" = "" ]; then
|
|
echo "Give the RnRS as the second argument"
|
|
echo "${supported_rnrs}"
|
|
exit 1
|
|
fi
|
|
|
|
if stringContain "${2}" "${supported_rnrs}"; then
|
|
sleep 0
|
|
else
|
|
echo "Unsupported RnRS: ${2}"
|
|
echo "${supported_rnrs}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${3}" = "" ]; then
|
|
echo "Give path for new virtual environment as third argument"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -d "${3}" ]; then
|
|
if [ -f "${3}/bin/scheme-venv-info" ]; then
|
|
echo "Directory is already venv, reiniting..."
|
|
else
|
|
echo "Path already exists, and is not scheme-venv (no /bin/scheme-venv-info)"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
## Build variables
|
|
implementation="${1}"
|
|
rnrs="${2}"
|
|
venvpath=$(realpath "${3}")
|
|
venvname=$(basename "${venvpath}")
|
|
downloadpath="${venvpath}/downloads"
|
|
toolinstallprefix="${venvpath}/tools"
|
|
docker_tag="${venvname}-${implementation}-${rnrs}"
|
|
scheme_compile_cmd=""
|
|
scheme_cmd=""
|
|
scheme_script_cmd=""
|
|
scheme_type="interpreter"
|
|
|
|
echo "scheme-venv version 1.0.0, scheme: ${implementation}, rnrs: ${rnrs}"
|
|
|
|
## Create venv directories
|
|
mkdir -p "${venvpath}"
|
|
mkdir -p "${venvpath}/bin"
|
|
if [ -d "${venvpath}/lib" ]; then
|
|
rm -rf "${venvpath}/lib"
|
|
fi
|
|
mkdir -p "${venvpath}/lib"
|
|
mkdir -p "${venvpath}/etc"
|
|
|
|
## Set scheme type if other than interpreter
|
|
case "${implementation}" in
|
|
"chicken") scheme_type=compiler ;;
|
|
"gambit") scheme_type=compiler ;;
|
|
esac
|
|
|
|
## bin/activate
|
|
{
|
|
cat << EOF
|
|
deactivate () {
|
|
unset SCHEME
|
|
unset COMPILE_R7RS
|
|
unset COMPILE_SCHEME
|
|
unset TEST_SCHEME
|
|
unset venvname
|
|
export PS1="\${SCHEME_VENV_OLD_PS1}"
|
|
unset SCHEME_VENV_OLD_PS1
|
|
export PATH="\${SCHEME_VENV_OLD_PATH}"
|
|
unset SCHEME_VENV_OLD_PATH
|
|
hash -r 2> /dev/null
|
|
}
|
|
|
|
export COMPILE_R7RS=${implementation}
|
|
export COMPILE_SCHEME=${implementation}
|
|
export TEST_SCHEME=${implementation}
|
|
export SCHEME=${implementation}
|
|
|
|
venvname="${venvname}"
|
|
|
|
export SCHEME_VENV_OLD_PS1="\${PS1}"
|
|
export PS1="(\${venvname}) \${PS1:-}"
|
|
|
|
export SCHEME_VENV_OLD_PATH="\${PATH}"
|
|
export PATH="${venvpath}/bin:\${PATH}"
|
|
hash -r 2> /dev/null
|
|
echo "${implementation} ${rnrs}"
|
|
echo "if [ "${rnrs}" = "r6rs" ]; then . ${venvpath}/lib/.akku/bin/activate; fi"
|
|
EOF
|
|
} > "${venvpath}/bin/activate"
|
|
|
|
## /etc/Dockerfile
|
|
{
|
|
cat << EOF
|
|
FROM docker.io/schemers/${implementation}:head
|
|
RUN apt-get update && apt-get install -y make gcc libffi-dev git ca-certificates curl xz-utils
|
|
WORKDIR /build
|
|
RUN git clone https://github.com/ashinn/chibi-scheme.git --depth=1
|
|
WORKDIR /build/chibi-scheme
|
|
RUN make
|
|
RUN make install
|
|
WORKDIR /build
|
|
RUN curl -o akku.tar.xz https://gitlab.com/-/project/6808260/uploads/094ce726ce3c6cf8c14560f1e31aaea0/akku-1.1.0.amd64-linux.tar.xz
|
|
RUN mkdir akku && tar -C akku --strip-components 1 -xf akku.tar.xz
|
|
WORKDIR /build/akku
|
|
RUN ./install.sh
|
|
WORKDIR /workdir
|
|
RUN ln -s ${venvpath}/bin/* /usr/local/bin/
|
|
#CMD ["bash", "--rcfile", "${venvpath}/bin/activate"]
|
|
CMD ["bash"]
|
|
EOF
|
|
} > "${venvpath}/etc/Dockerfile"
|
|
|
|
## /bin/docker
|
|
{
|
|
cat << EOF
|
|
docker build -f "${venvpath}/etc/Dockerfile" --tag="${docker_tag}"
|
|
docker run -v "${venvpath}":"${venvpath}" -it "${docker_tag}"
|
|
EOF
|
|
} > "${venvpath}/bin/docker"
|
|
chmod +x "${venvpath}/bin/docker"
|
|
|
|
## Set scheme commands
|
|
|
|
if [ "${rnrs}" = "r6rs" ]; then
|
|
## R6RS
|
|
case "${implementation}" in
|
|
"capyscheme")
|
|
scheme_cmd="capy --r6rs -L \"${venvpath}/lib\" --script \"\${IF}\""
|
|
;;
|
|
"chezscheme")
|
|
if command -v chezscheme >/dev/null 2>&1
|
|
then
|
|
scheme_cmd="chezscheme --libdirs ${venvpath}/lib/.akku/lib --program \"\${IF}\""
|
|
else
|
|
scheme_cmd="scheme --libdirs \"${venvpath}/lib/.akku/lib\" --program \"\${IF}\""
|
|
fi
|
|
;;
|
|
"guile")
|
|
scheme_cmd="guile --r6rs -x .sls -L \"${venvpath}/lib/.akku/lib\" -s \"\${IF}\""
|
|
;;
|
|
"ikarus")
|
|
scheme_cmd="IKARUS_LIBRARY_PATH=\"${venvpath}/lib/.akku/lib\" ikarus --r6rs-script \"\${IF}\""
|
|
;;
|
|
"ironscheme")
|
|
scheme_cmd="ironscheme -I \"${venvpath}/lib/.akku/lib\" \"\${IF}\""
|
|
;;
|
|
"larceny")
|
|
scheme_cmd="larceny -nobanner -quiet -utf8 -r6 -I \"${venvpath}/lib/.akku/lib\" \"\${IF}\""
|
|
;;
|
|
"loko")
|
|
scheme_cmd="LOKO_LIBRARY_PATH=\"${venvpath}/lib/.akku/lib\" loko --program \"\${IF}\""
|
|
scheme_compile_cmd="LOKO_LIBRARY_PATH=\"${venvpath}/lib/.akku/lib\" loko -o \"\${OF}\" --compile \"\${IF}\""
|
|
;;
|
|
"mosh")
|
|
scheme_cmd="mosh --loadpath=\"${venvpath}/lib/.akku/lib\" \"\${IF}\""
|
|
;;
|
|
"racket")
|
|
scheme_cmd="racket -I scheme/init -l r6rs/run.rkt -S \"${venvpath}/lib/.akku/lib\" \"\${IF}\""
|
|
;;
|
|
"sagittarius")
|
|
scheme_cmd="sash -r6 -L \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"ypsilon")
|
|
scheme_cmd="ypsilon --r6rs --sitelib \"${venvpath}/lib\" --top-level-program \"\${IF}\""
|
|
;;
|
|
*)
|
|
>&2 echo "Unsupported implementation RnRS combination: ${implementation} ${rnrs}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
echo "${scheme_script_cmd}" > "${venvpath}/bin/scheme-r6rs"
|
|
else
|
|
## R7RS
|
|
case "${implementation}" in
|
|
"capyscheme")
|
|
scheme_cmd="capy --r7rs -L \"${venvpath}/lib\" --script \"\${IF}\""
|
|
;;
|
|
"chibi")
|
|
scheme_cmd="chibi-scheme -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"chicken")
|
|
chicken_version=$(csi -version | grep "Version" | awk '{split($0,a," "); split(a[2],b,"."); print(b[1])}')
|
|
if [ "${chicken_version}" = "5" ]; then
|
|
#scheme_cmd="LD_LIBRARY_PATH=\"${venvpath}/lib\" csi -R r7rs -I \"${venvpath}/lib\" -script \"\${IF}\""
|
|
scheme_cmd="echo \"Chicken script not supported\" && exit 1"
|
|
scheme_compile_cmd="csc -static -X r7rs -R r7rs -o \"\${OF}\" \"\${IF}\""
|
|
else
|
|
#scheme_cmd="LD_LIBRARY_PATH=\"${venvpath}/lib\" csi -I \"${venvpath}/lib\" -script \"\${IF}\""
|
|
scheme_cmd="echo \"Chicken script not supported\" && exit 1"
|
|
scheme_compile_cmd="csc -static -o \"\${OF}\" \"\${IF}\""
|
|
fi
|
|
;;
|
|
"cyclone")
|
|
scheme_cmd="CYCLONE_LIBRARY_PATH=\"${venvpath}/lib\" icyc -I \"${venvpath}/lib\" \"\${IF}\""
|
|
scheme_compile_cmd="CYCLONE_LIBRARY_PATH=\"${venvpath}/lib\" cyclone -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"foment")
|
|
scheme_cmd="foment -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"gambit")
|
|
scheme_cmd="gsi \"${venvpath}/lib/\" \"\${IF}\""
|
|
#scheme_compile_cmd="gsc -o \"\${OF}\" -exe -nopreload \"${venvpath}/lib/\" \"\${IF}\""
|
|
scheme_compile_cmd="echo \"Gambit compiler not supported\" && exit 1"
|
|
;;
|
|
"gauche")
|
|
scheme_cmd="gosh -r7 -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"guile")
|
|
#scheme_cmd="guile --r7rs -x .sld -C \"${venvpath}/lib\" -L \"${venvpath}/lib\" -s \"\${IF}\""
|
|
scheme_cmd="echo \"Guile script not supported\" && exit 1"
|
|
scheme_compile_cmd="echo \"Guile compiler not supported\" && exit 1"
|
|
;;
|
|
"kawa")
|
|
scheme_cmd="kawa --r7rs --full-tailcalls -Dkawa.import.path=\"${venvpath}/lib/*.sld\" \"\${IF}\""
|
|
;;
|
|
"larceny")
|
|
scheme_cmd="larceny -nobanner -quiet -utf8 -r7 -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"loko")
|
|
scheme_cmd="LOKO_LIBRARY_PATH=\"${venvpath}/lib\" loko -std=r7rs --program \"\${IF}\""
|
|
scheme_compile_cmd="LOKO_LIBRARY_PATH=\"${venvpath}/lib\" loko -std=r7rs -o \"\${OF}\" --compile \"\${IF}\""
|
|
;;
|
|
"meevax")
|
|
scheme_cmd="meevax -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"mit-scheme")
|
|
scheme_cmd="mit-scheme --prepend-library=\"${venvpath}/lib/\" --batch-mode --load \"\${IF}\" --eval \"(exit 0)\" --args"
|
|
#scheme_cmd="echo \"MIT-scheme script not supported\" && exit 1"
|
|
scheme_compile_cmd="echo \"MIT-scheme compile not supported\" && exit 1"
|
|
;;
|
|
"mosh")
|
|
scheme_cmd="mosh --loadpath=\"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"racket")
|
|
scheme_cmd="racket -I r7rs -S \"${venvpath}/lib\" --script \"\${IF}\""
|
|
;;
|
|
"sagittarius")
|
|
scheme_cmd="sash -r7 -L \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"skint")
|
|
scheme_cmd="skint -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"stklos")
|
|
scheme_cmd="stklos -I \"${venvpath}/lib\" \"\${IF}\""
|
|
;;
|
|
"tr7")
|
|
scheme_cmd="TR7_LIB_PATH=\"${venvpath}/lib:\${TR7_LIB_PATH}\" tr7i -1 \"\${IF}\""
|
|
;;
|
|
"ypsilon")
|
|
scheme_cmd="ypsilon --r7rs --sitelib \"${venvpath}/lib\" --top-level-program \"\${IF}\""
|
|
;;
|
|
*)
|
|
>&2 echo "Unsupported implementation RnRS combination: ${implementation} ${rnrs}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
echo "${scheme_script_cmd}" > "${venvpath}/bin/scheme-r7rs"
|
|
fi
|
|
|
|
## bin/scheme-script
|
|
{
|
|
echo "#!/bin/sh"
|
|
echo "if [ \"\${1}\" = \"\" ]; then echo 'scheme-venv (${implementation} ${rnrs}) Give script file as argument' && exit 1; fi"
|
|
echo "if [ \"\${1}\" = \"--help\" ]; then echo 'scheme-venv (${implementation} ${rnrs}) Give script file as argument' && exit 1; fi"
|
|
echo "IF=\"\${1}\""
|
|
echo "shift"
|
|
echo "${scheme_cmd} \"\$@\""
|
|
} > "${venvpath}/bin/scheme-script"
|
|
chmod +x "${venvpath}/bin/scheme-script"
|
|
|
|
## bin/scheme-compile
|
|
if [ "${scheme_type}" = "interpreter" ]; then
|
|
{
|
|
echo "#!/bin/sh"
|
|
echo "IF=\"\$(realpath \"\${1}\")\""
|
|
echo "if [ \"${rnrs}\" = \"r6rs\" ]; then OF=\"\${IF%.sps}\"; else OF=\"\${IF%.scm}\"; fi"
|
|
# shellcheck disable=SC2028
|
|
echo "printf \"\n#|\nexec ${venvpath}/bin/scheme-script \\\"\\\${0}\\\" \\\"\\\$@\\\"\n|#\n\" > \"\${OF}\""
|
|
echo "cat \"\${IF}\" >> \"\${OF}\""
|
|
echo "chmod +x \"\${OF}\""
|
|
} > "${venvpath}/bin/scheme-compile"
|
|
chmod +x "${venvpath}/bin/scheme-compile"
|
|
else
|
|
{
|
|
echo "#!/bin/sh"
|
|
echo "IF=\$(realpath \"\${1}\")"
|
|
echo "if [ \"${rnrs}\" = \"r6rs\" ]; then OF=\"\${IF%.sps}\"; else OF=\"\${IF%.scm}\"; fi"
|
|
echo "cd ${venvpath}/lib"
|
|
echo "${scheme_compile_cmd}"
|
|
} > "${venvpath}/bin/scheme-compile"
|
|
chmod +x "${venvpath}/bin/scheme-compile"
|
|
fi
|
|
|
|
|
|
## bin/snow-chibi
|
|
impls=${implementation}
|
|
if [ "${rnrs}" = "r6rs" ]; then
|
|
impls=generic
|
|
fi
|
|
|
|
{
|
|
cat << EOF
|
|
#!/bin/sh
|
|
if [ "\${1}" = "install" ]; then
|
|
shift
|
|
snow-chibi \
|
|
install \
|
|
--impls=${impls} \
|
|
--install-source-dir=${venvpath}/lib \
|
|
--install-library-dir=${venvpath}/lib \
|
|
--install-data-dir=${venvpath}/lib \
|
|
--install-binary-dir=${venvpath}/bin \
|
|
"\$@"
|
|
else
|
|
snow-chibi "\$@"
|
|
fi
|
|
EOF
|
|
} > "${venvpath}/bin/snow-chibi"
|
|
chmod +x "${venvpath}/bin/snow-chibi"
|
|
|
|
## bin/akku
|
|
{
|
|
cat << EOF
|
|
#!/bin/sh
|
|
cd "${venvpath}/lib"
|
|
akku \$@
|
|
EOF
|
|
} > "${venvpath}/bin/akku"
|
|
chmod +x "${venvpath}/bin/akku"
|
|
|
|
|
|
## /bin/scheme-venv-info
|
|
{
|
|
cat << EOF
|
|
#!/bin/sh
|
|
echo "Scheme: ${implementation}"
|
|
echo "RNRS: ${rnrs}"
|
|
EOF
|
|
} > "${venvpath}/bin/scheme-venv-info"
|
|
chmod +x "${venvpath}/bin/scheme-venv-info"
|
|
|
|
echo "Initialized scheme-venv ${venvpath}, with ${implementation} and ${rnrs}"
|