BUCKannotatedBUCKsource98 lines · 3.7 KB · raw
1# zbanks/alttp, the C bot, built from its own sources. `zbanks-alttp/` is
2# upstream's tree byte for byte; everything a host needs is outside it
3# (../../packages/zbanks). The few changes to the bot itself are the carried
4# patches in `patches/`, applied at build time by `:patched` below, so a
5# patch that stops applying after a refresh fails the build instead of
6# silently going missing. The flags are upstream's Makefile CFLAGS, less
7# three things a different compiler forces - see README.md.
8
9_SRCS = [
10    "alttp.c",
11    "ap_map.c",
12    "ap_snes.c",
13    "ap_plan.c",
14    "ap_req.c",
15    "ap_item.c",
16    "pm.c",
17    "pq.c",
18    "lb.c",
19]
20
21_HEADERS = [
22    "alttp_public.h",
23    "ap_item.h",
24    "ap_macro.h",
25    "ap_map.h",
26    "ap_math.h",
27    "ap_plan.h",
28    "ap_req.h",
29    "ap_snes.h",
30    "bm.h",
31    "lb.h",
32    "pm.h",
33    "pq.h",
34]
35
36_PATCHES = glob(["patches/*.patch"])
37
38# Upstream's sources with `patches/*.patch` applied in name order. `patch`
39# refuses a hunk that does not match, and the genrule fails with it.
40genrule(
41    name = "patched",
42    srcs = ["zbanks-alttp/" + f for f in _SRCS + _HEADERS] + _PATCHES,
43    outs = {f: [f] for f in _SRCS + _HEADERS},
44    cmd = " && ".join([
45        "cp " + " ".join(["$SRCDIR/zbanks-alttp/" + f for f in _SRCS + _HEADERS]) + " $OUT/",
46        "chmod u+w $OUT/*",
47        "for p in $SRCDIR/patches/*.patch; do patch --batch --forward -p4 -d $OUT < $p || exit 1; done",
48    ]),
49)
50
51cxx_library(
52    name = "zbanks-alttp",
53    srcs = [
54        # ap_map.c creates every goal (ap_goal_add, as it adds each node).
55        # Renaming the calls there sends them through the host
56        # (../../packages/zbanks/shim/host.c, zb_goal_add), which declines a
57        # goal the save says is already done - uncle, on a start from a
58        # mid-game state with an imported map - and otherwise calls the real
59        # ap_goal_add in ap_plan.c, which is compiled without the rename.
60        (":patched[{}]".format(s), ["-Dap_goal_add=zb_goal_add"]) if s == "ap_map.c" else ":patched[{}]".format(s)
61        for s in _SRCS
62    ],
63    # Upstream compiles with `-I.` and includes its own headers both as
64    # "ap_macro.h" and <ap_macro.h>; bare names reproduce that.
65    exported_headers = {h: ":patched[{}]".format(h) for h in _HEADERS},
66    header_namespace = "",
67    compiler_flags = [
68        # Upstream's Makefile, verbatim, minus -Werror (below).
69        "-O3",
70        "-ggdb3",
71        "-Wall",
72        "-Wextra",
73        "-Wno-unused-parameter",
74        "-Wno-unused",
75        "-Wwrite-strings",
76        "-Wshadow",
77        "-std=c11",
78        "-D_DEFAULT_SOURCE",
79        # ap_snes.h DEFINES `bool ap_manual_mode;` and every .c includes it.
80        # gcc before 10 (upstream's era) merged such tentative definitions;
81        # clang 11+ and gcc 10+ default to -fno-common and fail the link with
82        # "multiple definition". -fcommon is the old default, restored.
83        "-fcommon",
84        # Upstream writes its debug files (goals.txt, map, map.pbm,
85        # full_map.dot, ...) with bare relative names, i.e. into whatever the
86        # process's working directory is - the repo root, for our apps. These
87        # two renames send every such fopen/rename through
88        # ../../packages/zbanks/shim/host.c, which puts them in the directory
89        # the host chose (run/zbanks-c/..., run/zbanks-window/). The call
90        # sites are untouched; only the symbol they bind to changes.
91        "-Dfopen=zb_fopen",
92        "-Drename=zb_rename",
93        # -Werror is dropped: upstream's code was warning-clean on ITS
94        # compiler; this one (clang 21) warns about things gcc of 2020 did
95        # not, and a warning is not a behaviour change.
96    ],
97    visibility = ["PUBLIC"],
98)