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

add support for desktop examples on MacOS (Apple Silicon M1=arm64/ x86_64/ i386) #2591

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
6 changes: 6 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,16 @@ build:ios_fat --config=ios
build:ios_fat --ios_multi_cpus=armv7,arm64
build:ios_fat --watchos_cpus=armv7k

# MacOS configs.
build:darwin_x86_64 --apple_platform_type=macos
build:darwin_x86_64 --macos_minimum_os=10.12
build:darwin_x86_64 --cpu=darwin_x86_64

# MacOS Big Sur with Apple Silicon M1
build:darwin_arm64 --apple_platform_type=macos
build:darwin_arm64 --macos_minimum_os=10.16
build:darwin_arm64 --cpu=darwin_arm64

# This bazelrc file is meant to be written by a setup script.
try-import %workspace%/.configure.bazelrc

Expand Down
107 changes: 107 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,113 @@ The source code is hosted in the
run code search using
[Google Open Source Code Search](https://cs.opensource.google/mediapipe/mediapipe).

### Build on MacOS

#### Prepare
1. install bazel/opencv/ffmpeg:
```bash
brew install bazel
brew install opencv@3
brew install ffmpeg
```

2. Set .bazelversion:
Run
```bash
brew list bazel
```
to get bazel version, which may print:
```
/opt/homebrew/Cellar/bazel/4.1.0/bin/bazel
/opt/homebrew/Cellar/bazel/4.1.0/bin/bazel-4.1.0
/opt/homebrew/Cellar/bazel/4.1.0/etc/bash_completion.d/bazel-complete.bash
/opt/homebrew/Cellar/bazel/4.1.0/libexec/bin/ (3 files)
/opt/homebrew/Cellar/bazel/4.1.0/share/zsh/site-functions/_bazel```
```

Update .bazelversion:
```bash
echo 4.1.0 > .bazelversion
```

1. Set the right paths to opencv/ffmpeg in WORKSPACE (line 212~222), for example:
```
new_local_repository(
name = "macos_opencv",
build_file = "@//third_party:opencv_macos.BUILD",
path = "/opt/homebrew/Cellar/opencv@3/3.4.14_3",
)

new_local_repository(
name = "macos_ffmpeg",
build_file = "@//third_party:ffmpeg_macos.BUILD",
path = "/opt/homebrew/Cellar/ffmpeg/4.4_2",
)
```

#### CPU: Apple Silicon M1
1. Build "hello_world":
```bash
bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --cpu darwin_arm64 mediapipe/examples/desktop/hello_world:hello_world
```
and run:
```bash
export GLOG_logtostderr=1
bazel-bin/mediapipe/examples/desktop/hello_world/hello_world
```
2. Build all available examples under mediapipe/examples/desktop:
```bash
bash build_macos_desktop_examples.sh --cpu m1 -b
```

3. Build and run one example app (e.g. mediapipe/examples/desktop/face_detection):
```
bash build_macos_desktop_examples.sh --cpu m1 --app face_detection -r
```

#### CPU: x86_64
1. Build "hello_world":
```bash
bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --cpu darwin_x86_64 mediapipe/examples/desktop/hello_world:hello_world
```
and run:
```bash
export GLOG_logtostderr=1
bazel-bin/mediapipe/examples/desktop/hello_world/hello_world
```

2. Build all available examples under mediapipe/examples/desktop:
```bash
bash build_macos_desktop_examples.sh --cpu x86_64 -b
Copy link

@mgebhard mgebhard Dec 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super helpful I finally got helloworld to build on my m1 but any help with:

In file included from mediapipe/util/annotation_renderer.cc:15:
In file included from ./mediapipe/util/annotation_renderer.h:20:
./mediapipe/framework/port/opencv_core_inc.h:18:10: fatal error: 'opencv2/core/version.hpp' file not found
#include <opencv2/core/version.hpp>
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Error in child process '/usr/bin/xcrun'. 1
Target //mediapipe/examples/desktop/face_detection:face_detection_cpu failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 1.591s, Critical Path: 1.41s
INFO: 175 processes: 131 internal, 44 darwin-sandbox.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mgebhard try modifiy the third_party/opencv_macos.BUILD :

--- a/third_party/opencv_macos.BUILD
+++ b/third_party/opencv_macos.BUILD
@@ -19,8 +19,8 @@ cc_library(
             "lib/libopencv_videoio.dylib",
         ],
     ),
-    hdrs = glob(["include/opencv2/**/*.h*"]),
-    includes = ["include/"],
+    hdrs = glob(["include/opencv4/opencv2/**/*.h*"]),
+    includes = ["include/opencv4/"],
     linkstatic = 1,
     visibility = ["//visibility:public"],
 )

