使用Bazel构建OpenCV代码

Joh*_*ang 13 opencv bazel

使用Bazel构建使用OpenCV库的C++代码的最佳方法是什么?即,BUILD规则是什么样的?

Bazel.io有外部依赖的文档,但不是很清楚.

kri*_*ina 26

有几种选择.最简单的方法可能是以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=/path/to/opencv/install ..
make install
Run Code Online (Sandbox Code Playgroud)

然后将以下内容添加到WORKSPACE文件中:

new_local_repository(
    name = "opencv",
    path = "/path/to/opencv/install",
    build_file = "opencv.BUILD",
)
Run Code Online (Sandbox Code Playgroud)

opencv.BUILD使用以下内容在与WORKSPACE相同的目录中创建:

cc_library(
    name = "opencv",
    srcs = glob(["lib/*.so*"]),
    hdrs = glob(["include/**/*.hpp"]),
    includes = ["include"],
    visibility = ["//visibility:public"], 
    linkstatic = 1,
)
Run Code Online (Sandbox Code Playgroud)

然后你的代码可以依赖于@opencv//:opencv在lib /下的.so中的链接,并引用include /下的头文件.

但是,这不是很便携.如果你想要一个便携式解决方案(并且你有野心),你可以将OpenCV git repo添加到你的工作区并下载和构建它.就像是:

# WORKSPACE
new_git_repository(
    name = "opencv",
    remote = "https://github.com/Itseez/opencv.git",
    build_file = "opencv.BUILD",
    tag = "3.1.0",
)
Run Code Online (Sandbox Code Playgroud)

并使opencv.BUILD类似于:

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"],
)

...
Run Code Online (Sandbox Code Playgroud)

那么你的代码可能依赖于更具体的目标,例如@opencv//:core.

作为第三个选项,您在WORKSPACE文件中声明了cmake和OpenCV,并使用genrule在Bazel内的OpenCV上运行cmake.


Flo*_*old 7

这是一个适用于当前版本bazel(v3.1.0) 的更新解决方案。在这个小项目中,我想构建一个依赖于最新openCV版本(4.3.0)的 C++ 程序,但仅依赖于一组选定的模块(core、highgui、imgcodecs、imgproc)。

不需要本地安装openCVbazel从 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()
Run Code Online (Sandbox Code Playgroud)

文件内容/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"],
)
Run Code Online (Sandbox Code Playgroud)

最后,你的目标取决于opencv,在我的例子中是一个文件/opencv/BUILD

cc_binary(
    name = "opencv",
    srcs = ["opencv.cpp"],
    data = [
      "LinuxLogo.jpg",
      "WindowsLogo.jpg",
    ],
    deps = ["//:opencv"],
)
Run Code Online (Sandbox Code Playgroud)

如果你想尝试一下,剩下的就是:blackliner/automata

git clone https://github.com/blackliner/automata.git
cd automata
bazel build ...
Run Code Online (Sandbox Code Playgroud)