Imported Upstream version 1.36.0
[platform/upstream/grpc.git] / tools / run_tests / helper_scripts / build_python.sh
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
16 set -ex
17
18 # change to grpc repo root
19 cd "$(dirname "$0")/../../.."
20
21 ##########################
22 # Portability operations #
23 ##########################
24
25 PLATFORM=$(uname -s)
26
27 function is_msys() {
28   if [ "${PLATFORM/MSYS}" != "$PLATFORM" ]; then
29     echo true
30   else
31     exit 1
32   fi
33 }
34
35 function is_mingw() {
36   if [ "${PLATFORM/MINGW}" != "$PLATFORM" ]; then
37     echo true
38   else
39     exit 1
40   fi
41 }
42
43 function is_darwin() {
44   if [ "${PLATFORM/Darwin}" != "$PLATFORM" ]; then
45     echo true
46   else
47     exit 1
48   fi
49 }
50
51 function is_linux() {
52   if [ "${PLATFORM/Linux}" != "$PLATFORM" ]; then
53     echo true
54   else
55     exit 1
56   fi
57 }
58
59 function 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.
66 function 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.
72 function 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.
81 function 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.
92 function 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
107 PYTHON=${1:-python2.7}
108 VENV=${2:-$(venv "$PYTHON")}
109 VENV_RELATIVE_PYTHON=${3:-$(venv_relative_python)}
110 TOOLCHAIN=${4:-$(toolchain)}
111
112 if [ "$(is_msys)" ]; then
113   echo "MSYS doesn't directly provide the right compiler(s);"
114   echo "switch to a MinGW shell."
115   exit 1
116 fi
117
118 ROOT=$(pwd)
119 export CFLAGS="-I$ROOT/include -std=gnu99 -fno-wrapv $CFLAGS"
120 export GRPC_PYTHON_BUILD_WITH_CYTHON=1
121 export 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.
125 DEFAULT_PARALLEL_JOBS=$(nproc) || DEFAULT_PARALLEL_JOBS=4
126 export 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.
129 if [ "$(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
138 fi
139
140 ############################
141 # Perform build operations #
142 ############################
143
144 if [[ "$(inside_venv)" ]]; then
145   VENV_PYTHON="$PYTHON"
146 else
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")
151 fi
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`.
156 curl https://bootstrap.pypa.io/2.7/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.
160 pip_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.
173 pip_install() {
174   /usr/bin/env -i PATH="$PATH" "$VENV_PYTHON" -m pip install "$@"
175 }
176
177 case "$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   ;;
185 esac
186
187
188 pip_install --upgrade setuptools==44.1.1
189 pip_install --upgrade pip==19.3.1
190 pip_install --upgrade cython
191 pip_install --upgrade six protobuf
192
193 if [ "$("$VENV_PYTHON" -c "import sys; print(sys.version_info[0])")" == "2" ]
194 then
195   pip_install --upgrade futures enum34
196 fi
197
198 pip_install_dir "$ROOT"
199
200 $VENV_PYTHON "$ROOT/tools/distrib/python/make_grpcio_tools.py"
201 pip_install_dir "$ROOT/tools/distrib/python/grpcio_tools"
202
203 # Build/install Channelz
204 $VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" preprocess
205 $VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" build_package_protos
206 pip_install_dir "$ROOT/src/python/grpcio_channelz"
207
208 # Build/install health checking
209 $VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" preprocess
210 $VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" build_package_protos
211 pip_install_dir "$ROOT/src/python/grpcio_health_checking"
212
213 # Build/install reflection
214 $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" preprocess
215 $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" build_package_protos
216 pip_install_dir "$ROOT/src/python/grpcio_reflection"
217
218 # Build/install status proto mapping
219 $VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" preprocess
220 $VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" build_package_protos
221 pip_install_dir "$ROOT/src/python/grpcio_status"
222
223 # Install testing
224 pip_install_dir "$ROOT/src/python/grpcio_testing"
225
226 # Build/install tests
227 pip_install coverage==4.4 oauth2client==4.1.0 \
228             google-auth>=1.17.2 requests==2.14.2 \
229             googleapis-common-protos>=1.5.5 rsa==4.0
230 $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" preprocess
231 $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" build_package_protos
232 pip_install_dir "$ROOT/src/python/grpcio_tests"