• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2# Copyright 2015 gRPC authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16set -ex
17
18# change to grpc repo root
19cd "$(dirname "$0")/../../.."
20
21##########################
22# Portability operations #
23##########################
24
25PLATFORM=$(uname -s)
26
27function is_msys() {
28  if [ "${PLATFORM/MSYS}" != "$PLATFORM" ]; then
29    echo true
30  else
31    exit 1
32  fi
33}
34
35function is_mingw() {
36  if [ "${PLATFORM/MINGW}" != "$PLATFORM" ]; then
37    echo true
38  else
39    exit 1
40  fi
41}
42
43function is_darwin() {
44  if [ "${PLATFORM/Darwin}" != "$PLATFORM" ]; then
45    echo true
46  else
47    exit 1
48  fi
49}
50
51function is_linux() {
52  if [ "${PLATFORM/Linux}" != "$PLATFORM" ]; then
53    echo true
54  else
55    exit 1
56  fi
57}
58
59function inside_venv() {
60  if [[ -n "${VIRTUAL_ENV}" ]]; then
61    echo true
62  fi
63}
64
65# Associated virtual environment name for the given python command.
66function venv() {
67  $1 -c "import sys; print('py{}{}'.format(*sys.version_info[:2]))"
68}
69
70# Path to python executable within a virtual environment depending on the
71# system.
72function venv_relative_python() {
73  if [ "$(is_mingw)" ]; then
74    echo 'Scripts/python.exe'
75  else
76    echo 'bin/python'
77  fi
78}
79
80# Distutils toolchain to use depending on the system.
81function toolchain() {
82  if [ "$(is_mingw)" ]; then
83    echo 'mingw32'
84  else
85    echo 'unix'
86  fi
87}
88
89# TODO(jtattermusch): this adds dependency on grealpath on mac
90# (brew install coreutils) for little reason.
91# Command to invoke the linux command `realpath` or equivalent.
92function script_realpath() {
93  # Find `realpath`
94  if [ -x "$(command -v realpath)" ]; then
95    realpath "$@"
96  elif [ -x "$(command -v grealpath)" ]; then
97    grealpath "$@"
98  else
99    exit 1
100  fi
101}
102
103####################
104# Script Arguments #
105####################
106
107PYTHON=${1:-python2.7}
108VENV=${2:-$(venv "$PYTHON")}
109VENV_RELATIVE_PYTHON=${3:-$(venv_relative_python)}
110TOOLCHAIN=${4:-$(toolchain)}
111
112if [ "$(is_msys)" ]; then
113  echo "MSYS doesn't directly provide the right compiler(s);"
114  echo "switch to a MinGW shell."
115  exit 1
116fi
117
118ROOT=$(pwd)
119export CFLAGS="-I$ROOT/include -std=gnu99 -fno-wrapv $CFLAGS"
120export GRPC_PYTHON_BUILD_WITH_CYTHON=1
121export LANG=en_US.UTF-8
122
123# Allow build_ext to build C/C++ files in parallel
124# by enabling a monkeypatch. It speeds up the build a lot.
125DEFAULT_PARALLEL_JOBS=$(nproc) || DEFAULT_PARALLEL_JOBS=4
126export GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS=${GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS:-$DEFAULT_PARALLEL_JOBS}
127
128# If ccache is available on Linux, use it.
129if [ "$(is_linux)" ]; then
130  # We're not on Darwin (Mac OS X)
131  if [ -x "$(command -v ccache)" ]; then
132    if [ -x "$(command -v gcc)" ]; then
133      export CC='ccache gcc'
134    elif [ -x "$(command -v clang)" ]; then
135      export CC='ccache clang'
136    fi
137  fi
138fi
139
140############################
141# Perform build operations #
142############################
143
144if [[ "$(inside_venv)" ]]; then
145  VENV_PYTHON="$PYTHON"
146else
147  # Instantiate the virtualenv from the Python version passed in.
148  $PYTHON -m pip install --user virtualenv==16.7.9
149  $PYTHON -m virtualenv "$VENV"
150  VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON")
151fi
152
153# See https://github.com/grpc/grpc/issues/14815 for more context. We cannot rely
154# on pip to upgrade itself because if pip is too old, it may not have the required
155# TLS version to run `pip install`.
156curl https://bootstrap.pypa.io/get-pip.py | $VENV_PYTHON
157
158# pip-installs the directory specified. Used because on MSYS the vanilla Windows
159# Python gets confused when parsing paths.
160pip_install_dir() {
161  PWD=$(pwd)
162  cd "$1"
163  ($VENV_PYTHON setup.py build_ext -c "$TOOLCHAIN" || true)
164  $VENV_PYTHON -m pip install --no-deps .
165  cd "$PWD"
166}
167
168# On library/version/platforms combo that do not have a binary
169# published, we may end up building a dependency from source. In that
170# case, several of our build environment variables may disrupt the
171# third-party build process. This function pipes through only the
172# minimal environment necessary.
173pip_install() {
174  /usr/bin/env -i PATH="$PATH" "$VENV_PYTHON" -m pip install "$@"
175}
176
177case "$VENV" in
178  *py36_gevent*)
179  # TODO(https://github.com/grpc/grpc/issues/15411) unpin this
180  pip_install gevent==1.3.b1
181  ;;
182  *gevent*)
183  pip_install -U gevent
184  ;;
185esac
186
187pip_install --upgrade pip==19.3.1
188pip_install --upgrade setuptools
189pip_install --upgrade cython
190pip_install --upgrade six enum34 protobuf
191
192if [ "$("$VENV_PYTHON" -c "import sys; print(sys.version_info[0])")" == "2" ]
193then
194  pip_install futures
195fi
196
197pip_install_dir "$ROOT"
198
199$VENV_PYTHON "$ROOT/tools/distrib/python/make_grpcio_tools.py"
200pip_install_dir "$ROOT/tools/distrib/python/grpcio_tools"
201
202# Build/install Channelz
203$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" preprocess
204$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" build_package_protos
205pip_install_dir "$ROOT/src/python/grpcio_channelz"
206
207# Build/install health checking
208$VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" preprocess
209$VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" build_package_protos
210pip_install_dir "$ROOT/src/python/grpcio_health_checking"
211
212# Build/install reflection
213$VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" preprocess
214$VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" build_package_protos
215pip_install_dir "$ROOT/src/python/grpcio_reflection"
216
217# Build/install status proto mapping
218$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" preprocess
219$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" build_package_protos
220pip_install_dir "$ROOT/src/python/grpcio_status"
221
222# Install testing
223pip_install_dir "$ROOT/src/python/grpcio_testing"
224
225# Build/install tests
226pip_install coverage==4.4 oauth2client==4.1.0 \
227            google-auth>=1.17.2 requests==2.14.2 \
228            googleapis-common-protos>=1.5.5 rsa==4.0
229$VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" preprocess
230$VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" build_package_protos
231pip_install_dir "$ROOT/src/python/grpcio_tests"
232