- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
211 lines
6.9 KiB
ReStructuredText
211 lines
6.9 KiB
ReStructuredText
.. _tutorial_bazel:
|
|
|
|
==========================
|
|
Experimental Bazel Support
|
|
==========================
|
|
|
|
|
|
Introduction
|
|
------------
|
|
|
|
EVerest offers support for `Bazel <https://bazel.build/>`.
|
|
With Bazel, you can efficiently build, test and deploy software projects of any
|
|
size.
|
|
|
|
For EVerest developers, Bazel offers a couple advantages:
|
|
|
|
* While developing features, that span multiple modules, Bazel can swiftly
|
|
rebuild only the necessary parts of the project.
|
|
* If you have already setup Bazel in your project, EVerest framework can be
|
|
integrated with it.
|
|
|
|
This tutorial will guide you through the process of setting up and using
|
|
Bazel in your EVerest projects.
|
|
|
|
Getting Started
|
|
---------------
|
|
|
|
To install Bazel, it's recommended to use bazelisk, which is a tool that
|
|
downloads and runs the correct version of Bazel for your project.
|
|
You can install bazelisk by following the
|
|
`instructions on the official GitHub repository <https://github.com/bazelbuild/bazelisk?tab=readme-ov-file#installation>`.
|
|
|
|
.. note::
|
|
Bazelisk provides a `bazel` command, and the rest of this tutorial will
|
|
refer to it as `bazel`.
|
|
|
|
C/C++ Compilers:
|
|
At the moment, Bazel will use the default C/C++ compilers on your system.
|
|
If it is not the desired compiler to build EVerest, you can set the environment
|
|
variables `CC` and `CXX` to the desired compiler.
|
|
|
|
All other dependencies are fetched by Bazel as needed.
|
|
|
|
Using Bazel Commands
|
|
--------------------
|
|
|
|
Once Bazel is configured, you can use various Bazel commands to build, test
|
|
and run.
|
|
|
|
Most useful commands are:
|
|
|
|
* `bazel build //...` - Build all targets in the project.
|
|
* `bazel test //...` - Run all tests in the project.
|
|
|
|
Dependency Management
|
|
---------------------
|
|
|
|
There are a few different ways of managing dependencies in EVerest.
|
|
|
|
* Dependencies that CMake takes from the system (e.g. boost).
|
|
These dependencies are configured in the `third_party/bazel/repos.bzl` file.
|
|
* Dependencies that are described in the `./dependencies.yaml` file. These
|
|
dependencies are pulled automatically by Bazel with help of `edm` tool.
|
|
* Rust dependencies are managed by cargo, and are described in the `Cargo.toml`
|
|
file. Cargo dependencies are automatically picked up by Bazel.
|
|
|
|
Defining C++ EVerest Modules
|
|
----------------------------
|
|
|
|
Let's assume, you have a module named `Example` with a single interface
|
|
implementation named `example`. This module depends on the `sigslot` library.
|
|
For a more realistic scenario, the module has two extra files `utils.cpp` and
|
|
`utils.hpp`.
|
|
|
|
.. code-block:: bash
|
|
|
|
modules/
|
|
└── Example
|
|
├── BUILD.bazel
|
|
├── CMakeLists.txt
|
|
├── Example.cpp
|
|
├── Example.hpp
|
|
├── manifest.yaml
|
|
├── utils.cpp
|
|
├── utils.hpp
|
|
└── example/
|
|
├── exampleImpl.cpp
|
|
└── exampleImpl.hpp
|
|
|
|
The `manifest.yaml` file for the module looks like this:
|
|
|
|
.. code-block:: yaml
|
|
|
|
description: Simple example module written in C++
|
|
provides:
|
|
example:
|
|
interface: example
|
|
description: This implements an example interface that uses multiple framework features
|
|
...
|
|
requires:
|
|
kvs:
|
|
interface: kvs
|
|
enable_external_mqtt: true
|
|
metadata:
|
|
license: https://opensource.org/licenses/Apache-2.0
|
|
authors:
|
|
- Example Authors
|
|
|
|
To build this module with Bazel, you need to create a `BUILD.bazel` file in the
|
|
module directory, next to the `manifest.yaml` file.
|
|
|
|
In the `BUILD.bazel`, use predefined macros to define the module:
|
|
|
|
.. code-block:: python
|
|
|
|
load("//modules:module.bzl", "cc_everest_module")
|
|
|
|
cc_everest_module(
|
|
# Name of the module, must be the same as the directory name.
|
|
name = "Example",
|
|
deps = [
|
|
# List of libraries, that module depends on.
|
|
# In CMakeLists.txt these are typically added as `target_link_libraries`.
|
|
# The should be listed in the `third_party/bazel/repos.bzl` file.
|
|
# Note that header-only libraries should be added here as well.
|
|
"@sigslot//:sigslot",
|
|
],
|
|
impls = [
|
|
# List of implementations in the module.
|
|
# This should correspond to the list of keys in the
|
|
# `provides` section of the manifest.yaml file.
|
|
"example",
|
|
],
|
|
# List of additional source files of the module.
|
|
#
|
|
# Here you only have to list the files that are not autogenerated.
|
|
# The mandatory module files are added automatically.
|
|
srcs = [
|
|
"utils.cpp",
|
|
"utils.hpp",
|
|
],
|
|
# Alternatively, you can use `glob` function to list files.
|
|
# srcs = glob(
|
|
# [
|
|
# "*.cpp",
|
|
# "*.hpp",
|
|
# ],
|
|
# ),
|
|
)
|
|
|
|
|
|
Defining Rust EVerest Modules
|
|
-----------------------------
|
|
|
|
To define a Rust module in EVerest, you need to create a BUILD.bazel file in
|
|
the module directory.
|
|
Generic `rust_binary` and `rust_test` are used at the moment.
|
|
|
|
.. code-block:: python
|
|
|
|
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test")
|
|
load("@everest_core_crate_index//:defs.bzl", "all_crate_deps")
|
|
load("@rules_rust//cargo:defs.bzl", "cargo_build_script")
|
|
|
|
# cargo_build_script describes to Bazel how to run autogeneration of the code.
|
|
# This should be pretty-much the same for every module
|
|
cargo_build_script(
|
|
name = "build_script",
|
|
srcs = ["build.rs"],
|
|
edition="2021",
|
|
build_script_env = {
|
|
# This is the path relative to the module directory.
|
|
"EVEREST_CORE_ROOT": "../..",
|
|
},
|
|
data = [
|
|
"manifest.yaml",
|
|
"@everest-core//interfaces",
|
|
"@everest-core//types",
|
|
],
|
|
deps = all_crate_deps(build = True),
|
|
)
|
|
|
|
# The module is described as a rust_binary at the moment.
|
|
rust_binary(
|
|
# Name of the module, must be the same as the directory name.
|
|
name = "RsIskraMeterBinary",
|
|
# List of source files of the module.
|
|
# In most cases this glob should be enough.
|
|
srcs = glob(["src/*.rs"]),
|
|
# Rust language edition, used in this module.
|
|
edition="2021",
|
|
# Bazel makes distinctions between dependencies needed on different
|
|
# stages of the build. This is the list of proc_macro dependencies.
|
|
# In most cases this is enough
|
|
proc_macro_deps = all_crate_deps(proc_macro = True),
|
|
visibility = ["//visibility:public"],
|
|
# List of "normal" dependencies.
|
|
# all_crate_deps will add all the dependencies from the Cargo.toml file.
|
|
# We need as well to add framework, bridge, and the result of the build_script.
|
|
# Typically this is enough.
|
|
deps = all_crate_deps(normal = True) + [
|
|
":build_script",
|
|
"//lib/everest/framework/everestrs/everestrs:everestrs_sys",
|
|
"//lib/everest/framework/everestrs/everestrs:everestrs_bridge",
|
|
],
|
|
)
|
|
|
|
----
|
|
|
|
**Authors**: Evgeny Petrov
|