```

3. Build and run one example app (e.g. mediapipe/examples/desktop/face_detection):
```
bash build_macos_desktop_examples.sh --cpu x86_64 --app face_detection -r
```

#### CPU: i386
1. Build "hello_world":
```bash
bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --cpu darwin_i386 mediapipe/examples/desktop/hello_world:hello_world
```

and run:
```bash
export GLOG_logtostderr=1
bazel-bin/mediapipe/examples/desktop/hello_world/hello_world
```

2. Build all available examples under mediapipe/examples/desktop:
```bash
bash build_macos_desktop_examples.sh --cpu i386 -b
```

3. Build and run one example app (e.g. mediapipe/examples/desktop/face_detection):
```
bash build_macos_desktop_examples.sh --cpu i386 --app face_detection -r
```

## Publications

* [Bringing artworks to life with AR](https://developers.googleblog.com/2021/07/bringing-artworks-to-life-with-ar.html)
Expand Down
12 changes: 12 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
workspace(name = "mediapipe")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
],
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
Expand Down
149 changes: 149 additions & 0 deletions build_macos_desktop_examples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/bin/bash
# Copyright 2020 The MediaPipe Authors.
#
# Licensed 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.
# =========================================================================
#
# Script to build/run all MediaPipe desktop example apps (with webcam input).
#
# CPU options: [arm64/m1/M1, x86_64, i386]
# To only build "face_detection" app and store it in out_dir for MacOS with M1 CPU:
# $ ./build_desktop_examples.sh -c m1 -d out_dir -a face_detection
# Omitting -d and the associated directory saves all generated apps in the
# current directory.
# To build and run all apps and store them in out_dir for MacOS with M1 CPU:
# $ ./build_desktop_examples.sh -c m1 -d out_dir
# Omitting -d and the associated directory saves all generated apps in the
# current directory.
# To build all apps and store them in out_dir for MacOS with x86_64 CPU:
# $ ./build_desktop_examples.sh -c x86_64 -d out_dir -b
# Omitting -d and the associated directory saves all generated apps in the
# current directory.
# To run all apps already stored in out_dir:
# $ ./build_desktop_examples.sh -d out_dir -r
# Omitting -d and the associated directory assumes all apps are in the current
# directory.

set -e

out_dir="."
build_only=false
run_only=false
# cpu options: [arm64/m1/M1, x86_64, i386]
# corresponding bazel cpu options: [darwin_arm64, darwin_x86_64, darwin]
cpu="arm64"
app_dir="mediapipe/examples/desktop"
app_name=""
bin_dir="bazel-bin"

while [[ -n $1 ]]; do
case $1 in
-d)
shift
out_dir=$1
;;
-c | --cpu)
shift
cpu=$1
;;
-a | --app)
shift
app_name=$1
;;
-b)
build_only=true
;;
-r)
run_only=true
;;
*)
echo "Unsupported input argument $1."
exit 1
;;
esac
shift
done

case $cpu in
x86_64 | i386)
cpu="darwin_$cpu"
;;
arm64 | m1 | M1)
cpu="darwin_arm64"
;;
*)
echo "Unsupported cpu argument $1."
exit 1
;;
esac

echo "app_dir: $app_dir"
echo "out_dir: $out_dir"
echo "cpu: $cpu"
echo "app_name: $app_name"

declare -a default_bazel_flags=(build -c opt --define MEDIAPIPE_DISABLE_GPU=1 --cpu $cpu)
declare -a bazel_flags

if [[ ! -z "${app_name}" ]]; then
echo "Only build app: ${app_dir}/${app_name}"
declare -a apps=("${app_dir}/${app_name}")
else
echo "Build all available apps under $app_dir"
apps="${app_dir}/*"
fi

for app in ${apps}; do
if [[ -d "${app}" ]]; then
target_name=${app##*/}
if [[ "${target_name}" == "autoflip" ||
"${target_name}" == "hello_world" ||
"${target_name}" == "media_sequence" ||
"${target_name}" == "object_detection_3d" ||
"${target_name}" == "template_matching" ||
"${target_name}" == "youtube8m" ]]; then
echo "Skip ${target_name}"
continue
fi
target="${app}:${target_name}_cpu"

echo "=== Target: ${target}"

if [[ $run_only == false ]]; then
bazel_flags=("${default_bazel_flags[@]}")
bazel_flags+=(${target})

bazel "${bazel_flags[@]}"
cp -f "${bin_dir}/${app}/"*"_cpu" "${out_dir}"
fi
if [[ $build_only == false ]]; then
if [[ ${target_name} == "object_tracking" ]]; then
graph_name="tracking/object_detection_tracking"
elif [[ ${target_name} == "upper_body_pose_tracking" ]]; then
graph_name="pose_tracking/upper_body_pose_tracking"
else
graph_name="${target_name}/${target_name}"
fi
if [[ ${target_name} == "holistic_tracking" ||
${target_name} == "iris_tracking" ||
${target_name} == "pose_tracking" ||
${target_name} == "upper_body_pose_tracking" ]]; then
graph_suffix="cpu"
else
graph_suffix="desktop_live"
fi
GLOG_logtostderr=1 "${out_dir}/${target_name}_cpu" \
--calculator_graph_config_file=mediapipe/graphs/"${graph_name}_${graph_suffix}.pbtxt"
fi
fi
done
12 changes: 11 additions & 1 deletion mediapipe/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ alias(
actual = select({
":macos_i386": ":macos_i386",
":macos_x86_64": ":macos_x86_64",
"//conditions:default": ":macos_i386", # Arbitrarily chosen from above.
":macos_arm64": ":macos_arm64",
"//conditions:default": ":macos_x86_64", # Arbitrarily chosen from above.
}),
visibility = ["//visibility:public"],
)
Expand Down Expand Up @@ -119,6 +120,15 @@ config_setting(
visibility = ["//visibility:public"],
)

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

[
config_setting(
name = arch,
Expand Down