使用Bazel构建使用OpenCV库的C ++代码的最佳方法是什么?即,BUILD规则是什么样的?
Bazel.io有docs for external dependencies,但不是很清楚。
答案 0 :(得分:22)
有几种选择。最简单的方法可能是以OpenCV网站建议的方式在本地安装:
NSJSONSerialization
然后将以下内容添加到您的WORKSPACE文件中:
git clone https://github.com/Itseez/opencv.git
cd opencv/
mkdir build install
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/path/to/opencv/install ..
make install
使用以下内容在与WORKSPACE相同的目录中创建new_local_repository(
name = "opencv",
path = "/path/to/opencv/install",
build_file = "opencv.BUILD",
)
:
opencv.BUILD
然后您的代码可以依赖cc_library(
name = "opencv",
srcs = glob(["lib/*.so*"]),
hdrs = glob(["include/**/*.hpp"]),
includes = ["include"],
visibility = ["//visibility:public"],
linkstatic = 1,
)
链接到lib /下的.so,并引用include /.下的标题。
但是,这不是非常便携。如果您想要一个便携式解决方案(并且您感觉雄心勃勃),您可以将OpenCV git仓库添加到您的工作区并下载&建立它。类似的东西:
@opencv//:opencv
并使opencv.BUILD类似:
# WORKSPACE
new_git_repository(
name = "opencv",
remote = "https://github.com/Itseez/opencv.git",
build_file = "opencv.BUILD",
tag = "3.1.0",
)
然后,您的代码可能依赖于更具体的目标,例如cc_library(
name = "core",
visibility = ["//visibility:public"],
srcs = glob(["modules/core/src/**/*.cpp"]),
hdrs = glob([
"modules/core/src/**/*.hpp",
"modules/core/include/**/*.hpp"]
) + [":module-includes"],
)
genrule(
name = "module-includes",
cmd = "echo '#define HAVE_OPENCV_CORE' > $@",
outs = ["opencv2/opencv_modules.hpp"],
)
...
。
作为第三个选项,您在WORKSPACE文件中声明了cmake和OpenCV,并使用genrule在Bazel内的OpenCV上运行cmake。
答案 1 :(得分:3)
我成功完成@kristina的第一个选择。
安装opencv:
git clone https://github.com/Itseez/opencv.git
cd opencv/
mkdir build install
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
make install
更改WORKSPACE文件(从github克隆的tensorflow / WORKSPACE)
new_local_repository(
name = "opencv",
path = "/usr/local",
build_file = "opencv.BUILD",
)
将opencv.BUILD文件放在与WORKSPACE文件相同的位置:
cc_library(
name = "opencv",
srcs = glob(["lib/*.so*"]),
hdrs = glob(["include/**/*.hpp"]),
includes = ["include"],
visibility = ["//visibility:public"],
linkstatic = 1,
)
您可能需要配置opencv libs路径:
一个。确保您的/etc/ld.so.conf.d/opencv.conf文件包含内容:
/usr/local/lib
湾运行命令:
sudo ldconfig -v
答案 2 :(得分:1)
这就是我为OpenCV 2.4.13.2,core/
所做的。这种方法来自opencv源,它改编自@kristina上面接受的答案。
首先要为opencv 2.4版本添加http_archive:
# OpenCV 2.4.13.2
new_http_archive(
name = "opencv2",
url = "https://github.com/opencv/opencv/archive/2.4.13.2.zip",
build_file = "third_party/opencv2.BUILD",
strip_prefix = "opencv-2.4.13.2",
)
然后,将文件third_party/opencv2.BUILD
添加为:
cc_library(
name = "dynamicuda",
hdrs = glob([
"modules/dynamicuda/include/**/*.hpp",
]),
includes = [
"modules/dynamicuda/include"
],
)
cc_library(
name = "core",
visibility = ["//visibility:public"],
srcs = glob(["modules/core/src/**/*.cpp"]),
hdrs = glob([
"modules/core/src/**/*.hpp",
"modules/core/include/**/*.hpp",
]) + [
":module_includes",
":cvconfig",
":version_string",
],
copts = [
"-Imodules/dynamicuda/include",
],
# Note that opencv core requires zlib and pthread to build.
linkopts = ["-pthread", "-lz"],
includes = [
"modules/core/include",
],
deps = [
":dynamicuda",
],
)
genrule(
name = "module_includes",
cmd = "echo '#define HAVE_OPENCV_CORE' > $@",
outs = ["opencv2/opencv_modules.hpp"],
)
genrule(
name = "cvconfig",
outs = ["cvconfig.h"],
cmd = """
cat > $@ <<"EOF"
// JPEG-2000
#define HAVE_JASPER
// IJG JPEG
#define HAVE_JPEG
// PNG
#define HAVE_PNG
// TIFF
#define HAVE_TIFF
// Compile for 'real' NVIDIA GPU architectures
#define CUDA_ARCH_BIN ""
// NVIDIA GPU features are used
#define CUDA_ARCH_FEATURES ""
// Compile for 'virtual' NVIDIA PTX architectures
#define CUDA_ARCH_PTX ""
EOF"""
)
genrule(
name = "version_string",
outs = ["version_string.inc"],
cmd = """
cat > $@ <<"EOF"
"\\n"
)
请注意,我没有在version_string.inc
中添加任何内容。它只是一个C ++字符串文字,不会影响OpenCV的功能。如果您对此文件真的感兴趣,请参阅此example。
在此之后,您应该能够在@opencv2//:core
上添加具有依赖关系的目标。
答案 3 :(得分:1)
这是一个最新的解决方案,可与当前bazel
(v3.1.0)集一起使用。在这个小项目中,我想构建一个C ++程序,该程序依赖于最新的openCV
版本(4.3.0),但仅依赖于一组选定的模块(核心,highgui,imgcodecs,imgproc)。
不需要本地安装openCV
,bazel
会从github加载所需的文件(尽管即使安装了旧版本的openCV
也可以):
/WORKSPACE
文件的内容:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
all_content = """filegroup(name = "all", srcs = glob(["**"]), visibility = ["//visibility:public"])"""
http_archive(
name = "opencv",
build_file_content = all_content,
strip_prefix = "opencv-4.3.0",
urls = ["https://github.com/opencv/opencv/archive/4.3.0.zip"],
)
http_archive(
name = "rules_foreign_cc",
strip_prefix = "rules_foreign_cc-master",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/master.zip",
)
load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies")
rules_foreign_cc_dependencies()
/BUILD
文件的内容:
load("@rules_foreign_cc//tools/build_defs:cmake.bzl", "cmake_external")
cmake_external(
name = "opencv",
cmake_options = [
"-GNinja",
"-DBUILD_LIST=core,highgui,imgcodecs,imgproc",
],
lib_source = "@opencv//:all",
make_commands = [
"ninja",
"ninja install",
],
out_include_dir = "include/opencv4",
shared_libraries = [
"libopencv_core.so",
"libopencv_highgui.so",
"libopencv_imgcodecs.so",
"libopencv_imgproc.so",
],
visibility = ["//visibility:public"],
)
最后,您的目标取决于opencv
,在我的情况下,取决于文件/opencv/BUILD
:
cc_binary(
name = "opencv",
srcs = ["opencv.cpp"],
data = [
"LinuxLogo.jpg",
"WindowsLogo.jpg",
],
deps = ["//:opencv"],
)
如果您想尝试一下,剩下的就是:blackliner/automata
git clone https://github.com/blackliner/automata.git
cd automata
bazel build ...
答案 4 :(得分:0)
以下是使用Bazel构建的OpenCV和C ++的简单演示:https://github.com/jcju/opencv_bazel_win
您可以在WORKSPACE中设置OpenCV路径并运行:
bazel run //src:main