Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe634c4582 | |||
| 8c2406ff6b |
@@ -19,6 +19,16 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Guards must run from the REPO ROOT — override the job's
|
||||
# defaults.run.working-directory: lang
|
||||
- name: Guard - single canonical runtime source
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: bash scripts/check-single-runtime.sh
|
||||
|
||||
- name: Guard - el_runtime.c growth budget
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: bash scripts/check-runtime-growth.sh
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
apt-get update -qq
|
||||
@@ -41,7 +51,7 @@ jobs:
|
||||
gcc -O2 \
|
||||
-I runtime \
|
||||
dist/elc-gen2.c \
|
||||
runtime/el_runtime.c \
|
||||
$(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm \
|
||||
-o dist/platform/elc
|
||||
chmod +x dist/platform/elc
|
||||
@@ -56,7 +66,7 @@ jobs:
|
||||
gcc -O2 \
|
||||
-I runtime \
|
||||
dist/elb.c \
|
||||
runtime/el_runtime.c \
|
||||
$(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm \
|
||||
-o dist/bin/elb
|
||||
chmod +x dist/bin/elb
|
||||
@@ -87,14 +97,20 @@ jobs:
|
||||
bash tests/html_sanitizer/run.sh
|
||||
|
||||
# Native El test suites (elc --test, compile-link-run)
|
||||
# el_runtime.c is precompiled to .o once and reused by all 8 modules.
|
||||
- name: Precompile el_runtime.o
|
||||
# The runtime is MULTI-FILE (see lang/runtime/SOURCES). Every .c is compiled
|
||||
# once into /tmp/libel.a and reused by all 8 test modules — compile-once,
|
||||
# link-many, as prescribed in DESIGN.md. Linking el_runtime.c alone fails
|
||||
# at `ld`: it calls into all six engram sibling TUs.
|
||||
- name: Precompile runtime into libel.a
|
||||
run: |
|
||||
set -euo pipefail
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
gcc -O2 -c -I "$RUNTIME" "$RUNTIME/el_runtime.c" \
|
||||
-o /tmp/el_runtime.o
|
||||
echo "el_runtime.o compiled"
|
||||
rm -rf /tmp/elrt && mkdir -p /tmp/elrt
|
||||
for src in $(../scripts/el-runtime-sources.sh --check "$RUNTIME"); do
|
||||
gcc -O2 -c -I "$RUNTIME" "$src" -o "/tmp/elrt/$(basename "${src%.c}").o"
|
||||
done
|
||||
ar rcs /tmp/libel.a /tmp/elrt/*.o
|
||||
echo "libel.a built from $(ls /tmp/elrt/*.o | wc -l) translation units"
|
||||
|
||||
- name: Run tests - native (core)
|
||||
run: |
|
||||
@@ -102,7 +118,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_core.el > /tmp/el_native_core.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_core.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_core.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_core
|
||||
/tmp/el_native_core
|
||||
|
||||
@@ -112,7 +128,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_text.el > /tmp/el_native_text.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_text.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_text.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_text
|
||||
/tmp/el_native_text
|
||||
|
||||
@@ -122,7 +138,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_string.el > /tmp/el_native_string.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_string.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_string.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_string
|
||||
/tmp/el_native_string
|
||||
|
||||
@@ -132,7 +148,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_math.el > /tmp/el_native_math.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_math.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_math.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_math
|
||||
/tmp/el_native_math
|
||||
|
||||
@@ -142,7 +158,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_state.el > /tmp/el_native_state.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_state.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_state.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_state
|
||||
/tmp/el_native_state
|
||||
|
||||
@@ -152,7 +168,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_time.el > /tmp/el_native_time.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_time.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_time.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_time
|
||||
/tmp/el_native_time
|
||||
|
||||
@@ -162,7 +178,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_json.el > /tmp/el_native_json.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_json.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_json.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_json
|
||||
/tmp/el_native_json
|
||||
|
||||
@@ -172,7 +188,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_env.el > /tmp/el_native_env.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_env.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_env.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_env
|
||||
/tmp/el_native_env
|
||||
|
||||
@@ -182,7 +198,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_fs.el > /tmp/el_native_fs.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_fs.c /tmp/el_runtime.o \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_fs.c /tmp/libel.a \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_fs
|
||||
/tmp/el_native_fs
|
||||
|
||||
@@ -306,8 +322,9 @@ jobs:
|
||||
FROM ${BASE}
|
||||
COPY dist/platform/elc /opt/el/dist/platform/elc
|
||||
COPY dist/bin/elb /opt/el/dist/bin/elb
|
||||
COPY runtime/el_runtime.c /opt/el/runtime/el_runtime.c
|
||||
COPY runtime/el_runtime.h /opt/el/runtime/el_runtime.h
|
||||
# Whole runtime link set — el_runtime.c alone does not link (it calls
|
||||
# into the six engram sibling TUs). See lang/runtime/SOURCES.
|
||||
COPY runtime/ /opt/el/runtime/
|
||||
COPY runtime/el_runtime.js /opt/el/runtime/el_runtime.js
|
||||
RUN chmod +x /opt/el/dist/platform/elc /opt/el/dist/bin/elb
|
||||
EOF
|
||||
|
||||
@@ -29,6 +29,16 @@ jobs:
|
||||
fi
|
||||
echo "Source branch check passed: ${SOURCE} -> stage"
|
||||
|
||||
# Guards must run from the REPO ROOT — override the job's
|
||||
# defaults.run.working-directory: lang
|
||||
- name: Guard - single canonical runtime source
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: bash scripts/check-single-runtime.sh
|
||||
|
||||
- name: Guard - el_runtime.c growth budget
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: bash scripts/check-runtime-growth.sh
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
apt-get update -qq
|
||||
@@ -48,7 +58,7 @@ jobs:
|
||||
gcc -O2 \
|
||||
-I runtime \
|
||||
dist/elc-gen2.c \
|
||||
runtime/el_runtime.c \
|
||||
$(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm \
|
||||
-o dist/platform/elc
|
||||
chmod +x dist/platform/elc
|
||||
@@ -86,7 +96,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_core.el > /tmp/el_native_core.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_core.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_core.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_core
|
||||
/tmp/el_native_core
|
||||
|
||||
@@ -96,7 +106,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_text.el > /tmp/el_native_text.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_text.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_text.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_text
|
||||
/tmp/el_native_text
|
||||
|
||||
@@ -106,7 +116,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_string.el > /tmp/el_native_string.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_string.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_string.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_string
|
||||
/tmp/el_native_string
|
||||
|
||||
@@ -116,7 +126,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_math.el > /tmp/el_native_math.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_math.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_math.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_math
|
||||
/tmp/el_native_math
|
||||
|
||||
@@ -126,7 +136,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_state.el > /tmp/el_native_state.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_state.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_state.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_state
|
||||
/tmp/el_native_state
|
||||
|
||||
@@ -136,7 +146,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_time.el > /tmp/el_native_time.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_time.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_time.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_time
|
||||
/tmp/el_native_time
|
||||
|
||||
@@ -146,7 +156,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_json.el > /tmp/el_native_json.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_json.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_json.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_json
|
||||
/tmp/el_native_json
|
||||
|
||||
@@ -156,7 +166,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_env.el > /tmp/el_native_env.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_env.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_env.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_env
|
||||
/tmp/el_native_env
|
||||
|
||||
@@ -166,7 +176,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_fs.el > /tmp/el_native_fs.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_fs.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_fs.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_fs
|
||||
/tmp/el_native_fs
|
||||
|
||||
@@ -178,7 +188,7 @@ jobs:
|
||||
gcc -O2 \
|
||||
-I runtime \
|
||||
dist/elb.c \
|
||||
runtime/el_runtime.c \
|
||||
$(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm \
|
||||
-o dist/bin/elb
|
||||
chmod +x dist/bin/elb
|
||||
@@ -290,8 +300,9 @@ jobs:
|
||||
FROM ${BASE}
|
||||
COPY dist/platform/elc /opt/el/dist/platform/elc
|
||||
COPY dist/bin/elb /opt/el/dist/bin/elb
|
||||
COPY runtime/el_runtime.c /opt/el/runtime/el_runtime.c
|
||||
COPY runtime/el_runtime.h /opt/el/runtime/el_runtime.h
|
||||
# Whole runtime link set — el_runtime.c alone does not link (it calls
|
||||
# into the six engram sibling TUs). See lang/runtime/SOURCES.
|
||||
COPY runtime/ /opt/el/runtime/
|
||||
COPY runtime/el_runtime.js /opt/el/runtime/el_runtime.js
|
||||
RUN chmod +x /opt/el/dist/platform/elc /opt/el/dist/bin/elb
|
||||
EOF
|
||||
|
||||
@@ -29,6 +29,16 @@ jobs:
|
||||
fi
|
||||
echo "Source branch check passed: ${SOURCE} -> main"
|
||||
|
||||
# Guards must run from the REPO ROOT — override the job's
|
||||
# defaults.run.working-directory: lang
|
||||
- name: Guard - single canonical runtime source
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: bash scripts/check-single-runtime.sh
|
||||
|
||||
- name: Guard - el_runtime.c growth budget
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: bash scripts/check-runtime-growth.sh
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
apt-get update -qq
|
||||
@@ -49,7 +59,7 @@ jobs:
|
||||
gcc -O2 \
|
||||
-I runtime \
|
||||
dist/elc-gen2.c \
|
||||
runtime/el_runtime.c \
|
||||
$(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm \
|
||||
-o dist/platform/elc
|
||||
chmod +x dist/platform/elc
|
||||
@@ -64,7 +74,7 @@ jobs:
|
||||
gcc -O2 \
|
||||
-I runtime \
|
||||
dist/elb.c \
|
||||
runtime/el_runtime.c \
|
||||
$(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm \
|
||||
-o dist/bin/elb
|
||||
chmod +x dist/bin/elb
|
||||
@@ -123,7 +133,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_core.el > /tmp/el_native_core.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_core.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_core.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_core
|
||||
/tmp/el_native_core
|
||||
|
||||
@@ -133,7 +143,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_text.el > /tmp/el_native_text.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_text.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_text.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_text
|
||||
/tmp/el_native_text
|
||||
|
||||
@@ -143,7 +153,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_string.el > /tmp/el_native_string.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_string.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_string.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_string
|
||||
/tmp/el_native_string
|
||||
|
||||
@@ -153,7 +163,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_math.el > /tmp/el_native_math.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_math.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_math.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_math
|
||||
/tmp/el_native_math
|
||||
|
||||
@@ -163,7 +173,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_state.el > /tmp/el_native_state.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_state.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_state.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_state
|
||||
/tmp/el_native_state
|
||||
|
||||
@@ -173,7 +183,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_time.el > /tmp/el_native_time.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_time.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_time.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_time
|
||||
/tmp/el_native_time
|
||||
|
||||
@@ -183,7 +193,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_json.el > /tmp/el_native_json.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_json.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_json.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_json
|
||||
/tmp/el_native_json
|
||||
|
||||
@@ -193,7 +203,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_env.el > /tmp/el_native_env.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_env.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_env.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_env
|
||||
/tmp/el_native_env
|
||||
|
||||
@@ -203,7 +213,7 @@ jobs:
|
||||
ELC="$(pwd)/dist/platform/elc"
|
||||
RUNTIME="$(pwd)/runtime"
|
||||
"$ELC" --test tests/native/test_fs.el > /tmp/el_native_fs.c
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_fs.c "$RUNTIME/el_runtime.c" \
|
||||
gcc -O2 -I "$RUNTIME" /tmp/el_native_fs.c $(../scripts/el-runtime-sources.sh "$RUNTIME") \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o /tmp/el_native_fs
|
||||
/tmp/el_native_fs
|
||||
|
||||
@@ -216,10 +226,17 @@ jobs:
|
||||
cp lang/dist/platform/elc dist/sdk/bin/elc
|
||||
cp lang/dist/bin/elb dist/sdk/bin/elb
|
||||
cp lang/dist/bin/epm dist/sdk/bin/epm
|
||||
cp lang/runtime/el_runtime.c dist/sdk/runtime/
|
||||
cp lang/runtime/el_runtime.h dist/sdk/runtime/
|
||||
cp lang/runtime/engram_store.c dist/sdk/runtime/
|
||||
cp lang/runtime/engram_store.h dist/sdk/runtime/
|
||||
# Ship the WHOLE runtime link set, not el_runtime.c alone. el_runtime.c
|
||||
# #includes six engram headers and calls into all six sibling .c files,
|
||||
# so an SDK carrying only el_runtime.c{,.h} + engram_store.c{,.h} cannot
|
||||
# link — downstream `ld` fails on engram_ground_json, eg_find_relation,
|
||||
# cog_assert_two_axis and friends. lang/runtime/SOURCES is the source of
|
||||
# truth; --check makes a missing file fail the release loudly.
|
||||
for f in $(scripts/el-runtime-sources.sh --check) \
|
||||
$(scripts/el-runtime-sources.sh --headers --check); do
|
||||
cp "lang/runtime/${f}" dist/sdk/runtime/
|
||||
done
|
||||
cp lang/runtime/SOURCES dist/sdk/runtime/
|
||||
cp lang/runtime/*.el dist/sdk/runtime/
|
||||
tar -czf dist/el-sdk-latest.tar.gz -C dist/sdk .
|
||||
echo "SDK tarball bundled: dist/el-sdk-latest.tar.gz"
|
||||
@@ -274,12 +291,16 @@ jobs:
|
||||
"${GITEA_API}/repos/${REPO}/releases/${RELEASE_ID}/assets"
|
||||
}
|
||||
|
||||
# Per-file assets (downstream CI needs these individually)
|
||||
# Per-file assets (downstream CI needs these individually).
|
||||
# lang/install.sh downloads every one of these by name — the list is
|
||||
# lang/runtime/SOURCES. Shipping el_runtime.c alone produced a lib/
|
||||
# that could not link; that is the bug this loop closes.
|
||||
upload_asset lang/dist/platform/elc elc
|
||||
upload_asset lang/runtime/el_runtime.c el_runtime.c
|
||||
upload_asset lang/runtime/el_runtime.h el_runtime.h
|
||||
upload_asset lang/runtime/engram_store.c engram_store.c
|
||||
upload_asset lang/runtime/engram_store.h engram_store.h
|
||||
for f in $(scripts/el-runtime-sources.sh --check) \
|
||||
$(scripts/el-runtime-sources.sh --headers --check); do
|
||||
upload_asset "lang/runtime/${f}" "${f}"
|
||||
done
|
||||
upload_asset lang/runtime/SOURCES SOURCES
|
||||
|
||||
# SDK bundle and installer binary
|
||||
upload_asset dist/el-sdk-latest.tar.gz el-sdk-latest.tar.gz
|
||||
@@ -350,6 +371,26 @@ jobs:
|
||||
--version="${VERSION}" \
|
||||
--source=runtime/el_runtime.js
|
||||
|
||||
# el-runtime-src — the COMPLETE runtime link set as one tarball.
|
||||
#
|
||||
# The el-runtime-c / el-runtime-h packages above are single files and are
|
||||
# kept for backward compatibility with consumers that already pull them,
|
||||
# but they are NOT sufficient to link: el_runtime.c calls into six engram
|
||||
# sibling translation units. New consumers should pull el-runtime-src and
|
||||
# link everything named in its SOURCES file.
|
||||
tar -czf /tmp/el-runtime-src.tar.gz \
|
||||
-C runtime SOURCES \
|
||||
$(../scripts/el-runtime-sources.sh --check) \
|
||||
$(../scripts/el-runtime-sources.sh --headers --check)
|
||||
|
||||
gcloud artifacts generic upload \
|
||||
--repository=foundation-prod \
|
||||
--location=us-central1 \
|
||||
--project=neuron-785695 \
|
||||
--package=el-runtime-src \
|
||||
--version="${VERSION}" \
|
||||
--source=/tmp/el-runtime-src.tar.gz
|
||||
|
||||
echo "Published El SDK version=${VERSION} to foundation-prod"
|
||||
# Keep key alive for the ci-base rebuild step below
|
||||
# (deleted in that step after docker push)
|
||||
@@ -386,8 +427,9 @@ jobs:
|
||||
FROM ${BASE}
|
||||
COPY dist/platform/elc /opt/el/dist/platform/elc
|
||||
COPY dist/bin/elb /opt/el/dist/bin/elb
|
||||
COPY runtime/el_runtime.c /opt/el/runtime/el_runtime.c
|
||||
COPY runtime/el_runtime.h /opt/el/runtime/el_runtime.h
|
||||
# Whole runtime link set — el_runtime.c alone does not link (it calls
|
||||
# into the six engram sibling TUs). See lang/runtime/SOURCES.
|
||||
COPY runtime/ /opt/el/runtime/
|
||||
COPY runtime/el_runtime.js /opt/el/runtime/el_runtime.js
|
||||
RUN chmod +x /opt/el/dist/platform/elc /opt/el/dist/bin/elb
|
||||
EOF
|
||||
|
||||
+42
-3
@@ -9,13 +9,52 @@ LANG_DIR="$ROOT/lang"
|
||||
RUNTIME="$LANG_DIR/runtime"
|
||||
ELC="$LANG_DIR/dist/platform/elc"
|
||||
|
||||
# Runtime guards — catch drift and growth before they are committed, not in CI.
|
||||
# check-single-runtime.sh : el_runtime.c must not be FORKED (a lagging copy
|
||||
# shipped to prod and dropped learned hebb edges).
|
||||
# check-runtime-growth.sh : el_runtime.c must not GROW (it is a 2026-05-03
|
||||
# build shim that was never retired; see BUDGET).
|
||||
echo "→ Runtime guards..."
|
||||
bash "$ROOT/scripts/check-single-runtime.sh"
|
||||
bash "$ROOT/scripts/check-runtime-growth.sh"
|
||||
|
||||
# If elc isn't built yet, skip with a warning rather than blocking
|
||||
if [ ! -x "$ELC" ]; then
|
||||
echo "⚠ elc not found at lang/dist/platform/elc — skipping pre-commit tests"
|
||||
echo " Build it first: cd lang && gcc -O2 -I runtime dist/elc-bootstrap.c runtime/el_runtime.c -lcurl -lpthread -o dist/elc-gen2 && ./dist/elc-gen2 el-compiler/src/compiler.el > /tmp/elc.c && gcc -O2 -I runtime /tmp/elc.c runtime/el_runtime.c -lcurl -lpthread -o dist/platform/elc"
|
||||
echo " Build it first: see 'Rebuilding the Compiler' in lang/AGENTS.md"
|
||||
echo " (link \$($ROOT/scripts/el-runtime-sources.sh $RUNTIME) — NOT el_runtime.c alone)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# The runtime is MULTI-FILE (lang/runtime/SOURCES). This hook used to link
|
||||
# "$RUNTIME/el_runtime.c" alone with stderr sent to /dev/null — so once
|
||||
# el_runtime.c started calling into the engram siblings, every native test
|
||||
# reported as FAILED with the real `ld` error invisible. Build the whole set
|
||||
# once into an archive, then link each test against it.
|
||||
|
||||
# macOS: Homebrew openssl@3 is not on the default include/lib search path, so
|
||||
# without these the link fails on -lssl/-lcrypto. Empty on Linux/CI.
|
||||
SSL_INC=""
|
||||
SSL_LIB=""
|
||||
if command -v brew >/dev/null 2>&1 && OSSL="$(brew --prefix openssl@3 2>/dev/null)" && [ -n "$OSSL" ]; then
|
||||
SSL_INC="-I$OSSL/include"
|
||||
SSL_LIB="-L$OSSL/lib"
|
||||
fi
|
||||
|
||||
echo "→ Building runtime (compile-once, link-many)..."
|
||||
HOOK_LIB="/tmp/el_hook_libel.a"
|
||||
HOOK_OBJ="/tmp/el_hook_obj"
|
||||
rm -rf "$HOOK_OBJ" && mkdir -p "$HOOK_OBJ"
|
||||
if ! for src in $("$ROOT/scripts/el-runtime-sources.sh" --check "$RUNTIME"); do
|
||||
gcc -O2 -c -I "$RUNTIME" $SSL_INC "$src" -o "$HOOK_OBJ/$(basename "${src%.c}").o" || exit 1
|
||||
done; then
|
||||
echo "✗ Pre-commit failed: the runtime does not compile."
|
||||
echo " Re-run without 2>/dev/null to see the error:"
|
||||
echo " gcc -O2 -c -I $RUNTIME \$($ROOT/scripts/el-runtime-sources.sh $RUNTIME)"
|
||||
exit 1
|
||||
fi
|
||||
ar rcs "$HOOK_LIB" "$HOOK_OBJ"/*.o
|
||||
|
||||
echo "→ Running El native tests..."
|
||||
PASS=0
|
||||
FAIL=0
|
||||
@@ -27,8 +66,8 @@ for test_file in "$LANG_DIR"/tests/native/test_*.el; do
|
||||
tmp_bin="/tmp/el_hook_${name}"
|
||||
|
||||
if "$ELC" --test "$test_file" > "$tmp_c" 2>/dev/null \
|
||||
&& gcc -O2 -I "$RUNTIME" "$tmp_c" "$RUNTIME/el_runtime.c" \
|
||||
-lcurl -lpthread -lm -o "$tmp_bin" 2>/dev/null \
|
||||
&& gcc -O2 -I "$RUNTIME" $SSL_INC $SSL_LIB "$tmp_c" "$HOOK_LIB" \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o "$tmp_bin" 2>/dev/null \
|
||||
&& "$tmp_bin" 2>/dev/null; then
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
|
||||
@@ -199,21 +199,35 @@ wrong, say so with a measurement rather than editing it.
|
||||
|
||||
All build/test commands run from `lang/` unless noted. Grounded in `.gitea/workflows/sdk-release.yaml`, `lang/install.sh`, and `lang/AGENTS.md`.
|
||||
|
||||
> ### The runtime is MULTI-FILE — never link `el_runtime.c` alone
|
||||
>
|
||||
> `lang/runtime/el_runtime.c` `#include`s six engram headers and makes hard cross-TU calls into all six sibling `.c` files. **Linking it by itself fails at `ld`** (undefined `engram_ground_json`, `engram_activate_inner`, `eg_find_relation`, `cog_assert_two_axis`, …). The canonical link set lives in exactly one place — **`lang/runtime/SOURCES`** — and is printed by `scripts/el-runtime-sources.sh`:
|
||||
>
|
||||
> ```bash
|
||||
> scripts/el-runtime-sources.sh lang/runtime # ten .c files, in link order
|
||||
> ```
|
||||
>
|
||||
> Use `$(scripts/el-runtime-sources.sh <runtime-dir>)` in every link line. Do not spell the list out longhand — it was written out in ~8 places, every copy drifted, and that is why the one-file link line below shipped broken for months. *(Corrected 2026-08-16.)*
|
||||
|
||||
**Self-host the compiler** (seed binary → gen2 elc):
|
||||
```bash
|
||||
cd lang
|
||||
dist/platform/elc-linux-amd64 elc-cli.el > dist/elc-gen2.c # seed is the committed linux-amd64 binary
|
||||
gcc -O2 -I el-compiler/runtime dist/elc-gen2.c \
|
||||
el-compiler/runtime/el_runtime.c \
|
||||
gcc -O2 -I runtime dist/elc-gen2.c \
|
||||
$(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm \
|
||||
-o dist/platform/elc
|
||||
```
|
||||
On macOS/arm64 the canonical local binary is `dist/platform/elc`; verify self-hosting by recompiling and `diff`ing the emitted `.c` (see `lang/AGENTS.md`). Note: `lang/AGENTS.md` says `el_seed.c` supersedes `el_runtime.c`, but the release workflow still links `el_runtime.c`/`.h` — treat `el_runtime.c` as the published runtime; reconcile which is canonical **(verify)**.
|
||||
On macOS/arm64 the canonical local binary is `dist/platform/elc`; verify self-hosting by recompiling and `diff`ing the emitted `.c` (see `lang/AGENTS.md`).
|
||||
|
||||
*(Corrected 2026-08-16: this recipe compiled `el-compiler/runtime/el_runtime.c`. That path is a **lagging fork** — the "DO NOT EDIT" list at the top of this file names it as such. Building the canonical compiler from a known-stale fork was a live defect. It now uses `lang/runtime/`, the canonical source.)*
|
||||
|
||||
**Which runtime file is canonical — resolved.** *(This note previously read "`lang/AGENTS.md` says `el_seed.c` supersedes `el_runtime.c`, but the release workflow still links `el_runtime.c`/`.h` — reconcile which is canonical **(verify)**." It is now reconciled.)* **Neither supersedes the other; both ship, together with eight more.** `el_runtime.c` was created on 2026-05-03 as an explicitly temporary build shim — deleted that afternoon, restored 25 minutes later "UNTIL the compiler is updated to emit `#include el_seed.h`" — and the `until` never happened, so it grew to 20.5k lines. The end state remains a seed-only boundary (`elc` emitting `#include "el_seed.h"`, `elb` dropping its hardcoded runtime path); until that lands, **the canonical unit is the set in `lang/runtime/SOURCES`, not any one file.**
|
||||
|
||||
**Build `elb`** (build coordinator, the `.NET`-style incremental linker — compiles each module independently, no monolithic blobs):
|
||||
```bash
|
||||
dist/platform/elc elb.el > dist/elb.c
|
||||
gcc -O2 -I el-compiler/runtime dist/elb.c el-compiler/runtime/el_runtime.c \
|
||||
gcc -O2 -I runtime dist/elb.c $(../scripts/el-runtime-sources.sh runtime) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm -o dist/bin/elb
|
||||
```
|
||||
`epm` and `el-install` are then built via `elb --clean --elc=… --runtime=… --out=…`.
|
||||
@@ -221,10 +235,16 @@ gcc -O2 -I el-compiler/runtime dist/elb.c el-compiler/runtime/el_runtime.c \
|
||||
**Compile + run an El program:**
|
||||
```bash
|
||||
elc src/app.el > dist/app.c
|
||||
cc -std=c11 -O2 -I <lib>/el_runtime -o dist/app dist/app.c <lib>/el_runtime.c -lcurl -lpthread
|
||||
cc -std=c11 -O2 -I <lib> -o dist/app dist/app.c \
|
||||
<lib>/el_runtime.c <lib>/el_seed.c \
|
||||
<lib>/engram_store.c <lib>/engram_vindex.c <lib>/engram_geometry.c \
|
||||
<lib>/engram_reason.c <lib>/engram_verify.c <lib>/engram_cognition.c \
|
||||
<lib>/eg_cosine_batch.c <lib>/eg_cosine_batch_strategy_cpu.c \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm
|
||||
```
|
||||
(Inside this repo, replace the file list with `$(scripts/el-runtime-sources.sh lang/runtime)`. `install.sh` installs all of these into `<lib>`.)
|
||||
|
||||
**Tests** — shell suites `bash tests/{text,calendar,time,html_sanitizer}/run.sh` (with `ELC=$(pwd)/dist/platform/elc EL_HOME=$(pwd)`), plus native suites via `elc --test tests/native/test_*.el` (core, text, string, math, state, time, json, env, fs) compiled and run against `el_runtime.c`.
|
||||
**Tests** — shell suites `bash tests/{text,calendar,time,html_sanitizer}/run.sh` (with `ELC=$(pwd)/dist/platform/elc EL_HOME=$(pwd)`), plus native suites via `elc --test tests/native/test_*.el` (core, text, string, math, state, time, json, env, fs) compiled and run against the full runtime set.
|
||||
|
||||
**Publishing — how downstream gets the SDK.** On push to `main`, `sdk-release.yaml`:
|
||||
1. Publishes a Gitea `latest` release with per-file assets `elc`, `el_runtime.c`, `el_runtime.h`, the SDK tarball, and `el-install`.
|
||||
|
||||
@@ -548,9 +548,13 @@ before `main` does anything. That is the dividend of discovery-precedes-executio
|
||||
|
||||
```
|
||||
# once, ever (or when the runtime/framework changes):
|
||||
cc -c el_runtime.c -o el_runtime.o
|
||||
elc eltest.el > eltest.c && cc -c eltest.c -o eltest.o
|
||||
ar rcs libeltest.a el_runtime.o eltest.o
|
||||
# The runtime is MULTI-FILE — compile every .c named in lang/runtime/SOURCES.
|
||||
# Linking el_runtime.c alone fails: it calls into the six engram sibling TUs.
|
||||
for src in $(scripts/el-runtime-sources.sh lang/runtime); do
|
||||
cc -c "$src" -o "obj/$(basename "${src%.c}").o"
|
||||
done
|
||||
elc eltest.el > eltest.c && cc -c eltest.c -o obj/eltest.o
|
||||
ar rcs libeltest.a obj/*.o
|
||||
|
||||
# per suite:
|
||||
elc --test foo_test.el > foo_test.c # registry + bodies only
|
||||
|
||||
+23
-5
@@ -77,14 +77,30 @@ This is where almost all work belongs. El programs are source files that get com
|
||||
|
||||
This is the self-contained C OS-boundary layer. It provides the `__`-prefixed primitives that compiled El programs call: libcurl HTTP, pthreads, filesystem I/O, arena allocation, etc. It is **not generated** — it is maintained by hand.
|
||||
|
||||
The runtime is native El (`runtime/*.el`) over a C OS-boundary. **Status (verified 2026-08-15):** the migration to a seed-only boundary is *in progress, not done*. Two files exist:
|
||||
- `runtime/el_runtime.c` (~860 KB) — **LIVE**. Holds the engram store (`EngramStore engram_global`) plus the `http_*`/`json_*`/`state_*`/`engram_*` impls. It is the authoritative single-file link target for the compiler, and `tools/install.sh` compiles it into `libel.a`. This is where a new C builtin's *implementation* must currently live to be linkable.
|
||||
- `runtime/el_seed.c` — the intended hand-maintained `__`-prefixed seed (thin wrappers over the above). It is compiled alongside `el_runtime.c` by `tools/install.sh`, but does **not** compile standalone yet (see the build-path caveat under "Rebuilding the Compiler").
|
||||
The runtime is native El (`runtime/*.el`) over a C OS-boundary. **Status (verified 2026-08-16):** the migration to a seed-only boundary is *in progress, not done*.
|
||||
|
||||
**The runtime is MULTI-FILE. There is no single-file link target and there has not been one for months.** The canonical link set is listed once, in **`runtime/SOURCES`**, and printed by `scripts/el-runtime-sources.sh`. It currently holds ten translation units: `el_runtime.c`, `el_seed.c`, the six `engram_*.c` concern files, and `eg_cosine_batch{,_strategy_cpu}.c`.
|
||||
|
||||
- `runtime/el_runtime.c` (~940 KB, 20.5k lines) — **LIVE, and oversized.** It began life on 2026-05-03 as a temporary build shim: it was deleted that afternoon ("runtime is 100% native El") and restored 25 minutes later, explicitly "UNTIL the compiler is updated to emit `#include el_seed.h`". That `until` never arrived, and in the 3.5 months since, the file doubled. **It is not a volatility unit — it is a dumping ground.** ~47.5% of it is engram code that belongs in the six sibling files that already exist. Do not add to it. See "Where a new C builtin goes" below.
|
||||
- `runtime/el_seed.c` — the intended hand-maintained `__`-prefixed seed (thin wrappers over the above).
|
||||
- `runtime/engram_{store,vindex,geometry,reason,verify,cognition}.c` — the engram concerns, each with its own header. `el_runtime.c` `#include`s all six headers and makes hard cross-TU calls into all six.
|
||||
|
||||
> **Linking `el_runtime.c` alone does not work and has not for months.** It fails at `ld` with undefined symbols (`engram_ground_json`, `engram_activate_inner`, `eg_find_relation`, `cog_assert_two_axis`, …). Any recipe, script, or CI step that names `el_runtime.c` by itself is stale — replace it with `$(scripts/el-runtime-sources.sh lang/runtime)`.
|
||||
|
||||
**Only edit these when you genuinely need OS-level access** (raw sockets, GPU calls, new libcurl features, a new engram store op). For everything else, write El.
|
||||
|
||||
#### Where a new C builtin goes
|
||||
|
||||
**Put it in the `.c` that owns the concern — NOT in `el_runtime.c`.**
|
||||
|
||||
*Placement is a link-time concern. The compiler cannot tell which `.c` a symbol came from, and never could.* `builtin_arity` in `el-compiler/src/codegen.el` maps NAME → ARITY INT and nothing else (~413 entries); the El name is emitted as the exact C symbol and resolved by `ld`. Proof, if you want it: `nm lang/dist/platform/elc` on the *shipped* compiler shows `T _engram_geo_reify_index_new` (defined in `engram_geometry.c`), `T _vindex_insert` (`engram_vindex.c`), `T _engram_think` (`engram_cognition.c`), `T _engram_reason_abduce` (`engram_reason.c`). **The shipped compiler is already linked from ten translation units.** A builtin defined in a sibling `.c` is exactly as linkable as one defined in `el_runtime.c`.
|
||||
|
||||
Choose the file by concern: engram store ops → `engram_store.c`; index → `engram_vindex.c`; geometry/priming → `engram_geometry.c`; reasoning → `engram_reason.c`; grounding/consistency → `engram_verify.c`; think/stance → `engram_cognition.c`. **If no existing file owns it, create one** — add the `.c` to `runtime/SOURCES` (one line) and every build path picks it up. For a builtin that belongs to a downstream program rather than the runtime, declare `c_source "path/to/file.c"` in that program's `manifest.el`; `elb` already links it (`parse_manifest_c_sources`, `lang/elb.el:82`).
|
||||
|
||||
> **`el_runtime.c` is on a ratchet and will reject your commit.** `runtime/BUDGET` caps it at its current line count *with no headroom*, and separately caps the number of `engram_*`/`eg_*`/`cog_*` function definitions in it. `scripts/check-runtime-growth.sh` enforces both in CI and in `.githooks/pre-commit`. **The numbers may only ever go down — do not raise them.** Every other runtime file is deliberately uncapped, because that is where the code is supposed to go. When you move code *out*, lower the numbers in the same commit; the guard tells you the new values.
|
||||
|
||||
When you add a C builtin (verbatim-emit recipe — the El name is emitted as the exact C symbol; `builtin_arity` is an arity guard only, not a dispatch table):
|
||||
1. Implement the C function in `el_runtime.c` (and declare it in `el_runtime.h`).
|
||||
1. Implement the C function in the **concern-owning `.c`** (and declare it in that file's `.h`). Add the file to `runtime/SOURCES` if it is new. Only put it in `el_runtime.c` if it is genuinely EL core (val/str/map/list/arena) — that is ~8% of what is in there today.
|
||||
2. Add a `__`-prefixed thin wrapper in `el_seed.c` and declare it in `el_seed.h`.
|
||||
3. Add the name to `builtin_arity` in `el-compiler/src/codegen.el` — add **both** the plain and `__`-prefixed spellings.
|
||||
4. Rebuild the elc binary (see below) and confirm the self-host fixpoint is byte-identical.
|
||||
@@ -125,7 +141,9 @@ diff elc-new.c elc-verify.c # must be identical
|
||||
mv dist/platform/elc-new dist/platform/elc
|
||||
```
|
||||
|
||||
> **Build-path caveat (verified 2026-08-15).** `el_seed.c` is the intended hand-maintained OS-boundary seed, but it does **not** compile standalone under modern clang: it wraps ~16 unprefixed `el_runtime.c` symbols (`http_serve`, `json_*`, `state_*`, `http_response`) without prototypes, and clang treats implicit declarations as errors (C99+). The productionised install (`tools/install.sh`) builds `libel.a` from **both** `el_seed.o` + `el_runtime.o` together, which is why linking succeeds there. To make `el_seed.c` build on its own, add prototypes for those symbols (or `#include "el_runtime.h"`, reconciling the `__http_serve` return-type mismatch first). Until then, `el_runtime.c` is the authoritative single-file link target for the compiler.
|
||||
> **Build-path caveat (verified 2026-08-15).** `el_seed.c` is the intended hand-maintained OS-boundary seed, but it does **not** compile standalone under modern clang: it wraps ~16 unprefixed `el_runtime.c` symbols (`http_serve`, `json_*`, `state_*`, `http_response`) without prototypes, and clang treats implicit declarations as errors (C99+). The productionised install (`tools/install.sh`) builds `libel.a` from **both** `el_seed.o` + `el_runtime.o` together, which is why linking succeeds there. To make `el_seed.c` build on its own, add prototypes for those symbols (or `#include "el_runtime.h"`, reconciling the `__http_serve` return-type mismatch first).
|
||||
>
|
||||
> **There is no single-file link target.** *(Corrected 2026-08-16 — this paragraph previously ended "`el_runtime.c` is the authoritative single-file link target for the compiler". Measured: that is false. Linking `elc-new.c` against `runtime/el_runtime.c` alone fails at `ld` with undefined `engram_ground_json`, `engram_activate_inner`, `eg_find_relation`, `cog_assert_two_axis`, and others, because `el_runtime.c` `#include`s six engram headers and calls into all six sibling `.c` files.)* Link the set in `runtime/SOURCES` via `$(../scripts/el-runtime-sources.sh runtime)`.
|
||||
|
||||
After changing `el_seed.c` only (no El source changes), rebuild downstream programs but do NOT need to rebuild the compiler binary itself — the seed is linked at the application level, not the compiler level.
|
||||
|
||||
|
||||
+39
-9
@@ -49,21 +49,47 @@ download() {
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "${TMP_DIR}"' EXIT
|
||||
|
||||
download "${RELEASE_BASE}/elc" "${TMP_DIR}/elc"
|
||||
download "${RELEASE_BASE}/el_runtime.c" "${TMP_DIR}/el_runtime.c"
|
||||
download "${RELEASE_BASE}/el_runtime.h" "${TMP_DIR}/el_runtime.h"
|
||||
# The runtime is MULTI-FILE. el_runtime.c #includes six engram headers and makes
|
||||
# hard cross-TU calls into all six sibling .c files, so installing el_runtime.c
|
||||
# alone produces a lib/ that CANNOT LINK — `ld` fails with undefined
|
||||
# engram_ground_json / engram_activate_inner / eg_find_relation / cog_assert_two_axis.
|
||||
# This list mirrors lang/runtime/SOURCES (the in-repo source of truth); keep them
|
||||
# in step. install.sh is standalone by design — it runs on machines with no repo
|
||||
# checkout — so it cannot call scripts/el-runtime-sources.sh.
|
||||
RUNTIME_SOURCES=(
|
||||
el_runtime.c el_seed.c
|
||||
engram_store.c engram_vindex.c engram_geometry.c
|
||||
engram_reason.c engram_verify.c engram_cognition.c
|
||||
eg_cosine_batch.c eg_cosine_batch_strategy_cpu.c
|
||||
)
|
||||
RUNTIME_HEADERS=(
|
||||
el_runtime.h el_seed.h
|
||||
engram_store.h engram_vindex.h engram_geometry.h
|
||||
engram_reason.h engram_verify.h engram_cognition.h
|
||||
eg_cosine_batch.h eg_cosine_batch_strategy.h
|
||||
)
|
||||
|
||||
download "${RELEASE_BASE}/elc" "${TMP_DIR}/elc"
|
||||
for f in "${RUNTIME_SOURCES[@]}" "${RUNTIME_HEADERS[@]}"; do
|
||||
download "${RELEASE_BASE}/${f}" "${TMP_DIR}/${f}"
|
||||
done
|
||||
|
||||
# Install
|
||||
install -m 755 "${TMP_DIR}/elc" "${BIN_DIR}/elc"
|
||||
install -m 644 "${TMP_DIR}/el_runtime.c" "${LIB_DIR}/el_runtime.c"
|
||||
install -m 644 "${TMP_DIR}/el_runtime.h" "${LIB_DIR}/el_runtime.h"
|
||||
install -m 755 "${TMP_DIR}/elc" "${BIN_DIR}/elc"
|
||||
for f in "${RUNTIME_SOURCES[@]}" "${RUNTIME_HEADERS[@]}"; do
|
||||
install -m 644 "${TMP_DIR}/${f}" "${LIB_DIR}/${f}"
|
||||
done
|
||||
|
||||
# Record the link set so downstream Makefiles can read it instead of hardcoding.
|
||||
printf '%s\n' "${RUNTIME_SOURCES[@]}" > "${TMP_DIR}/SOURCES"
|
||||
install -m 644 "${TMP_DIR}/SOURCES" "${LIB_DIR}/SOURCES"
|
||||
|
||||
echo
|
||||
echo "==> El SDK installed successfully"
|
||||
echo
|
||||
echo " elc binary : ${BIN_DIR}/elc"
|
||||
echo " runtime : ${LIB_DIR}/el_runtime.c"
|
||||
echo " header : ${LIB_DIR}/el_runtime.h"
|
||||
echo " runtime : ${LIB_DIR}/ (${#RUNTIME_SOURCES[@]} .c files, ${#RUNTIME_HEADERS[@]} headers)"
|
||||
echo " link set : ${LIB_DIR}/SOURCES"
|
||||
echo
|
||||
echo "Add the following to your Makefile to build El programs:"
|
||||
echo
|
||||
@@ -71,10 +97,14 @@ echo " EL_LIB := ${LIB_DIR}"
|
||||
echo " ELC := elc"
|
||||
echo " CC := cc"
|
||||
echo " CFLAGS := -std=c11 -O2 -I\$(EL_LIB)"
|
||||
echo " LDLIBS := -lcurl -lssl -lcrypto -lpthread -lm"
|
||||
echo
|
||||
echo " # The runtime is multi-file — link the whole set, not el_runtime.c alone."
|
||||
echo " EL_RUNTIME := \$(addprefix \$(EL_LIB)/,\$(shell cat \$(EL_LIB)/SOURCES))"
|
||||
echo
|
||||
echo " dist/myapp.c: src/myapp.el"
|
||||
echo " \t\$(ELC) src/myapp.el > dist/myapp.c"
|
||||
echo
|
||||
echo " dist/myapp: dist/myapp.c"
|
||||
echo " \t\$(CC) \$(CFLAGS) -o dist/myapp dist/myapp.c \$(EL_LIB)/el_runtime.c -lcurl -lpthread"
|
||||
echo " \t\$(CC) \$(CFLAGS) -o dist/myapp dist/myapp.c \$(EL_RUNTIME) \$(LDLIBS)"
|
||||
echo
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# BUDGET — a RATCHET on lang/runtime/el_runtime.c. Enforced by
|
||||
# scripts/check-runtime-growth.sh. These numbers may only ever go DOWN.
|
||||
#
|
||||
# WHY THIS FILE EXISTS
|
||||
# --------------------
|
||||
# scripts/check-single-runtime.sh guards against el_runtime.c being COPIED.
|
||||
# Nothing guarded against it GROWING. It grew from 10,607 lines to 20,527 —
|
||||
# 94% — in 3.5 months, while under an explicit commit-message promise that it
|
||||
# was a temporary shim about to be deleted.
|
||||
#
|
||||
# It grew because lang/AGENTS.md told every agent to grow it: it claimed
|
||||
# el_runtime.c was "the authoritative single-file link target" and that a new
|
||||
# C builtin "must live there to be linkable". That is false — placement is a
|
||||
# link-time concern, `builtin_arity` is an arity guard not a dispatch table,
|
||||
# and the shipped elc already links from ten translation units. The claim is
|
||||
# corrected, and this file is the mechanism that keeps it corrected.
|
||||
#
|
||||
# THIS IS A RATCHET, NOT A LIMIT
|
||||
# ------------------------------
|
||||
# The budget is set at the CURRENT size. There is no headroom, deliberately.
|
||||
# The file cannot grow by even one line. Any new code goes in the .c that owns
|
||||
# the concern — that is the whole point, and every other runtime file is
|
||||
# deliberately UNCAPPED.
|
||||
#
|
||||
# When you move code OUT, lower the number in the same commit. The guard tells
|
||||
# you to when you have earned it.
|
||||
#
|
||||
# FORMAT: <key> <value> — `#` comments and blank lines ignored.
|
||||
|
||||
# Maximum lines in lang/runtime/el_runtime.c.
|
||||
# 2026-08-16: 20,527 — the high-water mark, ratcheted from here.
|
||||
max_lines 20527
|
||||
|
||||
# Maximum top-level engram/eg_/cog_ function definitions in el_runtime.c.
|
||||
# ~47.5% of the file is engram code, and engram already owns six dedicated
|
||||
# sibling files (engram_{store,vindex,geometry,reason,verify,cognition}.c).
|
||||
# Every one of these belongs in one of them. This is the Stage 3 scoreboard.
|
||||
# 2026-08-16: 279.
|
||||
max_engram_fns 279
|
||||
@@ -0,0 +1,52 @@
|
||||
# SOURCES — the canonical El runtime link set.
|
||||
#
|
||||
# THIS FILE IS THE SINGLE SOURCE OF TRUTH for "what do I compile and link to
|
||||
# get the El runtime". Every build path — CI, install.sh, the SDK release, the
|
||||
# docs, elb, the engram test harnesses — reads it via scripts/el-runtime-sources.sh
|
||||
# instead of hardcoding its own list.
|
||||
#
|
||||
# WHY THIS FILE EXISTS
|
||||
# --------------------
|
||||
# The runtime has been multi-translation-unit since the engram siblings landed:
|
||||
# el_runtime.c #includes engram_{store,vindex,geometry,reason,verify,cognition}.h
|
||||
# and makes hard cross-TU calls into all six. Linking el_runtime.c ALONE has been
|
||||
# broken since then — `ld` fails with undefined symbols (engram_ground_json,
|
||||
# engram_activate_inner, eg_find_relation, cog_assert_two_axis, ...).
|
||||
#
|
||||
# It stayed broken because the link set was written out longhand in ~8 different
|
||||
# places, each of which drifted independently. A list copied 8 times is a list
|
||||
# that is wrong in 8 places. It is now written once, here.
|
||||
#
|
||||
# HOW TO USE IT
|
||||
# -------------
|
||||
# scripts/el-runtime-sources.sh # bare names, one per line
|
||||
# scripts/el-runtime-sources.sh lang/runtime # prefixed with a directory
|
||||
# cc ... $(scripts/el-runtime-sources.sh lang/runtime) -lcurl -lssl -lcrypto -lpthread -lm
|
||||
#
|
||||
# ADDING A FILE
|
||||
# -------------
|
||||
# Add the .c here and it is picked up by every build path at once. That is the
|
||||
# point: a new concern gets its own translation unit and costs one line, instead
|
||||
# of being appended to el_runtime.c because appending was the cheaper edit.
|
||||
#
|
||||
# Order is link order. Blank lines and `#` comments are ignored.
|
||||
|
||||
# --- EL core language runtime -------------------------------------------------
|
||||
el_runtime.c
|
||||
el_seed.c
|
||||
|
||||
# --- Engram: store, index, geometry, reasoning, verification, cognition -------
|
||||
# These are the six concern-owned translation units el_runtime.c calls into.
|
||||
engram_store.c
|
||||
engram_vindex.c
|
||||
engram_geometry.c
|
||||
engram_reason.c
|
||||
engram_verify.c
|
||||
engram_cognition.c
|
||||
|
||||
# --- Vector math: batch cosine + its CPU strategy ----------------------------
|
||||
# The ggml strategy (eg_cosine_batch_strategy_ggml.c) is an OPTIONAL swap-in and
|
||||
# is deliberately NOT in the default set — it needs ggml headers. Link it in
|
||||
# place of the cpu strategy when you have them.
|
||||
eg_cosine_batch.c
|
||||
eg_cosine_batch_strategy_cpu.c
|
||||
+11
-1
@@ -697,12 +697,22 @@ Every compiled program links against:
|
||||
- `el_runtime.h` — declaration header
|
||||
- `el_runtime.c` — implementation
|
||||
|
||||
The runtime is **multi-file**: `el_runtime.c` `#include`s the six `engram_*.h`
|
||||
headers and calls into all six sibling translation units, so linking it alone
|
||||
fails at `ld`. The canonical link set is `<runtime-dir>/SOURCES`.
|
||||
|
||||
Compile command:
|
||||
|
||||
```
|
||||
cc -std=c11 -I<runtime-dir> -o <prog> <prog>.c el_runtime.c
|
||||
cc -std=c11 -I<runtime-dir> -o <prog> <prog>.c \
|
||||
$(sed 's|^|<runtime-dir>/|' <runtime-dir>/SOURCES) \
|
||||
-lcurl -lssl -lcrypto -lpthread -lm
|
||||
```
|
||||
|
||||
Inside this repo, `scripts/el-runtime-sources.sh <runtime-dir>` prints that list
|
||||
(it strips comments; the raw `sed` above works against an installed SDK's
|
||||
`SOURCES`, which `install.sh` writes comment-free).
|
||||
|
||||
### 13.4 Output Format
|
||||
|
||||
```c
|
||||
|
||||
Executable
+161
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env bash
|
||||
# check-runtime-growth.sh — GROWTH guard for lang/runtime/el_runtime.c.
|
||||
#
|
||||
# Sibling to scripts/check-single-runtime.sh. That one guards against the file
|
||||
# being COPIED (a lagging fork shipped to prod and dropped learned hebb edges).
|
||||
# Nothing guarded against it GROWING — so it grew from 10,607 to 20,527 lines in
|
||||
# 3.5 months, while under an explicit commit-message promise that it was a
|
||||
# temporary shim about to be deleted.
|
||||
#
|
||||
# This enforces the RATCHET in lang/runtime/BUDGET: the numbers may only go down.
|
||||
#
|
||||
# It also checks two invariants that keep the multi-file runtime honest:
|
||||
# * every .c in lang/runtime/ is either in SOURCES or explicitly optional
|
||||
# * lang/install.sh's hardcoded download list matches SOURCES
|
||||
#
|
||||
# Exits non-zero on any violation. Run from anywhere; resolves the repo root.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
RUNTIME_DIR="lang/runtime"
|
||||
TARGET="$RUNTIME_DIR/el_runtime.c"
|
||||
BUDGET_FILE="$RUNTIME_DIR/BUDGET"
|
||||
SOURCES_FILE="$RUNTIME_DIR/SOURCES"
|
||||
|
||||
FAIL=0
|
||||
|
||||
for f in "$TARGET" "$BUDGET_FILE" "$SOURCES_FILE"; do
|
||||
if [ ! -f "$f" ]; then
|
||||
echo "FATAL: required file missing: $f" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
budget() {
|
||||
local key="$1"
|
||||
sed -e 's/#.*//' "$BUDGET_FILE" | awk -v k="$key" '$1==k {print $2; found=1} END{if(!found) exit 1}'
|
||||
}
|
||||
|
||||
MAX_LINES="$(budget max_lines)" || { echo "FATAL: no 'max_lines' in $BUDGET_FILE" >&2; exit 1; }
|
||||
MAX_ENGRAM="$(budget max_engram_fns)" || { echo "FATAL: no 'max_engram_fns' in $BUDGET_FILE" >&2; exit 1; }
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# The message every failure prints. The guard that existed before this one told
|
||||
# you what was wrong but not where the code should go — so it was easy to
|
||||
# "fix" by arguing with the guard. This one names the destination.
|
||||
# ---------------------------------------------------------------------------
|
||||
where_it_goes() {
|
||||
cat >&2 <<'MSG'
|
||||
|
||||
WHERE THE CODE ACTUALLY GOES
|
||||
----------------------------
|
||||
Placement is a LINK-TIME concern. The compiler cannot tell which .c a symbol
|
||||
came from: `builtin_arity` in el-compiler/src/codegen.el maps NAME -> ARITY
|
||||
INT only, the El name is emitted as the exact C symbol, and `ld` resolves it.
|
||||
The SHIPPED compiler already links from ten translation units — check it:
|
||||
|
||||
nm lang/dist/platform/elc | grep -E 'T _(engram_think|vindex_insert)'
|
||||
|
||||
So a builtin defined in a sibling .c is EXACTLY as linkable as one defined in
|
||||
el_runtime.c. Pick the file that owns the concern:
|
||||
|
||||
engram store ops ......... lang/runtime/engram_store.c
|
||||
ANN / vector index ....... lang/runtime/engram_vindex.c
|
||||
geometry, priming ........ lang/runtime/engram_geometry.c
|
||||
reasoning operators ...... lang/runtime/engram_reason.c
|
||||
grounding, consistency ... lang/runtime/engram_verify.c
|
||||
think, stance ............ lang/runtime/engram_cognition.c
|
||||
|
||||
No existing file owns it? Create one, add ONE line to lang/runtime/SOURCES,
|
||||
and every build path picks it up. Every runtime file EXCEPT el_runtime.c is
|
||||
deliberately uncapped.
|
||||
|
||||
Belongs to a downstream program, not the runtime? Declare
|
||||
`c_source "path/to/file.c"` in that program's manifest.el — elb already links
|
||||
it (parse_manifest_c_sources, lang/elb.el:82).
|
||||
|
||||
See lang/AGENTS.md "Where a new C builtin goes".
|
||||
MSG
|
||||
}
|
||||
|
||||
# --- 1. Line-count ratchet ---------------------------------------------------
|
||||
LINES="$(wc -l < "$TARGET" | tr -d ' ')"
|
||||
if [ "$LINES" -gt "$MAX_LINES" ]; then
|
||||
echo "FAIL: $TARGET grew past its budget." >&2
|
||||
echo " now: $LINES lines" >&2
|
||||
echo " budget: $MAX_LINES lines (lang/runtime/BUDGET: max_lines)" >&2
|
||||
echo " over by: $((LINES - MAX_LINES))" >&2
|
||||
echo "" >&2
|
||||
echo "This file is a 2026-05-03 build shim that was scheduled for deletion and" >&2
|
||||
echo "never retired. It does not get to grow. Do NOT raise the budget." >&2
|
||||
where_it_goes
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
# --- 2. Engram-concern ratchet ----------------------------------------------
|
||||
# ~47.5% of el_runtime.c is engram code, and engram already owns six sibling
|
||||
# files. This count is the Stage 3 scoreboard: it may only go down.
|
||||
ENGRAM_FNS="$(grep -cE '^(static +)?[A-Za-z_][A-Za-z0-9_ *]*\b(engram|eg|cog)_[a-z0-9_]+\(' "$TARGET" || true)"
|
||||
if [ "$ENGRAM_FNS" -gt "$MAX_ENGRAM" ]; then
|
||||
echo "FAIL: new engram/eg_/cog_ function(s) added to $TARGET." >&2
|
||||
echo " now: $ENGRAM_FNS definitions" >&2
|
||||
echo " budget: $MAX_ENGRAM (lang/runtime/BUDGET: max_engram_fns)" >&2
|
||||
echo "" >&2
|
||||
echo "Engram code belongs in the six engram_*.c files that already exist." >&2
|
||||
where_it_goes
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
# --- 3. Ratchet-down nudge (advisory, never fails) ---------------------------
|
||||
if [ "$LINES" -lt "$MAX_LINES" ]; then
|
||||
echo "NOTE: $TARGET is $((MAX_LINES - LINES)) lines under budget — lower" >&2
|
||||
echo " 'max_lines' to $LINES in $BUDGET_FILE in this same commit, so the" >&2
|
||||
echo " ground you gained cannot be quietly given back." >&2
|
||||
fi
|
||||
if [ "$ENGRAM_FNS" -lt "$MAX_ENGRAM" ]; then
|
||||
echo "NOTE: $((MAX_ENGRAM - ENGRAM_FNS)) engram fn(s) moved out — lower" >&2
|
||||
echo " 'max_engram_fns' to $ENGRAM_FNS in $BUDGET_FILE in this same commit." >&2
|
||||
fi
|
||||
|
||||
# --- 4. Every runtime .c is accounted for ------------------------------------
|
||||
# A new .c that is in neither SOURCES nor the optional list will not be
|
||||
# compiled by any build path — it would be silently dead. Catch that here.
|
||||
OPTIONAL_RE='^(el_android|el_gtk4|el_lvgl|el_sdl2|el_win32|el_runtime_win32|eg_cosine_batch_strategy_ggml|vindex_bench)\.c$'
|
||||
mapfile -t IN_SOURCES < <(scripts/el-runtime-sources.sh)
|
||||
for path in "$RUNTIME_DIR"/*.c; do
|
||||
base="$(basename "$path")"
|
||||
if printf '%s\n' "${IN_SOURCES[@]}" | grep -qxF "$base"; then continue; fi
|
||||
if [[ "$base" =~ $OPTIONAL_RE ]]; then continue; fi
|
||||
echo "FAIL: $path is in neither lang/runtime/SOURCES nor the platform-optional" >&2
|
||||
echo " list in this guard. It will not be compiled by any build path." >&2
|
||||
echo " Add it to SOURCES (one line), or add it to OPTIONAL_RE here if it" >&2
|
||||
echo " is a platform/strategy variant that is linked in deliberately." >&2
|
||||
FAIL=1
|
||||
done
|
||||
|
||||
# --- 5. install.sh must not drift from SOURCES -------------------------------
|
||||
# install.sh runs on machines with no repo checkout, so it cannot call
|
||||
# el-runtime-sources.sh and has to hardcode the list. That copy is exactly the
|
||||
# kind of duplicate that silently drifted before — so it is checked, not trusted.
|
||||
INSTALL_SH="lang/install.sh"
|
||||
if [ -f "$INSTALL_SH" ]; then
|
||||
EXPECTED="$(scripts/el-runtime-sources.sh | sort)"
|
||||
ACTUAL="$(sed -n '/^RUNTIME_SOURCES=(/,/^)/p' "$INSTALL_SH" \
|
||||
| grep -oE '[a-z_0-9]+\.c' | sort)"
|
||||
if [ "$EXPECTED" != "$ACTUAL" ]; then
|
||||
echo "FAIL: $INSTALL_SH RUNTIME_SOURCES has drifted from $SOURCES_FILE." >&2
|
||||
echo " Only in SOURCES: $(comm -23 <(echo "$EXPECTED") <(echo "$ACTUAL") | tr '\n' ' ')" >&2
|
||||
echo " Only in install.sh: $(comm -13 <(echo "$EXPECTED") <(echo "$ACTUAL") | tr '\n' ' ')" >&2
|
||||
echo " An SDK that ships the wrong set produces a lib/ that cannot link." >&2
|
||||
FAIL=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$FAIL" -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK: el_runtime.c within budget ($LINES/$MAX_LINES lines, $ENGRAM_FNS/$MAX_ENGRAM engram fns);"
|
||||
echo " runtime sources accounted for; install.sh in step with SOURCES."
|
||||
@@ -81,14 +81,14 @@ fi
|
||||
echo "OK: single canonical runtime source — $CANONICAL (no un-allowlisted forks)."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# CI wire-in:
|
||||
# foundation/el .gitea/workflows/ci-dev.yaml, ci-stage.yaml, sdk-release.yaml
|
||||
# Add an early step (before the build/publish steps). It must run from the
|
||||
# REPO ROOT, so override the job's `defaults.run.working-directory: lang`:
|
||||
# CI wire-in — DONE (2026-08-16). This block used to describe the wire-in as a
|
||||
# TODO, and it had never been done: the guard existed but ran nowhere, so it
|
||||
# caught nothing for as long as it has been in the tree. It is now an early step
|
||||
# in ci-dev.yaml, ci-stage.yaml and sdk-release.yaml (each with
|
||||
# `working-directory: ${{ github.workspace }}`, since the jobs default to lang/),
|
||||
# and it runs in .githooks/pre-commit.
|
||||
#
|
||||
# - name: Guard - single canonical runtime source
|
||||
# working-directory: ${{ github.workspace }}
|
||||
# run: bash scripts/check-single-runtime.sh
|
||||
#
|
||||
# Also add to .githooks/pre-commit so drift is caught before it is committed.
|
||||
# Its sibling scripts/check-runtime-growth.sh is wired in at the same points and
|
||||
# guards the other half of the problem: this script stops el_runtime.c being
|
||||
# COPIED, that one stops it GROWING.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Executable
+73
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bash
|
||||
# el-runtime-sources.sh — print the canonical El runtime link set.
|
||||
#
|
||||
# Reads lang/runtime/SOURCES (the single source of truth) and prints one path
|
||||
# per line, optionally prefixed with a directory. Use it anywhere a link line
|
||||
# would otherwise spell the runtime .c files out longhand:
|
||||
#
|
||||
# cc -std=c11 -O2 -I lang/runtime -o app app.c \
|
||||
# $(scripts/el-runtime-sources.sh lang/runtime) \
|
||||
# -lcurl -lssl -lcrypto -lpthread -lm
|
||||
#
|
||||
# Options:
|
||||
# --headers print the shipped headers instead of the .c sources
|
||||
# --check verify every listed file exists; exit non-zero if any is missing
|
||||
#
|
||||
# WHY: linking el_runtime.c alone has been broken since el_runtime.c started
|
||||
# calling into the engram siblings. The list was duplicated across ~8 build
|
||||
# paths and drifted. It lives in exactly one place now — see lang/runtime/SOURCES.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SOURCES="${ROOT}/lang/runtime/SOURCES"
|
||||
|
||||
if [ ! -f "$SOURCES" ]; then
|
||||
echo "FATAL: canonical runtime source list missing: $SOURCES" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MODE="sources"
|
||||
PREFIX=""
|
||||
CHECK=0
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--headers) MODE="headers" ;;
|
||||
--check) CHECK=1 ;;
|
||||
-*) echo "el-runtime-sources.sh: unknown option: $arg" >&2; exit 2 ;;
|
||||
*) PREFIX="${arg%/}/" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Strip comments and blank lines. Order is preserved — it is link order.
|
||||
mapfile -t FILES < <(sed -e 's/#.*//' -e 's/[[:space:]]*$//' "$SOURCES" | grep -v '^$')
|
||||
|
||||
if [ "${#FILES[@]}" -eq 0 ]; then
|
||||
echo "FATAL: $SOURCES lists no sources" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "headers" ]; then
|
||||
# Every .c's matching .h, plus the headers that carry no .c of their own.
|
||||
HDRS=()
|
||||
for f in "${FILES[@]}"; do
|
||||
h="${f%.c}.h"
|
||||
[ -f "${ROOT}/lang/runtime/${h}" ] && HDRS+=("$h")
|
||||
done
|
||||
# Interface-only headers: no matching .c, but required to compile against.
|
||||
for h in eg_cosine_batch_strategy.h el_native_target.h el_platform_win.h; do
|
||||
[ -f "${ROOT}/lang/runtime/${h}" ] && HDRS+=("$h")
|
||||
done
|
||||
FILES=("${HDRS[@]}")
|
||||
fi
|
||||
|
||||
RC=0
|
||||
for f in "${FILES[@]}"; do
|
||||
if [ "$CHECK" -eq 1 ] && [ ! -f "${ROOT}/lang/runtime/${f}" ]; then
|
||||
echo "MISSING: lang/runtime/${f} (listed in lang/runtime/SOURCES)" >&2
|
||||
RC=1
|
||||
fi
|
||||
printf '%s%s\n' "$PREFIX" "$f"
|
||||
done
|
||||
|
||||
exit $RC
|
||||
Reference in New Issue
Block a user