How to specify -std=c++11 option in bazel BUILD file? - c++

How to add this option into a target description section?
Thanks.

Add bazel build --cxxopt='-std=c++11' to .bazelrc file.

export BAZEL_CXXOPTS=-std=c++11
see source

Besides setting it globally in .bazelrc or using BAZEL_CXXOPTS , you can also set them individually for each target in their cc_binary or cc_test rules:
cc_binary(
name = "target1",
srcs = ["target1.cc"],
copts = ["--std=c++17"],
)
cc_binary(
name = "target2",
srcs = ["target2.cc"],
copts = ["--std=c++14"],
)

Related

Bazel include file not found

Edit (2022-05-28): for anyone who ends up here from searching for bazel + sfml, I gave up on trying to compile it from source with bazel.
Instead, I installed SFML with brew. Then in WORKSPACE.bazel:
new_local_repository(
name = "SFML",
path = "/opt/homebrew",
build_file = "third_party/SFML/BUILD.bazel"
)
and third_party/SFML/BUILD.bazel:
cc_library(
name = "sfml",
srcs = glob(["lib/libsfml-*.dylib"]),
hdrs = glob(["include/SFML/**/*.*"]),
include_prefix = "SFML",
strip_include_prefix = "include/SFML",
visibility = ["//visibility:public"],
)
finally, as a dependency in any BUILD.bazel:
cc_binary(
name = "main",
srcs = ["main.cc"],
deps = [
"#SFML//:sfml",
]
)
This allows me to #include <SFML/Graphics.hpp> for example in main.cc and so far it's working.
I'm trying to use bazel to build SFML from source and use it in a project. Right now I have a very simple setup:
foo/
src/
main.cc
BUILD
third_party/
SFML/
...
BUILD
BUILD
WORKSPACE
# third_party/SFML/BUILD
load("#rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "sfml",
srcs = glob(["src/*.cpp"]),
hdrs = glob(["include/*.hpp"]),
copts = ["-Ithird_party/SFML/include"],
linkopts = [
"-lsfml‑system",
"-lsfml‑window",
"-lsfml‑graphics",
"-lsfml‑audio",
],
visibility = ["//visibility:public"]
)
# src/BUILD
load("#rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
name = "mygame",
srcs = ["main.cc"],
deps = [
"//third_party/SFML:sfml",
],
)
and main.cc:
#include "third_party/SFML/sfml/Graphics.hpp"
#include "third_party/SFML/sfml/System.hpp"
#include "third_party/SFML/sfml/Window.hpp"
int main() {
// ...
}
When I run bazel build //src:mygame I get an error:
fatal error: 'third_party/SFML/Graphics.hpp' file not found
I also tried using #include "third_party/SFML/Graphics.hpp" but that doesn't work either.
Not sure what the correct include path needs to be. Any suggestions?

I can't properly add external dependency with bazel

