Skip to content

Commit

Permalink
python: Document Python3 support for Bionic
Browse files Browse the repository at this point in the history
  • Loading branch information
EricCousineau-TRI committed Dec 19, 2018
1 parent 9744053 commit 507752d
Show file tree
Hide file tree
Showing 16 changed files with 149 additions and 36 deletions.
5 changes: 5 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Import legacy .bazelrc file.
import %workspace%/tools/bazel.rc

# Import environment-specific configuration.
# TODO(eric.cousineau): Make this required once CI is configured to always run
# `install_prereqs_user_environment`.
try-import %workspace%/gen/environment.bazelrc

# Try to import user-specific configuration local to workspace.
try-import %workspace%/user.bazelrc
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ xcode

external/
/user.bazelrc
/gen/
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ if(APPLE)
find_program(PYTHON_EXECUTABLE NAMES python2)
endif()

# TODO(eric.cousineau) Ensure that we can switch between supported versions.
# TODO(jamiesnape) Ensure that we can switch between supported versions.
find_package(PythonInterp 2.7 EXACT MODULE REQUIRED)

if(CMAKE_BUILD_TYPE STREQUAL Debug)
Expand Down
3 changes: 3 additions & 0 deletions cmake/bazel.rc.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
# To use this file directly with Bazel call:
# bazel --bazelrc=@CMAKE_CURRENT_BINARY_DIR@/bazel.rc <command> <options>

# N.B. Please keep these alphabetized.

build --action_env=DRAKE_PYTHON_BIN_PATH=@PYTHON_EXECUTABLE@
build --compilation_mode=@BAZEL_COMPILATION_MODE@
build --python_path=@PYTHON_EXECUTABLE@
build --symlink_prefix=/
Expand Down
9 changes: 9 additions & 0 deletions doc/bazel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@ For more information, see https://github.com/bazelbuild/bazel/issues/2537.

.. _buildifier:

Python Versions
===============
By default, Python 2 will be used. To use Python 3 for both Bazel and the Python
bindings, use ``--config=python3``.

As an example to run all lint checks in Python 3::

bazel test --config=python3 --config=lint //...

Updating BUILD files
====================

Expand Down
16 changes: 11 additions & 5 deletions doc/developers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,22 @@ supported for CMake builds using the "Unix Makefiles" generator.
| | | CMake 3.5.1 | | GCC 5.4 | | | |
+----------------------------------+-----------------+-----------------+------------+-------------------+--------+
| Ubuntu 18.04 LTS (Bionic Beaver) | | Bazel 0.19.2 | | Clang 6.0 | OpenJDK 11 | R2018b | 2.7.15 |
| | | CMake 3.10.2 | | GCC 7.3 | | | |
+----------------------------------+-----------------+-----------------+------------+ | |
| macOS High Sierra (10.13) | | Bazel 0.19.2 | Apple LLVM 10.0 | Oracle 11 | | |
| | | CMake 3.10.2 | | GCC 7.3 | | | 3.6.7 |
+----------------------------------+-----------------+-----------------+------------+ +--------+
| macOS High Sierra (10.13) | | Bazel 0.19.2 | Apple LLVM 10.0 | Oracle 11 | | 2.7.15 |
+----------------------------------+ | CMake 3.13.0 | | | | |
| macOS Mojave (10.14) | | | | | |
+----------------------------------+-----------------+-----------------+------------+-------------------+--------+


macOS Mojave C++ and Python support and macOS and Ubuntu Bionic MATLAB support
is experimental and untested in continuous integration.
CPython is the only Python implementation supported. On all platforms, Python 2
is the default version.

The following configurations are presently untested in continuous integration:

- macOS Mojave: C++, Python
- macOS, Ubuntu Bionic: MATLAB
- Ubuntu Bionic: Python 3

.. _binary-packages:

Expand Down
21 changes: 10 additions & 11 deletions setup/mac/source_distribution/install_prereqs_user_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@

set -euo pipefail

