You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by GitBox <gi...@apache.org> on 2018/03/01 21:51:22 UTC
[GitHub] marcoabreu closed pull request #9943: [Don't MERGE] CI 2.0, revamp ci scripts and dockerfiles, integrate IoT builds
marcoabreu closed pull request #9943: [Don't MERGE] CI 2.0, revamp ci scripts and dockerfiles, integrate IoT builds
URL: https://github.com/apache/incubator-mxnet/pull/9943
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/.mxnet_root b/.mxnet_root
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d229cb0847d..ee4e8d6c70e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -102,6 +102,7 @@ else(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
add_definitions(-DNDEBUG=1)
+ #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -g -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -g")
else()
add_definitions(-DNDEBUG=1)
diff --git a/ci/README.md b/ci/README.md
new file mode 100644
index 00000000000..98c74e31d87
--- /dev/null
+++ b/ci/README.md
@@ -0,0 +1,50 @@
+# Containerized build & test utilities
+
+This folder contains scripts and dockerfiles used to build and test MXNet using Docker containers
+
+You need docker and nvidia docker if you have a GPU.
+
+If you are in ubuntu an easy way to install Docker CE is executing the following script:
+
+
+```
+#!/bin/bash
+set -e
+set -x
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y install curl
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+add-apt-repository \
+ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
+ $(lsb_release -cs) \
+ stable"
+apt-get update
+apt-get -y install docker-ce
+service docker restart
+usermod -a -G docker $SUDO_USER
+```
+
+For detailed instructions go to the docker documentation.
+
+
+## build.py
+
+The main utility to build is build.py which will run docker and mount the mxnet folder as a volume
+to do in-place builds.
+
+The build.py script does two functions, build the docker image, and it can be also used to run
+commands inside this image with the propper mounts and paraphernalia required to build mxnet inside
+docker from the sources on the parent folder.
+
+A set of helper shell functions are in `functions.sh`. `build.py --help` will display usage
+information about the tool.
+
+To build for armv7 for example:
+
+```
+./build.py -p armv7 /work/functions.sh build_armv7
+```
+
+## Warning
+Due to current limitations of the CMake build system creating artifacts in the source 3rdparty
+folder of the parent mxnet sources concurrent builds of different platforms is NOT SUPPORTED.
diff --git a/ci/build.py b/ci/build.py
new file mode 100755
index 00000000000..f9f1ba59c93
--- /dev/null
+++ b/ci/build.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""Multi arch dockerized build tool.
+
+"""
+
+__author__ = 'Marco de Abreu, Kellen Sunderland, Anton Chernov, Pedro Larroy'
+__version__ = '0.1'
+
+import os
+import sys
+import subprocess
+import logging
+import argparse
+from subprocess import check_call, call
+import glob
+import re
+from typing import *
+from itertools import chain
+from copy import deepcopy
+
+
+
+def get_platforms(path: Optional[str]="docker"):
+ """Get a list of architectures given our dockerfiles"""
+ dockerfiles = glob.glob(os.path.join(path, "Dockerfile.build.*"))
+ dockerfiles = list(filter(lambda x: x[-1] != '~', dockerfiles))
+ files = list(map(lambda x: re.sub(r"Dockerfile.build.(.*)", r"\1", x), dockerfiles))
+ files.sort()
+ platforms = list(map(lambda x: os.path.split(x)[1], files))
+ return platforms
+
+
+def get_docker_tag(platform: str) -> None:
+ return "mxnet/build.{0}".format(platform)
+
+
+def get_dockerfile(platform: str, path="docker"):
+ return os.path.join(path, "Dockerfile.build.{0}".format(platform))
+
+def get_docker_binary(use_nvidia_docker: bool):
+ if use_nvidia_docker:
+ return "nvidia-docker"
+ else:
+ return "docker"
+
+def build_docker(platform: str, docker_binary: str) -> None:
+ """Build a container for the given platform"""
+ tag = get_docker_tag(platform)
+ logging.info("Building container tagged '%s' with %s", tag, docker_binary)
+ cmd = [docker_binary, "build",
+ "-f", get_dockerfile(platform),
+ "-t", tag,
+ "."]
+ logging.info("Running command: '%s'", ' '.join(cmd))
+ check_call(cmd)
+
+def get_mxnet_root() -> str:
+ curpath = os.path.abspath(os.path.dirname(__file__))
+ def is_mxnet_root(path: str) -> bool:
+ return os.path.exists(os.path.join(path, ".mxnet_root"))
+ while not is_mxnet_root(curpath):
+ parent = os.path.abspath(os.path.join(curpath, os.pardir))
+ if parent == curpath:
+ raise RuntimeError("Got to the root and couldn't find a parent folder with .mxnet_root")
+ curpath = parent
+ return curpath
+
+
+def container_run(platform: str, docker_binary: str, command: List[str]) -> None:
+ tag = get_docker_tag(platform)
+ mx_root = get_mxnet_root()
+ local_build_folder = '{}/build_{}'.format(mx_root, platform)
+ # We need to create it first, otherwise it will be created by the docker daemon with root only permissions
+ os.makedirs(local_build_folder, exist_ok=True)
+ logging.info("Running %s in container %s", command, tag)
+ runlist = [docker_binary, 'run', '--rm',
+ #'-v', "{}:/work/mxnet:ro".format(mx_root), # mount mxnet root
+ '-v', "{}:/work/mxnet".format(mx_root), # mount mxnet root
+ '-v', "{}:/work/build".format(local_build_folder), # mount mxnet/build for storing build artifacts
+ #'-w', '/work/build',
+ '-u', '{}:{}'.format(os.getuid(), os.getgid()),
+ tag]
+ runlist.extend(command)
+ cmd = ' '.join(runlist)
+ logging.info("Executing: %s", cmd)
+ ret = call(runlist)
+ if ret != 0:
+ logging.error("Running of command in container failed: %s", cmd)
+ into_cmd = deepcopy(runlist)
+ idx = into_cmd.index('-u') + 2
+ into_cmd[idx:idx] = ['-ti', '--entrypoint', 'bash']
+ logging.error("You can try to get into the container by using the following command: %s", ' '.join(into_cmd))
+ raise subprocess.CalledProcessError(ret, cmd)
+
+def main() -> int:
+ # We need to be in the same directory than the script so the commands in the dockerfiles work as
+ # expected. But the script can be invoked from a different path
+ base = os.path.split(os.path.realpath(__file__))[0]
+ os.chdir(base)
+
+ logging.getLogger().setLevel(logging.INFO)
+ def script_name() -> str:
+ return os.path.split(sys.argv[0])[1]
+
+ logging.basicConfig(format='{}: %(asctime)-15s %(message)s'.format(script_name()))
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-p", "--platform",
+ help="platform",
+ type=str)
+
+ parser.add_argument("-b", "--build",
+ help="Build the container",
+ action='store_true')
+
+ parser.add_argument("-n", "--nvidiadocker",
+ help="Use nvidia docker",
+ action='store_true')
+
+ parser.add_argument("-l", "--list",
+ help="List platforms",
+ action='store_true')
+
+ parser.add_argument("command",
+ help="command to run in the container",
+ nargs='*', action='append', type=str)
+
+ args = parser.parse_args()
+ command = list(chain(*args.command))
+ docker_binary = get_docker_binary(args.nvidiadocker)
+
+ if args.list:
+ platforms = get_platforms()
+ print(platforms)
+
+ elif args.platform:
+ platform = args.platform
+ if args.build:
+ build_docker(platform, docker_binary)
+ tag = get_docker_tag(platform)
+ if command:
+ container_run(platform, docker_binary, command)
+ else:
+ cmd = ["/work/build_functions.sh", "build_{}".format(platform)]
+ logging.info("No command specified, trying default build: %s", ' '.join(cmd))
+ container_run(platform, docker_binary, cmd)
+
+ else:
+ platforms = get_platforms()
+ logging.info("Building for all architectures: {}".format(platforms))
+ logging.info("Artifacts will be produced in the build/ directory.")
+ for platform in platforms:
+ build_docker(platform, docker_binary)
+ cmd = ["/work/build_functions.sh", "build_{}".format(platform)]
+ logging.info("No command specified, trying default build: %s", ' '.join(cmd))
+ container_run(platform, docker_binary, cmd)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/ci/build_functions.sh b/ci/build_functions.sh
new file mode 100755
index 00000000000..0a6f50a7996
--- /dev/null
+++ b/ci/build_functions.sh
@@ -0,0 +1,254 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# build and install are separated so changes to build don't invalidate
+# the whole docker cache for the image
+
+set -ex
+
+clean_repo() {
+ set -ex
+ git clean -xfd
+ git submodule foreach --recursive git clean -xfd
+ git reset --hard
+ git submodule foreach --recursive git reset --hard
+ git submodule update --init --recursive
+}
+
+
+# Build commands: Every platform in docker/Dockerfile.build.<platform> should have a corresponding
+# function here with the same suffix:
+
+build_jetson() {
+ set -ex
+ pushd .
+ cd /work/build
+ cmake\
+ -DUSE_CUDA=OFF\
+ -DUSE_OPENCV=OFF\
+ -DUSE_OPENMP=ON\
+ -DUSE_SIGNAL_HANDLER=ON\
+ -DUSE_MKL_IF_AVAILABLE=OFF\
+ -DUSE_LAPACK=OFF\
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+ -G Ninja /work/mxnet
+ ninja
+ export MXNET_LIBRARY_PATH=`pwd`/libmxnet.so
+ cd /work/mxnet/python
+ python setup.py bdist_wheel --universal
+ cp dist/*.whl /work/build
+ popd
+}
+
+build_armv7() {
+ set -ex
+ pushd .
+ cd /work/build
+ cmake\
+ -DUSE_CUDA=OFF\
+ -DUSE_OPENCV=OFF\
+ -DUSE_OPENMP=OFF\
+ -DUSE_SIGNAL_HANDLER=ON\
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+ -DUSE_MKL_IF_AVAILABLE=OFF\
+ -G Ninja /work/mxnet
+ ninja
+ export MXNET_LIBRARY_PATH=`pwd`/libmxnet.so
+ cd /work/mxnet/python
+ python setup.py bdist_wheel --universal
+ cp dist/*.whl /work/build
+ popd
+}
+
+build_ubuntu_cpu() {
+ set -ex
+ pushd .
+ cd /work/build
+ cmake\
+ -DUSE_CPP_PACKAGE=ON\
+ -DUSE_CUDA=OFF\
+ -DUSE_OPENCV=ON\
+ -DUSE_OPENMP=ON\
+ -DUSE_SIGNAL_HANDLER=ON\
+ -DUSE_MKL_IF_AVAILABLE=OFF\
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+ -G Ninja /work/mxnet
+ ninja
+ popd
+}
+
+test_ubuntu_cpu_python2() {
+ set -ex
+ pushd .
+ export MXNET_LIBRARY_PATH=/work/build/libmxnet.so
+
+ VENV=mxnet_py2_venv
+ virtualenv -p `which python2` $VENV
+ source $VENV/bin/activate
+ pip install nose nose-timer
+
+ cd /work/mxnet/python
+ pip install -e .
+ cd /work/mxnet
+ python -m "nose" --with-timer --verbose tests/python/unittest
+ popd
+}
+
+test_ubuntu_cpu_python3() {
+ set -ex
+ pushd .
+ export MXNET_LIBRARY_PATH=/work/build/libmxnet.so
+ VENV=mxnet_py3_venv
+ virtualenv -p `which python3` $VENV
+ source $VENV/bin/activate
+
+ cd /work/mxnet/python
+ pip3 install nose nose-timer
+ pip3 install -e .
+ cd /work/mxnet
+ python3 -m "nose" --with-timer --verbose tests/python/unittest
+
+ popd
+}
+
+build_amzn_linux_cpu() {
+ cd /work/build
+ cmake\
+ -DUSE_CUDA=OFF\
+ -DUSE_OPENCV=ON\
+ -DUSE_OPENMP=ON\
+ -DUSE_SIGNAL_HANDLER=ON\
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+ -DUSE_MKL_IF_AVAILABLE=OFF\
+ -DUSE_LAPACK=OFF\
+ -G Ninja /work/mxnet
+ ninja
+ export MXNET_LIBRARY_PATH=`pwd`/libmxnet.so
+}
+
+build_arm64() {
+ cmake\
+ -DUSE_CUDA=OFF\
+ -DUSE_OPENCV=OFF\
+ -DUSE_OPENMP=OFF\
+ -DUSE_SIGNAL_HANDLER=ON\
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+ -DUSE_MKL_IF_AVAILABLE=OFF\
+ -G Ninja /work/mxnet
+ ninja
+ export MXNET_LIBRARY_PATH=`pwd`/libmxnet.so
+ cd /work/mxnet/python
+ python setup.py bdist_wheel --universal
+ cp dist/*.whl /work/build
+}
+
+build_android_arm64() {
+ set -ex
+ cd /work/build
+ cmake\
+ -DUSE_CUDA=OFF\
+ -DUSE_OPENCV=OFF\
+ -DUSE_OPENMP=OFF\
+ -DUSE_SIGNAL_HANDLER=ON\
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+ -DUSE_MKL_IF_AVAILABLE=OFF\
+ -G Ninja /work/mxnet
+ ninja
+ export MXNET_LIBRARY_PATH=`pwd`/libmxnet.so
+ cd /work/mxnet/python
+ python setup.py bdist_wheel --universal
+ cp dist/*.whl /work/build
+
+
+}
+
+build_ubuntu_gpu() {
+ # TODO
+ set -ex
+ echo FIXME
+}
+
+build_centos7_cpu() {
+ set -ex
+ cd /work/mxnet
+ make \
+ DEV=1 \
+ USE_PROFILER=1 \
+ USE_BLAS=openblas \
+ -j$(nproc)
+}
+
+build_centos7_gpu() {
+ set -ex
+ cd /work/mxnet
+ make \
+ DEV=1 \
+ USE_PROFILER=1 \
+ USE_BLAS=openblas \
+ USE_CUDA=1 \
+ USE_CUDA_PATH=/usr/local/cuda \
+ USE_CUDNN=1 \
+ -j$(nproc)
+}
+
+test_centos7_cpu() {
+ set -ex
+ cd /work/mxnet
+ python3.6 -m "nose" --with-timer --verbose tests/python/unittest
+ python3.6 -m "nose" --with-timer --verbose tests/python/train
+}
+
+test_centos7_gpu() {
+ set -ex
+ cd /work/mxnet
+ python3.6 -m "nose" --with-timer --verbose tests/python/gpu
+}
+
+
+
+
+# Testing
+
+sanity_check() {
+ set -ex
+ tools/license_header.py check
+ make cpplint rcpplint jnilint
+ make pylint
+}
+
+
+##############################################################
+# MAIN
+#
+# Run function passed as argument
+set +x
+if [ $# -gt 0 ]
+then
+ $@
+else
+ cat<<EOF
+
+$0: Execute a function by passing it as an argument to the script:
+
+Possible commands:
+
+EOF
+ declare -F | cut -d' ' -f3
+ echo
+fi
diff --git a/ci/docker/Dockerfile.build.amzn_linux_cpu b/ci/docker/Dockerfile.build.amzn_linux_cpu
new file mode 100644
index 00000000000..75a3ff33135
--- /dev/null
+++ b/ci/docker/Dockerfile.build.amzn_linux_cpu
@@ -0,0 +1,6 @@
+FROM amazonlinux
+COPY install_functions.sh /work/
+COPY build_functions.sh /work/
+WORKDIR /work/deps
+RUN /work/install_functions.sh amzn_linux_install_all_deps
+WORKDIR /work/mxnet
diff --git a/ci/docker/Dockerfile.build.android_arm64 b/ci/docker/Dockerfile.build.android_arm64
new file mode 100644
index 00000000000..198fc97ed1d
--- /dev/null
+++ b/ci/docker/Dockerfile.build.android_arm64
@@ -0,0 +1,51 @@
+# -*- mode: dockerfile -*-
+FROM dockcross/base:latest
+MAINTAINER Pedro Larroy "pllarroy@amazon.com"
+
+# The cross-compiling emulator
+RUN apt-get update && apt-get install -y \
+ qemu-user \
+ qemu-user-static \
+ unzip
+
+ENV CROSS_TRIPLE=aarch64-linux-android
+ENV CROSS_ROOT=/usr/${CROSS_TRIPLE}
+ENV AS=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-as \
+ AR=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-ar \
+ CC=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-gcc \
+ CPP=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-cpp \
+ CXX=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-g++ \
+ LD=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-ld
+
+
+ENV DEFAULT_DOCKCROSS_IMAGE dockcross/android-arm
+
+# Build-time metadata as defined at http://label-schema.org
+ARG BUILD_DATE
+ARG IMAGE
+ARG VCS_REF
+ARG VCS_URL
+LABEL org.label-schema.build-date=$BUILD_DATE \
+ org.label-schema.name=$IMAGE \
+ org.label-schema.vcs-ref=$VCS_REF \
+ org.label-schema.vcs-url=$VCS_URL \
+ org.label-schema.schema-version="1.0"
+
+ENV ARCH aarch64
+
+# Build OpenBLAS
+# https://github.com/xianyi/OpenBLAS/wiki/How-to-build-OpenBLAS-for-Android
+#ENV OPENBLAS_ROOT /work/OpenBLAS
+#ENV LIBRARY_PATH /work/OpenBLAS/lib/:/work/OpenBLAS/:$LIBRARY_PATH
+#ENV CPLUS_INCLUDE_PATH /work/OpenBLAS/include/:/work/OpenBLAS/:$CPLUS_INCLUDE_PATH
+#WORKDIR /work
+
+ENV CC=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-clang
+ENV CXX=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-clang++
+
+COPY install_functions.sh /work/
+COPY build_functions.sh /work/
+WORKDIR /work/deps
+RUN /work/install_functions.sh android_arm64_install_ndk
+RUN /work/install_functions.sh android_arm64_install_openblas
+WORKDIR /work/build
diff --git a/ci/docker/Dockerfile.build.android_armv7 b/ci/docker/Dockerfile.build.android_armv7
new file mode 100644
index 00000000000..12d53a41222
--- /dev/null
+++ b/ci/docker/Dockerfile.build.android_armv7
@@ -0,0 +1,78 @@
+# -*- mode: dockerfile -*-
+FROM dockcross/base:latest
+MAINTAINER Pedro Larroy "pllarroy@amazon.com"
+
+# The cross-compiling emulator
+RUN apt-get update && apt-get install -y \
+ qemu-user \
+ qemu-user-static \
+ unzip
+
+ENV CROSS_TRIPLE=arm-linux-androideabi
+ENV CROSS_ROOT=/usr/${CROSS_TRIPLE}
+ENV AS=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-as \
+ AR=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-ar \
+ CC=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-gcc \
+ CPP=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-cpp \
+ CXX=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-g++ \
+ LD=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-ld
+
+ENV ANDROID_NDK_REVISION 15c
+RUN mkdir -p /build && \
+ cd /build && \
+ curl -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip && \
+ unzip ./android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip && \
+ cd android-ndk-r${ANDROID_NDK_REVISION} && \
+ ./build/tools/make_standalone_toolchain.py \
+ --stl=libc++ \
+ --arch arm \
+ --api 16 \
+ --install-dir=${CROSS_ROOT} && \
+ cd / && \
+ rm -rf /build && \
+ find ${CROSS_ROOT} -exec chmod a+r '{}' \; && \
+ find ${CROSS_ROOT} -executable -exec chmod a+x '{}' \;
+
+
+ENV DEFAULT_DOCKCROSS_IMAGE dockcross/android-arm
+
+# COPY Toolchain.cmake ${CROSS_ROOT}/
+# ENV CMAKE_TOOLCHAIN_FILE ${CROSS_ROOT}/Toolchain.cmake
+
+# Build-time metadata as defined at http://label-schema.org
+ARG BUILD_DATE
+ARG IMAGE
+ARG VCS_REF
+ARG VCS_URL
+LABEL org.label-schema.build-date=$BUILD_DATE \
+ org.label-schema.name=$IMAGE \
+ org.label-schema.vcs-ref=$VCS_REF \
+ org.label-schema.vcs-url=$VCS_URL \
+ org.label-schema.schema-version="1.0"
+
+ENV CC /usr/arm-linux-androideabi/bin/arm-linux-androideabi-gcc
+ENV CXX /usr/arm-linux-androideabi/bin/arm-linux-androideabi-g++
+
+# Build OpenBLAS
+# https://github.com/xianyi/OpenBLAS/wiki/How-to-build-OpenBLAS-for-Android
+RUN git clone https://github.com/xianyi/OpenBLAS.git && \
+ cd OpenBLAS && \
+ make -j$(nproc) TARGET=ARMV7 ARM_SOFTFP_ABI=1 HOSTCC=gcc NOFORTRAN=1 libs
+
+ENV OPENBLAS_ROOT /work/OpenBLAS
+ENV LIBRARY_PATH /work/OpenBLAS/lib/:/work/OpenBLAS/:$LIBRARY_PATH
+ENV CPLUS_INCLUDE_PATH /work/OpenBLAS/include/:/work/OpenBLAS/:$CPLUS_INCLUDE_PATH
+WORKDIR /work
+
+ENV CC /usr/arm-linux-androideabi/bin/arm-linux-androideabi-clang
+ENV CXX /usr/arm-linux-androideabi/bin/arm-linux-androideabi-clang++
+ENV BUILD_OPTS "USE_BLAS=openblas USE_SSE=0 DMLC_LOG_STACK_TRACE=0 USE_OPENCV=0 USE_LAPACK=0"
+
+# Build MXNet
+ADD mxnet mxnet
+ADD arm.crosscompile.android.mk /work/mxnet/make/config.mk
+RUN cd mxnet && \
+ make -j$(nproc) $BUILD_OPTS
+
+WORKDIR /work/build/
+RUN cp /work/mxnet/lib/* .
diff --git a/ci/docker/Dockerfile.build.arm64 b/ci/docker/Dockerfile.build.arm64
new file mode 100644
index 00000000000..69c3faa8c4f
--- /dev/null
+++ b/ci/docker/Dockerfile.build.arm64
@@ -0,0 +1,19 @@
+# -*- mode: dockerfile -*-
+# dockerfile to build libmxnet.so for armv7
+FROM dockcross/linux-arm64
+
+ENV ARCH aarch64
+ENV CC /usr/bin/aarch64-linux-gnu-gcc
+ENV CXX /usr/bin/aarch64-linux-gnu-g++
+ENV FC /usr/bin/aarch64-linux-gnu-gfortran-4.9
+ENV HOSTCC gcc
+
+WORKDIR /work
+
+COPY install_functions.sh /work/
+COPY build_functions.sh /work/
+
+RUN /work/install_functions.sh arm64_install_all_deps
+ENV LD_LIBRARY_PATH /opt/OpenBLAS/lib
+ENV CPLUS_INCLUDE_PATH /opt/OpenBLAS/include
+WORKDIR /work/mxnet
diff --git a/ci/docker/Dockerfile.build.armv7 b/ci/docker/Dockerfile.build.armv7
new file mode 100644
index 00000000000..13a826f9766
--- /dev/null
+++ b/ci/docker/Dockerfile.build.armv7
@@ -0,0 +1,16 @@
+# -*- mode: dockerfile -*-
+# dockerfile to build libmxnet.so for armv7
+FROM dockcross/linux-armv7
+
+ENV ARCH armv71
+ENV CC /usr/bin/arm-linux-gnueabihf-gcc
+ENV CXX /usr/bin/arm-linux-gnueabihf-g++
+
+RUN apt-get update && \
+ apt-get install -y libopenblas-dev:armhf && \
+ rm -rf /var/lib/apt/lists/*
+
+COPY install_functions.sh /work/
+COPY build_functions.sh /work/
+#WORKDIR /work/deps
+WORKDIR /work/build
diff --git a/ci/docker/Dockerfile.build.centos7_cpu b/ci/docker/Dockerfile.build.centos7_cpu
new file mode 100644
index 00000000000..794bfea1d39
--- /dev/null
+++ b/ci/docker/Dockerfile.build.centos7_cpu
@@ -0,0 +1,9 @@
+FROM centos:7
+
+COPY install_functions.sh /work/
+WORKDIR /work/deps
+RUN /work/install_functions.sh centos7_all_deps
+COPY build_functions.sh /work/
+
+ENV PYTHONPATH=./python/
+WORKDIR /work/mxnet
diff --git a/ci/docker/Dockerfile.build.centos7_gpu b/ci/docker/Dockerfile.build.centos7_gpu
new file mode 100644
index 00000000000..b94ad453dda
--- /dev/null
+++ b/ci/docker/Dockerfile.build.centos7_gpu
@@ -0,0 +1,7 @@
+FROM nvidia/cuda:8.0-cudnn5-devel-centos7
+
+COPY install_functions.sh /work/
+WORKDIR /work/deps
+RUN /work/install_functions.sh centos7_all_deps
+COPY build_functions.sh /work/
+WORKDIR /work/mxnet
diff --git a/ci/docker/Dockerfile.build.jetson b/ci/docker/Dockerfile.build.jetson
new file mode 100644
index 00000000000..842c578a80e
--- /dev/null
+++ b/ci/docker/Dockerfile.build.jetson
@@ -0,0 +1,55 @@
+# -*- mode: dockerfile -*-
+# dockerfile to build libmxnet.so, and a python wheel for the Jetson TX1/TX2
+# This script assumes /work/mxnet exists and contains the mxnet code you wish to compile and
+# that /work/build exists and is the target for your output.
+
+FROM nvidia/cuda:8.0-cudnn6-devel as cudabuilder
+
+FROM dockcross/linux-arm64
+
+ENV ARCH aarch64
+ENV NVCCFLAGS "-m64"
+ENV CC /usr/bin/aarch64-linux-gnu-gcc
+ENV CXX /usr/bin/aarch64-linux-gnu-g++
+ENV FC /usr/bin/aarch64-linux-gnu-gfortran-4.9
+ENV HOSTCC gcc
+
+WORKDIR /work
+
+# Build OpenBLAS
+ADD https://api.github.com/repos/xianyi/OpenBLAS/git/refs/heads/master /tmp/openblas_version.json
+RUN git clone https://github.com/xianyi/OpenBLAS.git && \
+ cd OpenBLAS && \
+ make -j$(nproc) TARGET=ARMV8 && \
+ PREFIX=/usr make install
+
+# Setup CUDA build env (including configuring and copying nvcc)
+COPY --from=cudabuilder /usr/local/cuda /usr/local/cuda
+ENV PATH $PATH:/usr/local/cuda/bin
+ENV TARGET_ARCH aarch64
+ENV TARGET_OS linux
+
+# Install ARM depedencies based on Jetpack 3.1
+RUN JETPACK_DOWNLOAD_PREFIX=http://developer.download.nvidia.com/devzone/devcenter/mobile/jetpack_l4t/013/linux-x64 && \
+ ARM_CUDA_INSTALLER_PACKAGE=cuda-repo-l4t-8-0-local_8.0.84-1_arm64.deb && \
+ ARM_CUDNN_INSTALLER_PACKAGE=libcudnn6_6.0.21-1+cuda8.0_arm64.deb && \
+ ARM_CUDNN_DEV_INSTALLER_PACKAGE=libcudnn6-dev_6.0.21-1+cuda8.0_arm64.deb && \
+ wget -nv $JETPACK_DOWNLOAD_PREFIX/$ARM_CUDA_INSTALLER_PACKAGE && \
+ wget -nv $JETPACK_DOWNLOAD_PREFIX/$ARM_CUDNN_INSTALLER_PACKAGE && \
+ wget -nv $JETPACK_DOWNLOAD_PREFIX/$ARM_CUDNN_DEV_INSTALLER_PACKAGE && \
+ dpkg -i $ARM_CUDA_INSTALLER_PACKAGE && \
+ dpkg -i $ARM_CUDNN_INSTALLER_PACKAGE && \
+ dpkg -i $ARM_CUDNN_DEV_INSTALLER_PACKAGE && \
+ apt update -y && \
+ apt install cuda-cudart-cross-aarch64-8-0 cuda-cublas-cross-aarch64-8-0 \
+ cuda-nvml-cross-aarch64-8-0 cuda-nvrtc-cross-aarch64-8-0 cuda-cufft-cross-aarch64-8-0 \
+ cuda-curand-cross-aarch64-8-0 cuda-cusolver-cross-aarch64-8-0 cuda-cusparse-cross-aarch64-8-0 \
+ cuda-misc-headers-cross-aarch64-8-0 cuda-npp-cross-aarch64-8-0 libcudnn6 -y && \
+ cp /usr/local/cuda-8.0/targets/aarch64-linux/lib/*.so /usr/local/cuda/lib64/ && \
+ cp /usr/local/cuda-8.0/targets/aarch64-linux/lib/stubs/*.so /usr/local/cuda/lib64/stubs/ && \
+ cp -r /usr/local/cuda-8.0/targets/aarch64-linux/include/ /usr/local/cuda/include/ && \
+ rm $ARM_CUDA_INSTALLER_PACKAGE $ARM_CUDNN_INSTALLER_PACKAGE $ARM_CUDNN_DEV_INSTALLER_PACKAGE
+
+COPY install_functions.sh /work/
+COPY build_functions.sh /work/
+WORKDIR /work/mxnet
diff --git a/ci/docker/Dockerfile.build.ubuntu_cpu b/ci/docker/Dockerfile.build.ubuntu_cpu
new file mode 100644
index 00000000000..e8727dc0806
--- /dev/null
+++ b/ci/docker/Dockerfile.build.ubuntu_cpu
@@ -0,0 +1,6 @@
+FROM ubuntu:16.04
+COPY install_functions.sh /work/
+COPY build_functions.sh /work/
+WORKDIR /work/deps
+RUN /work/install_functions.sh ubuntu_install_all_deps
+WORKDIR /work/mxnet
diff --git a/ci/docker/Dockerfile.build.ubuntu_gpu b/ci/docker/Dockerfile.build.ubuntu_gpu
new file mode 100644
index 00000000000..bfa2c126475
--- /dev/null
+++ b/ci/docker/Dockerfile.build.ubuntu_gpu
@@ -0,0 +1,6 @@
+FROM nvidia/cuda:8.0-cudnn5-devel
+COPY install_functions.sh /work/
+COPY build_functions.sh /work/
+WORKDIR /work/deps
+RUN /work/install_functions.sh ubuntu_install_all_deps
+WORKDIR /work/mxnet
diff --git a/ci/install_functions.sh b/ci/install_functions.sh
new file mode 100755
index 00000000000..66fb3cece24
--- /dev/null
+++ b/ci/install_functions.sh
@@ -0,0 +1,384 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+set -ex
+
+# This script handles installation of build and test dependencies
+# for different platforms.
+
+#############################
+# Ubuntu Dependencies:
+
+ubuntu_install_all_deps() {
+ set -ex
+ ubuntu_install_core
+ ubuntu_install_python
+ ubuntu_install_scala
+ ubuntu_install_r
+ ubuntu_install_perl
+ ubuntu_install_lint
+}
+
+
+ubuntu_install_core() {
+ set -ex
+ apt-get update
+ apt-get install -y \
+ build-essential \
+ git \
+ libopenblas-dev \
+ liblapack-dev \
+ libopencv-dev \
+ libcurl4-openssl-dev \
+ cmake \
+ wget \
+ unzip \
+ sudo \
+ ninja-build \
+ python-pip
+
+ # Link Openblas to Cblas as this link does not exist on ubuntu16.04
+ ln -s /usr/lib/libopenblas.so /usr/lib/libcblas.so
+ pip install cpplint==1.3.0 pylint==1.8.2
+}
+
+ubuntu_install_nvidia() {
+ set -ex
+ apt install -y software-properties-common
+ add-apt-repository -y ppa:graphics-drivers
+ # Retrieve ppa:graphics-drivers and install nvidia-drivers.
+ # Note: DEBIAN_FRONTEND required to skip the interactive setup steps
+ apt update
+ DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends cuda-8-0
+}
+
+ubuntu_install_perl() {
+ set -ex
+ # install libraries for mxnet's perl package on ubuntu
+ apt-get install -y libmouse-perl pdl cpanminus swig libgraphviz-perl
+ cpanm -q Function::Parameters Hash::Ordered
+}
+
+ubuntu_install_python() {
+ set -ex
+ # install libraries for mxnet's python package on ubuntu
+ apt-get install -y python-dev python3-dev virtualenv
+
+ # the version of the pip shipped with ubuntu may be too lower, install a recent version here
+ wget -nv https://bootstrap.pypa.io/get-pip.py
+ python3 get-pip.py
+ python2 get-pip.py
+
+ pip2 install nose pylint numpy nose-timer requests h5py scipy
+ pip3 install nose pylint numpy nose-timer requests h5py scipy
+}
+
+ubuntu_install_r() {
+ set -ex
+ # install libraries for mxnet's r package on ubuntu
+ echo "deb http://cran.rstudio.com/bin/linux/ubuntu trusty/" >> /etc/apt/sources.list
+ gpg --keyserver keyserver.ubuntu.com --recv-key E084DAB9
+ gpg -a --export E084DAB9 | apt-key add -
+
+ apt-get update
+ apt-get install -y r-base r-base-dev libxml2-dev libssl-dev libxt-dev
+}
+
+ubuntu_install_scala() {
+ set -ex
+ # install libraries for mxnet's scala package on ubuntu
+ apt-get install -y software-properties-common
+ add-apt-repository -y ppa:webupd8team/java
+ apt-get update
+ echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections
+ apt-get install -y oracle-java8-installer
+ apt-get install -y oracle-java8-set-default
+ apt-get update && apt-get install -y maven
+}
+
+
+ubuntu_install_lint() {
+ set -ex
+ apt-get update
+ apt-get install -y python-pip sudo
+ #pip install cpplint==1.3.0 pylint==1.8.2
+}
+
+#############################
+# Amazon Linux
+
+amzn_linux_install_all_deps() {
+ pushd .
+ mkdir deps
+ amzn_linux_install_core
+ amzn_linux_install_opencv
+ amzn_linux_install_openblas
+ amzn_linux_install_python2
+ amzn_linux_install_python3
+ amzn_linux_install_testdeps
+ amzn_linux_install_julia
+ amzn_linux_install_maven
+ amzn_linux_install_library
+ popd
+}
+
+amzn_linux_install_core() {
+ set -ex
+ pushd .
+ yum install -y git
+ yum install -y wget
+ yum install -y sudo
+ yum install -y re2c
+ yum groupinstall -y 'Development Tools'
+
+ # Ninja
+ git clone --recursive https://github.com/ninja-build/ninja.git
+ cd ninja
+ ./configure.py --bootstrap
+ cp ninja /usr/local/bin
+ popd
+
+ # CMake
+ pushd .
+ git clone --recursive https://github.com/Kitware/CMake.git --branch v3.10.2
+ cd CMake
+ ./bootstrap
+ make -j$(nproc)
+ make install
+ popd
+}
+
+amzn_linux_install_opencv() {
+ set -ex
+ pushd .
+ yum install -y python27 python27-setuptools
+ git clone https://github.com/opencv/opencv
+ cd opencv
+ mkdir -p build
+ cd build
+ cmake -DBUILD_opencv_gpu=OFF -DWITH_EIGEN=ON -DWITH_TBB=ON -DWITH_CUDA=OFF -DWITH_1394=OFF \
+ -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=/usr/local -GNinja ..
+ #make PREFIX=/usr/local install
+ ninja install
+ popd
+}
+
+amzn_linux_install_openblas() {
+ set -ex
+ pushd .
+ git clone https://github.com/xianyi/OpenBLAS
+ cd OpenBLAS
+ make FC=gfortran -j $(($(nproc) + 1))
+ make PREFIX=/usr/local install
+ popd
+}
+
+amzn_linux_install_python2() {
+ set -ex
+ yum groupinstall -y "Development Tools"
+ yum install -y mlocate python27 python27-setuptools python27-tools python27-numpy python27-scipy python27-nose python27-matplotlib unzip
+ ln -s -f /usr/bin/python2.7 /usr/bin/python2
+ wget -nv https://bootstrap.pypa.io/get-pip.py
+ python2 get-pip.py
+ $(which easy_install-2.7) --upgrade pip
+ if [ -f /usr/local/bin/pip ] && [ -f /usr/bin/pip ]; then
+ mv /usr/bin/pip /usr/bin/pip.bak
+ ln /usr/local/bin/pip /usr/bin/pip
+ fi
+
+ ln -s -f /usr/local/bin/pip /usr/bin/pip
+ for i in ipython[all] jupyter pandas scikit-image h5py pandas sklearn sympy; do echo "${i}..."; pip install -U $i >/dev/null; done
+}
+
+
+amzn_linux_install_python3() {
+ set -ex
+ pushd .
+ wget -nv https://bootstrap.pypa.io/get-pip.py
+ mkdir py3
+ cd py3
+ wget -nv https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz
+ tar -xvzf Python-3.5.2.tgz
+ cd Python-3.5.2
+ yum install -y zlib-devel openssl-devel sqlite-devel bzip2-devel gdbm-devel ncurses-devel xz-devel readline-devel
+ ./configure --prefix=/opt/ --with-zlib-dir=/usr/lib64
+ make -j$(nproc)
+ mkdir /opt/bin
+ mkdir /opt/lib
+ make install
+ ln -s -f /opt/bin/python3 /usr/bin/python3
+ cd ../..
+ python3 get-pip.py
+ ln -s -f /opt/bin/pip /usr/bin/pip3
+
+ mkdir -p /home/jenkins/.local/lib/python3.5/site-packages/
+ pip3 install numpy
+ popd
+}
+
+amzn_linux_install_testdeps() {
+ set -ex
+ pip install cpplint 'pylint==1.4.4' 'astroid==1.3.6'
+ pip3 install nose
+ ln -s -f /opt/bin/nosetests /usr/local/bin/nosetests3
+ ln -s -f /opt/bin/nosetests-3.4 /usr/local/bin/nosetests-3.4
+}
+
+amzn_linux_install_julia() {
+ set -ex
+ wget -nv https://julialang.s3.amazonaws.com/bin/linux/x64/0.5/julia-0.5.0-linux-x86_64.tar.gz
+ mv julia-0.5.0-linux-x86_64.tar.gz /tmp/
+ tar xfvz /tmp/julia-0.5.0-linux-x86_64.tar.gz
+ rm -f /tmp/julia-0.5.0-linux-x86_64.tar.gz
+ # tar extracted in current directory
+ ln -s -f ${PWD}/julia-3c9d75391c/bin/julia /usr/bin/julia
+}
+
+amzn_linux_install_maven() {
+ set -ex
+ wget -nv http://mirrors.ocf.berkeley.edu/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
+ mv apache-maven-3.3.9-bin.tar.gz /tmp/
+ tar xfvz /tmp/apache-maven-3.3.9-bin.tar.gz
+ yum install -y java-1.8.0-openjdk-devel
+}
+
+
+amzn_linux_install_library() {
+ yum -y install graphviz
+ pip install graphviz
+ pip install opencv-python
+}
+
+centos7_all_deps() {
+ set -ex
+ centos7_install_core
+ centos7_install_python
+}
+
+centos7_install_core() {
+ # Multipackage installation does not fail in yum
+ yum -y install epel-release
+ yum -y install git
+ yum -y install wget
+ yum -y install atlas-devel # Provide clbas headerfiles
+ yum -y install openblas-devel
+ yum -y install lapack-devel
+ yum -y install opencv-devel
+ yum -y install openssl-devel
+ yum -y install gcc-c++
+ yum -y install make
+ yum -y install cmake
+ yum -y install wget
+ yum -y install unzip
+ yum -y install ninja-build
+}
+
+centos7_install_python() {
+ # Python 2.7 is installed by default, install 3.6 on top
+ yum -y install https://centos7.iuscommunity.org/ius-release.rpm
+ yum -y install python36u
+
+ # Install PIP
+ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
+ python2.7 get-pip.py
+ python3.6 get-pip.py
+
+ pip2 install nose pylint numpy nose-timer requests h5py scipy
+ pip3 install nose pylint numpy nose-timer requests h5py scipy
+}
+
+install_mkml() {
+ set -ex
+ pushd .
+ wget -nv --no-check-certificate -O /tmp/mklml.tgz https://github.com/01org/mkl-dnn/releases/download/v0.12/mklml_lnx_2018.0.1.20171227.tgz
+ tar -zxvf /tmp/mklml.tgz && cp -rf mklml_*/* /usr/local/ && rm -rf mklml_*
+ # ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/lib/gcc/x86_64-linux-gnu/5/
+ popd
+}
+
+
+arm64_install_all_deps() {
+ arm64_install_openblas
+}
+
+arm64_install_openblas() {
+ set -ex
+ pushd .
+ wget -nv https://api.github.com/repos/xianyi/OpenBLAS/git/refs/heads/master -O openblas_version.json
+ echo "Using openblas:"
+ cat openblas_version.json
+ git clone https://github.com/xianyi/OpenBLAS.git
+ cd OpenBLAS
+ make -j$(nproc) TARGET=ARMV8
+ make install
+ ln -s /opt/OpenBLAS/lib/libopenblas.so /usr/lib/libopenblas.so
+ ln -s /opt/OpenBLAS/lib/libopenblas.a /usr/lib/libopenblas.a
+ ln -s /opt/OpenBLAS/lib/libopenblas.a /usr/lib/liblapack.a
+ popd
+}
+
+android_arm64_install_all_deps() {
+ android_arm64_install_ndk
+ android_arm64_install_openblas
+}
+
+android_arm64_install_openblas() {
+ set -ex
+ pushd .
+ git clone https://github.com/xianyi/OpenBLAS.git
+ cd OpenBLAS
+ make -j$(nproc) TARGET=ARMV8 ARM_SOFTFP_ABI=1 HOSTCC=gcc NOFORTRAN=1 libs
+ cp libopenblas.a /usr/local/lib
+ popd
+}
+
+android_arm64_install_ndk() {
+ set -ex
+ pushd .
+ export ANDROID_NDK_REVISION=15c
+ curl -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip && \
+ unzip ./android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip && \
+ cd android-ndk-r${ANDROID_NDK_REVISION} && \
+ ./build/tools/make_standalone_toolchain.py \
+ --stl=libc++ \
+ --arch arm64 \
+ --api 21 \
+ --install-dir=${CROSS_ROOT} && \
+
+ popd
+}
+
+##############################################################
+# MAIN
+#
+# Run function passed as argument
+set +x
+if [ $# -gt 0 ]
+then
+ $@
+else
+ cat<<EOF
+
+$0: Execute a function by passing it as an argument to the script:
+
+Possible commands:
+
+EOF
+ declare -F | cut -d' ' -f3
+ echo
+fi
diff --git a/python/mxnet/libinfo.py b/python/mxnet/libinfo.py
index 9a82b797a90..1f6e065dd2e 100644
--- a/python/mxnet/libinfo.py
+++ b/python/mxnet/libinfo.py
@@ -20,6 +20,7 @@
from __future__ import absolute_import
import os
import platform
+import logging
def find_lib_path():
"""Find MXNet dynamic library files.
@@ -29,6 +30,16 @@ def find_lib_path():
lib_path : list(string)
List of all found path to the libraries.
"""
+ lib_from_env = os.environ.get('MXNET_LIBRARY_PATH')
+ if lib_from_env:
+ if os.path.isfile(lib_from_env):
+ if not os.path.isabs(lib_from_env):
+ logging.warn("MXNET_LIBRARY_PATH should be an absolute path, instead of: %s", lib_from_env)
+ else:
+ return [lib_from_env]
+ else:
+ logging.warn("MXNET_LIBRARY_PATH '%s' doesn't exist", lib_from_env)
+
curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
api_path = os.path.join(curr_path, '../../lib/')
cmake_build_path = os.path.join(curr_path, '../../build/')
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
With regards,
Apache Git Services