Consolidate build into one root Makefile; split run.sh into run-engine.sh/run-interpreter.sh
This commit is contained in:
@@ -1,74 +0,0 @@
|
||||
CC ?= cc
|
||||
CFLAGS ?= -std=c99 -Wall -Wextra -O2
|
||||
LDLIBS := -lm
|
||||
|
||||
SRC_DIR := src
|
||||
THIRD_PARTY := third_party/astronomy/astronomy.c
|
||||
TEST_DIR := tests
|
||||
BUILD_DIR := build
|
||||
OBJ_DIR := $(BUILD_DIR)/obj
|
||||
|
||||
# Final build output lives in dist/, next to (not inside) engine/ and res/.
|
||||
DIST_DIR := ../dist
|
||||
DIST_IMG_DIR := $(DIST_DIR)/img
|
||||
DIST_I18N_DIR := $(DIST_DIR)/i18n
|
||||
RES_IMG_DIR := ../res/img
|
||||
I18N_DIR := i18n
|
||||
SCRIPTS_DIR := scripts
|
||||
|
||||
# Engine logic shared by the CLI and the test binary (no main()).
|
||||
ENGINE_SRCS := $(SRC_DIR)/rng.c $(SRC_DIR)/tarot.c $(SRC_DIR)/tarot_data.c \
|
||||
$(SRC_DIR)/astro.c $(SRC_DIR)/reading.c $(SRC_DIR)/i18n.c $(THIRD_PARTY)
|
||||
ENGINE_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ENGINE_SRCS))
|
||||
|
||||
MAIN_OBJ := $(OBJ_DIR)/$(SRC_DIR)/main.o
|
||||
TEST_OBJ := $(OBJ_DIR)/$(TEST_DIR)/smoke_test.o
|
||||
|
||||
BINARY := $(DIST_DIR)/deck-engine
|
||||
TEST_BINARY := $(BUILD_DIR)/smoke_test
|
||||
|
||||
.PHONY: all test clean images scripts i18n
|
||||
|
||||
all: $(BINARY) images scripts i18n
|
||||
|
||||
$(BINARY): $(ENGINE_OBJS) $(MAIN_OBJ)
|
||||
@mkdir -p $(DIST_DIR)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
|
||||
|
||||
# The HTML report expects card art at img/<file> next to the binary, so
|
||||
# every build refreshes a copy alongside it (cheap: 22 small JPEGs).
|
||||
images:
|
||||
@mkdir -p $(DIST_IMG_DIR)
|
||||
cp $(RES_IMG_DIR)/*.jpeg $(DIST_IMG_DIR)/
|
||||
|
||||
# The CLI expects translation files at i18n/<lang>.lang next to the
|
||||
# binary (default --i18n-dir), so every build refreshes a copy alongside
|
||||
# it, same as images/. Add a new language by dropping another <code>.lang
|
||||
# file into engine/i18n/ - no code or Makefile change needed.
|
||||
i18n:
|
||||
@mkdir -p $(DIST_I18N_DIR)
|
||||
cp $(I18N_DIR)/*.lang $(DIST_I18N_DIR)/
|
||||
|
||||
# run.sh is refreshed every build. user.properties is only seeded once
|
||||
# (from the placeholder template) so a rebuild never clobbers the user's
|
||||
# own filled-in birth data.
|
||||
scripts:
|
||||
@mkdir -p $(DIST_DIR)
|
||||
cp $(SCRIPTS_DIR)/run.sh $(DIST_DIR)/run.sh
|
||||
chmod +x $(DIST_DIR)/run.sh
|
||||
test -f $(DIST_DIR)/user.properties || \
|
||||
cp $(SCRIPTS_DIR)/user.properties.template $(DIST_DIR)/user.properties
|
||||
|
||||
test: $(TEST_BINARY)
|
||||
./$(TEST_BINARY)
|
||||
|
||||
$(TEST_BINARY): $(ENGINE_OBJS) $(TEST_OBJ)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR) $(BINARY) $(DIST_IMG_DIR) $(DIST_I18N_DIR) $(DIST_DIR)/run.sh
|
||||
# user.properties holds the user's own data - never removed by clean.
|
||||
@@ -1,11 +1,12 @@
|
||||
#!/bin/sh
|
||||
# Runs deck-engine for "today": the tarot seed and the transit moment come
|
||||
# from the OS clock, birth data comes from user.properties next to this
|
||||
# script. Usage: ./run.sh [text|html] [lang]
|
||||
# script. Usage: ./run-engine.sh [text|html|json] [lang]
|
||||
#
|
||||
# [lang] overrides user.properties' lang= for this run only (e.g.
|
||||
# ./run.sh html de); omit it to use lang= from user.properties, which
|
||||
# itself defaults to "en" if unset.
|
||||
# ./run-engine.sh html de); omit it to use lang= from user.properties,
|
||||
# which itself defaults to "en" if unset. See run-interpreter.sh for a
|
||||
# significance report instead of the full reading.
|
||||
|
||||
set -eu
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
# Runs deck-engine (--format json) piped straight into interpreter-cli for
|
||||
# "today": same OS-clock seed/transit-moment and user.properties birth
|
||||
# data as run-engine.sh, but reports how significant today's transits are
|
||||
# instead of printing the full reading. Usage: ./run-interpreter.sh
|
||||
#
|
||||
# Requires both dist/deck-engine (built by engine/'s Makefile) and
|
||||
# dist/interpreter-cli (built by interpreter/'s own Makefile) to already
|
||||
# exist next to this script.
|
||||
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ENGINE_BINARY="$SCRIPT_DIR/deck-engine"
|
||||
INTERPRETER_BINARY="$SCRIPT_DIR/interpreter-cli"
|
||||
PROPERTIES_FILE="$SCRIPT_DIR/user.properties"
|
||||
|
||||
if [ ! -x "$ENGINE_BINARY" ]; then
|
||||
echo "error: $ENGINE_BINARY not found or not executable (run 'make' in engine/ first)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x "$INTERPRETER_BINARY" ]; then
|
||||
echo "error: $INTERPRETER_BINARY not found or not executable (run 'make' in interpreter/ first)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$PROPERTIES_FILE" ]; then
|
||||
echo "error: $PROPERTIES_FILE not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
birth_date=""
|
||||
birth_time=""
|
||||
birth_utc_offset=""
|
||||
birth_lat=""
|
||||
birth_lon=""
|
||||
|
||||
while IFS='=' read -r key value || [ -n "$key" ]; do
|
||||
key="$(printf '%s' "$key" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||
value="$(printf '%s' "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||
case "$key" in
|
||||
'' | '#'*) continue ;;
|
||||
esac
|
||||
case "$key" in
|
||||
birth_date) birth_date="$value" ;;
|
||||
birth_time) birth_time="$value" ;;
|
||||
birth_utc_offset) birth_utc_offset="$value" ;;
|
||||
birth_lat) birth_lat="$value" ;;
|
||||
birth_lon) birth_lon="$value" ;;
|
||||
esac
|
||||
done <"$PROPERTIES_FILE"
|
||||
|
||||
check_set() {
|
||||
case "$2" in
|
||||
'' | *YOUR_*)
|
||||
echo "error: $PROPERTIES_FILE: '$1' is not set - edit the file and fill in your details." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
check_set birth_date "$birth_date"
|
||||
check_set birth_time "$birth_time"
|
||||
check_set birth_utc_offset "$birth_utc_offset"
|
||||
check_set birth_lat "$birth_lat"
|
||||
check_set birth_lon "$birth_lon"
|
||||
|
||||
# OS-provided inputs: today's date is the tarot seed (stable all day, a
|
||||
# new spread each day), current UTC time drives today's transits. The
|
||||
# tarot seed doesn't matter for --format json (only "transits" is read
|
||||
# downstream) but it's kept identical to run-engine.sh's for consistency.
|
||||
seed="$(date +%Y-%m-%d)"
|
||||
transit_date="$(date -u +%Y-%m-%dT%H:%M)"
|
||||
|
||||
"$ENGINE_BINARY" \
|
||||
--seed "$seed" \
|
||||
--birth-date "$birth_date" \
|
||||
--birth-time "$birth_time" \
|
||||
--birth-utc-offset "$birth_utc_offset" \
|
||||
--birth-lat "$birth_lat" \
|
||||
--birth-lon "$birth_lon" \
|
||||
--date "$transit_date" \
|
||||
--format json \
|
||||
| exec "$INTERPRETER_BINARY"
|
||||
@@ -1,6 +1,7 @@
|
||||
# deck-in-a-dash user properties
|
||||
#
|
||||
# Fill in your birth details below, then run ./run.sh (or ./run.sh html).
|
||||
# Fill in your birth details below, then run ./run-engine.sh (or
|
||||
# ./run-engine.sh html).
|
||||
# This file is only copied here once by the build - it will not be
|
||||
# overwritten by later builds, so it's safe to edit in place.
|
||||
#
|
||||
|
||||
@@ -137,13 +137,13 @@ static void test_reading_print_json_shape(void) {
|
||||
printf("PASS test_reading_print_json_shape\n");
|
||||
}
|
||||
|
||||
/* Run with cwd == engine/ (as `make test` does), so the shipped
|
||||
* engine/i18n/ .lang files are reachable as i18n/<code>.lang. */
|
||||
/* Run with cwd == repo root (as `make test` does), so the shipped
|
||||
* engine/i18n/ .lang files are reachable at that path. */
|
||||
static void test_i18n_fallback_and_translation(void) {
|
||||
/* No catalog loaded yet: every lookup returns the caller's fallback. */
|
||||
assert(strcmp(i18n_get("does.not.exist", "fallback text"), "fallback text") == 0);
|
||||
|
||||
bool loaded = i18n_load("i18n/de.lang");
|
||||
bool loaded = i18n_load("engine/i18n/de.lang");
|
||||
assert(loaded && "expected engine/i18n/de.lang to exist and load");
|
||||
assert(strcmp(i18n_get("body.sun", "Sun"), "Sonne") == 0);
|
||||
assert(strcmp(i18n_get("does.not.exist", "fallback text"), "fallback text") == 0);
|
||||
@@ -158,11 +158,11 @@ static void test_i18n_fallback_and_translation(void) {
|
||||
|
||||
/* Loading a file that doesn't exist fails and leaves the previously
|
||||
* loaded catalog in place, rather than silently clearing it. */
|
||||
assert(!i18n_load("i18n/does-not-exist.lang"));
|
||||
assert(!i18n_load("engine/i18n/does-not-exist.lang"));
|
||||
assert(strcmp(i18n_get("body.sun", "Sun"), "Sonne") == 0);
|
||||
|
||||
/* Loading a different language replaces the catalog wholesale. */
|
||||
loaded = i18n_load("i18n/en.lang");
|
||||
loaded = i18n_load("engine/i18n/en.lang");
|
||||
assert(loaded);
|
||||
assert(strcmp(astro_body_name(PLANET_MOON), "Moon") == 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user