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.
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
Change WORKSPACE file (at tensorflow/WORKSPACE cloned from github)
new_local_repository( name = "opencv", path = "/usr/local", build_file = "opencv.BUILD", )
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, )
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