Show how to build and execute a binary, how to build a library, and how to build and run a test.
In this example we have declared 3 targets. A library, an executable, and a test. The binary and the test depends on the library.
-
//:my_lib: A library with a public header and a single cpp file. It can be defined in Bazel as follows:cc_library( name = "my_lib", srcs = ["my_lib.cpp"], hdrs = ["my_lib.h"], )
nameis the name for the target, it will also be used to create the library file in the form oflib<name>.aorlib<name>.sodepending on whether is a dynamic or a static library.hdrsis the list of public headers of the library, your interface to the rest of the world.srcsis the list of source files needed to generate the library, including private headers and cpp files. The public header files should not be present in this parameter, they are defined inhdrs. -
//:hello_world: A binary that depends on the library mentioned above. It can be defined in Bazel as follows:cc_binary( name = "hello_world", srcs = ["hello_world.cpp"], deps = [":my_lib"], )
nameis the name for the target, it will also be used to create the executable file in the form of<name>in Unix systems or<name>.exein Windows systems.srcsis the list of source files needed to generate the executable.depsis the list of libraries that your binary depends on. In this case we specify the target:my_libthat is the library that we want to use in this binary. -
//:my_test: A test formy_libtarget. In the end it is an executable also but Bazel will treat it different in several aspects. It can be defined in Bazel as follows:cc_test( name = "my_test", srcs = ["test.cpp"], deps = [":my_lib"], )
nameis the name for the target, it will also be used to create the executable file for the test in the form of<name>in Unix systems or<name>.exein Windows systems.srcsis the list of source files needed to generate the test executable. The requirement like a binary is that it has to contain amainfunction that returns anint. If it returns an 0 it is considered like the test passed, otherwise is considered as failure.depslike for the binary, is the list of libraries that your test depends on.
To run the executable you call:
bazel run //:hello_worldIt will run the executable and display the output on the terminal.
To run the test you call:
bazel test //:my_testIt will run the test without showing any output from the test but a Bazel output indicating if the test succeeded or failed.
//:my_test PASSED in 0.0sA test, compared to a binary executed with bazel run will not be allways executed. If Bazel detects that nothing changed it will cache the result of th test and show it in the report.
//:my_test (cached) PASSED in 0.0sIf you want to build the executable without running it you call:
bazel build //:hello_worldAnd if you want to build only the library you can do the same with the target of the library:
bazel build //:my_libIn this example we have one executable and one library. This brings us to two possibilities, to load the library during runtime (dynamic linking) or embed it into the executable (static linking).
The way to control it in Bazel is using --dynamic_mode. It has three options: default, fully and off. The most relevant for us are fully and off.
If we build the binary using off it will do static linking in all the cases that it is possible. Using fully it will do dynamic linking with all the targets.
How to pass it to the command line would be as follows:
bazel build //:hello_world --dynamic_mode=offYou can also pass it when calling directly bazel run.