Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Support for macOS #1

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ build --cxxopt="-std=c++14"
build --cxxopt="-D_GLIBCXX_USE_CXX11_ABI=0"
build --auto_output_filter=subpackages
build --copt="-Wall" --copt="-Wno-sign-compare"
build --linkopt="-lrt -lm"

# TF isn't built in dbg mode, so our dbg builds will segfault due to inconsistency
# of defines when using tf's headers. In particular in refcount.h.
Expand Down
8 changes: 8 additions & 0 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"""
import argparse
import os
import platform
import subprocess
import sys

Expand Down Expand Up @@ -69,6 +70,13 @@ def main():
reset_configure_bazelrc()
setup_python(environ_cp)

write_to_bazelrc('')
if platform.system() == 'Darwin':
write_to_bazelrc('# https://github.com/googleapis/google-cloud-cpp-spanner/issues/1003')
write_to_bazelrc('build --copt=-DGRPC_BAZEL_BUILD')
else:
write_to_bazelrc('build --linkopt="-lrt -lm"')


def get_from_env_or_user_or_default(environ_cp, var_name, ask_for_var,
var_default):
Expand Down
1 change: 1 addition & 0 deletions docker/dev.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ ARG pip_dependencies=' \
numpy \
oauth2client \
pandas \
platform \
portpicker'


Expand Down
1 change: 1 addition & 0 deletions docker/release.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ ARG pip_dependencies=' \
numpy \
oauth2client \
pandas \
platform \
portpicker'

# TODO(b/154930404): Update to 2.2.0 once it's out. May need to
Expand Down
55 changes: 39 additions & 16 deletions oss_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,40 @@ for python_version in $PYTHON_VERSIONS; do
bazel clean
fi

if [ "$python_version" = "3.6" ]; then
export PYTHON_BIN_PATH=/usr/bin/python3.6 && export PYTHON_LIB_PATH=/usr/local/lib/python3.6/dist-packages
elif [ "$python_version" = "3.7" ]; then
export PYTHON_BIN_PATH=/usr/local/bin/python3.7 && export PYTHON_LIB_PATH=/usr/local/lib/python3.7/dist-packages
ABI=cp37
elif [ "$python_version" = "3.8" ]; then
export PYTHON_BIN_PATH=/usr/bin/python3.8 && export PYTHON_LIB_PATH=/usr/local/lib/python3.8/dist-packages
ABI=cp38
if [ "$(uname)" = "Darwin" ]; then
if [ "$python_version" = "3.6" ]; then
export PYTHON_BIN_PATH=python3.6
elif [ "$python_version" = "3.7" ]; then
export PYTHON_BIN_PATH=python3.7
ABI=cp37
elif [ "$python_version" = "3.8" ]; then
export PYTHON_BIN_PATH=python3.8
ABI=cp38
else
echo "Error unknown --python. Only [3.6|3.7|3.8]"
exit
fi

export PYTHON_LIB_PATH=`$PYTHON_BIN_PATH -c 'import site; print("\\n".join(site.getsitepackages()))'`
bazel_config=""
version=`sw_vers | grep ProductVersion | awk '{print $2}' | sed 's/\./_/g' | cut -d"_" -f1,2`
PLATFORM="macosx_${version}_x86_64"
else
echo "Error unknown --python. Only [3.6|3.7|3.8]"
exit
if [ "$python_version" = "3.6" ]; then
export PYTHON_BIN_PATH=/usr/bin/python3.6 && export PYTHON_LIB_PATH=/usr/local/lib/python3.6/dist-packages
elif [ "$python_version" = "3.7" ]; then
export PYTHON_BIN_PATH=/usr/local/bin/python3.7 && export PYTHON_LIB_PATH=/usr/local/lib/python3.7/dist-packages
ABI=cp37
elif [ "$python_version" = "3.8" ]; then
export PYTHON_BIN_PATH=/usr/bin/python3.8 && export PYTHON_LIB_PATH=/usr/local/lib/python3.8/dist-packages
ABI=cp38
else
echo "Error unknown --python. Only [3.6|3.7|3.8]"
exit
fi

bazel_config="--config=manylinux2010"
PLATFORM="manylinux2010_x86_64"
fi

# Configures Bazel environment for selected Python version.
Expand All @@ -110,20 +133,20 @@ for python_version in $PYTHON_VERSIONS; do
# someone's system unexpectedly. We are executing the python tests after
# installing the final package making this approach satisfactory.
# TODO(b/157223742): Execute Python tests as well.
bazel test -c opt --copt=-mavx --config=manylinux2010 --test_output=errors //reverb/cc/...
bazel test -c opt --copt=-mavx $bazel_config --test_output=errors //reverb/cc/...

# Builds Reverb and creates the wheel package.
bazel build -c opt --copt=-mavx --config=manylinux2010 reverb/pip_package:build_pip_package
./bazel-bin/reverb/pip_package/build_pip_package --dst $OUTPUT_DIR $PIP_PKG_EXTRA_ARGS
# # Builds Reverb and creates the wheel package.
bazel build -c opt --copt=-mavx $bazel_config reverb/pip_package:build_pip_package
./bazel-bin/reverb/pip_package/build_pip_package --dst $OUTPUT_DIR $PIP_PKG_EXTRA_ARGS --plat "$PLATFORM"

# Installs pip package.
$PYTHON_BIN_PATH -mpip install ${OUTPUT_DIR}*${ABI}*.whl
$PYTHON_BIN_PATH -mpip install --force-reinstall ${OUTPUT_DIR}*${ABI}*.whl

if [ "$PYTHON_TESTS" = "true" ]; then
echo "Run Python tests..."
set +e

bash run_python_tests.sh |& tee ./unittest_log.txt
bash run_python_tests.sh 2>&1| tee ./unittest_log.txt
UNIT_TEST_ERROR_CODE=$?
set -e
if [[ $UNIT_TEST_ERROR_CODE != 0 ]]; then
Expand Down
9 changes: 9 additions & 0 deletions reverb/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ licenses(["notice"])

exports_files(["LICENSE"])

config_setting(
name = "macos",
values = {
"apple_platform_type": "macos",
"cpu": "darwin",
},
visibility = ["//visibility:public"],
)

reverb_pytype_strict_library(
name = "reverb",
srcs = ["__init__.py"],
Expand Down
27 changes: 19 additions & 8 deletions reverb/cc/platform/default/build_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,16 @@ def reverb_gen_op_wrapper_py(name, out, kernel_lib, linkopts = [], **kwargs):
"-fvisibility=hidden", # avoid symbol clashes between DSOs.
],
linkshared = 1,
linkopts = linkopts + _rpath_linkopts(module_name) + [
"-Wl,--version-script",
"$(location %s)" % version_script_file,
],
linkopts = linkopts + _rpath_linkopts(module_name) + select({
"//reverb:macos": [
"-Wl",
"$(location %s)" % version_script_file,
],
"//conditions:default": [
"-Wl,--version-script",
"$(location %s)" % version_script_file,
],
}),
**kwargs
)
native.genrule(
Expand Down Expand Up @@ -441,10 +447,15 @@ def reverb_pybind_extension(
"-fexceptions", # pybind relies on exceptions, required to compile.
"-fvisibility=hidden", # avoid pybind symbol clashes between DSOs.
],
linkopts = linkopts + _rpath_linkopts(module_name) + [
"-Wl,--version-script",
"$(location %s)" % version_script_file,
],
linkopts = linkopts + _rpath_linkopts(module_name) +
select({"//reverb:macos": [
"-Wl,-exported_symbols_list,$(location %s)" % exported_symbols_file,
],
"//conditions:default": [
"-Wl,--version-script",
"$(location %s)" % version_script_file,
],
}),
deps = depset(deps + [
exported_symbols_file,
version_script_file,
Expand Down
19 changes: 16 additions & 3 deletions reverb/cc/platform/default/repo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ def _find_python_solib_path(repo_ctx):
fail("Could not locate python shared library path:\n{}"
.format(exec_result.stderr))
solib_dir = exec_result.stdout.splitlines()[-1]
if repo_ctx.os.name.lower().find("mac") != -1:
basename = "lib{}m.dylib".format(version)
solib_dir = "/".join(solib_dir.split("/")[:-2])

full_path = repo_ctx.path("{}/{}".format(solib_dir, basename))
if not full_path.exists:
fail("Unable to find python shared library file:\n{}/{}"
Expand Down Expand Up @@ -219,17 +223,20 @@ filegroup(
def _tensorflow_solib_repo_impl(repo_ctx):
tf_lib_path = _find_tf_lib_path(repo_ctx)
repo_ctx.symlink(tf_lib_path, "tensorflow_solib")
suffix = "so.2"
if repo_ctx.os.name.lower().find("mac") != -1:
suffix = "2.dylib"

repo_ctx.file(
"BUILD",
content = """
cc_library(
name = "framework_lib",
srcs = ["tensorflow_solib/libtensorflow_framework.so.2"],
srcs = ["tensorflow_solib/libtensorflow_framework.{}"],
deps = ["@python_includes", "@python_includes//:numpy_includes"],
visibility = ["//visibility:public"],
)
""",
)
""".format(suffix))

