环境:Ubuntu18.04,gcc/g++ version>8.0, OpenCV version==3.4, Bazel version==3.7.2
1、安装Bazel
见官方文档:Installing Bazel using Bazelisk - Bazel main
2、下载MedianPipe源码
git clone https://github.com/google/mediapipe.git
cd mediapipe
3、安装OpenCV和FFmpeg
MedianPipe源码根目录中有写好的脚本setup_opencv.sh,但是在执行的时候很多opencv的前置依赖项并未安装,导致编译不通过;
参照此文章OpenCV-3编译安装方法及常见错误解决(Ubuntu平台) - 尚码园 安装前置依赖方可正常编译通过。
建议第一次编译不通过时,将setup_opencv.sh下载的opencv3.4和对应的contrib文件备份,同时注释下面几行代码:
#rm -rf /tmp/build_opencv
#mkdir /tmp/build_opencv
cd /tmp/build_opencv
#git clone git://github.com/opencv/opencv_contrib.git
#git clone git://github.com/opencv/opencv.git
cmake .. 后面的选项加上 -DWITH_V4AL=OFF -DWITH_LIBV4L=ON
4、GCC版本问题
ubuntu18.04自带gcc-7.5,编译MediaPipe 的HellowWorld Demo没有问题,但是要进行手势识别的编译,就会报错:
ERROR: /home/ubuntu/mediapipe/mediapipe/calculators/tensor/BUILD:657:11: C++ compilation of rule '//mediapipe/calculators/tensor:image_to_tensor_converter_o
pencv' failed (Exit 1): gcc failed: error executing command /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonh
eap-object -fno-omit-frame-pointer -g0 -O2 '-D_FORTIFY_SOURCE=1' -DNDEBUG -ffunction-sections ... (remaining 57 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox gcc failed: error executing command /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wun
used-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -g0 -O2 '-D_FORTIFY_SOURCE=1' -DNDEBUG -ffunction-sections ... (remaining 57 argumen
t(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
mediapipe/calculators/tensor/image_to_tensor_converter_opencv.cc: In member function 'virtual absl::lts_20210324::StatusOrmediapipe::Tensor mediapipe::{an
onymous}::OpenCvProcessor::Convert(const mediapipe::Image&, const mediapipe::RotatedRect&, const mediapipe::Size&, float, float)':
mediapipe/calculators/tensor/image_to_tensor_converter_opencv.cc:106:12: error: could not convert 'tensor' from 'mediapipe::Tensor' to 'absl::lts_20210324::
StatusOrmediapipe::Tensor'
return tensor;
^~~~~~
Target //mediapipe/examples/desktop/hand_tracking:hand_tracking_cpu failed to build
原因就是gcc版本过低,
//mediapipe/calculators/tensor:image_to_tensor_converter_gl_buffer · Issue #1684 · google/mediapipe · GitHub
更新gcc、g++至8.0版本之后即可解决该问题;
接下来再编译手势识别代码可能遇到:
[ERROR]
/home/base/.cache/bazel/_bazel_base/10f4be354af48e783fcaf1c23632155f/external/com_google_absl/absl/types/BUILD.bazel:54:11: undeclared inclusion(s) in rule '@com_google_absl//absl/types:bad_any_cast_impl':
this rule is missing dependency declarations for the following files included by 'com_google_absl/absl/types/bad_any_cast.cc':
'/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h'
'/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h'
'/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h'
Target //mediapipe/examples/desktop/libexample:libexample.so failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 1.981s, Critical Path: 0.28s
INFO: 106 processes: 106 internal.
FAILED: Build did NOT complete successfully
这是因为之前使用gcc-7.5版本编译,~/.cache/bazel中保留了7.5版本的缓存,直接升级gcc-8/9后,出现版本不对应的问题;解决方法:删除该文件夹。
接下来再次编译,可能遇到问题:
ERROR: /home/base/workspace/mediapipe/mediapipe/examples/desktop/hand_tracking/BUILD:27:10: Linking of rule '//mediapipe/examples/desktop/hand_tracking:hand_tracking_cpu' failed (Exit 1): gcc failed: error executing command /usr/bin/gcc @bazel-out/k8-opt/bin/mediapipe/examples/desktop/hand_tracking/hand_tracking_cpu-2.params
原因:opencv三方库没有全部链接上,修改opencv_linux.BUILD中的链接选项即可。
5、lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
/home/base/workspace/mediapipe/mediapipe/framework/tool/BUILD:107:10: Linking of rule '//mediapipe/framework/tool:encode_as_c_string' failed (Exit 1): crosstool_wrapper_driver_is_not_gcc failed: error executing command external/local_config_cuda/crosstool/clang/bin/crosstool_wrapper_driver_is_not_gcc @bazel-out/host/bin/mediapipe/framework/tool/encode_as_c_string-2.params
/usr/bin/ld: bazel-out/host/bin/external/com_google_absl/absl/strings/libstrings.a(charconv.o): undefined reference to symbol 'nan@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
但是,由于对bazel编译工具不熟悉,找不到对应链接库的位置,无法解决该问题;经过查找,找到了类似解答:
Undefined reference to symbol 'ceil@@GLIBC_2.2.5' at build time · Issue #1171 · tensorflow/tensorflow · GitHub
undefined reference to symbol xx@@GLIBC_2.2.5 - 海滨银枪小霸王 - 博客园
c - ld: undefined reference to symbol 'log2@@GLIBC_2.2.5' - Stack Overflow
Issue in TensorFlow CUDA Support on Jetson Nano · Issue #852 · google/mediapipe · GitHub
最后在mediapipe找到了和我一模一样的问题,由于他遇到了前置问题,我没能第一时间发现他后面写的问题描述。
所有问题解决方法均指向了这条解决方式:
而和我相同问题的兄弟说:
没错:在mediapipe/BUILD at master · google/mediapipe · GitHub这里加上一句linkopts = ["-lm"],(注意有逗号)即可解决问题,而这坑爹的103行其实并不是当时的那一行,所以加入只会报错。但是这个方法确实是对的,需要在编译的时候加入对应的链接库。
回头再看error内容:
第一句
/home/base/workspace/mediapipe/mediapipe/framework/tool/BUILD:107:10: Linking of rule '//mediapipe/framework/tool:encode_as_c_string' failed (Exit 1):
实际encode_as_c_string在 110行;
第二句
查看 bazel-out/host/bin/mediapipe/framework/tool/encode_as_c_string-2.params
这里-pthread等就是加入的编译相关链接库,直接在后面加入-lm试试;编译同时提示内容已经发生改变,再回头看看报错信息:
Linking of xxx/tool:encode_as_c_string error
原来是/home/base/workspace/mediapipe/mediapipe/framework/tool/BUILD中的encode_as_c_string这段需要补上对应的链接库
cc_binary(
name = "encode_as_c_string",
srcs = ["encode_as_c_string.cc"],
visibility = ["//visibility:public"],
deps = [
"@com_google_absl//absl/strings",
],
)
所以在里面加入 linkopts = ["-lm"], (注意有英文逗号)。
修改后编译生成的
bazel-out/host/bin/mediapipe/framework/tool/encode_as_c_string-2.params
中新加入了 -lm, 即可解决该问题。