# We require that Bazel uses the Python installed by Homebrew.
# TODO(jamiesnape): Also support a .bazelrc located in the WORKSPACE.
if [[ ! -f "${HOME}/.bazelrc" ]] || ! /usr/bin/grep -q '^build --python_path=' "${HOME}/.bazelrc"; then
echo "We need to add 'build --python_path=/usr/local/bin/python2' to ~/.bazelrc."
read -r -p 'Do you want to continue (y/N)? ' reply
if [[ "${reply}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo 'build --python_path=/usr/local/bin/python2' >> "${HOME}/.bazelrc"
fi
if [[ "${EUID}" -eq 0 ]]; then
echo 'This script must NOT be run as root' >&2
exit 1
fi

if [[ ! -f "${HOME}/.bazelrc" ]] || ! /usr/bin/grep -q '^build --python_path=/usr/local/bin/python2$' "${HOME}/.bazelrc"; then
echo 'Using a python other than /usr/local/bin/python2 is NOT supported' >&2
fi
workspace_dir="$(cd "$(dirname "${BASH_SOURCE}")/../../.." && pwd)"
bazelrc="${workspace_dir}/gen/environment.bazelrc"

mkdir -p "$(dirname "${bazelrc}")"
cat > "${bazelrc}" <<EOF
import %workspace%/tools/macos.bazelrc
EOF
11 changes: 11 additions & 0 deletions setup/ubuntu/binary_distribution/packages-bionic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,16 @@ python-tornado
python-u-msgpack
python-yaml
python-zmq
python3
python3-lxml
python3-matplotlib
python3-numpy
python3-pydot
python3-six
python3-tk
python3-tornado
python3-u-msgpack
python3-yaml
python3-zmq
qtbase5-dev
zlib1g
8 changes: 8 additions & 0 deletions setup/ubuntu/install_prereqs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,13 @@ source "${BASH_SOURCE%/*}/binary_distribution/install_prereqs.sh"

source "${BASH_SOURCE%/*}/source_distribution/install_prereqs.sh"

# Configure user environment, executing as user if we're under `sudo`.
user_env_script="${BASH_SOURCE%/*}/source_distribution/install_prereqs_user_environment.sh"
if [[ -n "${SUDO_USER:+D}" ]]; then
sudo -u ${SUDO_USER} bash "${user_env_script}"
else
source "${user_env_script}"
fi

trap : EXIT # Disable exit reporting.
echo 'install_prereqs: success'
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
#
# Write user environment prerequisites for source distributions of Drake on
# Ubuntu.

set -euo pipefail

if [[ "${EUID}" -eq 0 ]]; then
echo 'This script must NOT be run as root' >&2
exit 1
fi

workspace_dir="$(cd "$(dirname "${BASH_SOURCE}")/../../.." && pwd)"
bazelrc="${workspace_dir}/gen/environment.bazelrc"
codename=$(lsb_release -sc)

mkdir -p "$(dirname "${bazelrc}")"
cat > "${bazelrc}" <<EOF
import %workspace%/tools/ubuntu-${codename}.bazelrc
EOF
4 changes: 4 additions & 0 deletions setup/ubuntu/source_distribution/packages-bionic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ python-protobuf
python-pygame
python-sphinx
python-sphinx-rtd-theme
python3-dev
python3-protobuf
python3-sphinx
python3-sphinx-rtd-theme
ruby
unzip
valgrind
Expand Down
9 changes: 9 additions & 0 deletions tools/macos.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# N.B. Ensure we only use Homebrew's Python in `/usr/local`.

# Use Python 2 by default.
build --python_path=/usr/local/bin/python2
build --action_env=DRAKE_PYTHON_BIN_PATH=/usr/local/bin/python2

# Explicit configuration for Python 3.
build:python3 --python_path=/usr/local/bin/python3
build:python3 --action_env=DRAKE_PYTHON_BIN_PATH=/usr/local/bin/python3
7 changes: 7 additions & 0 deletions tools/ubuntu-bionic.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Use Python 2 by default.
build --python_path=/usr/bin/python2
build --action_env=DRAKE_PYTHON_BIN_PATH=/usr/bin/python2

# Explicit configuration for Python 3.
build:python3 --python_path=/usr/bin/python3
build:python3 --action_env=DRAKE_PYTHON_BIN_PATH=/usr/bin/python3
7 changes: 7 additions & 0 deletions tools/ubuntu-xenial.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Use Python 2 by default.
build --python_path=/usr/bin/python2
build --action_env=DRAKE_PYTHON_BIN_PATH=/usr/bin/python2

# Explicit configuration for Python 3.
build:python3 --python_path=/usr/bin/python3
build:python3 --action_env=DRAKE_PYTHON_BIN_PATH=/usr/bin/python3
60 changes: 42 additions & 18 deletions tools/workspace/python/repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ the "-undefined dynamic_lookup" linker flag, however in the rare cases that
this would cause an undefined symbol error, a :python_direct_link target is
provided. On Linux, these targets are identical.
The Python distribution is determined by `--action_env=PYTHON_BIN_PATH=<bin>`,
which should match Bazel's version (via `--python_path=<bin>`).
The Python distribution is determined by
`--action_env=DRAKE_PYTHON_BIN_PATH=<bin>`, which should match Bazel's version
(via `--python_path=<bin>`).
Example:
WORKSPACE:
Expand All @@ -35,13 +36,13 @@ load("@drake//tools/workspace:os.bzl", "determine_os")

_VERSION_SUPPORT_MATRIX = {
"ubuntu:16.04": ["2.7"],
"ubuntu:18.04": ["2.7"],
"ubuntu:18.04": ["2.7", "3.6"],
"macos:10.13": ["2.7"],
"macos:10.14": ["2.7"],
}

def _repository_python_info(repository_ctx):
# Using `PYTHON_BIN_PATH` from the environment, determine:
# Using `DRAKE_PYTHON_BIN_PATH` from the environment, determine:
# - `python` - binary path
# - `python_config` - configuration binary path
# - `site_packages_relpath` - relative to base of FHS
Expand All @@ -63,32 +64,55 @@ def _repository_python_info(repository_ctx):
# N.B. Unfortunately, it does not seem possible to get Bazel's Python
# interpreter during a repository rule, thus we can only catch mismatch
# issues via `//tools/workspace/python:py/python_bin_test`.
if os_result.is_macos:
version_supported_major, _ = versions_supported[0].split(".")

# N.B. On Mac, `which python{major}.{minor}` may refer to the system
# Python, not Homebrew Python.
python_default = "python{}".format(version_supported_major)
else:
python_default = "python{}".format(versions_supported[0])
python_from_env = repository_ctx.os.environ.get(
"PYTHON_BIN_PATH",
python_default,
)
python = str(which(repository_ctx, python_from_env))
# TODO(eric.cousineau): Make this an error once `.bazelrc` stops using
# `try-import` for configuration.
python_path = repository_ctx.os.environ.get("DRAKE_PYTHON_BIN_PATH")
if python_path == None:
if os_result.is_macos:
python_path = "/usr/local/bin/python{}".format(
versions_supported[0],
)
else:
python_path = "/usr/bin/python{}".format(versions_supported[0])
if not python_path.startswith("/"):
fail("`--action_env=DRAKE_PYTHON_BIN_PATH` must provide an " +
"absolute path.")
if which(repository_ctx, python_path) == None:
fail("Executable does not exist: {}".format(python_path))
python = str(python_path)
version = execute_or_fail(
repository_ctx,
[python, "-c", "from sys import version_info as v; print(\"{}.{}\"" +
".format(v.major, v.minor))"],
).stdout.strip()
version_major, _ = version.split(".")

# Perform sanity checks on supplied Python binary.
implementation = execute_or_fail(
repository_ctx,
[
python,
"-c",
"import platform as m; print(m.python_implementation())",
],
).stdout.strip()
if implementation != "CPython":
fail(("The implementation of '{}' is '{}', but only 'CPython' is " +
"supported.").format(python, implementation))

# Development Note: This should generally be the correct configuration. If
# you are hacking with `virtualenv` (which is officially unsupported),
# ensure that you manually symlink the matching `*-config` binary in your
# `virtualenv` installation.
python_config = "{}-config".format(python)

# Check if config binary exists.
if which(repository_ctx, python_config) == None:
fail((
"Cannot find corresponding config executable: {}\n" +
" For interpreter: {}"
).format(python_config, python_path))

# Warn if we do not the correct platform support.
if version not in versions_supported:
print((
Expand Down Expand Up @@ -233,7 +257,7 @@ py_library(
python_repository = repository_rule(
_impl,
environ = [
"PYTHON_BIN_PATH",
"DRAKE_PYTHON_BIN_PATH",
],
local = True,
)
2 changes: 1 addition & 1 deletion tools/workspace/python/test/python_bin_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_bazel_and_env(self):
message = (
"\n\nMismatch in Python executables:\n"
" bazel --python_path={}\n"
" bazel --action_env=PYTHON_BIN_PATH={}\n"
" bazel --action_env=DRAKE_PYTHON_BIN_PATH={}\n"
"If you specify one of these, please ensure that you "
"specify both.").format(python_bazel, python_actionenv)
# In Python2, providing a longMessage will override the useful text
Expand Down

0 comments on commit 507752d

Please sign in to comment.