Simplify the install process.

The installation script does not try anymore to create a virtual environment.
A message at the begining recommends to the user to be in a virtual env. That way
it is possible to use virtualenv, conda, python - m venv or none of this to
create (or not) a virtual environment. It's up to the user.

The script is simpler and *should* be POSIX compliant

Files that have been modified in this commit:
- Makefile
- src/Makefile
- src/msspec/spec/fortran/Makefile
- src/msspec/phagen/fortran/Makefile
- src/install.sh
This commit is contained in:
Sylvain Tricot 2019-11-28 18:35:37 +01:00
parent 4a5f6f1161
commit 4eceb1bf26
5 changed files with 150 additions and 281 deletions

View File

@ -1,34 +1,28 @@
MAKESELF:=makeself
#LICENSE:=$(cat ./license.txt)
#VERSION:=$(shell cd src && python -c "import msspec; print(msspec.__version__)")
VERSION:=$(shell git describe|sed 's/-\([[:digit:]]\+\)-.*/\.post\1/')
SETUPFILE:=MsSpec-$(VERSION).setup
.PHONY: clean purge version selfex
VERBOSE:=0
ifeq ($(VERBOSE),0)
SUPPRESS_OUPUT:=1>/dev/null 2>/dev/null
MAKEFLAGS += --no-print-directory
else
SUPPRESS_OUPUT:=
endif
clean:
@echo "Cleaning all..."
@find ./src -type f -name '*.pyc' -exec rm -f {} +
@find ./src -type d -name '__pycache__' -exec rm -rf {} +
+$(MAKE) -C src/ clean
+$(MAKE) -C doc/ clean
version:
@python ./CI/update_version.py
.PHONY: clean version selfex
purge: clean
@echo "Purging all..."
@rm -rf *.setup
+$(MAKE) -C src/ purge
selfex:
selfex: clean
@echo "Creating the self-extractible setup program... "
# update the version
# update the version
@cp ./src/msspec/version.py ./src/msspec/version.py.bak
@echo "__version__ = \"$(VERSION)\"" > ./src/msspec/version.py
# create the *.lsm file
# create the package folder
@mkdir -p package
# create the *.lsm file
@echo "Begin4" > msspec.lsm
@echo "Title: Python MsSpec" >> msspec.lsm
@echo "Version: $(VERSION)" >> msspec.lsm
@ -43,7 +37,22 @@ selfex:
@echo "Platforms:" >> msspec.lsm
@echo "Copying-policy: Gnu Library General Public License (GLPL) 2.0" >> msspec.lsm
@echo "End" >> msspec.lsm
$(MAKESELF) --license "./license.txt" --lsm ./msspec.lsm ./src $(SETUPFILE) "Python MsSpec" ./install.sh
# create the self-extractible archive
@$(MAKESELF) --license "./license.txt" --lsm ./msspec.lsm ./src package/$(SETUPFILE) "Python MsSpec" ./install.sh $(SUPPRESS_OUPUT)
# restore previous version.py file and remove *.lsm file
@mv ./src/msspec/version.py.bak ./src/msspec/version.py
@rm ./msspec.lsm
version:
@python ./CI/update_version.py
clean:
@echo "Cleaning all..."
@find ./src -type f -name '*.pyc' -exec rm -f {} +
@find ./src -type d -name '__pycache__' -exec rm -rf {} +
@rm -rf src/dist
@rm -rf src/*.egg*
@+$(MAKE) -C src/ clean $(SUPPRESS_OUPUT)
@+$(MAKE) -C doc/ clean $(SUPPRESS_OUPUT)
@rm -rf package

View File

@ -1,22 +1,42 @@
VERSION:=$(shell python -c "import msspec; print(msspec.__version__)")
VERBOSE:=0
ifeq ($(VERBOSE),0)
SUPPRESS_OUPUT:=1>/dev/null 2>/dev/null
MAKEFLAGS += --no-print-directory --silent
else
SUPPRESS_OUPUT:=
endif
install: sdist
@pip install dist/msspec-$(VERSION).tar.gz
@pip install dist/msspec-$(VERSION).tar.gz $(SUPPRESS_OUPUT)
sdist: pybinding
@python setup.py sdist
@echo "Creating Python source distribution..."
@python setup.py sdist $(SUPPRESS_OUPUT)
pybinding:
+$(MAKE) -C msspec/spec/fortran pybinding
+$(MAKE) -C msspec/phagen/fortran pybinding
@echo "Building Python binding for phagen and spec..."
@+$(MAKE) -C msspec/spec/fortran pybinding $(SUPPRESS_OUPUT)
@+$(MAKE) -C msspec/phagen/fortran pybinding $(SUPPRESS_OUPUT)
results: pybinding
@echo "Generating results for unittests"
@python -c "from msspec.tests import create_tests_results; create_tests_results()" $(SUPPRESS_OUPUT)
tests: pybinding
@echo "Runing unittests"
@python -c "from msspec.tests import run_tests; run_tests()" 1>/dev/null
clean:
+$(MAKE) -C msspec/spec/fortran clean
+$(MAKE) -C msspec/phagen/fortran clean
@echo "Cleaning all..."
@+$(MAKE) -C msspec/spec/fortran clean $(SUPPRESS_OUPUT)
@+$(MAKE) -C msspec/phagen/fortran clean $(SUPPRESS_OUPUT)
# remove previous sdist
@rm -rf dist
@rm -rf *.egg*
purge: clean
+$(MAKE) -C msspec/spec/fortran purge
+$(MAKE) -C msspec/phagen/fortran purge
help:
@echo "help message"

View File

@ -1,48 +1,40 @@
#!/bin/bash
#!/bin/sh
# vim: set ts=4 sw=4 sts noet mouse=a fdm=indent:
DEFAULT_DEST="${HOME}/.local/share"
DEFAULT_BIN="${HOME}/.local/bin"
BYPASS="n"
DEBUG="n"
SCRIPT_NAME=$(basename "$0")
PYTHON=python3
VERSION=$(cat ./msspec/version.py|cut -d\" -f2)
TIMEOUT=5
DEST_ALREADY_EXISTS="n"
ECHO="/bin/echo -e"
DATE=$(date +%Y%m%d_%H%M%S)
LOGFILE="${HOME}/msspec_install_${DATE}.log"
GETOUTFILE=$(mktemp)
LOCALBIN=$HOME/.local/bin
LINUX_OS="other_linux"
trap "abort_install" 2
trap "error_exit" 1 3 4 6
trap "abort_install" INT
trap "error_exit" HUP QUIT ILL ABRT
init_install () {
${ECHO} "Installation started on $(date)" > ${LOGFILE}
${ECHO} "0" > ${GETOUTFILE}
get_os
printf "Installation started on %s\n" "$(date)" > "${LOGFILE}"
printf "0" > "${GETOUTFILE}"
if [ "$BYPASS" = "n" ]; then
${ECHO} ""
${ECHO} "This program will install the MsSpec distribution on your computer"
${ECHO} -n "Press C^c to cancel now... "
for i in $(seq -s" " 0 $TIMEOUT); do
${ECHO} -n "\b";
${ECHO} -n $(( $TIMEOUT-i ));
sleep 1;
done
${ECHO} ""
printf ""
printf "This program will install the msspec python package on your system.\n"
printf "It is highly recommended to run this installation process within a\n"
printf "Python virtual environment. If you want to create and/or activate one,\n"
printf "you can answer \"n\" now and restart the setup program later.\n"
read_yes_no "Do you wish to continue" "y"
case "${ANSWER}" in
y) ;;
n) abort_install ;;
esac
fi
}
abort_install () {
${ECHO} "Installation aborted by the user" >> ${LOGFILE}
log_message "Installation aborted by the user"
error_exit
}
@ -57,60 +49,41 @@ log_message2 () {
}
cleanup () {
stty echo
rm -rf ${GETOUTFILE}
rm -rf "${GETOUTFILE}"
}
error_exit () {
# An error occured
printf "\n"
printf " /!\ An error occured during the installation process.\n"
printf " Please see the $(basename ${LOGFILE}) file in your HOME folder\n"
printf " Please see the %s file in your HOME folder\n" "$(basename "${LOGFILE}")"
printf " for more informations.\n"
printf " Below is an excerpt of the last 10 lines:\n"
printf "\n"
tail -v -n 10 "${LOGFILE}"
tail "${LOGFILE}"
# uninstall if needed
pip uninstall -y msspec
# if the DEST_FOLDER existed before, do NOT delete it
if [ x"$DEST_ALREADY_EXISTS" = "xn" ]; then
rm -rf ${DEST_FOLDER} 2>/dev/null
fi
cleanup && exit 1
}
get_os () {
for os in "ubuntu" "mageia" "archlinux"; do
cat /etc/*release /etc/*version /etc/*issue 2>/dev/null | grep -i "$os" 2>/dev/null 1>/dev/null
if test $? -eq 0; then
LINUX_OS="$os"
break
fi
done
}
read_yes_no () {
DEFAULT="$2"
PROMPT="$1 (y/n) [${DEFAULT}]? "
ANSWER=""
RESPONSE=""
INPUT=""
VALID=1
while test $VALID -ne 0; do
printf "${PROMPT}"
if [ x"$BYPASS" = "xn" ]; then
read "RESPONSE"
printf "%s" "${PROMPT}"
if [ x"$BYPASS" = xn ]; then
read -r "INPUT"
else
printf "\n"
fi
ANSWER="${RESPONSE:-${DEFAULT}}"
ANSWER="${INPUT:-${DEFAULT}}"
case "${ANSWER}" in
y|n) VALID=0 ;;
*) printf "Invalid choice, please answer \"y\" or \"n\".\n"; VALID=1 ;;
@ -120,57 +93,13 @@ read_yes_no () {
log_message "ANSWER : $ANSWER"
}
read_folder () {
DEFAULT="$2"
PROMPT="$1 [${DEFAULT}]: "
ANSWER=""
unset FOLDER
printf "${PROMPT}"
if [ x"$BYPASS" = "xn" ]; then
read "ANSWER"
else
printf "\n"
fi
export FOLDER="${ANSWER:-$DEFAULT}"
log_message "QUESTION: $PROMPT"
log_message "ANSWER : $FOLDER"
}
create_folder () {
FOLDER="$1"
ERR_MKDIR=1
ERR_ABORT=2
ERR_PERMS=3
if ! test -d "${FOLDER}" ; then
read_yes_no "The folder \"${FOLDER}\" does not exist. Should I create it" "y" #"$BYPASS"
case "${ANSWER}" in
y) mkdir -p "${FOLDER}" 2>>${LOGFILE} 1>>${LOGFILE} || return $ERR_MKDIR;;
n) log_message2 "Installation aborted by the user" && return $ERR_ABORT ;;
esac
fi
if ! test -w "${FOLDER}" ; then
log_message2 "You do not have permission to write into \"${FOLDER}\"."
return $ERR_PERMS
fi
}
wrap () {
log_message "================================================================================"
log_message "$2"
log_message "================================================================================"
if [ "$DEBUG" = "y" ]; then
eval "($1) 2>&1" | tee -a ${LOGFILE}
echo ${PIPESTATUS[0]} >${GETOUTFILE}
if [ "$DEBUG" = y ]; then
printf "%s...\n" "$2"
(eval "$1" || echo $? >"${GETOUTFILE}") | tee -a "${LOGFILE}"
rc=$(cat $GETOUTFILE)
if [ $rc != 0 ]; then
error_exit
@ -181,60 +110,38 @@ wrap () {
fi
}
update_path () {
# check if the shell path contains $BIN_FOLDER
SHELLRC="$HOME/.$(basename $SHELL)rc"
${ECHO} "$PATH" | grep "${BIN_FOLDER}" 2>/dev/null 1>/dev/null
if test $? -ne 0; then
${ECHO} "" >> $SHELLRC
${ECHO} "# Add the user's local binary folder" >> $SHELLRC
${ECHO} "export PATH=${BIN_FOLDER}:\$PATH" >> $SHELLRC
${ECHO} "Your PATH variable has been updated, the folder"
${ECHO} "${BIN_FOLDER} has been added to it."
${ECHO} ""
${ECHO} "Please source again your shell configuration file by typing:"
${ECHO} "source $SHELLRC"
fi
}
success_message () {
log_message "========================================================"
log_message "MsSpec was successfully installed."
log_message "========================================================"
}
patience () {
MSG=$1
MSG="$1"
PID=$!
i=0
${ECHO} -n "$MSG... "
printf "%s" "$MSG... "
while ps -p $PID > /dev/null
do
sleep 0.1
case $i in
0) ${ECHO} -n "\b\b- " ;;
1) ${ECHO} -n "\b\b\\ " ;;
2) ${ECHO} -n "\b\b| " ;;
3) ${ECHO} -n "\b\b/ "; i=-1 ;;
0) printf "\b\b- " ;;
1) printf "\b\b\\ " ;;
2) printf "\b\b| " ;;
3) printf "\b\b/ "; i=-1 ;;
esac
i=$((i+1))
i=$(( i+1 ))
done
if test $(cat ${GETOUTFILE}) -ne 0; then
${ECHO} "\b\b Aborted!"
if test "$(cat "${GETOUTFILE}")" -ne 0; then
printf "\b\b Aborted!"
error_exit
fi
${ECHO} "\b\b Done."
printf "\b\b Done.\n"
}
show_help () {
echo "Usage: $SCRIPT_NAME [OPTIONS]"
echo "List of possible options:"
echo " -p FOLDER Default FOLDER for installation."
echo " -b FOLDER Default FOLDER for binaries."
echo " -y Accept all default choices."
echo " -d Debug mode."
echo " -h Show this message."
@ -254,7 +161,7 @@ check_dependencies () {
command -V gfortran || return 1
gcc_ver=$(gcc -dumpversion)
echo "You have gfortran version $gcc_ver installed"
test $gcc_ver -ge $gcc_ver_min || return 1
test "$gcc_ver" -ge "$gcc_ver_min" || return 1
log_message "Ok\n"
# we need libcairo and dev files
@ -266,20 +173,19 @@ check_dependencies () {
py_ver_major_min=3
py_ver_minor_min=0
log_message "Checking if Python >= ${py_ver_major_min}.${py_ver_minor_min}..."
message="You need Python version ${py_ver_major_min}.${py_ver_minor_min}"
python --version|cut -d" " -f2 || return 1
command -V python || return 1
py_ver=$(python --version | cut -d" " -f2)
echo "You have Python version $py_ver installed"
py_ver_major=$(echo $py_ver|cut -d. -f1)
py_ver_minor=$(echo $py_ver|cut -d. -f2)
test $py_ver_major -ge $py_ver_major_min || return 1
test $py_ver_minor -ge $py_ver_minor_min || return 1
test "$py_ver_major" -ge "$py_ver_major_min" || return 1
test "$py_ver_minor" -ge "$py_ver_minor_min" || return 1
log_message "Ok\n"
# we need virtualenv
log_message "Checking if virtualenv is installed..."
command -V virtualenv || return 1
log_message "Ok\n"
#log_message "Checking if virtualenv is installed..."
#command -V virtualenv || return 1
#log_message "Ok\n"
}
@ -290,91 +196,24 @@ local_install () {
# check dependencies
wrap "check_dependencies" "Checking dependencies"
# ask for a place to put the binary
#read_folder "Please, type in the folder where to place the binary" "${DEFAULT_BIN}"
#BIN_FOLDER=${FOLDER}
#create_folder "${BIN_FOLDER}" || error_exit
#export BIN_FOLDER
# build the Fortran code
wrap "make pybinding VERBOSE=1" "Building Phagen and Spec Python dynamic library"
# If in a virtualenv, ask if we should install inside
if [ x"$VIRTUAL_ENV" != x ]; then
read_yes_no "You are running a Python virtual environment. Do you wish to install msspec inside ?" "y"
case ${ANSWER} in
y) # get the python version of this venv...
v=$(python -V 2>&1 | cut -d" " -f2 | cut -d. -f1)
# and stops if < 3
if [ $v -lt 3 ]; then
log_message "The Python version of this venv is < 3"
error_exit
fi
;;
n) # The user decided to stop there
log_message "Please deactivate your virtual environment and restart the setup program."
error_exit
;;
esac
# Else, we are not in a virtualenv
else
pip_opt=""
# so ask if we should create one
read_yes_no "Do you wish to create a virtual environment to install MsSpec inside" "y"
case ${ANSWER} in
y) # Create the destination folder
read_folder "Please, type in the base installation folder" "${DEFAULT_DEST}"
DEST_FOLDER=${FOLDER}/MsSpec-${VERSION}
if [ -d $DEST_FOLDER ]; then
export DEST_ALREADY_EXISTS="y" # to avoid cleaning the existing DEST_FOLDER in case of any problem
read_yes_no "The folder $DEST_FOLDER already exists. Overwrite" "y"
case ${ANSWER} in
y) # overwrite
create_folder "${DEST_FOLDER}" || error_exit
;;
n) # stop here otherwise
error_exit
;;
esac
fi
export DEST_FOLDER
wrap "virtualenv -vvv --python=${PYTHON} --system-site-packages --prompt=\"(msspec-${VERSION}) \" ${DEST_FOLDER}/venv" \
"Create a Python virtual environment"
. ${DEST_FOLDER}/venv/bin/activate
;;
n) # install in the user $HOME
pip_opt="--user"
;;
esac
fi
# build the source distribution
wrap "make sdist VERBOSE=1" "Building msspec python package"
# build and run setuptools to create a source distribution
wrap "make sdist" \
"Building MsSpec python package"
# install the package
wrap "make install VERBOSE=1" "Installing the msspec package"
# install the package with pip
wrap "pip install $pip_opt dist/msspec-*.tar.gz" \
"Installing pymsspec python package and its dependencies"
#
## move the frontend to the binary folder
##wrap "mkdir -p ${LOCALBIN} && \
## cp ./msspec ${LOCALBIN} && chmod u+x ${LOCALBIN}/msspec && \
## ${ECHO} \"msspec installed in ${LOCALBIN}\"" \
## "Installing the msspec frontend"
# "cp ./msspec ${BIN_FOLDER} && chmod ugo+rx ${BIN_FOLDER}/msspec" "Installing the msspec frontend"
#
## move the uninstal script
#wrap "cp ./uninstall.sh ${DEST}" "Moving the uninstall script"
#
# Run unit tests ?
read_yes_no "Do you wish to run unit tests (${LOGFILE})" "y"
if [ x"${ANSWER}" = "xy" ]; then
wrap "python -c \"from msspec.tests import run_tests; run_tests()\"" \
"Runing test suite"
read_yes_no "Do you wish to run unit tests" "y"
if [ x"${ANSWER}" = xy ]; then
wrap "make tests" "Runing test suite"
fi
# installation was a succes so ask if we keep the log file
read_yes_no "Do you wish to keep the log file (${LOGFILE})" "n"
if [ x"${ANSWER}" = "xn" ]; then
if [ x"${ANSWER}" = xn ]; then
rm -f "${LOGFILE}"
fi
@ -382,15 +221,9 @@ local_install () {
success_message
}
while getopts "p:b:yd" option
do
case $option in
p) export DEFAULT_DEST="$OPTARG"
;;
b) export DEFAULT_BIN="$OPTARG"
;;
y) export BYPASS="y"
;;
d) export DEBUG="y"
@ -402,7 +235,4 @@ do
esac
done
local_install

View File

@ -1,31 +1,35 @@
COMP=gfortran
OPTS := -g -Wall -Wextra -Warray-temporaries -Wconversion -fbacktrace -ffree-line-length-0 -fcheck=all -ffpe-trap=zero,overflow,underflow -finit-real=nan
OPTs :=
F2PY:=f2py3
COMP_OPTS:= -O2 -ffast-math
F2PY_OPTS:=
DEBUG:=0
objects_src := phagen_scf.f
objects := $(patsubst %.f,%.o, $(objects_src))
ifeq ($(DEBUG),1)
COMP_OPTS:=$(COMP_OPTS) -g -Wall -Wextra -Warray-temporaries -Wconversion -fbacktrace -ffree-line-length-0 -fcheck=all -ffpe-trap=zero,overflow,underflow -finit-real=nan
F2PY_OPTS:=$(F2PY_OPTS) --debug-capi --debug
endif
.PHONY: clean purge pybinding
.PHONY: clean
pybinding: libphagen.so
libphagen.so: $(objects) main.f
@echo "building Python binding..."
@f2py3 -I. $(objects) -c -m libphagen main.f
#f2py3 -I. $(objects) --debug-capi --debug -c -m libphagen main.f
@$(F2PY) -I. $(objects) $(F2PY_OPTS)-c -m libphagen main.f
@cp libphagen.cpython*.so ../
@mv libphagen.cpython*.so libphagen.so
$(objects): $(objects_src)
@echo "compiling subroutines and functions..."
@$(COMP) $(OPTS) -fPIC -c $^
@echo "compiling subroutines and functions for phagen..."
@$(COMP) $(COMP_OPTS) -fPIC -c $^
clean:
@echo "cleaning..."
rm -rf *.so *.o *.mod
purge: clean
@echo "Purging..."
rm -rf ../*.so
@rm -rf *.so *.o *.mod
@rm -rf ../*.so

View File

@ -1,21 +1,30 @@
COMP=gfortran
COMP:=gfortran
F2PY:=f2py3
COMP_OPTS:= -O2 -ffast-math
F2PY_OPTS:=
DEBUG:=0
objects_src := dim_mod.f modules.f renormalization.f allocation.f spec.f
objects := $(patsubst %.f,%.o, $(objects_src))
OPTS := -g -Wall -Wextra -Warray-temporaries -Wconversion -fbacktrace -ffree-line-length-0 -fcheck=all -ffpe-trap=zero,overflow,underflow -finit-real=nan
EXE=prog
ifeq ($(DEBUG),1)
COMP_OPTS:=$(COMP_OPTS) -g -Wall -Wextra -Warray-temporaries -Wconversion -fbacktrace -ffree-line-length-0 -fcheck=all -ffpe-trap=zero,overflow,underflow -finit-real=nan
F2PY_OPTS:=$(F2PY_OPTS) --debug-capi --debug
endif
.PHONY: clean purge pybinding
.PHONY: clean
pybinding: libspec.so
libspec.so: $(objects) main.f
@echo "building Python binding..."
#@f2py3 -I. $(objects) -c -m libspec main.f
@f2py3 -I. $(objects) --debug-capi --debug -c -m libspec main.f
@$(F2PY) -I. $(objects) $(F2PY_OPTS) -c -m libspec main.f
@cp libspec.cpython*.so ../
@mv libspec.cpython*.so libspec.so
@ -26,16 +35,13 @@ exe: $(objects) prog.f
$(objects): $(objects_src)
@echo "compiling subroutines and functions..."
#$(COMP) -cpp -fPIC -O2 -ffast-math -mcmodel=large -fdefault-real-4 -c $^
#@$(COMP) $(OPTS) -fPIC -mcmodel=large -c $^
@$(COMP) $(OPTS) -fPIC -c $^
@echo "compiling subroutines and functions for spec..."
# $(COMP) -cpp -fPIC -O2 -ffast-math -mcmodel=large -fdefault-real-4 -c $^
# @$(COMP) $(OPTS) -fPIC -mcmodel=large -c $^
@$(COMP) $(COMP_OPTS) -fPIC -c $^
clean:
@echo "cleaning..."
@rm -rf *.so *.o *.mod
purge: clean
@echo "Purging..."
@rm -rf $(EXE)
@rm -rf ../*.so