I trying to test "Hello World" C++ project with Bazel.
I have the following project structure:
WORKSPACE
/dependencies
BUILD
BUILD.gtest
/test
BUILD
WORKSPACE has the following structure:
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# gtest
http_archive(
name = "gtest",
url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
build_file = "#//dependencies:BUILD.gtest",
strip_prefix = "googletest-release-1.10.0",
)
BUILD.gtest has the following structure:
cc_library(
name = "main",
srcs = glob(
["src/*.cc"],
exclude = ["src/gtest-all.cc"]
),
hdrs = glob([
"include/**/*.h",
"src/*.h"
]),
copts = ["-Iexternal/gtest/include"],
linkopts = ["-pthread"],
visibility = ["//visibility:public"],
)
test BUILD has the following structure:
cc_test(
name = "unittests",
srcs = ["scanner_test.cc"],
copts = ["-Iexternal/gtest/include"],
deps = [
"//scanner:scanner",
"#gtest//:main"
]
)
when I execute
bazel build //test:unittests
I get
INFO: Analyzed target //test:unittests (26 packages loaded, 315 targets configured).
INFO: Found 1 target...
ERROR: ../test/BUILD:1:8: Compiling test/scanner_test.cc failed: (Exit 1): gcc failed: error executing command /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++0x' -MD -MF ... (remaining 25 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
test/scanner_test.cc:1:10: fatal error: gtest/gtest.h: No such file or directory
1 | #include "gtest/gtest.h"
| ^~~~~~~~~~~~~~~
compilation terminated.
Target //test:unittests failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 2.314s, Critical Path: 0.08s
INFO: 2 processes: 2 internal.
FAILED: Build did NOT complete successfully
As the other answer mentions:
The file BUILD.gtest is not needed.
Because gtest repo / release archive already provides one.
The reason why your own didn't behave as you might have expected is you've tried to point to the headers by manipulating copts which is applied only to building that one specific cc_library target (from linked docs):
The flags take effect only for compiling this target, not its dependencies, so be careful about header files included elsewhere.
Whereas to expose these interfaces to other targets consuming it you need to use includes (docs again):
Unlike COPTS, these flags are added for this rule and every rule that depends on it.
The file BUILD.gtest is not needed.
WORKSPACE.bazel:
workspace(name = "GTestDemo")
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "gtest",
url = "https://github.com/google/googletest/archive/release-1.10.0.tar.gz",
sha256 = "9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb",
strip_prefix = "googletest-release-1.10.0",
)
BUILD.bazel:
cc_test(
name = "tests",
srcs = ["test.cpp"],
deps = [
"#gtest//:gtest",
"#gtest//:gtest_main",
],
)
test.cpp:
#include <iostream>
#include <fstream>
#include "gtest/gtest.h"
using namespace std;
TEST(sample_test_case, sample_test) {
EXPECT_EQ(1, 1);
}
Tested with Bazel 4.1.0.

How to use Bazel in case of only header files (template classes/function) in C++?

I have the following problem:
Let's say that my project structure is:
├── project
│ ├── include
| | ├── BUILD
| | └── library.hpp
│ ├── src
| | ├── BUILD
| | └── main.cpp
| ├── test
| | ├── BUILD
| | └── library_test.cpp
└── WORKSPACE
library.hpp is a file which contains implementation of template class and it is included in main.cpp and library_test.cpp.
How to prepare BUILD files so I would not get compilation errors while compiling library_test.cpp and main.cpp that say:
src/main.cpp:2:10: fatal error: shared_ptr.hpp: No such file or directory
2 | #include "library.hpp"
| ^~~~~~~~~~~~~~~~
compilation terminated.
What I tried was:
include/BUILD
load("#rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "library",
srcs = ["library.hpp"],
includes = ["include"],
visibility = [
"//visibility:public",
]
)
Above I also tried having hdrs and textual_hdrs instead of srcs.
test/BUILD:
load("#rules_cc//cc:defs.bzl", "cc_test")
cc_test(
name = "library_test",
srcs = ["library_test.cpp"],
deps = [
"#gtest//:gtest",
"#gtest//:gtest_main",
],
includes = ["include"],
copts = ["-Iproject/include"],
)
and to be thorough my WORKSPACE:
load("#bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "gtest",
remote = "https://github.com/google/googletest",
branch = "v1.10.x",
)
I have a problem to figure it out by myself based on offical bazel tutorials, some presentations or similar questions I saw on the internet. They show only use of cc_library in case where definitions of the functions written in library are in cpp file and it can be compiled into object file.
# BUILD
cc_library(
name = "library",
hdrs= ["include/library.hpp"],
includes = ["include"],
visibility = [
"//visibility:public",
]
)
cc_test(
name = "library_test",
srcs = ["test/library_test.cpp"],
deps = [
"#gtest//:gtest_main", # gtest_main already contains gtest
":library"
],
)
cc_binary(
name = "binary",
srcs = ["src/main.cpp"],
deps = [
":library"
],
)
Notice:
Use hdrs, because srcs are not visible by dependent targets.
Do not use separate BUILD files for src/include/test directories. In Bazel you should create packages oriented by functionality, not by layer.
In you code a library_test target will not see headers from a library target, you must pass it as dependency via deps attribute. Bazel use sandboxing TL;DR: actions do not see files, which are not explicitly defined as dependency
Do not use copts = ["-Iproject/include"]. Bazel will do it for you when everything is done correctly: in that case you have to add an includes attribute to a library target. Include path will be set in a library_test, because the test targets depends on the library

Can bazel build dll?

