Skip to content

feat: new toolchain bzlmod extension #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module(
)

bazel_dep(name = "rules_cc", version = "0.0.9")
bazel_dep(name = "bazel_skylib", version = "1.4.2")
bazel_dep(name = "platforms", version = "0.0.7")
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "platforms", version = "0.0.9")
bazel_dep(name = "ecsact_cli", version = "0.3.1")

bazel_dep(name = "aspect_bazel_lib", version = "1.32.1", dev_dependency = True)
3,673 changes: 3,217 additions & 456 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions e2e/bzlmod-ecsact-sdk/.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ common --registry=https://raw.githubusercontent.com/ecsact-dev/bazel_registry/ma
common --registry=https://raw.githubusercontent.com/bazelboost/registry/main
common --registry=https://bcr.bazel.build

build [email protected]//:use_std_fs
query [email protected]//:use_std_fs
build [email protected]//:use_std_fs
query [email protected]//:use_std_fs

try-import %workspace%/../../.bazelrc.user
20 changes: 1 addition & 19 deletions e2e/bzlmod-ecsact-sdk/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
load("@bazel_skylib//rules:build_test.bzl", "build_test")
load("@rules_ecsact//ecsact:defs.bzl", "ecsact_codegen")

ecsact_codegen(
name = "all_default_codegen_plugins",
output_directory = "codegen_outputs",
srcs = [
"example.ecsact",
"extras.ecsact",
],
plugins = [
"@ecsact_sdk//codegen_plugins:cpp_header",
# TODO(zaucy): Make other builtin plugins available
# "@ecsact_sdk//codegen_plugins:cpp_meta_header",
# "@ecsact_sdk//codegen_plugins:cpp_systems_header",
# "@ecsact_sdk//codegen_plugins:csharp",
# "@ecsact_sdk//codegen_plugins:systems_header",
],
)

build_test(
name = "build_test",
targets = [
":all_default_codegen_plugins",
"@ecsact_cli",
],
)
22 changes: 17 additions & 5 deletions e2e/bzlmod-ecsact-sdk/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
module(name = "rules_ecsact_e2e_bzlmod_ecsact_sdk")

bazel_dep(name = "bazel_skylib", version = "1.4.2")
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "rules_ecsact")
bazel_dep(name = "boost.process", version = "1.83.0.bzl.2")
bazel_dep(name = "boost.dll", version = "1.83.0.bzl.2")
bazel_dep(name = "ecsact_cli", version = "0.3.1")
bazel_dep(name = "toolchains_llvm", version = "1.0.0", dev_dependency = True)

local_path_override(
module_name = "rules_ecsact",
path = "../..",
)

ecsact = use_extension("@rules_ecsact//ecsact:extensions.bzl", "ecsact")
ecsact.sdk_toolchain(version = "0.6.2")
use_repo(ecsact, "ecsact_toolchains", "ecsact_sdk")
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True)
llvm.toolchain(llvm_version = "17.0.6")
use_repo(llvm, "llvm_toolchain")

register_toolchains("@ecsact_toolchains//:all")
ecsact = use_extension("@rules_ecsact//ecsact:extensions.bzl", "ecsact", dev_dependency = True)
ecsact.toolchain(use_ecsact_cli = True)
use_repo(ecsact, "ecsact_toolchain")

register_toolchains(
"@llvm_toolchain//:all",
"@ecsact_toolchain//:all",
dev_dependency = True,
)
134 changes: 65 additions & 69 deletions ecsact/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,98 +5,72 @@ package(default_visibility = ["//visibility:public"])
exports_files(glob["**/*"])
"""

_ECSACT_TOOLCHAINS_BUILD_FILE_CONTENTS = """
load("@rules_ecsact//ecsact:toolchain.bzl", "ecsact_toolchain")

package(default_visibility = ["//visibility:public"])

ecsact_toolchain(
name = "ecsact_sdk_system",
target_tool_path = "{ecsact_exe_path}",
)

