Glob not found in bazel - c++

I am currently using Bazel to build a C++ project. Here is my WORKSPACE file:
cc_library(
name = "Boost",
srcs = glob(["/usr/local/lib/libboost*.so"]),
hdrs = glob(["/home/duttama/boost_1_55_0/**/*.h"]),
)
cc_library(
name = "OpenCV",
srcs = glob(["/usr/lib/x86_64-linux-gnu/libopencv*.so"]),
hdrs = glob(["/home/duttama/opencv-2.4.13/**/*.h"]),
)
cc_library(
name = "AffectivaSources",
srcs = glob(["/root/affdex-sdk/lib/*.so"]),
hdrs = glob(["/root/affdex-sdk/include/*.h"]),
)
And here is my BUILD file:
cc_binary(
name = "video-demo",
srcs = ["video-demo.cpp"],
deps = ["//lib:OpenCV",
"//lib:AffectivaSources",
"//lib:Boost",
],
)
When I run it, I get this error:
ERROR: /root/sdk-samples/WORKSPACE:17:12: Traceback (most recent call last):
File "/root/sdk-samples/WORKSPACE", line 15
cc_library(name = "AffectivaSources", srcs = ..."]), ..."]))
File "/root/sdk-samples/WORKSPACE", line 17, in cc_library
glob
name 'glob' is not defined
My question is why is it not finding the glob function. I am not sure what else to specify in the WORKSPACE file or how to import this glob function.

The WORKSPACE file is not meant for cc_binary/cc_rules; it's for defining project-wide rules such as external dependencies, and the glob function is not available in WORKSPACE files. See https://docs.bazel.build/versions/master/be/workspace.html for WORKSPACE rules.
It seems like you're importing c++ dependencies into your project: check out the new_local_repository rule here. This allows you to point to a folder in your local system. It will require you to write BUILD files containing the respective cc_library rules for each external dependency.
For example, in your WORKSPACE file:
new_local_repository(
name = "affectivalibrary",
path = "/root/affdex-sdk/",
build_file = "BUILD.affectiva",
)
and in your project, create a BUILD.affectiva:
cc_library(
name = "aff",
srcs = glob(["lib/*.so"]),
hdrs = glob(["include/*.h"]),
)
Once you've done this, you can depend on them in your BUILD files with the syntax:
cc_binary(
name = "video-demo",
srcs = ["video-demo.cpp"],
deps = ["#affectivalibrary//:aff", ...]
)
I'm also seeing that you are using absolute file paths in the srcs/hdrs attributes - glob patterns cannot be absolute. Please refer to the BUILD file target label syntax here: https://docs.bazel.build/versions/master/build-ref.html#lexi
If you're still confused, there's an example c++ project in the Bazel repository: https://github.com/bazelbuild/bazel/tree/master/examples/cpp

Related

Include a header file from a third party package to a C++ code in my project

I am trying to include a header file from a third party package to a C++ code in my project. This is how I structured it:
main_repo/
- third_party/some_lib/
- BUILD
- header_file.h
- extensions/my_project/
- BUILD
- my_app.cpp
- my_app.hpp
main_repo/extensions/my_project/BUILD
cc_library(
name = "my_app",
srcs = ["my_app.cpp"],
hdrs = ["my_app.hpp"],
visibility = ["//visibility:public"],
deps = [
"//third_party/some_lib:some_lib",
],
)
main_repo/third_party/some_lib/BUILD
cc_library(
name = "some_lib",
hdrs = glob(["*.h"]),
includes = ["."],
visibility = ["//visibility:public"],
)
main_repo/extensions/my_project/my_app.hpp
// some code here
#include "header_file.h"
// some code here
I see
header_file.h: No such file or directory
error when I try building it. Do you see a problem with my approach?

How to properly link the QT library during bazel build compilation?

