Last active
October 23, 2020 23:29
-
-
Save JCGoran/e39c14ee6fdb03b4b405834ddf3d0be4 to your computer and use it in GitHub Desktop.
Script for building and running cadmus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# a POSIX-compatible shell script that builds cadmus the easy way | |
# requirements: | |
# - git | |
# - python3 (with pip and venv) | |
# - make | |
# - cmake | |
# - a C++ compiler (g++ will do) | |
# - pulseaudio | |
# - libGL (see for instance https://packages.debian.org/buster/libgl1) | |
# - one of the following shells: bash (default), zsh, tcsh, csh, fish | |
# on Debian- and Ubuntu- based distros, they can be installed using: | |
# apt-get install git python3-pip python3-venv make cmake g++ pulseaudio libgl1 | |
CADMUS_USAGE='USAGE: `${SHELL} [NAME_OF_THIS_FILE].sh [build|run]` while in some (preferably empty) directory' | |
# env variables | |
# the path to the global python interpreter | |
# this should work on all distros, as long as `python3` is a symlink to `python`, | |
# but in case `python3` doesn't exist, we fall back to `python` (and hope it's the right one) | |
PYTHON="$(command -v python3 || command -v python)" | |
# NOTE: this cadmus repo contains the fix for the slider | |
REPO_CADMUS="${REPO_CADMUS:-https://github.com/mmarsalko/cadmus}" | |
# dir where it will be cloned | |
DESTINATION_CADMUS="${DESTINATION_CADMUS:-cadmus}" | |
# noise suppression repo | |
REPO_NOISESUP="${REPO_NOISESUP:-https://github.com/werman/noise-suppression-for-voice}" | |
# where it will be cloned | |
DESTINATION_NOISESUP="${DESTINATION_NOISESUP:-noise-suppression}" | |
# name of the dir with the environment (subdir of $DESTINATION_CADMUS) | |
VENV_CADMUS="${VENV_CADMUS:-environment}" | |
# since ${SHELL} returns the full path of the shell, | |
# we need to do a string comparison instead | |
# taken from: | |
# https://stackoverflow.com/a/8811800 | |
contains(){ | |
string="$1" | |
substring="$2" | |
if test "${string#*$substring}" != "$string" | |
then | |
return 0 # $substring is in $string | |
else | |
return 1 # $substring is not in $string | |
fi | |
} | |
# main build script | |
build_cadmus(){ | |
# clone cadmus | |
git clone "${REPO_CADMUS}" "${DESTINATION_CADMUS}" | |
# add the noise-suppression-for-voice module | |
git -C "${DESTINATION_CADMUS}" submodule add "${REPO_NOISESUP}" "${DESTINATION_NOISESUP}" | |
# build the noise-suppression-for-voice library | |
# we only need the LADSPA plugin, which has no dependencies | |
cmake \ | |
-B"${DESTINATION_CADMUS}/${DESTINATION_NOISESUP}/build" \ | |
-H"${DESTINATION_CADMUS}/${DESTINATION_NOISESUP}" \ | |
-DCMAKE_BUILD_TYPE=Release \ | |
-DBUILD_VST_PLUGIN=NO \ | |
-DBUILD_LV2_PLUGIN=NO | |
make -j -C "${DESTINATION_CADMUS}/${DESTINATION_NOISESUP}/build" | |
# path to shared object file of the LADSPA plugin | |
# TODO: maybe we could use `find` in case it's not there anymore at some point? | |
PATH_RNNOISE_DEFAULT="${DESTINATION_CADMUS}/${DESTINATION_NOISESUP}/build/bin/ladspa/librnnoise_ladspa.so" | |
# path where it will be copied | |
PATH_LIB_CADMUS="${DESTINATION_CADMUS}/src/main/resources/base/" | |
# make sure the shared object file exists | |
if [ -e "${PATH_RNNOISE_DEFAULT}" ] | |
then | |
# copy it to the dir indicated in the README (first make it if it doesn't exist) | |
mkdir -p "${PATH_LIB_CADMUS}" | |
cp -a "${PATH_RNNOISE_DEFAULT}" "${PATH_LIB_CADMUS}" | |
else | |
# in case noise-suppression-for-voice doesn't build it in the right location | |
printf "Error: the file ${PATH_RNNOISE_DEFAULT} doesn't exist!\n" | |
return 1 | |
fi | |
# make the virtual environment (venv) in the dir `environment` (default name) | |
"${PYTHON}" -m venv "${DESTINATION_CADMUS}/${VENV_CADMUS}" | |
# activate the venv | |
# see table at: | |
# https://docs.python.org/3/library/venv.html | |
# for why we need so many checks for shells | |
# NOTE: this probably doesn't work on Windows | |
if contains "${SHELL}" "bash" || contains "${SHELL}" "zsh" | |
then | |
source "${DESTINATION_CADMUS}/${VENV_CADMUS}/bin/activate" | |
elif contains "${SHELL}" "fish" | |
then | |
. "${DESTINATION_CADMUS}/${VENV_CADMUS}/bin/activate.fish" | |
# the latter is probably redundant since "csh" is a substring of "tcsh" | |
elif contains "${SHELL}" "csh" || contains "${SHELL}" "tcsh" | |
then | |
source "${DESTINATION_CADMUS}/${VENV_CADMUS}/bin/activate.csh" | |
else | |
printf "Error: unknown shell ${SHELL}\n" | |
return 2 | |
fi | |
# check it's actually running | |
if [ -n "${VIRTUAL_ENV}" ] | |
then | |
# re-set python so it's the one INSIDE the venv (otherwise pip installs it OUTSIDE the venv) | |
PYTHON="$(command -v python3 || command -v python)" | |
# for the exported variable, see: | |
# https://github.com/pypa/pip/issues/6773#issuecomment-515857335 | |
export PYTHON_KEYRING_BACKEND="keyring.backends.null.Keyring" | |
# reset requirements without pinned versions | |
sed -i 's/==.*//g' "${DESTINATION_CADMUS}/requirements.txt" | |
# pin version of PyQt5 for older versions of pip, see: | |
# https://stackoverflow.com/a/59797479 | |
sed -i 's/^PyQt5$/PyQt5==5.14.0/' "${DESTINATION_CADMUS}/requirements.txt" | |
# also pin PyInstaller to avoid the fbs error | |
sed -i 's/^PyInstaller$/PyInstaller==3.4/' "${DESTINATION_CADMUS}/requirements.txt" | |
# install cadmus-specific dependencies, and don't use cache | |
"${PYTHON}" -m pip install wheel --no-cache | |
"${PYTHON}" -m pip install -r "${DESTINATION_CADMUS}/requirements.txt" --no-cache | |
else | |
# otherwise abort | |
printf "The venv is not activated!\n" | |
return 3 | |
fi | |
} | |
run_cadmus(){ | |
# check the dir exists | |
if [ -d "${DESTINATION_CADMUS}/${VENV_CADMUS}" ] | |
then | |
# activate the venv | |
# see table at: | |
# https://docs.python.org/3/library/venv.html | |
# for why we need so many checks for shells | |
# NOTE: this probably doesn't work on Windows | |
if contains "${SHELL}" "bash" || contains "${SHELL}" "zsh" | |
then | |
source "${DESTINATION_CADMUS}/${VENV_CADMUS}/bin/activate" | |
elif contains "${SHELL}" "fish" | |
then | |
. "${DESTINATION_CADMUS}/${VENV_CADMUS}/bin/activate.fish" | |
# the latter is probably redundant since "csh" is a substring of "tcsh" | |
elif contains "${SHELL}" "csh" || contains "${SHELL}" "tcsh" | |
then | |
source "${DESTINATION_CADMUS}/${VENV_CADMUS}/bin/activate.csh" | |
else | |
printf "Error: unknown shell ${SHELL}\n" | |
return 2 | |
fi | |
# check it's actually running | |
if [ -n "${VIRTUAL_ENV}" ] | |
then | |
# re-set python so it's the one INSIDE the venv | |
PYTHON="$(command -v python3 || command -v python)" | |
# run cadmus (inside the venv) | |
cd "${DESTINATION_CADMUS}" | |
"${PYTHON}" "src/main/python/main.py" | |
else | |
# otherwise abort | |
printf "The venv is not activated!\n" | |
return 3 | |
fi | |
else | |
printf "Error: the directory ${DESTINATION_CADMUS}/${VENV_CADMUS} doesn't exist; make sure you are in the correct directory and that you're ran '$0 build' beforehand!\n" | |
return 4 | |
fi | |
} | |
# option parser | |
parse_options(){ | |
if [ "$#" -ne 1 ] | |
then | |
printf "${CADMUS_USAGE}\n" | |
return 255 | |
else | |
case "$1" in | |
"build" ) | |
build_cadmus | |
;; | |
"run" ) | |
run_cadmus | |
;; | |
* ) | |
printf "Error: unknown command - '$1'\n" | |
return 254 | |
;; | |
esac | |
fi | |
} | |
parse_options "$@" |
Thanks @JCGoran for your kind response. Here's the current version of cadmus.sh that I have (between lines 129-146):
# the requirements are a bit bizarre, so we re-set them without pinned versions
#sed -i 's/==.*//g' "${DESTINATION_CADMUS}/requirements.txt"
# changes suggested by @AnonymerNiklasistanonym https://gist.github.com/JCGoran/e39c14ee6fdb03b4b405834ddf3d0be4#gistcomment-3468749
# some requirements are a bit old so we update them to more current versions
sed -i s/sip==4.19.8/sip==5.0.0/ "${DESTINATION_CADMUS}/requirements.txt"
sed -i s/PyQt5==5.9.2/PyQt5==5.14.2/ "${DESTINATION_CADMUS}/requirements.txt"
# install cadmus-specific dependencies
# NOTE: the following error, or a similar one, may appear:
# `fbs 0.9.0 has requirement PyInstaller==3.4, but you'll have pyinstaller 4.0 which is incompatible`
# this makes no difference to properly running cadmus
"${PYTHON}" -m pip install wheel
"${PYTHON}" -m pip install -r "${DESTINATION_CADMUS}/requirements.txt" --no-cache
else
# otherwise abort
printf "The venv is not activated!\n"
return 3
fi
I also applied changes from @AnonymerNiklasistanonym and still I get the same error 😞
Thanks @JCGoran for your kind response. Here's the current version of cadmus.sh that I have (between lines 129-146):
# the requirements are a bit bizarre, so we re-set them without pinned versions
#sed -i 's/==.*//g' "${DESTINATION_CADMUS}/requirements.txt"
# changes suggested by @AnonymerNiklasistanonym https://gist.github.com/JCGoran/e39c14ee6fdb03b4b405834ddf3d0be4#gistcomment-3468749
# some requirements are a bit old so we update them to more current versions
sed -i s/sip==4.19.8/sip==5.0.0/ "${DESTINATION_CADMUS}/requirements.txt"
sed -i s/PyQt5==5.9.2/PyQt5==5.14.2/ "${DESTINATION_CADMUS}/requirements.txt"
# install cadmus-specific dependencies
# NOTE: the following error, or a similar one, may appear:
# `fbs 0.9.0 has requirement PyInstaller==3.4, but you'll have pyinstaller 4.0 which is incompatible`
# this makes no difference to properly running cadmus
"${PYTHON}" -m pip install wheel
"${PYTHON}" -m pip install -r "${DESTINATION_CADMUS}/requirements.txt" --no-cache
else
# otherwise abort
printf "The venv is not activated!\n"
return 3
fi
I also applied changes from @AnonymerNiklasistanonym and still I get the same error 😞
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It is possible that the currently installed (and cached) version of PyQt5 on your machine is older than the one required by cadmus, but since the above script modifies the
requirements.txt
file so it doesn't have specific version requirements,pip
happily uses the cached versions.You could try to force
pip
not to use the cache, so it installs the latest version of PyQt5 (and others), you just need to change the following line (currently 136) from:into: