Skip to content

Commit

Permalink
merge: #3498
Browse files Browse the repository at this point in the history
3498: feat(ci): enable release and debug builds r=adamhjk a=adamhjk

This PR enables release and debug builds for buck2. By default, we will always do debug builds (or, more accurately, whatever the rustc compiler thinks the defaults should be).

If you want to build for release or debug explicitly, you can do that with:

```
$ buck2 build `@//mode/release` //bin/sdf:sdf
```

And the result will be compiled with release optimizations. You can also use ``@//mode/debug`` if you want. Those files are just ways of DRY-ing up the configuration options - you could also pass them directly on the command line.

We can add as many configuration options as we want, and as many toolchain configurations as we want, by extending the options in the `//config` tree, adding a new toolchain statement, and extending the select statement for the `:rust` alias.

<img src="https://media1.giphy.com/media/MFg6kb46z2tNOEIBox/giphy.gif"/>

Co-authored-by: Adam Jacob <[email protected]>
  • Loading branch information
si-bors-ng[bot] and adamhjk authored Apr 3, 2024
2 parents cbdf26f + 22e0fc5 commit 7886e40
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .buckconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ fbsource = none

[parser]
target_platform_detector_spec = \
target:root//...->prelude//platforms:default \
target:prelude-si//...->prelude//platforms:default
target:root//...->prelude-si//platforms:default \
target:prelude-si//...->prelude-si//platforms:default \
target:toolchains//...->prelude-si//platforms:default \

[project]
ignore = \
Expand Down
3 changes: 3 additions & 0 deletions config/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
constraint_setting(name = "rust_build_mode", visibility = ["PUBLIC"])
constraint_value(name = "build_debug", constraint_setting = ":rust_build_mode", visibility = ["PUBLIC"])
constraint_value(name = "build_release", constraint_setting = ":rust_build_mode", visibility = ["PUBLIC"])
1 change: 1 addition & 0 deletions mode/debug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--config=rustc.mode=build_debug
1 change: 1 addition & 0 deletions mode/release
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--config=rustc.mode=build_release
3 changes: 3 additions & 0 deletions prelude-si/build_context/build_context_srcs_from_deps.bxl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def _build_context_srcs_from_deps_impl(ctx):
# Add candidate path entries for the Buck2 prelude directories (we want *all* these files)
raw_paths.append("prelude")
raw_paths.append("prelude-si")
raw_paths.append("config")
raw_paths.append("mode")
raw_paths.append("toolchains")

# While not officially in a prelude, there are macros that Reindeer used to create the Rust
# third-party targets, so we will include this directory as well.
Expand Down
88 changes: 88 additions & 0 deletions prelude-si/platforms/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# The custom platform for SI. This is taken from the prelude, but includes our customizations for
# rust build flags.
#
# Essentially, we should be adding any custom configuration into root//config, and then plumbing it
# through the execution_platform defined below.
#
# To actually add new configuration, you'll extend the relevant python function to output the
# correct configuration info, and then you can use it in a select() statement at will.

load(":defs.bzl", "execution_platform", "host_configuration")

prelude = native

_rust_build_mode = read_root_config("rustc", "mode", "build_debug")
_rust_build_mode_constraint = "root//config:" + _rust_build_mode

execution_platform(
name = "default",
cpu_configuration = host_configuration.cpu,
os_configuration = host_configuration.os,
rust_build_mode = _rust_build_mode_constraint,
use_windows_path_separators = host_info().os.is_windows,
)

prelude.constraint_setting(
name = "runs_remote",
)

prelude.constraint_value(
name = "may_run_remote",
constraint_setting = ":runs_remote",
visibility = ["PUBLIC"],
)

prelude.constraint_setting(
name = "runs_local",
visibility = ["PUBLIC"],
)

prelude.constraint_value(
name = "may_run_local",
constraint_setting = ":runs_local",
visibility = ["PUBLIC"],
)

prelude.constraint_setting(
name = "runs_only",
)

prelude.constraint_value(
name = "runs_only_local",
constraint_setting = ":runs_only",
visibility = ["PUBLIC"],
)

prelude.constraint_value(
name = "runs_only_remote",
constraint_setting = ":runs_only",
visibility = ["PUBLIC"],
)

prelude.constraint_setting(
name = "fat_platform_marker",
)

prelude.constraint_value(
name = "fat_platform_enabled",
constraint_setting = ":fat_platform_marker",
visibility = ["PUBLIC"],
)

# This is mostly here for a rule type to add a dependency on it to mark all
# instances of that rule type as incompatible with a fat platform. Ideally,
# toolchains could affect the target compatibility of their users directly but
# toolchains are currently all exec deps and so cannot do that. We'd like
# buck2 to support a form of dep that inherited its users execution platform
# so that toolchains could basically get visibility and affect both target and
# execution configuration, but that's not implemented yet.
export_file(
name = "fat_platform_incompatible",
# @oss-disable: src = "TARGETS.v2",
src = "BUCK", # @oss-enable
target_compatible_with = select({
":fat_platform_enabled": ["config//:none"],
"DEFAULT": [],
}),
visibility = ["PUBLIC"],
)
66 changes: 66 additions & 0 deletions prelude-si/platforms/defs.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.

def _execution_platform_impl(ctx: AnalysisContext) -> list[Provider]:
constraints = dict()
constraints.update(ctx.attrs.cpu_configuration[ConfigurationInfo].constraints)
constraints.update(ctx.attrs.os_configuration[ConfigurationInfo].constraints)
constraints.update(ctx.attrs.rust_build_mode[ConfigurationInfo].constraints)
cfg = ConfigurationInfo(constraints = constraints, values = {})

name = ctx.label.raw_target()
platform = ExecutionPlatformInfo(
label = name,
configuration = cfg,
executor_config = CommandExecutorConfig(
local_enabled = True,
remote_enabled = False,
use_windows_path_separators = ctx.attrs.use_windows_path_separators,
),
)

return [
DefaultInfo(),
platform,
PlatformInfo(label = str(name), configuration = cfg),
ExecutionPlatformRegistrationInfo(platforms = [platform]),
]

execution_platform = rule(
impl = _execution_platform_impl,
attrs = {
"cpu_configuration": attrs.dep(providers = [ConfigurationInfo]),
"os_configuration": attrs.dep(providers = [ConfigurationInfo]),
"rust_build_mode": attrs.dep(providers = [ConfigurationInfo]),
"use_windows_path_separators": attrs.bool(),
},
)

def _host_cpu_configuration() -> str:
arch = host_info().arch
if arch.is_aarch64:
return "prelude//cpu:arm64"
elif arch.is_arm:
return "prelude//cpu:arm32"
elif arch.is_i386:
return "prelude//cpu:x86_32"
else:
return "prelude//cpu:x86_64"

def _host_os_configuration() -> str:
os = host_info().os
if os.is_macos:
return "prelude//os:macos"
elif os.is_windows:
return "prelude//os:windows"
else:
return "prelude//os:linux"

host_configuration = struct(
cpu = _host_cpu_configuration(),
os = _host_os_configuration(),
)
27 changes: 26 additions & 1 deletion toolchains/BUCK
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
load(":toolchain.bzl", "toolchain_alias")
load("@prelude//toolchains:cxx.bzl", "system_cxx_toolchain")
load("@prelude//toolchains:genrule.bzl", "system_genrule_toolchain")
load(
Expand Down Expand Up @@ -45,9 +46,33 @@ system_python_bootstrap_toolchain(
)

system_rust_toolchain(
name = "rust",
name = "rust_release",
default_edition = "2021",
clippy_toml = "root//:clippy.toml",
visibility = ["PUBLIC"],
rustc_flags = [
"-Copt-level=3",
"-Cdebuginfo=none",
"-Cdebug-assertions=false",
"-Coverflow-checks=false",
"-Clto=false",
"-Ccodegen-units=16"
]
)

system_rust_toolchain(
name = "rust_debug",
default_edition = "2021",
clippy_toml = "root//:clippy.toml",
visibility = ["PUBLIC"]
)

toolchain_alias(
name = "rust",
actual = select({
"root//config:build_debug": ":rust_debug",
"root//config:build_release": ":rust_release",
}),
visibility = ["PUBLIC"],
)

Expand Down
17 changes: 17 additions & 0 deletions toolchains/toolchain.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
def _toolchain_alias_impl(ctx: AnalysisContext) -> list[Provider]:
return ctx.attrs.actual.providers

toolchain_alias = rule(
doc="""
toolchain_alias acts like alias but for toolchain rules.
The toolchain_alias itself is a toolchain rule and the `actual` argument is
expected to be a toolchain_rule as well.
""",
attrs={
"actual": attrs.toolchain_dep(
doc="The actual toolchain that is being aliased. This should be a toolchain rule."
)
},
impl=_toolchain_alias_impl,
is_toolchain_rule=True,
)

0 comments on commit 7886e40

Please sign in to comment.