8.1.5. Bazel¶
8.1.5.1. Background¶
Your project is built using Bazel.
8.1.5.2. What can be configured?¶
You can add a cc_toolchain for and platform for the Axivion tools to your setup, either by using the supplied rules_axivion ruleset or by manually creating one using the templates shown here.
8.1.5.3. What needs to be done?¶
Before the Axivion Suite can be used with Bazel, a corresponding toolchain must be configured for the Axivion tools. In addition, an Axivion platform should be defined for an artificial cpu to be targeted by the toolchain.
Using the rules_axivion ruleset¶
The rules_axivion ruleset provides functions to integrate the Axivion Suite as a repository in Bazel,
and to automatically create cc toolchains based on existing toolchain configurations.
The ruleset can be added to your workspace by copying the snippet below into your WORKSPACE.bazel file
and replacing REPLACE_WITH_YOUR_DASHBOARD_URL with the URL of your dashboard. (See Bazel Integration API for the API reference.)
http_archive(
name = "rules_axivion",
urls = ["REPLACE_WITH_YOUR_DASHBOARD_URL/api/bazel/rules_axivion.tar.gz"],
sha256 = "190e5f0e7b3bfb9ea06de16f8159d68831e47fb4cce137eb87e4c9fcf822445e"
)
load("@rules_axivion//axivion:repositories.bzl", "rules_axivion_dependencies")
rules_axivion_dependencies()
Note
The ruleset requires Bazel 7 or newer and only supports the WORKSPACE dependency system.
This code snippet below shows how rules_axivion can be used to create a cc_toolchain for the Axivion tools using a locally installed Axivion Suite and the cc_toolchain Bazel configures automatically.
...
load("@rules_axivion//axivion:repositories.bzl", "axivion_suite_repo_local")
# The rule `axivion_suite_repo_local` creates a repository
# for the locally installed Axivion Suite at /opt/axivion_suite
# and adds the license key from the example_users home directory.
# Alternatively, it is also possible to download an installer package using
# the `axivion_suite_repo_http` rule instead of using a local installation.
axivion_suite_repo_local(
name = "axivion_suite",
path = "/opt/axivion_suite",
axivion_license_key = "/home/example_user/.bauhaus/bauhaus.key"
)
load("@rules_axivion//axivion:repositories.bzl", "setup_axivion_toolchain")
# The rule `setup_axivion_toolchain` creates a repository and cc_toolchain configuration
# for the Axivion compiler based on the given `origin_cc_toolchain_config`.
# This example uses the default cc_toolchain configuration generated by Bazel as the base.
setup_axivion_toolchain(
name = "example_axivion_toolchain_repository",
toolchain_name="example_axivion_toolchain",
origin_cc_toolchain_config = "@@local_config_cc//:local",
)
# The created toolchain is not registered automatically; this has to be done manually.
register_toolchains(
"@example_axivion_toolchain_repository//:example_axivion_toolchain"
)
Manual configuration with templates¶
You can find preconfigured toolchain templates for Unix and Windows systems under $AXIVION_INSTALLDIR/profiles/bazel
that can be used as a basis for creating an Axivion toolchain.
These templates are modified versions of Bazel’s default cc toolchains and require additional configuration.
To use, you can copy the relevant file into your project’s axivion configuration directory and rename it to BUILD.bazel.
In most cases, it will be helpful to identify the currently used cc toolchain configuration
and check the used system includes and compiler flags.
This can be done by calling Bazel with the --toolchain_resolution_debug=".*" flag, to show the selected toolchains.
The directory containing the toolchain configuration can then be found under external.
The following example shows what the output of --toolchain_resolution_debug=".*" can look like.
The highlighted lines specify the selected toolchain together with the host and target platforms.
With this we can see that the selected toolchain is @@bazel_tools~cc_configure_extension~local_config_cc//:cc-compiler-k8
and can be found in external/bazel_tools~cc_configure_extension~local_config_cc/BUILD.
bazel build --toolchain_resolution_debug=".*" //main:hello-world
INFO: ToolchainResolution: Target platform @@local_config_platform//:host: Selected execution platform @@local_config_platform//:host,
INFO: ToolchainResolution: Performing resolution of @@bazel_tools//tools/cpp:toolchain_type for target platform @@local_config_platform//:host
ToolchainResolution: Rejected toolchain @@bazel_tools~cc_configure_extension~local_config_cc//:cc-compiler-armeabi-v7a; mismatching values: armv7, android
ToolchainResolution: Toolchain @@bazel_tools~cc_configure_extension~local_config_cc//:cc-compiler-k8 is compatible with target platform, searching for execution platforms:
ToolchainResolution: Compatible execution platform @@local_config_platform//:host
ToolchainResolution: All execution platforms have been assigned a @@bazel_tools//tools/cpp:toolchain_type toolchain, stopping
ToolchainResolution: Recap of selected @@bazel_tools//tools/cpp:toolchain_type toolchains for target platform @@local_config_platform//:host:
ToolchainResolution: Selected @@bazel_tools~cc_configure_extension~local_config_cc//:cc-compiler-k8 to run on execution platform @@local_config_platform//:host
INFO: ToolchainResolution: Target platform @@local_config_platform//:host: Selected execution platform @@local_config_platform//:host,
type @@bazel_tools//tools/cpp:toolchain_type -> toolchain @@bazel_tools~cc_configure_extension~local_config_cc//:cc-compiler-k8
INFO: ToolchainResolution: Target platform @@local_config_platform//:host: Selected execution platform @@local_config_platform//:host,
INFO: ToolchainResolution: Target platform @@local_config_platform//:host: Selected execution platform @@local_config_platform//:host,
INFO: Analyzed target //main:hello-world (68 packages loaded, 309 targets configured).
...
From here, you can copy the used cc_toolchain_config from the BUILD file into the template file and adjust it to work with the Axivion tools.
The necessary adjustments are marked with TODO in the template files.
In general, this includes changing the tool_paths to the Axivion tools
and depending on your compiler, adding the directory containing the axivion_preinc.h to the system include directories.
For gcc for example, the directory would be $AXIVION_INSTALLDIR/profiles/gnu.
Additionally -no-absolute_filenames should be added to the compile_flags to stop cafeCC from using absolute paths in error messages and *.d files.
For Unix systems, it is possible to only copy the system include directories to the predefined cc_toolchain_config in the template file
and make sure the compiler flags are correct.
# Copyright 2016 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This is a template BUILD file to configure a cc toolchain for the Axivion Suite on Unix.
It is based on the default Unix cc toolchain configuration
and contains a `axivion` platform and partial cc toolchain definition.
"""
load("@bazel_tools//tools/cpp:unix_cc_toolchain_config.bzl", "cc_toolchain_config")
package(default_visibility = ["//visibility:public"])
# TODO: Specify the absolute path to the Axivion Suite installation directory
PATH_TO_AXIVION_SUITE_DIR = ""
constraint_value(
name = "axivion_cpu",
constraint_setting = "@platforms//cpu",
visibility = ["//visibility:public"],
)
platform(
name = "axivion",
constraint_values = [
":axivion_cpu",
],
visibility = ["//visibility:public"],
)
filegroup(
name = "empty",
srcs = [],
)
filegroup(
name = "compiler_config",
srcs = glob(["*.json"]),
visibility = ["//visibility:public"],
)
filegroup(
name = "compiler_deps",
srcs = [
":compiler_config",
],
)
toolchain(
name = "axivion-cc-toolchain",
exec_compatible_with = [
"@platforms//cpu:x86_64",
],
target_compatible_with = [":axivion_cpu"],
toolchain = ":cc-compiler-axivion",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
cc_toolchain(
name = "cc-compiler-axivion",
all_files = ":compiler_deps",
ar_files = ":compiler_deps",
as_files = ":compiler_deps",
compiler_files = ":compiler_deps",
dwp_files = ":empty",
linker_files = ":compiler_deps",
module_map = None,
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 1,
toolchain_config = ":local",
toolchain_identifier = "local",
)
cc_toolchain_config(
name = "local",
abi_libc_version = "local",
abi_version = "local",
compile_flags = [
"-fstack-protector",
"-Wall",
"-Wunused-but-set-parameter",
"-Wno-free-nonheap-object",
"-fno-omit-frame-pointer",
# axivion flags
"-no_absolute_filenames",
"--diag_suppress=1561",
],
compiler = "compiler",
coverage_compile_flags = ["--coverage"],
coverage_link_flags = ["--coverage"],
cpu = "axivion",
# TODO: Define used include directories
cxx_builtin_include_directories = [
# Add all system include paths here
# All subdirectories need to be declared separately
# Add the path to the used axivion_preinc.h if necessary
# PATH_TO_AXIVION_SUITE_DIR + "/profiles/COMPILER",
],
cxx_flags = ["-std=c++14"],
dbg_compile_flags = ["-g"],
host_system_name = "local",
link_flags = [
"-fuse-ld=lld",
"-Wl,-no-as-needed",
"-Wl,-z,relro,-z,now",
"-B/usr/bin",
"-pass-exit-codes",
],
link_libs = [
"-Wl,--push-state,-as-needed",
"-lstdc++",
"-Wl,--pop-state",
"-Wl,--push-state,-as-needed",
"-lm",
"-Wl,--pop-state",
],
opt_compile_flags = [
"-g0",
"-O2",
"-D_FORTIFY_SOURCE=1",
"-DNDEBUG",
"-ffunction-sections",
"-fdata-sections",
],
opt_link_flags = ["-Wl,--gc-sections"],
supports_start_end_lib = True,
target_libc = "local",
target_system_name = "local",
tool_paths = {
"ar": PATH_TO_AXIVION_SUITE_DIR + "/bin/cafeAR",
"ld": PATH_TO_AXIVION_SUITE_DIR + "/bin/cafeCC",
"llvm-cov": "None",
"cpp": PATH_TO_AXIVION_SUITE_DIR + "/bin/cafeCC",
"gcc": PATH_TO_AXIVION_SUITE_DIR + "/bin/cafeCC",
"dwp": "/usr/bin/true",
"gcov": "None",
"nm": "/usr/bin/true",
"objcopy": PATH_TO_AXIVION_SUITE_DIR + "/bin/irOBJCOPY",
"objdump": PATH_TO_AXIVION_SUITE_DIR + "/bin/irOBJDUMP",
"strip": PATH_TO_AXIVION_SUITE_DIR + "/bin/irSTRIP",
},
toolchain_identifier = "local",
unfiltered_compile_flags = [
"-fno-canonical-system-headers",
"-Wno-builtin-macro-redefined",
"-D__DATE__=\"redacted\"",
"-D__TIMESTAMP__=\"redacted\"",
"-D__TIME__=\"redacted\"",
],
)
The provided configuration file $AXIVION_INSTALLDIR/profiles/bazel/.axivion.bazelrc sets the required options to execute the build with the Axivion toolchain,
when Bazel is called with the --config=axivion flag.
# Configuration file for the Axivion toolchain
# Call Bazel with the --config=axivion flag to use these options
# Enables cc toolchain resolution based on the specified platform.
# This is enabled by default starting with Bazel 7.
# Remove this, if you do not want to use platforms.
build:axivion --incompatible_enable_cc_toolchain_resolution
# Sets the target to the Axivion platform, so that the Axivion toolchain is selected.
# This assumes that the BUILD file containing the platform definition
# is placed inside the axivion directory at the root of your project.
# Adjust this option accordingly, depending on where the platform is defined.
build:axivion --platforms=//axivion:axivion
# Registers the Axivion toolchain
# This assumes that the BUILD file containing the toolchain definition
# is placed inside the axivion directory at the root of your project
# Adjust this option accordingly, depending on where your toolchain is defined.
build:axivion --extra_toolchains //axivion:axivion-cc-toolchain
# Makes sure BAUHAUS_CONFIG is available during the build.
build:axivion --action_env BAUHAUS_CONFIG
# Makes sure CAFECC_BASEPATH is available during the build.
# This environment variable is set by axivion_ci and allows cafeCC to use relative paths.
build:axivion --action_env CAFECC_BASEPATH
# Bazel 7 changed the way the linux-sandbox and darwin-sandbox work.
# This results in the following issue: cafeCC will store source code paths in the sandbox into the generated IR, eventually preventing source file lookup from Axivion Dashboard. For the cafeCC call, relative paths to the worktree should be used.
# We reduce the sandbox strictness to avoid this problem.
build:axivion --spawn_strategy=processwrapper-sandbox
You can either copy the file into the axivion configuration directory
and include it into your existing configuration by adding try-import %workspace%/axivion/.axivion.bazelrc to your main .bazelrc file,
or copy the options directly.
To verify your setup, you can again check with --toolchain_resolution_debug=".*" that the selected toolchain is now the Axivion one.
8.1.5.4. Known issues?¶
These are known potential issues with the Bazel integration, with possible solutions or explanations for why they occur.
Missing license file¶
The license file should either be placed under $AXIVION_INSTALLDIR/config or inside a directory pointed to by the environment variable BAUHAUS_CONFIG
to make sure it can be found by all Axivion tools during the analysis.
Generated files¶
This setup does not allow Axivion to use relative paths for files generated during the build that only exists inside the Bazel cache, which will cause violations inside these file to move between analysis runs depending on the cache directory path. Because of that, the Bazel cache directory should generally be excluded from the analysis.
Using irCC/irCXX or similar wrapper scripts¶
Using irCC/irCXX or similar tools in the cc toolchain configuration is generally fine, but doing so in addition to having Axivion tool-specific flags in the toolchain config can lead to compiler errors when the standard compiler tools are used instead of the Axivion ones.
Use with Rules ForeignCc¶
Rules ForeignCc allows building projects as part of a Bazel build, that themselves use a different build system (i.e. cmake, make, meson or ninja). The inclusion of different build systems can require additional configuration to ensure they are working with the Axivion toolchain.