Building OpenCV code using Bazel

John Zhang picture John Zhang · Jan 25, 2016 · Viewed 8.2k times · Source

What is the best way to build C++ code that uses the OpenCV library using Bazel? I.e., what would the BUILD rules look like?

Bazel.io has docs for external dependencies but it's not very clear.

Answer

kristina picture kristina · Jan 26, 2016

There are a couple of options. The easiest way is probably to install locally in the way the OpenCV site recommends:

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

Then add the following to your WORKSPACE file:

new_local_repository(
    name = "opencv",
    path = "/path/to/opencv/install",
    build_file = "opencv.BUILD",
)

Create opencv.BUILD in the same directory as WORKSPACE with the following:

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

Then your code can depend on @opencv//:opencv to link in the .so's under lib/ and reference the headers under include/.

However, this isn't very portable. If you want a portable solution (and you're feeling ambitious), you could add the OpenCV git repo to your workspace and download & build it. Something like:

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

And make opencv.BUILD something like:

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

...

Then your code could depend on more specific targets, e.g., @opencv//:core.

As a third option, you declare both cmake and OpenCV in your WORKSPACE file and use a genrule to run cmake on OpenCV from within Bazel.