I've tried to compile a DLL using bazel for days.
I followed the example bazel build hoping to generate a DLL.
The BUILD file I used is as follow:
cc_binary(
name = "expdtctlib",
srcs = ["expdtctlib.cpp"],
deps = [
"//tensorflow/core:tensorflow",
],
linkshared = 1,
)
cc_binary(
name = "expdetect",
srcs = ["expdetect.cpp"],
data = [":expdtctlib.dll"],
deps = [
"//tensorflow/core:tensorflow",
],
)
I ran the command :
bazel build :expdetect
But an error said the "expdtctlib.dll" was missing.
Don't bazel first generate "expdtctlib.dll" and then compile "expdetect.cpp"?
Besides,I've tried to use a another way to build DLL.The BUILD file is as follow:
cc_library(
name = "ExpDetector",
srcs = ["ExpDetector.cc"],
hdrs = ["ExpDetector.h"],
deps = [
"//tensorflow/core:tensorflow",
],
)
cc_binary(
name = "expdetect",
srcs = ["expdetect.cc"],
deps = [
"//tensorflow/core:tensorflow",
":ExpDetector",
],
)
After a long time compiling,though a EXE file was output and ran well,I could only find .lib and .exp file but the .dll file.
Is there anyone successfully build DLL using bazel?I need your help please.
I modified two BUILD files as follow and it worked well!
filegroup(
name = "srcs",
srcs = glob(["**"]),
visibility = ["//examples:__pkg__"],
)
cc_binary(
name = "expdtctlib.dll",
srcs = ["expdtctlib.cc",
"expdtctlib.h"],
deps = [
"//tensorflow/core:tensorflow",
],
linkshared = 1,
)
cc_binary(
name = "expdetect",
srcs = ["expdetect.cc"],
data = [":expdtctlib.dll"],
deps = [
"//tensorflow/core:tensorflow",
],
)
The one below is in "//tensorflow".
exports_files(
[
"LICENSE",
"ACKNOWLEDGEMENTS",
],
)
package(default_visibility = ["//visibility:public"])
filegroup(
name = "srcs",
srcs = glob(["**"]) + [
"//tensorflow/tensorflow/detector0405:srcs",
],
)
I am not familiar with bazel and c++,but these modification work.I'll read Bazel Document to learn more.

Why isn't my eval function in my Makefile working?

When I try to run the following make file (updated with suggestions below):
# Build Directories
src_dir=src
obj_dir=obj
bin_dir=bin
cc=cl
cc_flags=
configs = dbg rel
# create the directory for the current target.
dir_guard=#mkdir -p $(#D)
# source files
src = MainTest.cpp
define build_template =
# object files - replace .cpp on source files with .o and add the temp directory prefix
obj_$(1) = $$(addprefix $$(obj_dir)/$(1)/, $$(addsuffix .obj, $$(basename $$(src))))
testVar = "wooo"
# build TwoDee.exe from all of the object files.
$$(bin_dir)/$(1)/MainTest.exe : $$(obj_$(1))
$$(dir_guard)
$$(cc) -out:$$# $$(obj_$(1)) -link
# build all of the object files in the temp directory from their corresponding cpp files.
$$(obj): $$(obj_dir)/$(1)/%.obj : $$(src_dir)/%.cpp
$$(dir_guard)
$$(cc) $$(cc_flags) -Fo$$(obj_dir)/$$(1) -c $$<
endef
$(foreach cfg_dir,$(configs),$(eval $(call build_template,$(cfg_dir))))
release: $(bin_dir)/rel/MainTest.exe
debug: cc_flags += -Yd -ZI
debug: $(bin_dir)/dbg/MainTest.exe
$(warning testVar $(testVar))
All I get is:
$ make
Makefile:41: testVar
make: *** No rule to make target `bin/rel/MainTest.exe', needed by `release'. Stop.
You can see from the output that the testVar variable is never set. I made these changes based on my last question: Why doesn't my makefile target-specific variable work?
There are some spaces which confuse Make. Try this:
$(foreach cfg_dir,$(configs),$(eval $(call build_template,$(cfg_dir))))
Also make sure that you specify the right objects to link:
$$(cc) -out:$$# $$(obj_$(1)) -link
And as #Beta pointed out in the comments below, the = in the template definition syntax requires GNU make 3.82 or later. So better omit it from the line:
define build_template