build opencv with bazel

459 views
Skip to first unread message

Shusen Zhang

unread,
Dec 26, 2023, 1:17:30 PM12/26/23
to bazel-discuss
Hello everyone,

I am new to bazel and need to build with opencv after build with eigen is ok. I tried to follow the following instruction. I attempted two methods one with new_local_repository the other with http_archive.  


In both situations, including @opencv in main BUILD file actually worked. But I got stuck on once I start to include "#include". The vscode editor seems to understand where the header files are but bazelisk build will generate error related to can't find header.

main/hello-world.cc:7:10: fatal error: opencv2/core.hpp: No such file or directory
    7 | #include "opencv2/core.hpp"
      |          ^~~~~~~~~~~~~~~~~~
compilation terminated.

I tried several different options of cc_library and cc_binary, they all ends with the same error. Where does bazel actually look for external headers? How can I further debug this?

Best regards,

Shusen

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

cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
# linkopts = ["$(pkg-config --libs opencv4)"],
linkopts = [
"path_to_so_files",
],
deps = [
":hello-greet",
"//lib:hello-time",
"//lib_2:hello-time-shusen",
"@eigen",
# "@opencv",
# "@opencv//:lib/libopencv_core.so",
"@opencv//:opencv-lib",
],
)

Filip Filmar

unread,
Dec 26, 2023, 3:10:52 PM12/26/23
to Shusen Zhang, bazel-discuss
On Tue, Dec 26, 2023 at 10:17 AM 'Shusen Zhang' via bazel-discuss <bazel-...@googlegroups.com> wrote:
I am new to bazel and need to build with opencv after build with eigen is ok. I tried to follow the following instruction. I attempted two methods one with new_local_repository the other with http_archive.  

Do you have an example repository that you could share and we could look at?
What archive did you download? The source archive at https://github.com/opencv/opencv/releases/tag/4.8.1 does not have a 'core.hpp' to be included.
 
main/hello-world.cc:7:10: fatal error: opencv2/core.hpp: No such file or directory
    7 | #include "opencv2/core.hpp"
      |          ^~~~~~~~~~~~~~~~~~
compilation terminated.

That's because this file is not found - either because it does not exist, or because it's not in the sandbox used for compilation. Which one it is, depends on how you set up your repository. Which we can not know unless you have a sample repository to share.
 
Where does bazel actually look for external headers? How can I further debug this?

Bazel doesn't look for headers. It sets up an environment for your compiler to do the actual work, based on the build rule implementations. If that environment is set up correctly, then your compiler will be able to do its work. If it is not, for whatever reason, then you will have an issue.

If you add a flag `--subcommands`, bazel will print the command line it is using to invoke your compiler, so you can check the command line and verify that the correct -I flag (as "Include dir") has been added to the compiler's command line.

If you want a glimpse into what your compiler sees when it is trying to compile your code, also add `--sandbox_debug`. This will keep the sandbox environment for inspection, and you can `cd` there and see what your compiler sees. If the files are not in their correct places, then you will see compilation issues.
 

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


I think you should not 'glob' any of the above, since then you won't know if bazel is not finding the files you need. Include them directly. For example, if you `glob` your headers, you will know whether the file `include/opencv2/hpp` is present or not, until you try to include it. Similarly with `lib/opencv_world.so`, since you are using a glob instead of just a list of files, I *think* the glob will just silently evaluate to an empty list if this file does not exist.
 
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
# linkopts = ["$(pkg-config --libs opencv4)"],
linkopts = [
"path_to_so_files",
],
deps = [
":hello-greet",
"//lib:hello-time",
"//lib_2:hello-time-shusen",
"@eigen",
# "@opencv",
# "@opencv//:lib/libopencv_core.so",
"@opencv//:opencv-lib",
],
)

--

Since you are adding `@opencv//:opencv-lib`, and assuming that the library was built correctly (which we currently don't know since we haven't seen your problem repo!), you should not need to add any `linkopts` at all. As soon as you are able to produce a viable `cc_library` target, bazel should propagate all the needed settings to any downstream uses of that library. That this does not happen in your case likely means that the library was somehow not set up correctly for use in bazel. To say more, we'd probably need to see your sample repository.