I am working on extending a project using bazel to build. However, one of my thrid_party dependency relying on a dynamic linked QT library. And I had a hard time linking it.
My project base is envpool, and I am using procgen as my third-party dependency. However, procgen relies on a series of QT library.
My approachs so far:
In the WorkSpace file, I specify the local directory of the qt library. (I am working on a new EC2 instance of Ubuntu 20.04 LTS on amazon cloud, and install qt5 and other base tools)
// download the github project
maybe(
http_archive,
name = "procgen",
sha256 = "8d443b7b8fba44ef051b182e9a87abfa4e05292568e476ca1e5f08f9666a1b72",
strip_prefix = "procgen-0.10.7/procgen/src/",
urls = [
"https://github.com/openai/procgen/archive/refs/tags/0.10.7.zip"
]
build_file = "//third_party/procgen:procgen.BUILD",
)
new_local_repository(
name = "qt",
path = "/usr/include/x86_64-linux-gnu/qt5", // I check indeed the header files are there
build_file = "BUILD.qt"
)
And the BUILD.qt file is
cc_library(
name = "qt_core",
hdrs = glob(["QtCore/**"]),
includes = ["."],
linkopts = [
"-lQt5Core",
],
visibility = ["//visibility:public"],
)
cc_library(
name = "qt_widgets",
hdrs = glob(["QtWidgets/**"]),
includes = ["."],
deps = [":qt_core"],
linkopts = [
"-lQt5Widgets",
],
visibility = ["//visibility:public"],
)
cc_library(
name = "qt_gui",
hdrs = glob(["QtGui/**"]),
includes = ["."],
deps = [":qt_core"],
linkopts = [
"-lQt5Gui",
],
visibility = ["//visibility:public"],
)
And the BUILD file for the procgen is
package(default_visibility = ["//visibility:public"])
cc_library(
name = "procgen",
srcs = glob(["*.cpp", "games/*.cpp"]),
hdrs = glob(["*.h"]),
deps = [
"#qt//:qt_widgets",
"#qt//:qt_gui",
"#qt//:qt_core",
]
)
However, when I use Bazel to build the project, it gives back the error that
Use --sandbox_debug to see verbose messages from the sandbox
In file included from external/procgen/games/starpilot.cpp:2:
external/procgen/games/../assetgen.h:10:10: fatal error: QColor: No such file or directory
10 | #include <QColor>
| ^~~~~~~~
compilation terminated.
I know I probably mess up the path or header file's include somewhere. For example, I am basically follow this post to include the QT library in the project, but I notice that guys use the full path "#include <qt/QTWidgets/xxxx>" instead. But I cannot change the code for "include" in the procgen.
This is the first time I use bazel, and on such a big project. Really appreciate if someone could help me out.
I put my current whole project package at here for reproducibility. You can use short-cut "sudo make bazel-build" to build it.
Best,
YJ

Bazel build: dependency parameterized by command line

I have a project for a plugin in C/C++ where I have different implementations and I would like to be able to select which implementation to use when building.
WORKSPACE
plugin/
BUILD
plugin.c
plugin.h
plugin_impl1/
BUILD
...
plugin_impl2/
BUILD
...
plugin_impl1/BUILD:
cc_library(
name = "plugin_impl1"
srcs = [...]
hdrs = [...]
)
plugin_impl2/BUILD:
cc_library(
name = "plugin_impl2"
srcs = [...]
hdrs = [...]
)
I want to know how to write plugin/BUILD so that I could write something like:
bazel build //plugin --which plugin_impl2
The executable name should always be the same so having multiple rules with different target names (for plugin) is not an option.

The hdrs of cc_library seems not working of Bazel

