I am trying to use a locally built package (this one) within an existing bazel project. It bazel builds without any errors, but when I try to bazel run it, it immediately segfaults. I tried building it in debug mode, but when I run it in debug mode it still immediately segfaults without any useful error message.
I built the external package following the instructions in the README and the examples run fine (outside of bazel), so I know that the external libraries are not the issue.
I made a repository to access this package in my WORKSPACE file
new_local_repository(
name = "ApproxMVBB",
path = "/absolute/path/to/ApproxMVBB",
build_file = "approxmvbb.BUILD", )
The approxmvbb.BUILD file looks like this
cc_library(
name = "ApproxMVBB-lib",
srcs = glob(["**/*.a"])+glob(["**/*.so"]),
hdrs = glob(["**/*.hpp"]),
includes = ["include", "build/include", "external/Diameter/include", "external/GeometryPredicates/include"],
visibility = ["//visibility:public"],
)
And the cc_binary I am trying to run looks like this
cc_binary(
name = "TestMVBB",
srcs = [
"src/test_approxmvbb.cpp",
],
deps = [
"#ApproxMVBB//:ApproxMVBB-lib",
],
linkopts = ["-shared"],
)
The source code for the binary src/test_approvmvbb.cpp
#include <iostream>
#include "ApproxMVBB/ComputeApproxMVBB.hpp"
int main(int argc, char** argv)
{
ApproxMVBB::Matrix3Dyn points(3,10000);
points.setRandom();
ApproxMVBB::OOBB oobb = ApproxMVBB::approximateMVBB(points,0.001,500,5,0,5);
oobb.expandToMinExtentRelative(0.1);
return 0;
}
I found my mistakes. First, I was changing a lot of things and forgot to rebuild the external package, so the libraries didn't exist... oops.
But more importantly, when the external package is built, it outputs library files that have file extensions other than .o and .so so I had to change the following line in the cc_library target
srcs = glob(["**/*.a"])+glob(["**/*.so"])+glob(["**/*.so.2.1.1"]),
Hope this helps someone in the future!!
Related
I am working on a c++ project with bazel BUILD system in the vscode IDE environment. To illustrate, one could take one of the large open source projects such as tensorflow.
While the intellisense functionality works very well for source/header dependencies within the project folder itself, vscode seems unable to recognize headers included from third_party/external dependencies, such as protobuf headers in the tensorflow project (see below screenshot). So is there a way for vscode to recognize such headers, with the help of both c++/clang and bazel plugins?
To provide more details:
This protobuf header is included by the following BAZEL target in tensorflow/lite/toco/BUILD,
cc_library(
name = "toco_port",
srcs = [
"toco_port.cc",
],
hdrs = [
"format_port.h",
"toco_port.h",
"toco_types.h",
],
deps = [
"//tensorflow/core:framework_lite",
"//tensorflow/core:lib",
"//tensorflow/core:lib_internal",
"#com_google_absl//absl/status",
"#com_google_protobuf//:protobuf_headers",
],
)
which in turn is defined by the following workspace rule in tensorflow/workspace2.bzl
tf_http_archive(
name = "com_google_protobuf",
patch_file = ["//third_party/protobuf:protobuf.patch"],
sha256 = "cfcba2df10feec52a84208693937c17a4b5df7775e1635c1e3baffc487b24c9b",
strip_prefix = "protobuf-3.9.2",
system_build_file = "//third_party/systemlibs:protobuf.BUILD",
system_link_files = {
"//third_party/systemlibs:protobuf.bzl": "protobuf.bzl",
"//third_party/systemlibs:protobuf_deps.bzl": "protobuf_deps.bzl",
},
urls = tf_mirror_urls("https://github.com/protocolbuffers/protobuf/archive/v3.9.2.zip"),
)
The downloaded external repository is usually stored in a local directory ~/.cache/_bazel, specified by the --output_user_root flag in bazel.
I'm building a simple C++ application on macOS with Bazel. I want to use OpenCV in my application. I installed OpenCV with brew install opencv and I followed Building OpenCV code using Bazel to create my setup.
In my WORKSPACE file, I have:
new_local_repository(
name = "opencv",
path = "/usr/local/opt/opencv",
build_file = "opencv.BUILD",
)
In my opencv.BUILD file, I have:
cc_library(
name = "opencv",
srcs = glob(["lib/*.dylib"]),
hdrs = glob(["include/opencv4/opencv2/**/*.h*"]),
includes = ["include/opencv4"],
visibility = ["//visibility:public"],
linkstatic = 1,
)
In my BUILD file, I have:
cc_library(
name = "lib",
srcs = ["hello.cpp"],
deps = [
"#opencv//:opencv",
],
)
This works as long as the opencv target takes the OpenCV .dlyb files (srcs = glob(["lib/*.dylib"])).
But now I want to build the OpenCV libraries statically into my binary. When I change the opencv target to take OpenCV's .a files (srcs = glob(["lib/*.a"])), I get a bunch of Undefined symbols errors about AVFoundation classes. In my code I use the OpenCV Capture API (which I assume uses AVFoundation under the hood), so this sorta makes sense, but I'm not sure how to fix it.
How should I configure my Bazel targets to build OpenCV statically into my binary?
I would just like to know if someone has tried doing this?
I am currently using nelhage/rules_boost for my boost dependencies(just to make some things compile for the meantime), but since the code I'm working with is only 100% compatible with 1.55 I cannot use his rules for long.
I could also try adapting his code to work with boost 1.55, but I think it would make it a lot easier if I just make Bazel depend on an installation of boost since I am also working with containers.
I usually use boost as pre-built external dependency with Bazel. I just reference the local installation in my WORKSPACE file and then create a BUILD file for it, e.g.:
# WORKSPACE file
new_local_repository(
name = "boost",
path = "/your/path/to/boost",
build_file = "third_party/boost.BUILD",
)
In the BUILD file you can choose to split headers and libs into separate rules or combine them together. In the following example I keep all the headers as a rule and separate libraries into different rules:
# third_party/boost.BUILD
cc_library(
name = "boost-headers",
hdrs = glob(["include/boost/**"]),
visibility = ["//visibility:public"],
includes = ['include'],
)
cc_library(
name = "boost-atomic",
srcs = ["lib/libboost_atomic.a"],
visibility = ["//visibility:public"],
)
cc_library(
name = "boost-chrono",
srcs = ["lib/libboost_chrono.a"],
visibility = ["//visibility:public"],
)
...
Then in my binary/library I pick-up the dependencies:
cc_binary(
name = 'main',
srcs = ['main.cc'],
deps = [
'#boost//:boost-headers',
'#boost//:boost-regex',
]
)
This should also work is you have boost installed into /usr/include / /usr/lib, but I haven't tried to be honest.
Hope this helps.
I've got a very simple bazel project which builds out a library and a binary like below:
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [":hello-greet"],
)
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
Yes it works in my ubuntu box:
# cat hello-greet.cc
#include<stdio.h>
void f(){
printf("f function\n");
}
# cat hello-world.cc
#include<stdio.h>
#include"hello-greet.h"
int main(){
f();
printf("%s \n", "abc");
return 0;
}
"bazel build hello-world && bazel run hello-world" will print:
f function
abc
Ok, fine. But I cannot find where is my libhello-greet.so is, where is it stored? I cannot find it under my current directory.
Thanks a lot.
Bazel treats the source tree as read-only and puts its outputs in a separate output directory. The official way to find the this directory is to run bazel info output_base. However, as a convenience, Bazel also makes a symlink to this directory called bazel-out in the workspace root.
In your specific case, there may or may not be a shared library for hello-greet actually created—it's perfectly possible to build a binary without creating the intermediate shared objects. bazel build //:hello-greet should build and display the path to a shared object for hello-greet.
It says where in the output of bazel build. Typically in bazel-bin/..., following the same directory structure as the source file.
I'm building a program with gRPC library using bazel. My WORKSPACE file:
http_archive(
name = "com_github_grpc_grpc",
urls = ["https://github.com/grpc/grpc/archive/v1.8.3.zip"],
sha256 = "57a2c67abe789ce9e80d49f473515c7479ae494e87dba84463b10bbd0990ad62",
strip_prefix = "grpc-1.8.3",
)
load("#com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()
BUILD file:
proto_library(
name = "test_proto",
srcs = ["test.proto"],
)
cc_proto_library(
name = "test_cc_proto",
deps = [":test_proto"],
)
cc_binary(
name = "hello",
srcs = ["hello.cc"],
deps = [
":test_cc_proto",
"#com_github_grpc_grpc//:grpc++",
],
)
Compiling this throws error:
every rule of type proto_library implicitly depends upon the target '#com_google_protobuf_cc//:cc_toolchain', but this target could not be found because of: no such package '#com_google_protobuf_cc//': The repository could not be resolved.
If I include com_google_protobuf_cc repository manually, the version doesn't match and I get error saying test.pb.h was generated using a newer version of protoc.
How do I make gRPC load right version of com_google_protobuf_cc?
How are you including Protobuf manually, what did you put in your BUILD and/or WORKSPACE file/s to achieve this? It's hard to comment on what could be wrong without knowing exactly what you have tried.
As far as I know you can include it by downloading the version you require then adding something like the following to your WORKSPACE file:
local_repository(
name = "com_google_protobuf",
path = "../protobuf-3.4.1",
)
local_repository(
name = "com_google_protobuf_cc",
path = "../protobuf-3.4.1",
)
Of course change the paths to match the version and location of your downloaded copy of Protobuf. Alternatively you can probably use http_archive to point it directly to where it should be downloaded, in the same way as you have done for gRPC.