Skip to content

Commit

Permalink
Add README
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinh Tran committed Feb 6, 2024
1 parent 4bcd6b5 commit 3fa174d
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 4 deletions.
File renamed without changes.
67 changes: 67 additions & 0 deletions cc-toolchain/01-minimal-gcc-toolchain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
This is an example of how to set up a hermetic single-platform gcc toolchain using the `cc_toolchain_config` rule provided from [`@bazel_tools//tools/cpp:unix_cc_toolchain_config.bzl`](https://github.com/bazelbuild/bazel/blob/master/tools/cpp/unix_cc_toolchain_config.bzl).

The example contains several pieces:

1. Download `glibc` from [toolchains.bootlin.com](toolchains.bootlin.com) which includes gcc and C standard library (aka `libc`)

2. Write the BUILD file for the glibc repository. The BUILD file

a. A `cc_toolchain_config` target to specify compiler flags, linker flags, a map of gcc tools, and the sysroot. To ensures `gcc` uses the downloaded headers instead of system headers, compiler flags include `-fno-canonical-system-headers`.

b. A `cc_toolchain` target to specify all the inputs that cc actions need in addition to the toolchain config.

c. A `toolchain` target to specify the exec and target configuration, and the corresponding cc toolchain.

## Testing
To test the toolchain, run

```
$ bazel build //main:hello-world
INFO: Analyzed target //main:hello-world (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
$ bazel-bin/main/hello-world
Hello, World!
```

## Debugging

To confirm the build is hermetic, add `-v` to compiler flags and linker flags to ensure the header and library search paths and tools are in the toolchain (i.e. begining with `external/gcc_toolchain`) instead of system.

## Limitation

In Bazel sandbox, the linker fails finding `libc.so.6` since `($SYSROOT)/usr/lib/libc.so` refers to `libc.so.6` as

```
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )
```

This is because linker fails to find resolve `($SYSROOT)/lib64/libc.so.6` correctly in the sandbox. See https://stackoverflow.com/questions/52386530/linker-fails-in-sandbox-when-running-through-bazel-but-works-when-sandboxed-comm for more context. We can confirm this is an issue in sandbox in two ways

1. Running the build with `--spawn_strategy=standalone`
2. Running the link command directly outside of Bazel

There are several ways to fix this:

1. If you have control over `libc.so`, change it to
```
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc_nonshared.a AS_NEEDED ( /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 ) )
```

where the paths exist relative to the sysroot root.

2. Setting symbolic links
```
$ ln -s /lib/x86_64-linux-gnu/libc_nonshared.a /lib/x86_64-linux-gnu/libc_nonshared.a
$ ln -s /lib/x86_64-linux-gnu/libc.so.6 /lib64/libc.so.6
```
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

def instal_basic_gcc_toolchain():
def instal_minimal_gcc_toolchain():
http_archive(
name = "gcc_toolchain",
urls = ["https://toolchains.bootlin.com/downloads/releases/toolchains/x86-64/tarballs/x86-64--glibc--stable-2023.11-1.tar.bz2"],
strip_prefix = "x86-64--glibc--stable-2023.11-1",
sha256 = "e3c0ef1618df3a3100a8a167066e7b19fdd25ee2c4285cf2cfe3ef34f0456867",
build_file = "//basic/gcc/toolchain:cc_toolchain.BUILD",
build_file = "//01-minimal-gcc-toolchain:cc_toolchain.BUILD",
)

native.register_toolchains(
Expand Down
12 changes: 12 additions & 0 deletions cc-toolchain/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
This folder contains examples of setting up cc toolchain in Bazel. The examples are broken down into several repositories to show different layers of complexity and flexibity that Bazel provides to take control of your cc builds.


* 01-minimal-gcc-toolchain: A gcc toolchain for single-platform build

Work-in-progress:
* 00-minimal-gcc-toolchain: A gcc toolchain for single-platform build using system tools
* 02-minimal-clang-toolchain: A clang toolchain for single-compilation build
* 03-crosstool-clang-toolchain: A clang toolchain for cross-compilation build. The example has implementation of a `CcToolchainConfigInfo` provider to use advanced concepts such as `feature` and `action_config` to have more control over

> All of the examples assume your host os is `linux` and host cpu is `x86_64`. If you have different host configuration, please tweak the setup to match with yours.

4 changes: 2 additions & 2 deletions cc-toolchain/WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
load("//basic/gcc/toolchain:defs.bzl", "instal_basic_gcc_toolchain")
load("//01-minimal-gcc-toolchain:defs.bzl", "instal_minimal_gcc_toolchain")

instal_basic_gcc_toolchain()
instal_minimal_gcc_toolchain()

0 comments on commit 3fa174d

Please sign in to comment.