feat: doxygen compilation from source (wip)
diff --git a/doxygen/doxygen.bzl b/doxygen/doxygen.bzl
index 02e0828..e635c31 100644
--- a/doxygen/doxygen.bzl
+++ b/doxygen/doxygen.bzl
@@ -2,7 +2,7 @@
def _expand_make_variables(string, ctx):
"""Replace make variables in a string with their values.
-
+
Args:
string: The string to expand.
ctx: The context object.
@@ -44,7 +44,7 @@
outputs = outs,
arguments = [doxyfile.path] + ctx.attr.doxygen_extra_args,
progress_message = "Running doxygen",
- executable = ctx.executable._executable,
+ executable = ctx.executable.executable,
)
return [
@@ -104,7 +104,7 @@
doc = "The dot executable to use. Must refer to an executable file.",
),
"doxygen_extra_args": attr.string_list(default = [], doc = "Extra arguments to pass to the doxygen executable."),
- "_executable": attr.label(
+ "executable": attr.label(
executable = True,
cfg = "exec",
allow_single_file = True,
@@ -1113,7 +1113,7 @@
_add_generic_configuration(configurations, "MSCFILE_DIRS", mscfile_dirs)
if doxyfile_template:
- kwargs["doxyfile_template"] = doxyfile_template
+ kwargs["doxyfile_template"] = doxyfile_template
_doxygen(
name = name,
diff --git a/examples/MODULE.bazel b/examples/MODULE.bazel
index f74aa16..b532738 100644
--- a/examples/MODULE.bazel
+++ b/examples/MODULE.bazel
@@ -9,6 +9,43 @@
bazel_dep(name = "aspect_bazel_lib", version = "2.10.0")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "rules_foreign_cc", version = "0.14.0")
+bazel_dep(name = "libconfig", version = "1.7.3")
+bazel_dep(name = "rules_flex", version = "0.4")
+bazel_dep(name = "rules_bison", version = "0.4")
+
+github_archive = use_repo_rule("//:git_archive.bzl", "github_archive")
+
+github_archive(
+ name = "doxygen_source",
+ build_file = "//:doxygen_source.BUILD.bazel",
+ commit = "200cec9b87fa544f39deeb96966568985f40aea8",
+ repository = "doxygen/doxygen",
+ sha256 = "6aa71da24aa7b8fc8f9eba5a6651b1fb47c569c68d3e226b011d39a15087c2fb",
+)
+
+bison = use_extension(
+ "@rules_bison//bison/extensions:bison_repository_ext.bzl",
+ "bison_repository_ext",
+)
+bison.repository(
+ name = "bison",
+ version = "3.3.2",
+ extra_copts = ["-O3"],
+)
+use_repo(bison, "bison")
+register_toolchains("@bison//:toolchain")
+
+flex = use_extension(
+ "@rules_flex//flex/extensions:flex_repository_ext.bzl",
+ "flex_repository_ext",
+)
+flex.repository(
+ name = "flex",
+ version = "2.6.4",
+ extra_copts = ["-O3"],
+)
+use_repo(flex, "flex")
+register_toolchains("@flex//:toolchain")
doxygen_extension = use_extension("@rules_doxygen//:extensions.bzl", "doxygen_extension")
diff --git a/examples/doxygen_source.BUILD.bazel b/examples/doxygen_source.BUILD.bazel
new file mode 100644
index 0000000..5f7ca4e
--- /dev/null
+++ b/examples/doxygen_source.BUILD.bazel
@@ -0,0 +1,35 @@
+load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")
+
+filegroup(
+ name = "all_srcs",
+ srcs = glob(["**"]),
+ visibility = ["//visibility:public"],
+)
+
+cmake(
+ name = "doxygen",
+ lib_source = ":all_srcs",
+ out_binaries = ["doxygen"],
+ visibility = ["//visibility:public"],
+ env = {
+ "FLEX": "$$EXT_BUILD_DEPS/flex/bin/flex/bin",
+ },
+ build_data = [
+ "@rules_flex//flex:current_flex_toolchain",
+ "@rules_bison//bison:current_bison_toolchain",
+ ],
+)
+
+genrule(
+ name = "doxygen_binary",
+ srcs = [":doxygen"],
+ outs = ["doxygen_bin"],
+ cmd = "cp $$1 $@",
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "doxygen_source",
+ srcs = [":doxygen_binary"],
+ visibility = ["//visibility:public"],
+)
diff --git a/examples/git_archive.bzl b/examples/git_archive.bzl
new file mode 100644
index 0000000..745a5ac
--- /dev/null
+++ b/examples/git_archive.bzl
@@ -0,0 +1,93 @@
+"""Repository rules for downloading archives from GitHub and GitLab"""
+
+def workspace_and_buildfile(ctx):
+ """Utility function for writing WORKSPACE and, if requested, a BUILD file.
+
+ This rule is intended to be used in the implementation function of a
+ repository rule.
+ It assumes the parameters `name`, `build_file`, `build_file_content`,
+ `workspace_file`, and `workspace_file_content` to be
+ present in `ctx.attr`; the latter four possibly with value None.
+
+ Args:
+ ctx: The repository context of the repository rule calling this utility
+ function.
+ """
+ if ctx.attr.build_file and ctx.attr.build_file_content:
+ ctx.fail("Only one of build_file and build_file_content can be provided.")
+
+ if ctx.attr.workspace_file and ctx.attr.workspace_file_content:
+ ctx.fail("Only one of workspace_file and workspace_file_content can be provided.")
+
+ if ctx.attr.workspace_file:
+ ctx.file("WORKSPACE", ctx.read(ctx.attr.workspace_file))
+ elif ctx.attr.workspace_file_content:
+ ctx.file("WORKSPACE", ctx.attr.workspace_file_content)
+ else:
+ ctx.file("WORKSPACE", "workspace(name = \"{name}\")\n".format(name = ctx.name))
+
+ if ctx.attr.build_file:
+ ctx.file("BUILD.bazel", ctx.read(ctx.attr.build_file))
+ elif ctx.attr.build_file_content:
+ ctx.file("BUILD.bazel", ctx.attr.build_file_content)
+
+def _github_archive_impl(repository_ctx):
+ """A rule to be called in the WORKSPACE that adds an external from github using a workspace rule.
+
+ The required name= is the rule name and so is used for @name//... labels when referring to this archive from BUILD files.
+
+ The required commit= is the git hash to download.
+ When the git project is also a git submodule in CMake, this should be kept in sync with the git submodule commit used there.
+ This can also be a tag.
+
+ The required sha256= is the checksum of the downloaded archive.
+ When unsure, you can omit this argument (or comment it out) and then the checksum-mismatch error message message will offer a suggestion.
+
+ The optional build_file= is the BUILD file label to use for building this external.
+ When omitted, the BUILD file(s) within the archive will be used.
+
+ The optional local_repository_override= can be used for temporary local testing;
+ instead of retrieving the code from github, the code is retrieved from the local filesystem path given in the argument.
+
+ Args:
+ repository_ctx: The context object for the repository rule.
+ """
+ if repository_ctx.attr.build_file and repository_ctx.attr.build_file_content:
+ fail("Only one of build_file and build_file_content can be provided.")
+ if repository_ctx.attr.workspace_file and repository_ctx.attr.workspace_file_content:
+ fail("Only one of workspace_file and workspace_file_content can be provided.")
+
+ repository = repository_ctx.attr.repository
+ commit = repository_ctx.attr.commit
+
+ urls = ["https://github.com/%s/archive/%s.tar.gz" % (repository, commit)]
+
+ repository_split = repository.split("/")
+ if len(repository_split) != 2:
+ fail("The repository must be formatted as 'organization/project'. Got: %s" % repository)
+ _, project = repository_split
+
+ # Github archives omit the "v" in version tags, for some reason.
+ strip_commit = commit.removeprefix("v")
+ strip_prefix = project + "-" + strip_commit
+
+ repository_ctx.download_and_extract(
+ urls,
+ sha256 = repository_ctx.attr.sha256,
+ stripPrefix = strip_prefix,
+ )
+ workspace_and_buildfile(repository_ctx)
+
+github_archive = repository_rule(
+ implementation = _github_archive_impl,
+ local = True,
+ attrs = {
+ "repository": attr.string(mandatory = True, doc = "The github repository to download from."),
+ "commit": attr.string(mandatory = True, doc = "The git commit hash to download."),
+ "sha256": attr.string(default = "0" * 64, doc = "The sha256 checksum of the downloaded archive."),
+ "build_file": attr.label(doc = "The BUILD file label to use for building this external."),
+ "build_file_content": attr.string(doc = "The content for the BUILD file for this repository."),
+ "workspace_file": attr.label(doc = "The file to use as the `WORKSPACE` file for this repository."),
+ "workspace_file_content": attr.string(doc = "The content for the WORKSPACE file for this repository."),
+ },
+)
diff --git a/examples/source/BUILD.bazel b/examples/source/BUILD.bazel
new file mode 100644
index 0000000..4f51bf7
--- /dev/null
+++ b/examples/source/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@doxygen//:doxygen.bzl", "doxygen")
+
+doxygen(
+ name = "doxygen",
+ srcs = glob([
+ "*.h",
+ "*.cpp",
+ ]),
+ executable = "@doxygen_source//:doxygen_source",
+ project_brief = "Example project for doxygen",
+ project_name = "base",
+)
diff --git a/examples/source/README.md b/examples/source/README.md
new file mode 100644
index 0000000..c7f1c01
--- /dev/null
+++ b/examples/source/README.md
@@ -0,0 +1,8 @@
+# Basic usage example
+
+This is a basic example of how to use the rules.
+Move to the parent directory and run the following command:
+
+```bash
+bazel build //base:doxygen
+```
diff --git a/examples/source/lib.cpp b/examples/source/lib.cpp
new file mode 100644
index 0000000..e9c08bc
--- /dev/null
+++ b/examples/source/lib.cpp
@@ -0,0 +1,9 @@
+/**
+ * @file lib.cpp
+ * @author Ernesto Casablanca (casablancaernesto@gmail.com)
+ * @copyright 2024
+ */
+
+#include "lib.h"
+
+int add(int a, int b) { return a + b; }
\ No newline at end of file
diff --git a/examples/source/lib.h b/examples/source/lib.h
new file mode 100644
index 0000000..9608ca2
--- /dev/null
+++ b/examples/source/lib.h
@@ -0,0 +1,18 @@
+/**
+ * @file lib.h
+ * @author Ernesto Casablanca (casablancaernesto@gmail.com)
+ * @copyright 2024
+ */
+#pragma once
+
+/**
+ * @brief Add two integers
+ *
+ * Who knows what the result will be?
+ * @note This function is very complex. Use it with caution.
+ * @warning The result can be greater than the maximum value that can be stored!
+ * @param a First integer
+ * @param b Second integer
+ * @return Sum of a and b
+ */
+int add(int a, int b);
\ No newline at end of file