All checks were successful
The freestanding build (-DAKERR_USE_STDLIB=OFF) did not compile at all: bool, PATH_MAX and NULL were used unconditionally in the public header but only included under the stdlib branch, and the CMake option was pasted straight into a preprocessor definition, so a non-numeric cache spelling (-DAKERR_USE_STDLIB=ON) silently evaluated to 0. - Normalize AKERR_USE_STDLIB to a plain 1/0 in CMake before stamping it, and use a consistent '#if AKERR_USE_STDLIB' everywhere it is tested. - Include <stdbool.h>/<stddef.h> unconditionally (freestanding-safe); keep <stdlib.h>/<string.h>/<stdio.h> behind AKERR_USE_STDLIB; move <limits.h> out of the public header into src/error.c, its only user. - Define the freestanding runtime contract: AKERR_RUNTIME_HEADER must name a header providing exit, memset, snprintf, strcmp, strlen and strncpy when AKERR_USE_STDLIB is OFF, or the header #errors naming them. Add cmake/akerr_default_runtime.h, a libc-backed convenience default so this repo's own OFF build and tests work out of the box. - Route ENSURE_ERROR_READY's pool-exhaustion path through akerr_exit() instead of a direct exit(1). Deliberate behavior change: that exit code moves from 1 to AKERR_EXIT_STATUS_UNREPRESENTABLE (125), the same sentinel every other unrepresentable status already uses. Documented in docs/building.md and UPGRADING.md. Not an ABI break. - Retire PATH_MAX: AKERR_MAX_ERROR_FNAME_LENGTH is now stamped by scripts/generrno.sh from a new AKERR_MAX_ERROR_FNAME_LENGTH cache variable, defaulting to 4096 (PATH_MAX on Linux/glibc) so sizeof(akerr_ErrorContext) and the soname are unchanged. Rewrite the now-stale PATH_MAX justification in src/lock.h's feature-test-macro comment. - Fail the configure with a FATAL_ERROR, not a warning, when AKERR_USE_STDLIB=OFF and AKERR_THREADS would resolve to pthread, naming -DAKERR_THREADS=none as the fix. - Keep the generated errno table (errno.c) out of the OFF build; skip the 'errno --list' shellout in scripts/generrno.sh under OFF and stamp AKERR_LAST_ERRNO_VALUE from a new fallback cache variable (default 133, Linux's EHWPOISON) instead. - Update docs/building.md: drop the known-defect paragraph, fix sprintf -> snprintf, add size_t, drop PATH_MAX, and document the new options and the exit-code change. - Guard tests/err_errno.c's registered-name assertion behind AKERR_USE_STDLIB: akerr_init_errno() is not called when it is OFF. - Add a CI job that configures/builds/tests AKERR_USE_STDLIB=OFF with AKERR_THREADS=none, plus a compile-only -nostdinc -ffreestanding check of tests/freestanding_fixture.c against the generated header. Bump the project version to 2.0.2 (no ABI break: soname and struct layout are unchanged). Verified locally: OFF+none configures and builds clean with all tests passing; ON and the plain default build both build and pass their full test suites (37/37); OFF with the default/auto thread backend fails configure with a message naming -DAKERR_THREADS=none; sizeof(akerr_ErrorContext) is unchanged (37296 bytes, fname/function still 4096 each) versus the pre-change tree. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
75 lines
3.3 KiB
Bash
75 lines
3.3 KiB
Bash
#!/bin/bash
|
|
|
|
srcdir=$1
|
|
outdir=$2
|
|
# 1 when the library was configured with a threading backend, 0 for
|
|
# -DAKERR_THREADS=none. Stamped into the header so a consumer cannot disagree
|
|
# with the library about whether it locks and whether its per-thread state is
|
|
# thread local. Defaults to 1 for a hand-run of this script.
|
|
thread_safe=${3:-1}
|
|
# 1 for a normal (libc-linked) build, 0 for -DAKERR_USE_STDLIB=OFF. The
|
|
# freestanding build cannot shell out to `errno --list` (moreutils) or
|
|
# #include <errno.h>, so it skips the errno scrape entirely and stamps
|
|
# AKERR_LAST_ERRNO_VALUE from a fixed fallback instead. Defaults to 1 for a
|
|
# hand-run of this script.
|
|
use_stdlib=${4:-1}
|
|
# AKERR_LAST_ERRNO_VALUE to stamp when use_stdlib is 0. Defaults to 133
|
|
# (Linux's EHWPOISON) so the reserved band assertion in akerror.tmpl.h still
|
|
# holds.
|
|
last_errno_fallback=${5:-133}
|
|
# Bytes reserved for the fname/function fields of akerr_ErrorContext. Defaults
|
|
# to 4096 (PATH_MAX on Linux/glibc) so sizeof(akerr_ErrorContext) and the
|
|
# soname stay unchanged from before this became a build option.
|
|
max_error_fname_length=${6:-4096}
|
|
|
|
if [ "${thread_safe}" != "0" ] && [ "${thread_safe}" != "1" ]; then
|
|
echo "$0: thread-safe argument must be 0 or 1, got '${thread_safe}'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${use_stdlib}" != "0" ] && [ "${use_stdlib}" != "1" ]; then
|
|
echo "$0: use-stdlib argument must be 0 or 1, got '${use_stdlib}'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p ${outdir}/src
|
|
mkdir -p ${outdir}/include
|
|
rm -f ${outdir}/src/errno.c
|
|
|
|
if [ "${use_stdlib}" = "1" ]; then
|
|
echo "#include <akerror.h>" >> ${outdir}/src/errno.c
|
|
echo "#include <errno.h>" >> ${outdir}/src/errno.c
|
|
cat >> ${outdir}/src/errno.c <<'EOF'
|
|
|
|
/*
|
|
* These names belong to the library's own reserved band, and this runs from
|
|
* akerr_init(), which has no caller to raise into -- so it goes through
|
|
* __akerr_name_library_status(), which reports a refusal and terminates rather
|
|
* than leaving every later stack trace to print "Unknown Error" for an errno.
|
|
* Keeping the branch in src/error.c also keeps this generated file free of
|
|
* control flow no test can reach.
|
|
*/
|
|
EOF
|
|
echo "void akerr_init_errno(void) {" >> ${outdir}/src/errno.c
|
|
maxval=$(errno --list | cut -d ' ' -f 2 | sort -g | tail -n 1)
|
|
errno --list | while read LINE; do
|
|
define=$(echo "$LINE" | cut -d ' ' -f 1);
|
|
value=$(echo "$LINE" | cut -d ' ' -f 2);
|
|
desc=$(echo "$LINE" | cut -d ' ' -f 3-);
|
|
echo " __akerr_name_library_status(${define}, \"${desc}\");" >> ${outdir}/src/errno.c ;
|
|
done;
|
|
echo "}" >> ${outdir}/src/errno.c
|
|
else
|
|
# Freestanding: no `errno --list` shellout (requires moreutils and
|
|
# <errno.h>, neither freestanding-safe), and no errno.c at all -- CMake
|
|
# does not compile it into the library under AKERR_USE_STDLIB=OFF. Still
|
|
# write a stub so the OUTPUT this rule promises always exists.
|
|
echo "/* AKERR_USE_STDLIB=OFF: no errno table generated. */" >> ${outdir}/src/errno.c
|
|
maxval=${last_errno_fallback}
|
|
fi
|
|
|
|
sed -e "s/#define AKERR_LAST_ERRNO_VALUE .*/#define AKERR_LAST_ERRNO_VALUE ${maxval}/" \
|
|
-e "s/#define AKERR_THREAD_SAFE .*/#define AKERR_THREAD_SAFE ${thread_safe}/" \
|
|
-e "s/#define AKERR_MAX_ERROR_FNAME_LENGTH .*/#define AKERR_MAX_ERROR_FNAME_LENGTH ${max_error_fname_length}/" \
|
|
${srcdir}/include/akerror.tmpl.h > ${outdir}/include/akerror.h
|