def _python_includes_repo_impl(repo_ctx):
python_include_path = _find_python_include_path(repo_ctx)
Expand Down Expand Up @@ -332,6 +339,12 @@ def _reverb_protoc_archive(ctx):
urls = [
"https://github.com/protocolbuffers/protobuf/releases/download/v%s/protoc-%s-linux-x86_64.zip" % (version, version),
]
if ctx.os.name.lower().find("mac") != -1:
urls = [
"https://github.com/protocolbuffers/protobuf/releases/download/v%s/protoc-%s-osx-x86_64.zip" % (version, version),
]
sha256 = "" # TODO(Feiteng) set this in WORKSPACE

ctx.download_and_extract(
url = urls,
sha256 = sha256,
Expand Down
25 changes: 23 additions & 2 deletions reverb/pip_package/build_pip_package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function build_wheel() {
pushd ${TMPDIR} > /dev/null

echo $(date) : "=== Building wheel"
"${PYTHON_BIN_PATH}" setup.py bdist_wheel ${PKG_NAME_FLAG} ${RELEASE_FLAG} ${TF_VERSION_FLAG} --plat manylinux2010_x86_64 > /dev/null
"${PYTHON_BIN_PATH}" setup.py bdist_wheel ${PKG_NAME_FLAG} ${RELEASE_FLAG} ${TF_VERSION_FLAG} --plat $PLATFORM | grep so # > /dev/null
DEST=${TMPDIR}/dist/
if [[ ! "$TMPDIR" -ef "$DESTDIR" ]]; then
mkdir -p ${DESTDIR}
Expand Down Expand Up @@ -69,8 +69,23 @@ function prepare_src() {
# TODO(b/155300149): Don't move .so files to the top-level directory.
# This copies all .so files except for those found in the ops directory, which
# must remain where they are for TF to find them.
find "${TMPDIR}/reverb/cc" -type d -name ops -prune -o -name '*.so' \
find "${TMPDIR}/reverb/cc" -type d -name ops -prune -o -name '*.so' -prune -o -name '*.dylib'

find "${TMPDIR}/reverb/cc" -type d -name ops -prune -o -name '*.so' -prune -o -name '*.dylib' \
-exec mv {} "${TMPDIR}/reverb" \;

# Copy darwin libs over so they can be loaded at runtime
so_lib_dir=$(ls $RUNFILES | grep solib) || true
if [ -n "${so_lib_dir}" ]; then
mkdir -p "${TMPDIR}/${so_lib_dir}"
proto_so_dir=$(ls ${RUNFILES}/${so_lib_dir} | grep proto) || true
for dir in ${proto_so_dir}; do
echo "===== DIR = $dir"
cp -R ${RUNFILES}/${so_lib_dir}/${dir} "${TMPDIR}/${so_lib_dir}"
done

cp -r $TMPDIR/${so_lib_dir} `dirname $PYTHON_LIB_PATH`
fi
}

function usage() {
Expand All @@ -80,6 +95,7 @@ function usage() {
echo " --release build a release version"
echo " --dst path to copy the .whl into."
echo " --tf-version tensorflow version dependency passed to setup.py."
echo " --plat platform."
echo ""
exit 1
}
Expand All @@ -91,6 +107,8 @@ function main() {
# This is where the source code is copied and where the whl will be built.
DST_DIR=""

PLATFORM="manylinux2010_x86_64"

while true; do
if [[ "$1" == "--help" ]]; then
usage
Expand All @@ -103,6 +121,9 @@ function main() {
elif [[ "$1" == "--tf-version" ]]; then
shift
TF_VERSION_FLAG="--tf-version $1"
elif [[ "$1" == "--plat" ]]; then
shift
PLATFORM=$1
fi

if [[ -z "$1" ]]; then
Expand Down
13 changes: 13 additions & 0 deletions reverb/pip_package/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ def run_setup(self):
long_description = f.read()

version, project_name = self._get_version()

so_lib_paths = [
i for i in os.listdir('.')
if os.path.isdir(i) and fnmatch.fnmatch(i, '_solib_*')
]

matches = []
for path in so_lib_paths:
matches.extend(['../' + x for x in find_files('*', path) if '.py' not in x])

setup(
name=project_name,
version=version,
Expand All @@ -125,6 +135,9 @@ def run_setup(self):
packages=find_packages(),
headers=list(find_files('*.proto', 'reverb')),
include_package_data=True,
package_data={
'reverb': matches,
},
install_requires=self._get_required_packages(),
extras_require={
'tensorflow': self._get_tensorflow_packages(),
Expand Down