Rules
- cc_binary
- cc_import
- cc_library
- cc_shared_library
- cc_static_library
- cc_test
- cc_toolchain
- fdo_prefetch_hints
- fdo_profile
- memprof_profile
- propeller_optimize
cc_binary
View rule sourceopen_in_newname of the target should be the same as the name of the
source file that is the main entry point of the application (minus the extension).
For example, if your entry point is in main.cc, then your name should
be main.
Implicit output targets
name.stripped(only built if explicitly requested): A stripped version of the binary.strip -gis run on the binary to remove debug symbols. Additional strip options can be provided on the command line using--stripopt=-foo.name.dwp(only built if explicitly requested): If Fission is enabled: a debug information package file suitable for debugging remotely deployed binaries. Else: an empty file.
Arguments
cc_import
View rule sourceopen_in_newcc_import rules allows users to import precompiled C/C++ libraries.
The following are the typical use cases:
- Linking a static library
- Linking a shared library (Unix)
- Linking a shared library with interface library
- Linking a shared library with
system_provided=True
- Linking to static or shared library
cc_import supports an include attribute. For example:
Arguments
cc_library
View rule sourceopen_in_newcc_library() for C++-compiled libraries.
The result is either a .so, .lo,
or .a, depending on what is needed.
If you build something with static linking that depends on
a cc_library, the output of a depended-on library rule
is the .a file. If you specify
alwayslink=True, you get the .lo file.
The actual output file name is libfoo.so for
the shared library, where foo is the name of the rule. The
other kinds of libraries end with .lo and .a,
respectively. If you need a specific shared library name, for
example, to define a Python module, use a genrule to copy the library
to the desired name.
Header inclusion checking
All header files that are used in the build must be declared in thehdrs or srcs of cc_* rules.
This is enforced.
For cc_library rules, headers in hdrs comprise the
public interface of the library and can be directly included both
from the files in hdrs and srcs of the library
itself as well as from files in hdrs and srcs
of cc_* rules that list the library in their deps.
Headers in srcs must only be directly included from the files
in hdrs and srcs of the library itself. When
deciding whether to put a header into hdrs or srcs,
you should ask whether you want consumers of this library to be able to
directly include it. This is roughly the same decision as
between public and private visibility in programming languages.
cc_binary and cc_test rules do not have an exported
interface, so they also do not have a hdrs attribute. All headers
that belong to the binary or test directly should be listed in
the srcs.
To illustrate these rules, look at the following example.
foo.cc is allowed to directly
include foo.h and bar.h, but not baz.h.
The inclusion checking rules only apply to direct
inclusions. In the example above
foo.cc is allowed to
include bar.h, which may include baz.h, which in
turn is allowed to include baz-impl.h. Technically, the
compilation of a .cc file may transitively include any header
file in the hdrs or srcs in
any cc_library in the transitive deps closure. In
this case the compiler may read baz.h and baz-impl.h
when compiling foo.cc, but foo.cc must not
contain #include "baz.h". For that to be
allowed, baz must be added to the deps
of foo.
Bazel depends on toolchain support to enforce the inclusion checking rules.
The layering_check feature has to be supported by the toolchain
and requested explicitly, for example via the
--features=layering_check command-line flag or the
features parameter of the
package function. The toolchains
provided by Bazel only support this feature with clang on Unix and macOS.
Examples
We use thealwayslink flag to force the linker to link in
this code although the main binary code doesn’t reference it.
third_party/python2_4_3/BUILD.
Some of the code uses the dl library (to load
another, dynamic library), so this
rule specifies the -ldl link option to link the
dl library.
third_party/kde/BUILD.
We keep pre-built .so files in the depot.
The header files live in a subdirectory named include.
third_party/gles/BUILD.
Third-party code often needs some defines and
linkopts.
Arguments
Note that the
linkopts attribute only applies
when creating .so files or executables, not
when creating .a or .lo files.
So if the linkstatic=True attribute is set, the
linkopts attribute has no effect on the creation of
this library, only on other targets which depend on this library.
Also, it is important to note that “-Wl,-soname” or “-Xlinker -soname”
options are not supported and should never be specified in this attribute.
The .so files produced by cc_library
rules are not linked against the libraries that they depend
on. If you’re trying to create a shared library for use
outside of the main repository, e.g. for manual use
with dlopen() or LD_PRELOAD,
it may be better to use a cc_binary rule
with the linkshared=True attribute.
See cc_binary.linkshared.
| linkstamp | Label; default is None Simultaneously compiles and links the specified C++ source file into the final binary. This trickery is required to introduce timestamp information into binaries; if we compiled the source file to an object file in the usual way, the timestamp would be incorrect. A linkstamp compilation may not include any particular set of compiler flags and so should not depend on any particular header, compiler option, or other build variable. This option should only be needed in the base package. |
| linkstatic | Boolean; default is False For cc_binary and cc_test: link the binary in static mode. For cc_library.link_static: see below. By default this option is on for cc_binary and off for the rest. If enabled and this is a binary or test, this option tells the build tool to link in .a’s instead of .so’s for user libraries whenever possible. System libraries such as libc (but not the C/C++ runtime libraries, see below) are still linked dynamically, as are libraries for which there is no static library. So the resulting executable will still be dynamically linked, hence only mostly static. There are really three different ways to link an executable: * STATIC with fully_static_link feature, in which everything is linked statically; e.g. “gcc -static foo.o libbar.a libbaz.a -lm”. This mode is enabled by specifying fully_static_link in the features attribute. * STATIC, in which all user libraries are linked statically (if a static version is available), but where system libraries (excluding C/C++ runtime libraries) are linked dynamically, e.g. “gcc foo.o libfoo.a libbaz.a -lm”. This mode is enabled by specifying linkstatic=True. * DYNAMIC, in which all libraries are linked dynamically (if a dynamic version is available), e.g. “gcc foo.o libfoo.so libbaz.so -lm”. This mode is enabled by specifying linkstatic=False. If the linkstatic attribute or fully_static_link in features is used outside of //third_party please include a comment near the rule to explain why. The linkstatic attribute has a different meaning if used on a cc_library() rule. For a C++ library, linkstatic=True indicates that only static linking is allowed, so no .so will be produced. linkstatic=False does not prevent static libraries from being created. The attribute is meant to control the creation of dynamic libraries. There should be very little code built with linkstatic=False in production. If linkstatic=False, then the build tool will create symlinks to depended-upon shared libraries in the *.runfiles area. |
| local_defines | List of strings; default is [] List of defines to add to the compile line. Subject to “Make” variable substitution and Bourne shell tokenization. Each string, which must consist of a single Bourne shell token, is prepended with -D and added to the compile command line for this target, but not to its dependents. Unlike defines, the defines are only added to the compile command line for this target. |
| module_interfaces | List of labels; default is [] The list of files are regarded as C++20 Modules Interface. C++ Standard has no restriction about module interface file extension * Clang use cppm * GCC can use any source file extension * MSVC use ixx The use is guarded by the flag --experimental_cpp_modules. |
| strip_include_prefix | String; default is "" The prefix to strip from the paths of the headers of this rule. When set, the headers in the hdrs attribute of this rule are accessible at their path with this prefix cut off. If it’s a relative path, it’s taken as a package-relative one. If it’s an absolute one, it’s understood as a repository-relative path. The prefix in the include_prefix attribute is added after this prefix is stripped. This attribute is only legal under third_party. |
| textual_hdrs | List of labels; default is [] The list of header files published by this library to be textually included by sources in dependent rules. This is the location for declaring header files that cannot be compiled on their own; that is, they always need to be textually included by other source files to build valid code. |
| win_def_file | Label; default is None The Windows DEF file to be passed to linker. This attribute should only be used when Windows is the target platform. It can be used to export symbols during linking a shared library. |
cc_shared_library
View rule sourceopen_in_newExample
foo_shared statically links foo
and baz, the latter being a transitive dependency. It doesn’t
link bar because it is already provided dynamically by the
dynamic_dep bar_shared.
foo_shared uses a linker script *.lds file to control which
symbols should be exported. The cc_shared_library rule logic does
not control which symbols get exported, it only uses what is assumed to be
exported to give errors during analysis phase if two shared libraries export the
same targets.
Every direct dependency of cc_shared_library is assumed to be
exported. Therefore, Bazel assumes during analysis that foo is being
exported by foo_shared. baz is not assumed to be exported
by foo_shared. Every target matched by the exports_filter
is also assumed to be exported.
Every single cc_library in the example should appear at most in one
cc_shared_library. If we wanted to link baz also into
bar_shared we would need to add
tags = ["LINKABLE_MORE_THAN_ONCE"] to baz.
Due to the shared_lib_name attribute, the file produced by
bar_shared will have the name bar.so as opposed
to the name libbar.so that it would have by default on Linux.
Errors
Two shared libraries in dependencies export the same symbols.
This will happen whenever you are creating a target with two different
cc_shared_library dependencies that export the same target. To fix this
you need to stop the libraries from being exported in one of the
cc_shared_library dependencies.
Two shared libraries in dependencies link the same library statically
This will happen whenever you are creating a new cc_shared_library with two
different cc_shared_library dependencies that link the same target statically.
Similar to the error with exports.
One way to fix this is to stop linking the library into one of the
cc_shared_library dependencies. At the same time, the one that still links it
needs to export the library so that the one not linking it keeps visibility to
the symbols. Another way is to pull out a third library that exports the target.
A third way is to tag the culprit cc_library with LINKABLE_MORE_THAN_ONCE
but this fix should be rare and you should absolutely make sure that the
cc_library is indeed safe to link more than once.
'//foo:foo' is already linked statically in '//bar:bar' but not exported`
This means that a library in the transitive closure of your deps is reachable
without going through one of the cc_shared_library dependencies but is already
linked into a different cc_shared_library in dynamic_deps and is not
exported.
The solution is to export it from the cc_shared_library dependency or pull out
a third cc_shared_library that exports it.
Do not place libraries which only contain a precompiled dynamic library in deps.
If you have a precompiled dynamic library, this doesn’t need to and cannot be
linked statically into the current cc_shared_library target that you are
currently creating. Therefore, it doesn’t belong in deps of the
cc_shared_library. If this precompiled dynamic library is a dependency of one
of your cc_libraries, then the cc_library needs to depend on it
directly.
Trying to export a library already exported by a different shared library
You will see this error if on the current rule you are claiming to export a
target that is already being exported by one of your dynamic dependencies.
To fix this, remove the target from deps and just rely on it from the dynamic
dependency or make sure that the exports_filter doesn’t catch this target.
Arguments
cc_static_library
View rule sourceopen_in_newdeps as well as their transitive dependencies, with preference given to
PIC objects.
Output groups
linkdeps
A text file containing the labels of those transitive dependencies of targets listed in
deps that did not contribute any object files to the static library, but do
provide at least one static, dynamic or interface library. The resulting static library
may require these libraries to be available at link time.
linkopts
A text file containing the user-provided linkopts of all transitive
dependencies of targets listed in deps.
Duplicate symbols
By default, thecc_static_library rule checks that the resulting static
library does not contain any duplicate symbols. If it does, the build fails with an error
message that lists the duplicate symbols and the object files containing them.
This check can be disabled per target or per package by setting
features = ["-symbol_check"] or globally via
--features=-symbol_check.
Toolchain support for symbol_check
The auto-configured C++ toolchains shipped with Bazel support the
symbol_check feature on all platforms. Custom toolchains can add support for
it in one of two ways:
- Implementing the
ACTION_NAMES.validate_static_libraryaction and enabling it with thesymbol_checkfeature. The tool set in the action is invoked with two arguments, the static library to check for duplicate symbols and the path of a file that must be created if the check passes. - Having the
symbol_checkfeature add archiver flags that cause the action creating the static library to fail on duplicate symbols.
Arguments
cc_test
View rule sourceopen_in_newcc_test() rule compiles a test. Here, a test
is a binary wrapper around some testing code.
By default, C++ tests are dynamically linked.
To statically link a unit test, specify
linkstatic=True.
It would probably be good to comment why your test needs
linkstatic; this is probably not obvious.
Implicit output targets
name.stripped(only built if explicitly requested): A stripped version of the binary.strip -gis run on the binary to remove debug symbols. Additional strip options can be provided on the command line using--stripopt=-foo.name.dwp(only built if explicitly requested): If Fission is enabled: a debug information package file suitable for debugging remotely deployed binaries. Else: an empty file.
stamp argument is set to 0 by default for tests and
that cc_test has extra attributes common to all test rules (*_test).
Arguments
cc_toolchain
View rule sourceopen_in_new- Collecting all artifacts needed for C++ actions to run. This is done by
attributes such as
all_files,compiler_files,linker_files, or other attributes ending with_files). These are most commonly filegroups globbing all required files. - Generating correct command lines for C++ actions. This is done using
CcToolchainConfigInfoprovider (details below).
toolchain_config attribute to configure the C++ toolchain.
See also this
page for elaborate C++ toolchain configuration and toolchain selection documentation.
Use tags = ["manual"] in order to prevent toolchains from being built and configured
unnecessarily when invoking bazel build //...