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.
Related
We are migrating a CMake project to Bazel. We have several header only libraries that are tagged SYSTEM in CMake project to suppress some warnings. When migrating these to Bazel, the way we are able to make this work is by using the below
cc_library(
name = "lib",
srcs = ["include/header1.h", ...],
includes = ["include"],
)
This works but as per Bazel C++ documentation, it is not recommended to have interface/public headers in srcs. Those should be part of hdrs. Adding these to headers doesn't work because it uses the regular -I based inclusion instead of -isystem.
Is our way of doing this fine, although not recommended by bazel? If not, what would be the correct way of doing it?
EDIT:
After some digging, found the textual_hdrs attribute on cc_library and using that it seems to work too. And this seems to be a cleaner approach than adding the public headers to srcs. Now the rule looks like this
cc_library(
name = "lib",
textual_hdrs = ["include/header1.h", ...],
includes = ["include"],
)
This looks like a good solution for us, except that the documentation on textual_hdrs isn't clear enough to indicate that this is what it is meant for.
PS: It is really not possible for us to refactor the code to fix the warnings as there are numerous libraries like this and just completely outside the scope of this migration effort.
It turns out adding it to hdrs does work if you make sure that strip_include_prefix is None (or not passed). We had a macro that was wrapping up the cc_library instance and it was defaulting strip_include_prefix to empty string. Interestingly this doesn't affect textual_hdrs or srcs, but does affect hdrs
In summary the below seems to work fine
cc_library(
name = "lib",
hdrs = ["include/header1.h", ...],
includes = ["include"],
)
When I specify build rules in bazel, my dependencies are either full paths (from the root of the repo), or just the target name (since its in the same directory):
cc_binary(
name = "program",
srcs = ["main.cpp"],
deps = ["//a/full/path/to/the/library:lib",
"foo"]
)
Assume I'm writing a build rule from directory "the".
I was hoping to do something like this:
cc_binary(
name = "program",
srcs = ["main.cpp"],
deps = ["library:lib",
"foo"]
)
This does not seem to be possible. Is there some kind of way, where I can specify the target deeper starting from the location of the BUILD file?
You cannot.
Relative labels cannot be used to refer to targets in other packages;
the repository identifier and package name must always be specified in this case.
From Bazel labels documentation
I am writing a sample C++ project that uses Bazel to serve as an example idiom for other collaborators to follow.
Here is the repository: https://github.com/thinlizzy/bazelexample
I am interested to know if I am doing it 'right', more specifically about this file: https://github.com/thinlizzy/bazelexample/blob/38cc07931e58ff5a888dd6a83456970f76d7e5b3/demo/BUILD
when regarding to pick particular implementations.
cc_library(
name = "demo",
srcs = ["demo.cpp"],
deps = [
"//example:frontend",
],
)
cc_binary(
name = "main_win",
deps = [
":demo",
"//example:impl_win",
],
)
cc_binary(
name = "main_linux",
deps = [
":demo",
"//example:impl_linux",
],
)
Is this following a correct/expected idiom for Bazel projects? I am doing this way already for other projects, by concentrating all the platform-specific dependencies in separate targets and then the binaries just depend on them.
Someone in bazel-discuss list told me to use select, instead, but my attempts failed to 'detect' the operating system. I'm sure I did something wrong, but the lack of info and examples don't tell me much how to use it properly.
#bazel_tools contains predefined platform conditions:
$ bazel query #bazel_tools//src/conditions:all
#bazel_tools//src/conditions:windows_msys
#bazel_tools//src/conditions:windows_msvc
#bazel_tools//src/conditions:windows
#bazel_tools//src/conditions:remote
#bazel_tools//src/conditions:host_windows_msys
#bazel_tools//src/conditions:host_windows_msvc
#bazel_tools//src/conditions:host_windows
#bazel_tools//src/conditions:freebsd
#bazel_tools//src/conditions:darwin_x86_64
#bazel_tools//src/conditions:darwin
You can use them directly in the BUILD file:
cc_library(
name = "impl",
srcs = ["Implementation.cpp"] + select({
"#bazel_tools//src/conditions:windows": ["ImplementationWin.cpp"],
"#bazel_tools//src/conditions:darwin": ["ImplementationMacOS.cpp"],
"//conditions:default": ["ImplementationLinux.cpp"],
}),
# .. same for hdrs and data
)
cc_binary(
name = "demo",
deps = [":impl"],
)
See the documentation for select for details on the syntax.
Add a .bazelrc to your project. Add the lines build:vs2019 --cxxopt=/std:c++14 and build:gcc --cxxopt=-std=c++14. Build your code bazel build --config=msvc //... or bazel build --config=gcc //....
#Vertexwahn's answer caused some confusion on my end, so I hope this answer helps clarify a bit. While his answer does not directly tie into the question, it may be of use to others trying to build on entirely different platforms without file specific inclusions.
Here is a link to where I answered that particular question: How do I specify portable build configurations for different operating systems for Bazel?
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.
I'm doing a shared library which uses Tensorflow. For now I placed it in Tensorflow's source tree as subproject with the following BUILD file:
cc_binary(
name = "recognizer.so",
srcs = glob(["recognizer.cpp"]),
linkshared = 1,
deps = [
"//tensorflow:сore"
],
)
Everything links together but I end up with a shared library about 94 megabytes in size and not depended on libtensorflow_cc.so. Actually there is even no such binary as libtensorflow_cc.so built.
There is a target //tensorflow:libtensorflow_cc.so . It is declared as cc_binary which means (according to bazel) I cannot depend on it. Moreover this target is actually non-public, which means that I can build it but not refer to it from another subproject. At least with bazel.
So, is there any way to do such a simple thing?
I cannot comment on why libtensorflow.so or libtensorflow_cc.so are :internal. But there is a trick you can do in Bazel to be able to depend on a shared library created by cc_binary: declare it as a source of a cc rule.
cc_binary(
name = "liba.so",
srcs = [ "a.cc" ],
linkshared = 1
)
cc_binary(
name = "main",
srcs = [ "main.cc", "liba.so" ],
)
Now this is highly unsupported :) In fact, we are going to change how we handle shared libraries in the following months, so I can almost promise you it will break. You can subscribe to https://github.com/bazelbuild/bazel/issues/1920 or follow bazel-dev# to be updated.