# # Pebble app build rules for Deck in a Dash. # # Unlike a typical `pebble new-project` skeleton, this app's C sources # aren't all under src/c/ - most of the actual reading logic lives in # ../engine/src/ (rng, tarot, tarot_data, astro, i18n, reading) and is # shared byte-for-byte with the desktop deck-engine/interpreter-cli # binaries (see the root CLAUDE.md's "Portability to the watch" # section). build() below explicitly lists the engine source files this # app needs and glues them onto src/c/**/*.c's own sources - it does NOT # glob ../engine/src/*.c wholesale, because that directory also contains # reading.c's desktop-only fprintf-based print functions (compiled out # under #ifndef PBL_SDK_3, so harmless to include) but must never pull in # engine/third_party/astronomy/ (the vendored high-precision ephemeris, # ~127KB compiled - alone bigger than a whole Pebble app's 64KB # code+data+bss budget). This app uses lowprec_ephemeris.c instead - see # that file's own header comment. import os.path import subprocess import sys top = '.' out = 'build' # Engine source files this app links in, relative to ../engine/src/ - # see the module comment above for why this is an explicit list rather # than a glob. ENGINE_SRCS = [ 'rng.c', 'tarot.c', 'tarot_data.c', 'astro.c', 'i18n.c', 'reading.c', 'lowprec_ephemeris.c', ] # interpreter/'s significance/narrative/guidance scoring and text - see # CLAUDE.md's "Interpretation" section. Unlike the desktop interpreter-cli # (which deliberately keeps these header-only against the engine, for # independent testability without a real ephemeris - see significance.h's # own comment), the watch links their real .c implementations straight # into the same binary as the engine above: there's no deck-engine/ # interpreter-cli JSON pipe to speak of on a single device, just one # process computing and immediately rendering its own reading. json.c/ # reading_io.c (the JSON parser/loader) are never linked - the watch has # no JSON to parse, it calls reading_generate() directly. INTERP_SRCS = [ 'significance.c', 'narrative.c', 'guidance.c', ] def options(ctx): ctx.load('pebble_sdk') def configure(ctx): ctx.load('pebble_sdk') def build(ctx): ctx.load('pebble_sdk') # Regenerate src/c/i18n_tables.auto.c from engine/i18n/*.lang, and # resources/img/*.png from res/img/*.jpeg, before compiling/bundling # anything - see each script's own doc comment. Both run eagerly (not # as waf Tasks) since the bundle step below depends on their output # existing; gen_card_images.py skips any card whose PNG is already # up to date, so this stays cheap on repeat builds. Requires Pillow # (`pip install Pillow`) - see watch/README.md. subprocess.check_call([sys.executable, 'scripts/gen_i18n_tables.py']) subprocess.check_call([sys.executable, 'scripts/gen_card_images.py']) engine_dir = ctx.path.parent.find_dir('engine/src') engine_nodes = [engine_dir.find_node(name) for name in ENGINE_SRCS] interp_dir = ctx.path.parent.find_dir('interpreter/src') interp_nodes = [interp_dir.find_node(name) for name in INTERP_SRCS] binaries = [] cached_env = ctx.env for platform in ctx.env.TARGET_PLATFORMS: ctx.env = ctx.all_envs[platform] ctx.set_group(ctx.env.PLATFORM_NAME) app_elf = '{}/pebble-app.elf'.format(ctx.env.BUILD_DIR) app_sources = ctx.path.ant_glob('src/c/**/*.c') + engine_nodes + interp_nodes ctx.pbl_build(source=app_sources, target=app_elf, bin_type='app') binaries.append({'platform': platform, 'app_elf': app_elf}) ctx.env = cached_env ctx.set_group('bundle') ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob(['src/pkjs/**/*.js', 'src/pkjs/**/*.json']), js_entry_file='src/pkjs/index.js')