Permalink
Browse files

Install solvers to a relevant site-package by default (#517)

- if user has virtual environment activated, simply install solvers in
  virtualenv's site packages
- otherwise (debian's pip logic):
  - if user is root, install to system site/dist packages
  - else if user has user site enabled, install solvers user-local
  - otherwise, try installing to system site packages and probably
    fail.

* Update help/docs/readme to reflect new bindings dir
* New bindings dir default in solver installers
* Add pip-like default package location heuristic helper
* Add debian-like solver install location heuristic
* Installer creates bindings/install dir recursively
* Use default bindings dir in Travis/Appveyor tests
* Fix example runner in tests (no ls, no subshell)
* Patch python path for examples in tests
* CI: Caching venv
  • Loading branch information...
randomir authored and marcogario committed Sep 3, 2018
1 parent 14bfefd commit 20c377d31dba20ae3cde926fa2e3fcef3c64c93d
Showing with 125 additions and 43 deletions.
  1. +6 −1 .travis.yml
  2. +5 −8 README.rst
  3. +0 −6 appveyor.yml
  4. +9 −7 ci/travis_install.sh
  5. +18 −6 ci/travis_script.sh
  6. +9 −7 docs/getting_started.rst
  7. +10 −8 pysmt/cmd/install.py
  8. +68 −0 pysmt/cmd/installers/base.py
View
@@ -1,5 +1,9 @@
language: python
env:
global:
- PYSMT_CUSTOM_BINDINGS_PATH="FALSE"
matrix:
include:
- os: linux
@@ -243,7 +247,8 @@ cache:
directories:
- ${HOME}/.cache/pip
- ${HOME}/Library/Caches/Homebrew # For MacOSX
- ${HOME}/python_bindings
#- ${HOME}/python_bindings
- ${VIRTUAL_ENV}
addons:
View
@@ -200,15 +200,12 @@ The script *pysmt-install* can be used to simplify the installation of the solve
$ pysmt-install --msat
will install MathSAT 5. Once the installation is complete, you
can use the option ``--env`` to obtain a string to update your
``PYTHONPATH``::
will install MathSAT 5.
$ pysmt-install --env
export PYTHONPATH="/home/pysmt/.smt_solvers/python-bindings-2.7:${PYTHONPATH}"
By default the solvers are installed in your home directory in the
folder ``.smt_solvers``. ``pysmt-install`` has many options to
By default the solvers are downloaded, unpacked and built in your home directory
in the ``.smt_solvers`` folder. Compiled libraries and actual solver packages are
installed in the relevant ``site-packages`` directory (e.g. virtual environment's
packages root or local user-site). ``pysmt-install`` has many options to
customize its behavior.
*Note:* This script does not install required
View
@@ -68,12 +68,6 @@ install:
# Install the solvers
- cmd: "python install.py --confirm-agreement"
# Set and check the pythonpath
- cmd: "python install.py --env > bindings_path.bat"
- cmd: "call ./bindings_path.bat"
- ECHO "PythonPath=%PYTHONPATH%"
- ECHO "Path=%PATH%"
build: false
test_script:
View
@@ -60,13 +60,15 @@ fi
#
# Install Solvers
#
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER}_${TRAVIS_OS_NAME}"
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER_FOLDER//,/$'_'}"
export BINDINGS_FOLDER=${HOME}/python_bindings/${PYSMT_SOLVER_FOLDER}
mkdir -p ${BINDINGS_FOLDER}
python install.py --confirm-agreement --bindings-path ${BINDINGS_FOLDER}
eval `python install.py --env --bindings-path ${BINDINGS_FOLDER}`
if [ "${PYSMT_CUSTOM_BINDINGS_PATH}" == "TRUE" ]; then
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER}_${TRAVIS_OS_NAME}"
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER_FOLDER//,/$'_'}"
BINDINGS_FOLDER="${HOME}/python_bindings/${PYSMT_SOLVER_FOLDER}"
python install.py --confirm-agreement --bindings-path "${BINDINGS_FOLDER}"
eval "$(python install.py --env --bindings-path "${BINDINGS_FOLDER}")"
else
python install.py --confirm-agreement
fi
if [ "${PYSMT_SOLVER}" == "all" ] || [ "${PYSMT_SOLVER}" == *"z3_wrap"* ]; then
python install.py --z3 --conf --force;
View
@@ -35,12 +35,16 @@ fi
echo "Check that the correct version of Python is running"
python ${DIR}/check_python_version.py "${TRAVIS_PYTHON_VERSION}"
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER}_${TRAVIS_OS_NAME}"
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER_FOLDER//,/$'_'}"
export BINDINGS_FOLDER=${HOME}/python_bindings/${PYSMT_SOLVER_FOLDER}
# Update PYTHONPATH only if needed
if [ "${PYSMT_CUSTOM_BINDINGS_PATH}" == "TRUE" ]; then
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER}_${TRAVIS_OS_NAME}"
PYSMT_SOLVER_FOLDER="${PYSMT_SOLVER_FOLDER//,/$'_'}"
BINDINGS_FOLDER="${HOME}/python_bindings/${PYSMT_SOLVER_FOLDER}"
eval "$(python install.py --env --bindings-path "${BINDINGS_FOLDER}")"
fi
eval `python install.py --env --bindings-path ${BINDINGS_FOLDER}`
echo ${PYTHONPATH}
echo "${PYTHONPATH}"
python install.py --env
python install.py --check
#
@@ -60,5 +64,13 @@ if [ "${PYSMT_SOLVER}" == "all" ];
then
python install.py --msat --conf --force;
cp -v $(find ~/.smt_solvers/ -name mathsat -type f) /tmp/mathsat;
(for ex in `ls examples/*.py`; do echo $ex; python $ex || exit $?; done);
# since we're relying on relative `pysmt` import in examples,
# ensure `.` is added to `sys.path`
export PYTHONPATH=${PYTHONPATH:-.}
for ex in examples/*.py; do
echo $ex
python $ex
done
fi
View
@@ -37,15 +37,17 @@ installed with the same script: e.g., ::
$ pysmt-install --msat
installs the MathSAT5 solver. Once the installation is complete, you
can use the option ``--env`` to obtain a string to update your
``PYTHONPATH``::
installs the MathSAT5 solver.
$ pysmt-install --env
export PYTHONPATH="/home/pysmt/.smt_solvers/python-bindings-2.7:${PYTHONPATH}"
By default the solvers are downloaded, unpacked and built in your home directory
in the ``.smt_solvers`` folder. Compiled libraries and actual solver packages are
installed in the relevant ``site-packages`` directory (e.g. virtual environment's
packages root or local user-site).
By default the solvers are installed in your home directory in the
folder ``.smt_solvers``. ``pysmt-install`` has many options to
If you specified a custom ``--bindings-path`` during install, you
can use the ``--env`` option to obtain a string to update your
``PYTHONPATH``. When defaults are used, there's not need to update
the ``PYTHONPATH``. ``pysmt-install`` has many options to
customize its behavior.
.. _gs-hello-world:
View
@@ -24,6 +24,7 @@
from pysmt.cmd.installers import MSatInstaller, Z3Installer, PicoSATInstaller
from pysmt.cmd.installers import CVC4Installer, YicesInstaller, BtorInstaller
from pysmt.cmd.installers import CuddInstaller
from pysmt.cmd.installers.base import solver_install_site
from pysmt.environment import get_env
from pysmt.exceptions import PysmtException
@@ -137,19 +138,20 @@ def parse_options():
parser.add_argument('--confirm-agreement', dest='skip_intro',
action='store_true', default=False,
help='Confirm that you agree with the licenses of the\
solvers and skip the interactive question')
help='Confirm that you agree with the licenses of the'
' solvers and skip the interactive question')
install_path_default = os.path.join("~", ".smt_solvers")
parser.add_argument('--install-path', dest='install_path',
type=str, default=install_path_default,
help='The folder to use for the installation')
help='The folder to use for the installation'
' (defaults to: {!r})'.format(install_path_default))
py_bindings = os.path.join(install_path_default,
"python-bindings-%d.%d" % sys.version_info[0:2])
py_bindings = solver_install_site(plat_specific=True)
parser.add_argument('--bindings-path', dest='bindings_path',
type=str, default=py_bindings,
help='The folder to use for the bindings')
help='The folder to use for the bindings (defaults to the'
' relevant site-packages directory: {!r})'.format(py_bindings))
options = parser.parse_args()
return options
@@ -187,12 +189,12 @@ def main():
# This should work on any platform
install_dir = os.path.expanduser(options.install_path)
if not os.path.exists(install_dir):
os.mkdir(install_dir)
os.makedirs(install_dir)
# This should work on any platform
bindings_dir = os.path.expanduser(options.bindings_path)
if not os.path.exists(bindings_dir):
os.mkdir(bindings_dir)
os.makedirs(bindings_dir)
solvers_to_install = []
all_solvers = options.all_solvers
@@ -23,6 +23,7 @@
from contextlib import contextmanager
from distutils import spawn
from distutils.dist import Distribution
import six.moves
from six.moves import xrange
@@ -307,3 +308,70 @@ def find_python_config(self):
if command is not None:
break
return command
def package_install_site(name='', user=False, plat_specific=False):
"""pip-inspired, distutils-based method for fetching the
default install location (site-packages path).
Returns virtual environment or system site-packages, unless
`user=True` in which case returns user-site (typ. under `~/.local/
on linux).
If there's a distinction (on a particular system) between platform
specific and pure python package locations, set `plat_specific=True`
to retrieve the former.
"""
dist = Distribution({'name': name})
dist.parse_config_files()
inst = dist.get_command_obj('install', create=True)
# NOTE: specifying user=True will create user-site
if user:
inst.user = user
inst.prefix = ""
inst.finalize_options()
# platform-specific site vs. purelib (platform-independent) site
if plat_specific:
loc = inst.install_platlib
else:
loc = inst.install_purelib
# install_lib specified in setup.cfg has highest precedence
if 'install_lib' in dist.get_option_dict('install'):
loc = inst.install_lib
return loc
def running_under_virtualenv():
"""
Return True if we're running inside a virtualenv, False otherwise.
Note: copied from pip.
"""
if hasattr(sys, 'real_prefix'):
return True
elif sys.prefix != getattr(sys, "base_prefix", sys.prefix):
return True
return False
def solver_install_site(plat_specific=False):
"""Determine solver's install site similarly to pip behaviour on Debian."""
# install to local user-site, unless in virtualenv or running as root
default_user = True
if running_under_virtualenv():
default_user = False
try:
if os.geteuid() == 0:
default_user = False
except:
# getuid/geteuid not supported on windows
pass
return package_install_site(user=default_user, plat_specific=plat_specific)

0 comments on commit 20c377d

Please sign in to comment.