toolchain(
name = "ecsact_sdk_system_toolchain",
toolchain = ":ecsact_sdk_system",
toolchain_type = "@rules_ecsact//ecsact:toolchain_type",
)
_ECSACT_TOOLCHAIN_SDK = """
# Ecsact toolchain from your locally installed SDK
# https://github.com/ecsact-dev/ecsact_sdk
ecsact_toolchain(name = "ecsact_sdk_system", target_tool_path = "{ecsact_exe_path}")
toolchain(name = "ecsact_sdk_system_toolchain", toolchain = ":ecsact_sdk_system", toolchain_type = "@rules_ecsact//ecsact:toolchain_type")
"""

_ECSACT_SDK_BUILD_FILE_CONTENTS = """
load("@rules_ecsact//ecsact:defs.bzl", "ecsact_codegen_plugin")

package(default_visibility = ["//visibility:public"])

ecsact_codegen_plugin(
name = "cpp_header",
output_extension = "hh",
plugin_path = "cpp_header",
)
_ECSACT_TOOLCHAIN_CLI = """
# Ecsact toolchain from the ecsact_cli bazel module
# https://github.com/ecsact-dev/ecsact_cli
ecsact_toolchain(name = "ecsact_cli", target_tool = "@ecsact_cli")
toolchain(name = "ecsact_cli_toolchain", toolchain = ":ecsact_cli", toolchain_type = "@rules_ecsact//ecsact:toolchain_type")
"""

def _ecsact_sdk_repository_impl(rctx):
rctx.file(
"BUILD.bazel",
executable = False,
content = "",
)
def _ecsact_toolchain_repository_impl(rctx):
# type: (repository_ctx) -> None

rctx.file(
"codegen_plugins/BUILD.bazel",
executable = False,
content = _ECSACT_SDK_BUILD_FILE_CONTENTS,
)
build_file_contents = 'load("@rules_ecsact//ecsact:toolchain.bzl", "ecsact_toolchain")\n'
build_file_contents += 'package(default_visibility = ["//visibility:public"])\n\n'

_ecsact_sdk_repository = repository_rule(
implementation = _ecsact_sdk_repository_impl,
attrs = {
},
)
if rctx.attr.ecsact_system_sdk_exe:
build_file_contents += _ECSACT_TOOLCHAIN_SDK.format(
ecsact_exe_path = rctx.attr.ecsact_system_sdk_exe.replace("\\", "/"),
)

if rctx.attr.use_ecsact_cli:
build_file_contents += _ECSACT_TOOLCHAIN_CLI

def _ecsact_toolchains_repository_impl(rctx):
rctx.file(
"BUILD.bazel",
executable = False,
content = _ECSACT_TOOLCHAINS_BUILD_FILE_CONTENTS.format(
ecsact_exe_path = rctx.attr.ecsact_exe.replace("\\", "/"),
),
content = build_file_contents,
)

_ecsact_toolchains_repository = repository_rule(
implementation = _ecsact_toolchains_repository_impl,
_ecsact_toolchain_repository = repository_rule(
implementation = _ecsact_toolchain_repository_impl,
attrs = {
"ecsact_exe": attr.string(mandatory = True),
"ecsact_system_sdk_exe": attr.string(mandatory = False),
"use_ecsact_cli": attr.bool(mandatory = True),
},
)

def _windows_find_ecsact_from_app_installer(ctx):
def _windows_find_ecsact_from_app_installer(mctx):
# type: (module_ctx) -> path

# ctx.which doesn't work for everything available on Windows. Using cmd's
# built-in 'where' command can find programs installed from the Microsoft
# store or MSIX packages.
cmd = ctx.which("cmd.exe")
cmd = mctx.which("cmd.exe")
if cmd:
where_result = ctx.execute([cmd, "/C", "where ecsact.exe"])
where_result = mctx.execute([cmd, "/C", "where ecsact.exe"])
if where_result.stdout:
return ctx.path(where_result.stdout.strip())
return mctx.path(where_result.stdout.strip())

return None

def _ecsact_impl(mctx):
wanted_ecsact_version = None

for mod in mctx.modules:
for sdk_toolchain in mod.tags.sdk_toolchain:
if wanted_ecsact_version != None:
fail("ecsact extension sdk_toolchain called multiple times. Please only call it once.")
wanted_ecsact_version = sdk_toolchain.version
def _get_escact_system_sdk(mctx, wanted_ecsact_version = None):
# type: (module_ctx, string) -> string

ecsact_exe = mctx.which("ecsact")

if ecsact_exe == None and mctx.os.name.startswith("windows"):
ecsact_exe = _windows_find_ecsact_from_app_installer(mctx)

if ecsact_exe == None:
fail("Cannot find the Ecsact SDK installed on your system. See https://ecsact.dev/start for instructions.")
return None

ecsact_version_output = mctx.execute([ecsact_exe, "--version"])
if ecsact_version_output.return_code != 0:
Expand All @@ -113,19 +87,41 @@ def _ecsact_impl(mctx):
if found_ecsact_version != wanted_ecsact_version and found_ecsact_version != "refs/tags/{}".format(wanted_ecsact_version):
fail("Wanted Ecsact SDK {}, but {} is installed on your system".format(wanted_ecsact_version, found_ecsact_version))

_ecsact_sdk_repository(
name = "ecsact_sdk",
)
_ecsact_toolchains_repository(
name = "ecsact_toolchains",
ecsact_exe = str(ecsact_exe),
return ecsact_exe

def _ecsact_impl(mctx):
# type: (module_ctx) -> None

wanted_ecsact_version = None
use_ecsact_cli = False

for mod in mctx.modules:
for toolchain in mod.tags.toolchain:
if toolchain.use_ecsact_cli:
use_ecsact_cli = True

if toolchain.version:
if wanted_ecsact_version != None:
fail("ecsact extension toolchain called multiple times. Please only call it once.")
wanted_ecsact_version = toolchain.version

ecsact_exe = _get_escact_system_sdk(mctx, wanted_ecsact_version)

if ecsact_exe != None:
ecsact_exe = str(ecsact_exe)

_ecsact_toolchain_repository(
name = "ecsact_toolchain",
ecsact_system_sdk_exe = ecsact_exe,
use_ecsact_cli = use_ecsact_cli,
)

ecsact = module_extension(
implementation = _ecsact_impl,
tag_classes = {
"sdk_toolchain": tag_class(attrs = {
"version": attr.string(mandatory = True),
"toolchain": tag_class(attrs = {
"use_ecsact_cli": attr.bool(mandatory = False, default = False),
"version": attr.string(mandatory = False),
}),
},
)
2 changes: 1 addition & 1 deletion ecsact/private/ecsact_binary.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain", "use_cc_toolchain")
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain", "use_cc_toolchain")
load("//ecsact/private:ecsact_build_recipe.bzl", "EcsactBuildRecipeInfo")

def _ecsact_binary_impl(ctx):
Expand Down
6 changes: 4 additions & 2 deletions ecsact/private/ecsact_build_recipe.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ EcsactBuildRecipeInfo = provider(
)

def _ecsact_build_recipe(ctx):
# type: (ctx) -> None

recipe_yaml = ctx.actions.declare_file("{}.yml".format(ctx.attr.name))

sources = []
Expand All @@ -17,15 +19,15 @@ def _ecsact_build_recipe(ctx):
for src in ctx.files.srcs:
sources.append({
"path": src.path,
"outdir": "src",
"outdir": src.dirname,
"relative_to_cwd": True,
})
recipe_data.append(src)

for codegen_plugin in ctx.attr.codegen_plugins:
info = codegen_plugin[EcsactCodegenPluginInfo]
sources.append({
"codegen": [info.plugin],
"codegen": info.plugin.path,
"outdir": ctx.attr.codegen_plugins[codegen_plugin],
})
recipe_data.append(info.plugin)
Expand Down