I'm working on a project, which depends on a third party project, let's say project E, which is a precompiled libraries. I've set a new repository_rule and invoked it in the workspace.bzl, and in the BUILD of the project E, the corresponding library rule has been set like following:
cc_library(
name = "e_lib",
srcs = [
"#e//:e_lib1",
"#e//:e_lib2",
],
hdrs = ["#e//:e_headers"],
visibility = ["//visibility:public"],
)
And the target e_lib1, e_lib2 and e_headers are defined in the file e.BUILD, and it is correctly symblo linked to the downloaded contents folder in the last part of implementation function of repository_rule.
The e.BUILD is something like:
filegroup(
name = "e_headers",
srcs = glob(["include/*"]),
visibility = ["//visibility:public"],
)
filegroup(
name = "e_lib1",
srcs = if_darwin(["lib/lib1.dylib"])
+ if_linux_x86_64(["lib/lib1.so"]),
visibility = ["//visibility:public"],
)
filegroup(
name = "e_lib2",
srcs = if_darwin(["lib/lib2.dylib"])
+ if_linux_x86_64(["lib/lib2.so"]),
visibility = ["//visibility:public"],
)
Let's say there is a header baz.h in the directory include of the project E.But during the building phase, an error, baz.h file not found, occurred when bazel tried to compile a file core.cc. The pseudocodes are something like:
// core.cc
#include "core.h"
...
// core.h
#include "im.h"
...
// im.h
#include "baz.h"
// This file doesn't have the corresponding
// .cc file since all the implementations
// are put in this header.
The dependency of these files is core.cc -> core.h -> im.h -> baz.h, and the building rule of core.cc is:
cc_library(
name = "core",
srcs = [
"core.cc",
],
hdrs = "core.h",
deps = [
"//third_party/E:e_lib"],
alwayslink = 1,
)
So is there something wrong with my BUILD file? I guess that maybe the core.cc doesn't directly depend on the e_lib, so the deps of it is actually useless. Should I build a cc_library for the im.h?

Bazel build with OpenCV 3.3 dependencies

I'm trying to use Bazel to compile and distribute an OpenCV based C++ code and I'm facing an issue I can't resolve.
I build and install OpenCV 3.3 from sources, on an Ubuntu 16.04 LTS, with CUDA support (CUDA 8). I install it in the standard directory /usr/local.
Given it, I created my project with this WORKSPACE file :
new_local_repository(
name = "opencv",
path = "/usr/local",
build_file = "opencv.BUILD",
)
The opencv.BUILD contains :
cc_library(
name = "opencv",
srcs = glob(["lib/*.so*"]),
hdrs = glob(["include/**/*.hpp"]),
includes = ["include"],
visibility = ["//visibility:public"],
linkstatic = 1,
)
And I can use it in my own code using :
cc_binary(
name = "main",
srcs = ["main.cc"],
deps = [
"#opencv//:opencv"
],
)
but some source files in OpenCV, as :
/usr/local/include/opencv2/flann/flann_base.hpp
includes headers file from the same directory, like :
#include "general.h"
And when I build with Bazel, I get this error :
ERROR: /home/damien/main/BUILD:1:1: C++ compilation of rule '//main:main' failed (Exit 1)
In file included from external/opencv/include/opencv2/flann.hpp:48:0,
from external/opencv/include/opencv2/opencv.hpp:62,
from main/main.cc:1:
external/opencv/include/opencv2/flann/flann_base.hpp:38:21: fatal error: general.h: No such file or directory
(general.h is in the same directory as flann_base.hpp).
If I rewrite the #include directive as :
#include "opencv2/flann/general.h"
It compiles well. But this is not a convenient solution.
So my question is : is there a way to tell Bazel to look for headers in the same directory as the "current" file in this library ? I look upon every C++ directives of Bazel, but I don't see anything to achieve it.
Thank you in advance.
Ok, shame on me. I have to import *.h :
cc_library(
name = "opencv",
srcs = glob(["lib/*.so*"]),
hdrs = glob(["include/**/*.hpp", "include/**/*.h"]),
includes = ["include"],
visibility = ["//visibility:public"],
linkstatic = 1,
)
In my case using opencv4 and Damien setup I was getting the error while including highgui.hpp:
external/opencv/include/opencv4/opencv2/highgui.hpp:46:10: fatal
error: opencv2/core.hpp: No such file or directory #include
"opencv2/core.hpp"
I could fix it adjusting the includes adding opencv4:
cc_library(
name = "opencv",
srcs = glob(["lib/*.so*"]),
hdrs = glob(["include/**/*.hpp", "include/**/*.h"]),
includes = ["include/opencv4"],
visibility = ["//visibility:public"],
linkstatic = 1,
)