blob: 7092fb1a50c77c776848d35291f749297c0c3610 [file] [view]
# Basic usage example
This is a basic example of how to use the doxygen rule with make variable substitutions.
The advantage of using make variable substitutions instead of directly working over the values passed to the doxygen rule is that you can access informations from other rules and toolchains and use them in the documentation.
Move to the parent directory and run the following command:
```bash
# Version: _empty_ , Description: "no stamp"
bazel build //substitutions:doxygen
# or
# Version: _empty_ , Description: "stamp fallback"
bazel build //substitutions:doxygen --stamp
# or
# Version: 1.0.0 , Description: "MyBuildDescription"
bazel build //substitutions:doxygen --stamp --//substitutions:build_description="MyBuildDescription" --embed_label=1.0.0
```
> [!NOTE]
> If `--stamp` is not passed, the version will be undetermined, usually an empty string or the last stamped value.
## Custom substitutions
We are reading variables from three sources:
- Hardcoded constant strings in the `BUILD.bazel` file (e.g. `NAME`).
- String flags passed through the command line (e.g. `--substitutions:build_description=MyBuildDescription`).
- The `stamp` information stored in the `bazel-out/stable-status.txt` file.
### Make variables
For the first two kind of substitution we need to define a simple rule that will apply the make variable substitutions.
Let's say we want to pass a description to the doxygen rule from a command line flag, but only if the build is stamped.
So, first we use `skylib` to define a string flag.
```bzl
# BUILD.bazel
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
string_flag(
name = "build_description",
build_setting_default = "stamp fallback",
)
```
> [!TIP]
> You can define an alias for the flag to make it easier to use in the command line.
> Create a `.bazelrc` file in the root of your workspace with the following content:
>
> ```bash
> build --flag_alias=build_description=//substitutions:build_description
> ```
>
> Now you can use `--build_description=MyBuildDescription` instead of `--//substitutions:build_description=MyBuildDescription`.
Then we create a substitution rule.
```bzl
# make_var_substitution.bzl
load("@aspect_bazel_lib//lib:stamping.bzl", "STAMP_ATTRS", "maybe_stamp")
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
def _make_var_substitution_impl(ctx):
vars = dict(ctx.attr.variables)
stamp = maybe_stamp(ctx)
if stamp: # If the build is stamped, use the value from --//substitutions:build_description as the build version.
vars["BUILD_DESCRIPTION"] = ctx.attr._build_description[BuildSettingInfo].value
else: # Otherwise use the hardcoded value.
vars["BUILD_DESCRIPTION"] = "no stamp"
return [platform_common.TemplateVariableInfo(vars)]
make_var_substitution = rule(
implementation = _make_var_substitution_impl,
attrs = dict({
"variables": attr.string_dict(),
"_build_description": attr.label(default = "//substitutions:build_description"),
}, **STAMP_ATTRS),
)
```
Finally, the substitution rule can be used as a toolchain in the doxygen rule.
All configurations using the make variable syntax will be replaced with the values defined in the make_var_substitution rule.
### Stamp information
To retrieve the stamp information from the `bazel-out/stable-status.txt` file, we have to define a genrule that reads the file and extracts the `BUILD_EMBED_LABEL` .
That information will be used to modify our custom `Doxyfile.template` file we will provide to the doxygen rule.
```bzl
# BUILD.bazel
# Use a shell script to read the version from the stable-status.txt file
# It will replace the pattern {{PROJECT_NUMBER}} in the Doxyfile.template file
genrule(
name = "doxyfile_template",
srcs = ["Doxyfile.template"],
outs = ["NewDoxyfile"],
cmd = "sed s/{{PROJECT_NUMBER}}/$(grep -oP '(?<=BUILD_EMBED_LABEL ).+' bazel-out/stable-status.txt)/ $(SRCS) > $@",
cmd_ps = "Get-content $(SRCS) | ForEach-Object { $$_ -replace '{{PROJECT_NUMBER}}', (Select-String -Pattern '(?<=BUILD_EMBED_LABEL +)(.+)' bazel-out/stable-status.txt -AllMatches | Select-Object -Expand Matches | Select-Object -Expand Value) } > $@",
stamp = -1, # Only update if --stamp is passed
)
```
### Final result
```bzl
# BUILD.bazel
load("@doxygen//:doxygen.bzl", "doxygen")
load("//substitutions:make_var_substitution.bzl", "make_var_substitution")
# Use a shell script to read the version from the stable-status.txt file
# It will replace the pattern {{PROJECT_NUMBER}} in the Doxyfile.template file
genrule(
name = "doxyfile_template",
srcs = ["Doxyfile.template"],
outs = ["NewDoxyfile"],
cmd = "sed s/{{PROJECT_NUMBER}}/$(grep -oP '(?<=BUILD_EMBED_LABEL ).+' bazel-out/stable-status.txt)/ $(SRCS) > $@",
cmd_ps = "Get-content $(SRCS) | ForEach-Object { $$_ -replace '{{PROJECT_NUMBER}}', (Select-String -Pattern '(?<=BUILD_EMBED_LABEL +)(.+)' bazel-out/stable-status.txt -AllMatches | Select-Object -Expand Matches | Select-Object -Expand Value) } > $@",
stamp = -1, # Only update if --stamp is passed
)
# Use the make_var_substitution rule to define some other custom substitutions
make_var_substitution(
name = "make_var_substitution",
variables = {
"NAME": "substitutions",
},
)
doxygen(
name = "doxygen",
srcs = glob([
"*.h",
"*.cpp",
]),
project_brief = "$(DESCRIPTION)", # => "no stamp" or "//substitutions:build_description" if the build is stamped
project_name = "$(NAME)", # => "substitutions"
doxyfile_template = ":doxyfile_template",
toolchains = [":make_var_substitution"],
)
```