Skip to content

Commit

Permalink
simlify pkg test script; readme updates and add list of problems; pin…
Browse files Browse the repository at this point in the history
… bazel version; ensure that docker is used for MakeDeb and PackageTar actions

The MakeDeb and PackageTar actions were just being executed on the host with `--config docker`. Note that `remote` is the highest priority strategy enabled by default, so we've not had to override it as we do with the experimental docker sandbox.

CentOS6's Python 3.4 is too old and is not supported for pkg_tar (though is for pkg_rpm!) we could avoid this by enforing the MakrTar action to run not-remote, i.e.  "remote,worker,sandboxed,local" -> "worker,sandboxed,local" or possible by removing the exec_platforms.
  • Loading branch information
nickbreen committed Sep 17, 2023
1 parent e55ab7c commit 122e442
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 46 deletions.
13 changes: 8 additions & 5 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,26 @@ test:ci --test_output=all
build:docker --experimental_docker_verbose
build:docker --experimental_enable_docker_sandbox
build:docker --experimental_docker_use_customized_images
build:docker --strategy=CppCompile=docker --strategy=CppLink=docker --strategy=CcStrip=docker --strategy=MakeRpm=docker
build:docker --strategy=CppCompile=docker --strategy=CppLink=docker --strategy=CcStrip=docker --strategy=MakeRpm=docker --strategy=MakeDeb=docker --strategy=PackageTar=docker
build:docker --experimental_docker_privileged

build:remote --bes_results_url=http://localhost:8080/invocation/
build:remote --bes_backend=grpc://localhost:1985
build:remote --remote_cache=grpc://localhost:1985
build:remote --remote_timeout=120
build:remote --remote_executor=grpc://localhost:1985
build:remote --remote_header=x-buildbuddy-api-key=M3LUl7prhCCaqVCUAb18

build:bb --build_metadata=ROLE=CI
build:bb --bes_results_url=https://app.buildbuddy.io/invocation/
build:bb --bes_backend=grpcs://remote.buildbuddy.io
build:bb --remote_cache=grpcs://remote.buildbuddy.io
build:bb --remote_executor=grpcs://remote.buildbuddy.io
build:bb --remote_upload_local_results
#build:bb --host_platform=@buildbuddy_toolchain//:platform
#build:bb --platforms=@buildbuddy_toolchain//:platform
#build:bb --crosstool_top=@buildbuddy_toolchain//:toolchain
build:bb --jobs=100

build --toolchain_resolution_debug=@rules_python//python:toolchain_type

# Invalidate all outputs by setting a new value for the environment variable "FUDGE".
# e.g. export FUDGE="$(date)"
build --action_env=FUDGE
test --test_env=FUDGE
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.3.2
11 changes: 4 additions & 7 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,12 @@ pkg_tar(
srcs = [":pkg/hello"],
)

