Building OpenCV code using Bazel

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.


Here is an up2date solution that works with the current set of bazel(v3.1.0). In this little project i wanted to build a C++ program that depends on the newest openCV release (4.3.0), but only on a selected set of modules (core,highgui,imgcodecs,imgproc).

No local installed openCV required, bazel loads the needed files from github (although it works even when there is an old version of openCV installed):

Content of /WORKSPACE file:

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()

Content of /BUILD file:

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

And finally, your target that depends on opencv, in my case a file /opencv/BUILD:

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

If you want to try it out, here is the rest: blackliner/automata

git clone https://github.com/blackliner/automata.git
cd automata
bazel build ...

I succeed with @kristina's first option.

  1. Install 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
    
  2. Change WORKSPACE file (at tensorflow/WORKSPACE cloned from github)

    new_local_repository(
    
    name = "opencv",
    
    path = "/usr/local",
    
    build_file = "opencv.BUILD",
    
    )
    
  3. Make opencv.BUILD file at the same place as WORKSPACE file:

    cc_library(
    
    name = "opencv",
    
    srcs = glob(["lib/*.so*"]),
    
    hdrs = glob(["include/**/*.hpp"]),
    
    includes = ["include"],
    
    visibility = ["//visibility:public"], 
    
    linkstatic = 1,
    
    )
    
  4. You may have to config the opencv libs path:

a. Make sure you have /etc/ld.so.conf.d/opencv.conf file with content:

    /usr/local/lib

b. Run the command:

    sudo ldconfig -v

Tags:

Opencv

Bazel