From 4eceb1bf2646064ee6dec02b5972599e4c379c4f Mon Sep 17 00:00:00 2001 From: Sylvain Tricot Date: Thu, 28 Nov 2019 18:35:37 +0100 Subject: [PATCH] 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 --- Makefile | 51 +++--- src/Makefile | 38 +++- src/install.sh | 280 ++++++----------------------- src/msspec/phagen/fortran/Makefile | 30 ++-- src/msspec/spec/fortran/Makefile | 32 ++-- 5 files changed, 150 insertions(+), 281 deletions(-) diff --git a/Makefile b/Makefile index 5d76615..e4fa355 100644 --- a/Makefile +++ b/Makefile @@ -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 + diff --git a/src/Makefile b/src/Makefile index 3ddcfb8..b48a36d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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" diff --git a/src/install.sh b/src/install.sh index 169f653..ea4cfe8 100755 --- a/src/install.sh +++ b/src/install.sh @@ -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 with pip - wrap "pip install $pip_opt dist/msspec-*.tar.gz" \ - "Installing pymsspec python package and its dependencies" + # install the package + wrap "make install VERBOSE=1" "Installing the msspec package" -# -## 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 diff --git a/src/msspec/phagen/fortran/Makefile b/src/msspec/phagen/fortran/Makefile index 6e409f7..b6b4528 100644 --- a/src/msspec/phagen/fortran/Makefile +++ b/src/msspec/phagen/fortran/Makefile @@ -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 diff --git a/src/msspec/spec/fortran/Makefile b/src/msspec/spec/fortran/Makefile index ea07511..cba5c62 100644 --- a/src/msspec/spec/fortran/Makefile +++ b/src/msspec/spec/fortran/Makefile @@ -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