If I had to compile opencv with bazel today, and if I wasn't able to find a binary distribution that works for me, I'd try to compile it from source using `rules_foreign_cc`
and its `cmake` rule. On the flip side, I understand that opencv is a large library, so it may then require you to repeat the same exercise for all of its dependencies.

Since this could turn into an exercise of its own, maybe consider *not* using bazel unless using bazel in particular is somehow central to what you want to do.
I find it quite pleasurable to use bazel with libraries that someone else has prepared for use in bazel.
Less so if I have to be the one to do that.

F
 

Filip Filmar

unread,
Dec 26, 2023, 3:14:39 PM12/26/23
to Shusen Zhang, bazel-discuss
On Tue, Dec 26, 2023 at 12:10 PM Filip Filmar <fil...@gmail.com> wrote:
 find it quite pleasurable to use bazel with libraries that someone else has prepared for use in bazel.

... which reminds me. eigen and opencv seem to be somewhat frequent flyers on the "how to build with bazel" flight.
Is it possible that there isn't a readily available bazel module or some such with all the legwork already done?

F
 

Xudong Yang

unread,
Dec 26, 2023, 3:26:54 PM12/26/23
to Filip Filmar, Shusen Zhang, bazel-discuss
Apparently eigen is in BCR already (https://registry.bazel.build/modules/eigen/3.4.0.bcr.1), but opencv isn't.

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAKaOXihipi08DhzcLkE%2BSEjRN_K%3DXhk_sJLZQNXZkP4mLHO9Og%40mail.gmail.com.

Shusen Zhang

unread,
Dec 27, 2023, 8:43:48 AM12/27/23
to Filip Filmar, bazel-discuss
Hi bazel community,

I got it to work after some experimenting and debugging work for the option of using new_local_repository_rule. There must be some directory changes in newer opencv versions, which is causing the original post to not work.


The settings need to be very specific. Then a few things needs to be changes:

1. When building opencv we need to build with a single .so file opencv_world.so. This step enables resolving issue #2 easier. Debugging message does not explicitly show this. This is done by trial and error. 

2. The glob pattern actually does not work, we need to be more specific. The actual reason for this is unknown. Debugging message does not show explicitly what needs to be done.

Target //main:hello-world failed to build
INFO: Elapsed time: 0.507s, Critical Path: 0.16s
INFO: 2 processes: 2 internal.
FAILED: Build did NOT complete successfully
ERROR: Build failed. Not running target

3. include needs to extend to include/opencv4. The debugging message is showing that some header files can't be found, so it is reasonable to inspect the specific opencv folder and check the include structure. The bafelling part is if this is fixed, if #1 and #2 are not resolved the software will not build also. We need to be mindful that the file structure of opencv or other packages such as pcl and libgeos are all changing.

main/hello-world.cc:7:10: fatal error: opencv2/core/core.hpp: No such file or directory
    7 | #include <opencv2/core/core.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~~~~

4. hdrs needs to include .h file along with .hpps. Debugging messages will only show meaningful information if #1, #2 and #3 are resolved first. This is relatively the easier one to fix.

external/opencv/include/opencv4/opencv2/core.hpp:52:10: fatal error: opencv2/core/cvdef.h: No such file or directory
   52 | #include "opencv2/core/cvdef.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~





cc_library(
name = "opencv-lib",

# the following glob does not work
# srcs = glob(["lib/*.so*"]),

# the following glob does works
srcs = glob(["lib/opencv_world.so"]),

# this following does work but both hpp and h files has to be included
hdrs = glob(
[
"include/**/*.hpp",
"include/**/*.h",
],
),

# this does work need extra layer under include
includes = ["include/opencv4"],
linkstatic = 1,
visibility = ["//visibility:public"],
)
On Tue, Dec 26, 2023 at 12:10 PM Filip Filmar <fil...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages