Skip to content
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

extra_targets, user configurable toolchains, and wasm support #85

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
050af4b
llvm_toolchain: first pass at using `cc_toolchain_config` from @bazel…
rrbutani Feb 9, 2021
b6a8da5
llvm_toolchain: formatting and cleanup
rrbutani Feb 9, 2021
f3b6256
llvm_toolchain: fix a typo
rrbutani Feb 9, 2021
58558de
tests: bump rules_go
rrbutani Feb 9, 2021
c9fdc9a
llvm_toolchain: unbreak linking on macOS
rrbutani Feb 10, 2021
595c2b9
llvm_toolchain: don't break when used with dev builds of bazel
rrbutani Feb 12, 2021
8ac151d
llvm_toolchain: fixes for `builtin_sysroot` and older Bazel versions
rrbutani Aug 15, 2021
8df8200
llvm_toolchain: fixes for using/running the toolchain from other loca…
rrbutani Aug 15, 2021
37c4562
llvm_toolchain: don't use an empty sysroot for `builtin_sysroot`
rrbutani Aug 17, 2021
22e0206
llvm_toolchain: first pass at processing target-triple architectures
rrbutani Aug 15, 2021
9044046
llvm_toolchain: add bits to process the os and env parts of target tr…
rrbutani Aug 15, 2021
362feef
misc: add a note about cc toolchain resolution to the readme
rrbutani Aug 15, 2021
69ae7ba
llvm_toolchain: more bits to process target triples
rrbutani Aug 15, 2021
87d913c
llvm_toolchain: add the plumbing to make and register additional tool…
rrbutani Aug 15, 2021
b920164
llvm_toolchain: have separate sysroots for each toolchain target
rrbutani Aug 16, 2021
1ffc061
llvm_toolchain: add machinery for overriding the host configuration i…
rrbutani Aug 16, 2021
d706f69
llvm_toolchain: add more knobs to `cc_toolchain_config`
rrbutani Aug 16, 2021
b16945e
llvm_toolchain: add support for explicitly specifying the repo in whi…
rrbutani Aug 16, 2021
35b95d5
misc: add docs about `extra_toolchains` and an example of the manual …
rrbutani Aug 16, 2021
e1c3682
llvm_toolchain: add `@platforms` as a dep
rrbutani Aug 16, 2021
15cdb95
llvm_toolchain: tweaks and fixes
rrbutani Aug 16, 2021
ab65846
llvm_toolchain: add support for setting/grabbing sysroots for `extra_…
rrbutani Aug 16, 2021
ae0d085
llvm_toolchain: add sysroots for wasm32/wasi
rrbutani Aug 16, 2021
b69988e
llvm_toolchain: add compiler_rt for wasm32/wasi
rrbutani Aug 16, 2021
a0f0eb4
misc: some WIP examples
rrbutani Aug 16, 2021
0904ea2
llvm_toolchain: make `process_sysroot` public (for custom toolchains)
rrbutani Sep 3, 2021
677453e
llvm_toolchain: change the toolchain names generated by `cc_toolchain…
rrbutani Sep 3, 2021
f353e0a
llvm_toolchain: add an option for extra linker flags to `cc_toolchain…
rrbutani Sep 3, 2021
b763a30
ci: switch the arch base image to `archlinux`
rrbutani Sep 4, 2021
53a0025
ci: use the GITHUB_TOKEN secret for $BAZELISK_GITHUB_TOKEN
rrbutani Sep 4, 2021
18b34d3
llvm_toolchain: actually have `host_sysroot_path` return the sysroot
rrbutani Sep 4, 2021
496a403
llvm_toolchain: deduplicate `extra_target` toolchain entries in `cc_t…
rrbutani Sep 12, 2021
8035a6a
misc: add a `.bazelrc`, just for local testing
rrbutani Sep 13, 2021
451bfa0
llvm_toolchain: add some notes about `extra_targets` ordering and `un…
rrbutani Sep 13, 2021
fd575fe
misc: cleanup
rrbutani Sep 13, 2021
61074f3
tests: add a simple binary target (for extra targets that aren't hosted)
rrbutani Sep 13, 2021
38649c3
llvm_toolchain: don't hardcode the linux toolchains in `cc_toolchain_…
rrbutani Sep 13, 2021
cd0ffbf
llvm_toolchain: use the wasi sysroot/compiler_rt for non-wasi wasm ta…
rrbutani Sep 13, 2021
d910fb8
tests: actually add `simple.cc`
rrbutani Sep 13, 2021
2984417
tests: add an `extra_targets` package
rrbutani Sep 13, 2021
7775fd4
tests: add some transitions for wasi/wasm targets
rrbutani Sep 13, 2021
1d0aa6e
tests: add wasi/wasm build tests
rrbutani Sep 13, 2021
a89ddef
misc: update the README
rrbutani Sep 13, 2021
e6511c5
tests: bump the llvm version
rrbutani Sep 13, 2021
e86b0c9
llvm_toolchain: add `wasm-ld` and friends to the linker filegroup
rrbutani Sep 13, 2021
cdfb672
wasm: pass in `-mthread-model=single` for wasm for LLVM 12
rrbutani Sep 13, 2021
6c2aa15
release_names: stopgap fix for ubuntu 18.04 releases
rrbutani Sep 13, 2021
eb2ef33
tests: bump the llvm version
rrbutani Sep 13, 2021
94a4975
release_names: some cleanup and a fix
rrbutani Sep 13, 2021
52170d6
llvm_toolchain: expose hooks for extra-targets to override the linker…
rrbutani Sep 13, 2021
7e4ed65
llvm_toolchain: expose hooks for extra-targets to override some linke…
rrbutani Sep 13, 2021
99ed2f7
wasm: update the overrides
rrbutani Sep 13, 2021
55211fe
llvm_toolchain: add a fix for the library search path and linux hosts
rrbutani Sep 13, 2021
6af237b
release_names: fix some other distros
rrbutani Sep 13, 2021
7342fa4
misc: fix a typo in the README
rrbutani Sep 15, 2021
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
3 changes: 3 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# For testing purposes only! Note that CI passes in `--bazelrc=/dev/null` and
# does *not* use this file.
build --incompatible_enable_cc_toolchain_resolution
2 changes: 1 addition & 1 deletion .github/workflows/migration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ jobs:
- uses: actions/checkout@v2
- name: test
env:
BAZELISK_GITHUB_TOKEN: ${{ secrets.BAZELISK_GITHUB_TOKEN }}
BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TEST_MIGRATION: true
run: tests/scripts/run_tests.sh
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v2
- name: test
env:
BAZELISK_GITHUB_TOKEN: ${{ secrets.BAZELISK_GITHUB_TOKEN }}
BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: tests/scripts/${{ matrix.script }}
container_test:
runs-on: ubuntu-latest
Expand All @@ -30,5 +30,5 @@ jobs:
- uses: actions/checkout@v2
- name: test
env:
BAZELISK_GITHUB_TOKEN: ${{ secrets.BAZELISK_GITHUB_TOKEN }}
BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: tests/scripts/${{ matrix.script }}_test.sh
202 changes: 202 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ For overriding toolchains on the command line, please use the
`--extra_toolchains` flag in lieu of the deprecated `--crosstool_top` flag.
For example, `--extra_toolchains=@llvm_toolchain//:cc-toolchain-linux`.

Note: you may need to add `build --incompatible_enable_cc_toolchain_resolution`
to your `.bazelrc` to enable toolchain resolution for `cc` toolchains (see
[this][enable-cc-toolchain-res] issue). If you do this, the
`llvm_register_toolchains` call in `WORKSPACE` shown in the example above should
be sufficient to get Bazel to use the toolchain.

[enable-cc-toolchain-res]: https://github.com/bazelbuild/bazel/issues/7260

If you would like to use the older method of selecting toolchains, you can
continue to do so with `--crosstool_top=@llvm_toolchain//:toolchain`.

Expand Down Expand Up @@ -78,6 +86,200 @@ Notes:
depend on these tools directly in the bin directory of the toolchain. For
example, `@llvm_toolchain//:bin/clang-format` is a valid and visible target.

## Setting Up Toolchains for Other Targets

### Using `extra_targets`

```starlark
load("@com_grail_bazel_toolchain//toolchain:rules.bzl", "llvm_toolchain")
llvm_toolchain(
name = "llvm_toolchain",
llvm_version = "8.0.0",
extra_targets = [
"wasm32-unknown-wasi",
],

# Extra targets can have their sysroots overriden too:
sysroot = {
"linux": "@some_example_sysroot_repo//:linux_sysroot",
"darwin": "@some_example_sysroot_repo//:macos_sysroot",

"linux_wasm32-unknown-wasi": "@some_example_sysroot_repo//:wasi_sysroot",
"darwin_wasm32-unknown-wasi": "@some_example_sysroot_repo//:wasi_sysroot",
},
)

load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains")
llvm_register_toolchains()

http_archive(
name = "some_example_sysroot_repo",
...
)
```

The toolchain that is created will have the appropriate constraints so that Bazel
will pick it when resolving a toolchain for a particular platform. For example:

```starlark
platform(
name = "wasi",
constraints = [
"@platforms//os:wasi",
"@platforms//cpu:wasm32",
]
)

cc_library(
name = "test",
srcs = [...],
)
```

Running `bazel build //:test --platforms //:wasm` should use the configured
`wasm32-unknown-wasi` toolchain and produce an object file with wasm32 assembly
in it.

Note that this should work also work with rules that apply a
[transition][transition] to require that a target be built for a particular
platform.

[transition]: https://docs.bazel.build/versions/main/skylark/config.html#user-defined-transitions

Also note that the order of the triples in `extra_targets` influences how toolchains will be considered during [toolchain resolution][t-res] as does using a target triple ending with `-unknown` instead of `-none` (as a rule of thumb, prefer `-none` over `-unknown` unless you have a good reason not to). See [this comment][extra-target-pitfalls-comment] for some context.

[t-res]: https://docs.bazel.build/versions/main/toolchains.html#toolchain-resolution
[extra-target-pitfalls-comment]: WORKSPACE#L31-L63

Currently only the following extra targets are implemented/tested at all:
- `wasm32-unknown-wasi`
- `wasm32-unknown-none`

Other targets *can* be specified but are unlikely to work as the glue needed to
fetch their sysroots/compiler-rt (i.e. `libclang_rt.builtins-...`) is not yet
implemented.

[`tests/extra_targets`](tests/extra_targets) contains some examples that use the extra toolchains configured in this repo's workspace.

### Manually

For other targets (or if you just want to make modifications to the toolchains that the machinery in this repo produces) you can set up a toolchain manually. The process for doing so looks something like this:

```starlark
# WORKSPACE
# (parts to set up `@llvm_toolchain` have been elided; see above)

llvm_toolchain(
name = "llvm_toolchain",
llvm_version = "8.0.0",

# NOTE: This is required to set up toolchains outside of `@llvm_toolchain`, unfortunately
absolute_paths = True,
)

# This registers the default toolchains.
load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains", "register_toolchain")

llvm_register_toolchains()

# Now let's make our own:
http_archive(
name = "thumbv7-sysroot",
urls = ["example.com"],
)
register_toolchain("//tests:custom_toolchain_example")

# BUILD file:
# Example Custom Toolchain:
load("@llvm_toolchain//:cc_toolchain_config.bzl", "cc_toolchain_config")

# Docs for this function and `overrides` are in `cc_toolchain_config.bzl.tpl`.
cc_toolchain_config(
name = "custom_toolchain_example_config",
host_platform = "linux",
custom_target_triple = "thumbv7em-unknown-none-gnueabihf",
overrides = {
"target_system_name": "thumbv7em-unknown-none-gnueabihf",
"target_cpu": "thumbv7em",
"target_libc": "unknown",
"abi_libc_version": "unknown",

# If you omit this, be sure to depend on
# `@llvm_toolchain:host_sysroot_components`.
# "sysroot_path": "external/thumbv7-sysroot/sysroot",

"extra_compile_flags": [
"-mthumb",
"-mcpu=cortex-m4",
"-mfpu=fpv4-sp-d16",
"-mfloat-abi=hard",
],
"omit_hosted_linker_flags": True,
"omit_cxx_stdlib_flag": False,
"use_llvm_ar_instead_of_libtool_on_macos": True,
}
)

load("@com_grail_bazel_toolchain//toolchain:rules.bzl", "conditional_cc_toolchain")
conditional_cc_toolchain(
name = "custom_toolchain",
toolchain_config = ":custom_toolchain_example_config",
host_is_darwin = False,

sysroot_label = "@llvm_toolchain//:host_sysroot_components", # use this if not overriding
# sysroot_label = "@thumbv7-sysroot//:sysroot", # override

absolute_paths = True, # this is required for toolchains set up outside of `@llvm_toolchain`, unfortunately
llvm_repo_label_prefix = "@llvm_toolchain//",
)

# Constraints come from here: https://github.com/bazelbuild/platforms
toolchain(
name = "custom_toolchain_example",
exec_compatible_with = [
"@platforms//cpu:x86_64",
"@platforms//os:linux",
],
target_compatible_with = [
"@platforms//cpu:armv7", # `v7e-mf` has not yet made it to stable Bazel?
# "@platforms//os:none",
],
toolchain = ":custom_toolchain",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
```

As with the `wasm32-unknown-wasi` example above, you can "use" the toolchain by
creating a platform matching the constraints which the toolchain satisfies and
then either specifying that platform globally (on the command line) or for a
particular target via a transition.

Here's an example of using `target_compatible_with` on a target to get it to
only build when an appropriate target platform is specified:

```starlark
platform(
name = "arm",
constraint_values = [
"@platforms//cpu:armv7",
# "@platforms//os:none",
]
)

cc_library(
name = "custom_target_test",
srcs = ["test.cc"],
target_compatible_with = [
"@platforms//cpu:armv7",
]
)
```

Ultimately the goal is to add support for extra targets directly in this repo;
PRs are very welcome :-).

## Misc

Other examples of toolchain configuration:

https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain
Expand Down
69 changes: 58 additions & 11 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,51 @@ load("@com_grail_bazel_toolchain//toolchain:rules.bzl", "llvm_toolchain")

llvm_toolchain(
name = "llvm_toolchain",
# LLVM 9.0.0 needs /usr/lib/libtinfo.so.5 that is not very straightforward
# to set up in all linux distros we test.
llvm_version = "8.0.0",
llvm_version = "12.0.0",
extra_targets = [
# NOTE: we do *not* use `wasm32-unknown-unknown` here; using `unknown`
# makes the generated toolchain have no OS constraint which will result
# in toolchain resolution matching the toolchain even for targets that
# do have an OS.
#
# For example `wasm-unknown-unknown` which has no OS constraint will
# match `wasm-unknown-wasi` which has an `os:wasi` constraint: even
# though we'd _rather_ use `wasm32-unknown-wasi` when targeting
# `wasm32-unknown-wasi`, it's not _wrong_ to use `wasm32-unknown-none`
# since it *will* produce code that can run on `wasm32-unknown-wasi`
# systems.
#
# In other words, the target platform has to satisfy the toolchain's
# constraints, not the other way around.
#
# What we'd really like is for individual *targets* that require stdlib
# and "platform" functionality to be able to say they need "os:wasi"
# and thus need to be built with `wasm32-unknown-wasi` but this isn't
# how toolchain resolution works; targets only filter the execution
# platforms.
#
# The real solution is to actually specify an OS constraint even for
# `unknown` target triple toolchains OR to always put `unknown` target
# triple toolchains behind their OS-constraint-having peers in this
# list so toolchain resolution will pick them as a _last_ resort.
#
# For now we don't map `unknown` to `os:none` in case there are
# situations where this behavior is desirable (i.e. you want to fall
# back to `thumbv7em-unknown-unknown` when you're asked to build for
# a triple like `thumbv7em-unknown-netbsd`).
#
# Note that there is no default constraint for `//platforms/os`:
# https://github.com/bazelbuild/platforms/blob/98939346da932eef0b54cf808622f5bb0928f00b/os/BUILD#L14
"wasm32-unknown-none",
"wasm32-unknown-wasi",
],
# absolute_paths = True,
)

load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains")
load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains", "register_toolchain")

llvm_register_toolchains()
register_toolchain("//tests:custom_toolchain_example")

## Toolchain example with a sysroot.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
Expand All @@ -58,8 +95,20 @@ llvm_toolchain(
},
)

# Well known repos; present here only for testing.
# `bazel_skylib`; we're using its `build_test` test
http_archive(
name = "bazel_skylib",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
],
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
)

load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()

# Well known repos; present here only for testing.
http_archive(
name = "com_google_googletest",
sha256 = "9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb",
Expand Down Expand Up @@ -89,19 +138,17 @@ http_archive(
urls = ["https://www.openssl.org/source/openssl-1.1.1c.tar.gz"],
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "io_bazel_rules_go",
sha256 = "e6a6c016b0663e06fa5fccf1cd8152eab8aa8180c583ec20c872f4f9953a7ac5",
sha256 = "7904dbecbaffd068651916dce77ff3437679f9d20e1a7956bff43826e7645fcc",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.22.1/rules_go-v0.22.1.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.22.1/rules_go-v0.22.1.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.25.1/rules_go-v0.25.1.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.25.1/rules_go-v0.25.1.tar.gz",
],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")

go_rules_dependencies()

go_register_toolchains()
go_register_toolchains(version = "1.15.7")
Loading