# Expand :tar to build for all platforms. the MakeTar action does *not* have its
# strategy set to docker, so while it will execute with the default strategies:
# remote,worker,sandboxed,local
# It will build for each platform and package the matching :hello binary.
# Expand :tar to build for all platforms on each platform.
platforms(
name = "tars",
actual = ":tar",
exec_platforms = [
"//platforms:centos/6",
#"//platforms:centos/6", # CentOS6's Python 3.4 is too old for pkg_tar.
"//platforms:centos/7",
"//platforms:debian/11",
"//platforms:debian/12",
Expand All @@ -122,7 +119,7 @@ platforms(
"//platforms:ubuntu/jammy",
],
target_platforms = [
"//platforms:centos/6",
#"//platforms:centos/6", # CentOS6's Python 3.4 is too old for pkg_tar.
"//platforms:centos/7",
"//platforms:debian/11",
"//platforms:debian/12",
Expand Down Expand Up @@ -157,7 +154,7 @@ sh_test(
platforms_test(
name = "platform-tar-test-suite",
platforms = [
"//platforms:centos/6",
# "//platforms:centos/6", # CentOS6's Python 3.4 is too old for pkg_tar.
"//platforms:centos/7",
"//platforms:debian/11",
"//platforms:debian/12",
Expand Down
109 changes: 78 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,111 @@
[![Bazel CI](https://github.com/nickbreen/bz-platforms2/actions/workflows/bazel.yml/badge.svg)](https://github.com/nickbreen/bz-platforms2/actions/workflows/bazel.yml)

Assuming you have `bazelisk` on your path as `bazel` and a recent `docker`:
Assumptions: you have `bazelisk` on your path as `bazel` and a recent `docker`.

Emulate remote builds with the experimental docker strategy:

( cd executors; docker buildx bake )
bazel build --config docker //:hellos //:tars //:rpms //:debs
bazel test --config docker //:platform-{hello,tar,deb,rpm}-test-suite

Start a local instance of BuildBuddy with remote execution enabled and your API
Key configured in `~/.bazelrc`
as `build:remote --remote_header=x-buildbuddy-api-key=[REDACTED]`:

docker compose up -d
bazel build --config remote //:hellos //:tars //:rpms //:debs
bazel test --config remote //:platform-{hello,tar,deb,rpm}-test-suite

Use BuildBuddy Cloud and your API Key configured in `~/.bazelrc`
as `build:bb --remote_header=x-buildbuddy-api-key=[REDACTED]`:

bazel test --config bb //:platform-{hello,tar,deb,rpm}-test-suite

Bazel will cache the outputs and results, so you'll need to invalidate them if
you want to run these builds/tests repeatedly.

`.bazelrc` configures an environment variable `FUDGE` that can be set to a new
value to invalidate all build outputs and test results. E.g.

export FUDGE="$(date)"

---

We want to target platforms with varied GLIBC versions.

OS Family PKG GLIBC Dependency
-------------- ------ --- ----- ----------------------------
centos:6 redhat RPM 2.12 glibc-2.12-1.212.el6.x86_64
centos:7 redhat RPM 2.17 glibc-2.17-317.el7.x86_64
debian:11 debian DEB 2.31 libc6=2.31-13+deb11u5
debian:12 debian DEB 2.36 libc6=2.36-9
fedora:37 redhat RPM 2.36 glibc-2.36-9.fc37.x86_64
fedora:38 redhat RPM 2.37 glibc-2.37-4.fc38.x86_64
rockylinux:8 redhat RPM 2.28 glibc-2.28-211.el8.x86_64
rockylinux:9 redhat RPM 2.34 glibc-2.34-60.el9.x86_64
ubuntu:focal debian DEB 2.31 libc6=2.31-0ubuntu9.9
ubuntu:jammy debian DEB 2.35 libc6=2.35-0ubuntu3.1
We want to target various platforms:

OS Family PKG GLIBC GCC
-------------- ------ ---- ----- -------
centos:6 redhat RPM 2.12 4.4.7
centos:7 redhat RPM 2.17 4.8.5
debian:11 debian DEB 2.31 10.2.1
debian:12 debian DEB 2.36 12.2.0
fedora:37 redhat RPM 2.36 12.3.1
fedora:38 redhat RPM 2.37 13.2.1
rockylinux:8 redhat RPM 2.28 8.5.0
rockylinux:9 redhat RPM 2.34 11.3.1
ubuntu:focal debian DEB 2.31 9.4.0
ubuntu:jammy debian DEB 2.35 11.4.0

We could use https://github.com/wheybags/glibc_version_header
to link to lowest-common denominator GLIBC symbols. But, glibc 2.34 has a
hard break where you cannot compile with 2.34 and have it work with older
glibc versions even if you use those version headers. It will always
link `__libc_start_main@GLIBC_2.34`.

So, to target various versions of GLIBC we need to be clever-er.
We could reduce the compilations down to GNU libc 2.12 and 2.34 as the two
lowest common version and then package; this assumes that GNU libc is the only
compilation dependency with some version issue. Consider GCC, or adding OpenSSL too...

So, we sort of have a sparse matrix of GLIBC versions:
So, we sort of have a sparse matrix of:

GLIBC versions:
- 2.12
- 2.17
- 2.28
- 2.31
- 2.34 *** hard break `__libc_start_main@GLIBC_2.34`!
- 2.34 *** backwards-incompatible change: `__libc_start_main@GLIBC_2.34`!
- 2.36
- 2.37
- 2.38

By OS/Family/Packaging:

- RPM
- DEB
GCC versions:
- 4.4.7
- 4.8.5
- 8.5.0
- 9.4.0
- 10.2.1
- 11.3.1
- 11.4.0
- 12.2.0
- 12.3.1
- 13.2.1

Packaging Type & OS Family:
- RPM & RedHat-likes
- DEB & Debian-likes
- TGZ

We could reduce the compilations down to GNU libc 2.12 and 2.34 as the two
lowest common version and then package; this assumes that GNU libc is the only
compilation dependency with some version issue. Consider adding OpenSSL too.
Or python, or what-have-you. So...
RPM version:
- 4.8.0
- 4.11.3
- 4.14.3
- 4.16.1.3
- 4.18.1

Python version:
- 3.4.10
- 3.6.8
- 3.6.8
- 3.8.10
- 3.9.16
- 3.9.2
- 3.10.12
- 3.11.2
- 3.11.4
- 3.11.5

So, to target various combinations of these tools' versions we need to be clever-er.

The idea will be to build `hello.c` for each of these platforms and
"automatically" build it in a matching container. The extra nice part of this
is that the host platform is now entirely irrelevant. It will generate the
same outputs on MacOS, Linux, whatever.
is that the host platform is now entirely irrelevant.

---

Expand All @@ -69,6 +114,8 @@ What next?
- We might also want one for the host system too, whatever that is.
- Musl libc and Alpine!

---

References:

- https://bazel.build/extending/config
Expand Down
4 changes: 3 additions & 1 deletion toolchains/cc/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
load("@rules_cc//cc:defs.bzl", "cc_toolchain")
load("@bazel_tools//tools/cpp:unix_cc_toolchain_config.bzl", "cc_toolchain_config")

# A non-hermetic CC toochain for each combination of OS, GLIBC, and GCC.

# The bazel documentation for configuration of C toolchains is voluminous but
# general. Most examples have "local" or "unknown" set for several attributes
# without explanation. The following cc_toolchain_config and cc_toolchain rules
Expand Down Expand Up @@ -62,7 +64,7 @@ link_libs = [
opt_link_flags = ["-Wl,--gc-sections"]

# None of these toolchains are hermetic as far as bazel is concerned, so we need
# and empty set of files to provide to the cc_toolchain rule.
# an empty set of files to provide to the cc_toolchain rule.
filegroup(name = "exec-platform-provided")

# While these are named for OS/version they are actually just
Expand Down
9 changes: 7 additions & 2 deletions toolchains/python/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# Python3 toolchain used by pkg_deb, compatible with everything.
load("@rules_python//python:defs.bzl", "py_runtime", "py_runtime_pair")

# A non-hermetic Python toolchain.

# Define a Python 3 toolchain used by pkg_*, compatible with everything. We
# could be more specific in here (a la //platforms/cc) but it's over the top
# for Python, assuming that all the various 3.x versions are compatible enough.

py_runtime(
name = "python3/runtime",
interpreter_path = "/usr/bin/python3",
python_version = "PY3",
stub_shebang = "#!/usr/bin/python3", # For gods' sake, stop using /usr/bin/env python3, you never know which (if any) one you'll get
stub_shebang = "#!/usr/bin/python3",
)

py_runtime_pair(
Expand Down
10 changes: 10 additions & 0 deletions toolchains/rpmbuild/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# RPM Build toolchain used by pkg_rpm, compatible only with redhat family.
load("@rules_pkg//toolchains/rpm:rpmbuild.bzl", "rpmbuild_toolchain")

# A non-hermetic RPM build toolchain.

# We could use the version attribute of rpmbuild_toolchain to be specific about
# which versions of RPM are available on each host, but the versions are not
# sufficiently different o bother.

rpmbuild_toolchain(
name = "default",
path = "/usr/bin/rpmbuild",
Expand All @@ -18,4 +24,8 @@ toolchain(
toolchain_type = "@rules_pkg//toolchains/rpm:rpmbuild_toolchain_type",
)

# Because RPM builds are non-hermetic, the OS's currently installed for RPM
# macros pollute the specs pkg_rpm generates. So define out own one that
# slightly reduces that pollution. Theoretically we'd need one of these for
# each target OS to codify the idiosyncrasies of each OS.
exports_files(["template.spec.tpl"])

0 comments on commit 122e442

Please sign in to comment.