nandi/jolt-nativepublic Fork 0
258bbc5161b93d580a4c84363acabe63b0624e88
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Ship the object without the notes nobody reads aabacba · on 258bbc5161b93d580a4c84363acabe63b0624e88 · nandi · 18d ago
BUCK · 167 lines · 7.5 KBPython Blame HistoryRaw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
load("//dist:generated.bzl", "DIST")
load(":defs.bzl", "hermetic_cxx_toolchain", "hermetic_rust_toolchain")
load("@prelude//toolchains:genrule.bzl", "system_genrule_toolchain")
load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain")

# Tools come from the DotSlash files in scripts/, so the build depends on
# pinned upstream releases rather than whatever the host happens to have.
#
# The paths are absolute, and read out of .buckconfig.local rather than written
# here, because neither of the obvious spellings works. A build script runs in
# a directory of its own, and the prelude re-execs the compiler from there, so
# a project-relative `scripts/zcc` is not found; and the shim that does the
# re-exec calls os.execl rather than os.execlp, so a bare `zcc` on PATH is not
# found either. aws-lc-sys is where both show up. The `buck` recipe in justfile
# writes that file, so the absolute paths are generated rather than committed.
#
# rustc does not come this way any more — see the toolchain at the bottom of
# this file. These three are what is left to make into dependencies.
_SCRIPTS = read_root_config("jolt", "scripts", "scripts")

# The compiler's version, written by the `buck` recipe alongside the paths.
#
# It has to reach the actions somehow, because the prelude names rustc as the
# bare string "rustc" — the binary is not an input, so its identity is not in
# any action's cache digest. Two compilers therefore produce artifacts under
# the same digest, and a shared cache will hand one build the other's rlibs;
# the failure is E0514, a long way from the cause. Naming the version in a cfg
# nothing reads is enough to keep the digests apart.
# The C toolchain's version, written by the `buck` recipe alongside the paths.
#
# rustc no longer needs this: it is a dependency now, so its identity is in
# every action's digest and two compilers cannot collide on one cache entry.
# zig still does. It is named by an absolute path that does not change when the
# binary behind it does, so a version bump would silently reuse entries built
# by the old one — the E0514 failure, one toolchain over. Naming the version in
# a cfg nothing reads keeps the digests apart until zig is a dependency too.
_ZIG_VERSION = read_root_config("jolt", "zig_version", "unknown")

# The NDK's, for the same reason and read from the pin rather than the machine.
# The C toolchain does not need it — the archive is a dependency there, so it
# is in every cxx action's digest already. rustc does: it links an Android
# target through scripts/android-cc, an absolute path that does not change when
# the NDK behind it does.
_NDK_VERSION = DIST["android-ndk"]["linux-x86_64"]["strip_prefix"]
#
# This is the same arrangement .cargo/config.toml used to describe: zig cc
# carries its own glibc sysroot, which is why this repo builds on a machine
# with no `cc` at all.
#
# Android is the one target it cannot serve. zig brings a glibc sysroot and no
# bionic, so there is nothing there to link an Android object against; the
# NDK's own clang is the driver that knows where libc.so and the platform stubs
# live. Only the archive and the wrapper change — the toolchain either side of
# them is the same construction, which is the point of asking a wrapper for a
# mode rather than naming binaries here.
hermetic_cxx_toolchain(
    name = "cxx",
    dist = select({
        "DEFAULT": "toolchains//dist:zig",
        # DotSlash, not the NDK: ndk.sh fetches the NDK where it runs, which is
        # the difference between a worker downloading three gigabytes from
        # Google and this machine uploading them to the CAS first.
        "prelude//os:android": "toolchains//dist:dotslash",
    }),
    manifest = select({
        "DEFAULT": None,
        "prelude//os:android": "root//scripts:android-ndk.dotslash",
    }),
    wrapper = select({
        "DEFAULT": "toolchains//:zcc.sh",
        "prelude//os:android": "toolchains//:ndk.sh",
    }),
    platform_name = select({
        "DEFAULT": "x86_64",
        "prelude//os:android": "arm64",
    }),
    visibility = ["PUBLIC"],
)

system_genrule_toolchain(
    name = "genrule",
    visibility = ["PUBLIC"],
)

system_python_bootstrap_toolchain(
    name = "python_bootstrap",
    visibility = ["PUBLIC"],
)

# The compiler is the dist tarball in toolchains//dist, not a name resolved
# against the machine. See defs.bzl for why that distinction is the whole
# point, and dist.bzl for where the tarball comes from.
hermetic_rust_toolchain(
    name = "rust",
    dist = "toolchains//dist:rust",
    wrapper = "toolchains//:rustc.sh",
    default_edition = "2021",
    # Pipelined builds compile each crate against its dependencies'
    # `-Zno-codegen` metadata rather than their rlibs. On the Android graph the
    # two disagree for android-activity, and what comes out the far side is a
    # link that cannot find winit — or glutin-winit, or anything else that
    # reaches the event loop through it. Build real rlibs there. The desktop
    # graph pipelines fine and keeps the parallelism.
    nightly_features = select({
        "DEFAULT": True,
        "prelude//os:android": False,
    }),
    # Which libstd rustc is given. The desktop configuration takes the
    # component the dist tarball carries for its own host; Android needs two
    # triples in one directory, so it takes the stitched one.
    sysroot = select({
        "DEFAULT": None,
        "prelude//os:android": "toolchains//dist:android-sysroot",
    }),
    rustc_flags = select({
        "DEFAULT": ["-Clinker=" + _SCRIPTS + "/zcc"],
        # zig has no bionic to link against; the NDK's clang does. The cfg
        # nothing reads is what keeps the digests apart, as above.
        "prelude//os:android": [
            "-Clinker=" + _SCRIPTS + "/android-cc",
            "--cfg=jolt_ndk=\"" + _NDK_VERSION + "\"",
        ],
    }) + [
        # What [profile.release] in Cargo.toml says, and for the reason given
        # there: the tree walk and the texture uploads are hot every frame, and
        # the media plane decodes H.264. buck2 optimises nothing by default, so
        # without this the two objects are debug builds wearing release names.
        # OPT_LEVEL=2 in the buildscript fixups is the same setting for the C.
        "-Copt-level=2",
        # Debug info is 5.9M of the 14.5M Android object, and nothing reads it:
        # the .so ships in the APK, and a crash comes back through logcat as a
        # bionic backtrace against the loaded segments, not a DWARF line table.
        # cargo's release profile already carries none — its object strips to
        # within 168 bytes of itself — so this is buck2 matching that, not a
        # new decision about what is debuggable. Drop the flag to get it back.
        "-Cstrip=debuginfo",
        "--cfg=jolt_cc=\"" + _ZIG_VERSION + "\"",
    ],
    # Only triples there is an archive for can be named here: the desktop one
    # comes out of the dist tarball, the Android one out of the libstd fetched
    # beside it.
    rustc_target_triple = select({
        "DEFAULT": "x86_64-unknown-linux-gnu",
        "prelude//os:android": "aarch64-linux-android",
    }),
    visibility = ["PUBLIC"],
)

# The wrapper the Rust toolchain runs rustc through, as an artifact so it is an
# input to every action that compiles anything.
export_file(
    name = "zcc.sh",
    mode = "reference",
    visibility = ["PUBLIC"],
)

export_file(
    name = "ndk.sh",
    mode = "reference",
    visibility = ["PUBLIC"],
)

export_file(
    name = "rustc.sh",
    mode = "reference",
    visibility = ["PUBLIC"],
)