Home | History | Annotate | Download | only in pip_package
      1 #!/usr/bin/env bash
      2 # Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      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 
     17 
     18 set -e
     19 
     20 function is_absolute {
     21   [[ "$1" = /* ]] || [[ "$1" =~ ^[a-zA-Z]:[/\\].* ]]
     22 }
     23 
     24 function real_path() {
     25   is_absolute "$1" && echo "$1" || echo "$PWD/${1#./}"
     26 }
     27 
     28 function cp_external() {
     29   local src_dir=$1
     30   local dest_dir=$2
     31 
     32   pushd .
     33   cd "$src_dir"
     34   for f in `find . ! -type d ! -name '*.py' ! -path '*local_config_cuda*' ! -path '*local_config_tensorrt*' ! -path '*local_config_syslibs*' ! -path '*org_tensorflow*'`; do
     35     mkdir -p "${dest_dir}/$(dirname ${f})"
     36     cp "${f}" "${dest_dir}/$(dirname ${f})/"
     37   done
     38   popd
     39 
     40   mkdir -p "${dest_dir}/local_config_cuda/cuda/cuda/"
     41   cp "${src_dir}/local_config_cuda/cuda/cuda/cuda_config.h" "${dest_dir}/local_config_cuda/cuda/cuda/"
     42 }
     43 
     44 PLATFORM="$(uname -s | tr 'A-Z' 'a-z')"
     45 function is_windows() {
     46   if [[ "${PLATFORM}" =~ (cygwin|mingw32|mingw64|msys)_nt* ]]; then
     47     true
     48   else
     49     false
     50   fi
     51 }
     52 
     53 function prepare_src() {
     54   if [ $# -lt 1 ] ; then
     55     echo "No destination dir provided"
     56     exit 1
     57   fi
     58 
     59   TMPDIR="$1"
     60   mkdir -p "$TMPDIR"
     61   EXTERNAL_INCLUDES="${TMPDIR}/tensorflow/include/external"
     62 
     63   echo $(date) : "=== Preparing sources in dir: ${TMPDIR}"
     64 
     65   if [ ! -d bazel-bin/tensorflow ]; then
     66     echo "Could not find bazel-bin.  Did you run from the root of the build tree?"
     67     exit 1
     68   fi
     69 
     70   if is_windows; then
     71     rm -rf ./bazel-bin/tensorflow/tools/pip_package/simple_console_for_window_unzip
     72     mkdir -p ./bazel-bin/tensorflow/tools/pip_package/simple_console_for_window_unzip
     73     echo "Unzipping simple_console_for_windows.zip to create runfiles tree..."
     74     unzip -o -q ./bazel-bin/tensorflow/tools/pip_package/simple_console_for_windows.zip -d ./bazel-bin/tensorflow/tools/pip_package/simple_console_for_window_unzip
     75     echo "Unzip finished."
     76     # runfiles structure after unzip the python binary
     77     cp -R \
     78       bazel-bin/tensorflow/tools/pip_package/simple_console_for_window_unzip/runfiles/org_tensorflow/tensorflow \
     79       "${TMPDIR}"
     80     cp_external \
     81       bazel-bin/tensorflow/tools/pip_package/simple_console_for_window_unzip/runfiles \
     82       "${EXTERNAL_INCLUDES}/"
     83     RUNFILES=bazel-bin/tensorflow/tools/pip_package/simple_console_for_window_unzip/runfiles/org_tensorflow
     84   else
     85     RUNFILES=bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles/org_tensorflow
     86     if [ -d bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles/org_tensorflow/external ]; then
     87       # Old-style runfiles structure (--legacy_external_runfiles).
     88       cp -R \
     89         bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles/org_tensorflow/tensorflow \
     90         "${TMPDIR}"
     91       cp_external \
     92         bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles/org_tensorflow/external \
     93         "${EXTERNAL_INCLUDES}"
     94       # Copy MKL libs over so they can be loaded at runtime
     95       so_lib_dir=$(ls $RUNFILES | grep solib) || true
     96       if [ -n "${so_lib_dir}" ]; then
     97         mkl_so_dir=$(ls ${RUNFILES}/${so_lib_dir} | grep mkl) || true
     98         if [ -n "${mkl_so_dir}" ]; then
     99           mkdir "${TMPDIR}/${so_lib_dir}"
    100           cp -R ${RUNFILES}/${so_lib_dir}/${mkl_so_dir} "${TMPDIR}/${so_lib_dir}"
    101         fi
    102       fi
    103     else
    104       # New-style runfiles structure (--nolegacy_external_runfiles).
    105       cp -R \
    106         bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles/org_tensorflow/tensorflow \
    107         "${TMPDIR}"
    108       cp_external \
    109         bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles \
    110         "${EXTERNAL_INCLUDES}"
    111       # Copy MKL libs over so they can be loaded at runtime
    112       so_lib_dir=$(ls $RUNFILES | grep solib) || true
    113       if [ -n "${so_lib_dir}" ]; then
    114         mkl_so_dir=$(ls ${RUNFILES}/${so_lib_dir} | grep mkl) || true
    115         if [ -n "${mkl_so_dir}" ]; then
    116           mkdir "${TMPDIR}/${so_lib_dir}"
    117           cp -R ${RUNFILES}/${so_lib_dir}/${mkl_so_dir} "${TMPDIR}/${so_lib_dir}"
    118         fi
    119       fi
    120     fi
    121   fi
    122 
    123   # protobuf pip package doesn't ship with header files. Copy the headers
    124   # over so user defined ops can be compiled.
    125   mkdir -p ${TMPDIR}/google
    126   mkdir -p ${TMPDIR}/third_party
    127   pushd ${RUNFILES%org_tensorflow} > /dev/null
    128   for header in $(find protobuf_archive -name \*.h); do
    129     mkdir -p "${TMPDIR}/google/$(dirname ${header})"
    130     cp "$header" "${TMPDIR}/google/$(dirname ${header})/"
    131   done
    132   popd > /dev/null
    133   cp -R $RUNFILES/third_party/eigen3 ${TMPDIR}/third_party
    134 
    135   cp tensorflow/tools/pip_package/MANIFEST.in ${TMPDIR}
    136   cp tensorflow/tools/pip_package/README ${TMPDIR}
    137   cp tensorflow/tools/pip_package/setup.py ${TMPDIR}
    138 }
    139 
    140 function build_wheel() {
    141   if [ $# -lt 2 ] ; then
    142     echo "No src and dest dir provided"
    143     exit 1
    144   fi
    145 
    146   TMPDIR="$1"
    147   DEST="$2"
    148   PKG_NAME_FLAG="$3"
    149 
    150   # Before we leave the top-level directory, make sure we know how to
    151   # call python.
    152   if [[ -e tools/python_bin_path.sh ]]; then
    153     source tools/python_bin_path.sh
    154   fi
    155 
    156   pushd ${TMPDIR} > /dev/null
    157   rm -f MANIFEST
    158   echo $(date) : "=== Building wheel"
    159   "${PYTHON_BIN_PATH:-python}" setup.py bdist_wheel ${PKG_NAME_FLAG} >/dev/null
    160   mkdir -p ${DEST}
    161   cp dist/* ${DEST}
    162   popd > /dev/null
    163   echo $(date) : "=== Output wheel file is in: ${DEST}"
    164 }
    165 
    166 function usage() {
    167   echo "Usage:"
    168   echo "$0 [--src srcdir] [--dst dstdir] [options]"
    169   echo "$0 dstdir [options]"
    170   echo ""
    171   echo "    --src                 prepare sources in srcdir"
    172   echo "                              will use temporary dir if not specified"
    173   echo ""
    174   echo "    --dst                 build wheel in dstdir"
    175   echo "                              if dstdir is not set do not build, only prepare sources"
    176   echo ""
    177   echo "  Options:"
    178   echo "    --project_name <name> set project name to name"
    179   echo "    --gpu                 build tensorflow_gpu"
    180   echo "    --gpudirect           build tensorflow_gpudirect"
    181   echo "    --nightly_flag        build tensorflow nightly"
    182   echo ""
    183   exit 1
    184 }
    185 
    186 function main() {
    187   PKG_NAME_FLAG=""
    188   PROJECT_NAME=""
    189   GPU_BUILD=0
    190   NIGHTLY_BUILD=0
    191   SRCDIR=""
    192   DSTDIR=""
    193   CLEANSRC=1
    194   while true; do
    195     if [[ "$1" == "--help" ]]; then
    196       usage
    197       exit 1
    198     elif [[ "$1" == "--nightly_flag" ]]; then
    199       NIGHTLY_BUILD=1
    200     elif [[ "$1" == "--gpu" ]]; then
    201       GPU_BUILD=1
    202     elif [[ "$1" == "--gpudirect" ]]; then
    203       PKG_NAME_FLAG="--project_name tensorflow_gpudirect"
    204     elif [[ "$1" == "--project_name" ]]; then
    205       shift
    206       if [[ -z "$1" ]]; then
    207         break
    208       fi
    209       PROJECT_NAME="$1"
    210     elif [[ "$1" == "--src" ]]; then
    211       shift
    212       SRCDIR="$(real_path $1)"
    213       CLEANSRC=0
    214     elif [[ "$1" == "--dst" ]]; then
    215       shift
    216       DSTDIR="$(real_path $1)"
    217     else
    218       DSTDIR="$(real_path $1)"
    219     fi
    220     shift
    221 
    222     if [[ -z "$1" ]]; then
    223       break
    224     fi
    225   done
    226 
    227   if [[ -z "$DSTDIR" ]] && [[ -z "$SRCDIR" ]]; then
    228     echo "No destination dir provided"
    229     usage
    230     exit 1
    231   fi
    232 
    233   if [[ -z "$SRCDIR" ]]; then
    234     # make temp srcdir if none set
    235     SRCDIR="$(mktemp -d -t tmp.XXXXXXXXXX)"
    236   fi
    237 
    238   prepare_src "$SRCDIR"
    239 
    240   if [[ -z "$DSTDIR" ]]; then
    241       # only want to prepare sources
    242       exit
    243   fi
    244 
    245   if [[ -n ${PROJECT_NAME} ]]; then
    246     PKG_NAME_FLAG="--project_name ${PROJECT_NAME}"
    247   elif [[ ${NIGHTLY_BUILD} == "1" && ${GPU_BUILD} == "1" ]]; then
    248     PKG_NAME_FLAG="--project_name tf_nightly_gpu"
    249   elif [[ ${NIGHTLY_BUILD} == "1" ]]; then
    250     PKG_NAME_FLAG="--project_name tf_nightly"
    251   elif [[ ${GPU_BUILD} == "1" ]]; then
    252     PKG_NAME_FLAG="--project_name tensorflow_gpu"
    253   fi
    254 
    255   build_wheel "$SRCDIR" "$DSTDIR" "$PKG_NAME_FLAG"
    256 
    257   if [[ $CLEANSRC -ne 0 ]]; then
    258     rm -rf "${TMPDIR}"
    259   fi
    260 }
    261 
    262 main "$@"
    263