summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-04-18 15:27:27 -0400
committerTavian Barnes <tavianator@tavianator.com>2024-04-19 15:50:45 -0400
commit0035cc4ff492cab91adeb49d0c577fe5982064bd (patch)
tree6fcd6b48b00ceb4ae696a5a3d9d03e23c9676a70
parentd7d5e1c474e4e110172b7180de9c41e5ebbf93f6 (diff)
downloadbfs-0035cc4ff492cab91adeb49d0c577fe5982064bd.tar.xz
config: Check for program_invocation_short_name
This lets us pick it up on musl too, since there's no __MUSL__ macro. Link: https://wiki.musl-libc.org/faq#Q:-Why-is-there-no-%3Ccode%3E__MUSL__%3C/code%3E-macro?
-rwxr-xr-xconfig/cc-define.sh19
-rw-r--r--config/config.mk11
-rw-r--r--config/flags.mk1
-rw-r--r--config/getprogname-gnu.c9
-rw-r--r--config/getprogname.c9
-rw-r--r--config/header.mk38
-rw-r--r--config/pkg.mk4
-rw-r--r--config/prelude.mk3
-rw-r--r--src/bfstd.c6
-rw-r--r--src/prelude.h2
10 files changed, 96 insertions, 6 deletions
diff --git a/config/cc-define.sh b/config/cc-define.sh
new file mode 100755
index 0000000..edb5c87
--- /dev/null
+++ b/config/cc-define.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# Copyright © Tavian Barnes <tavianator@tavianator.com>
+# SPDX-License-Identifier: 0BSD
+
+# Output a C preprocessor definition based on whether a C source file could be
+# compiled successfully
+
+set -eu
+
+SLUG="${1#config/}"
+SLUG="${SLUG%.c}"
+MACRO="BFS_HAS_$(printf '%s' "$SLUG" | tr 'a-z-' 'A-Z_')"
+
+if config/cc.sh "$1"; then
+ printf '#define %s true\n' "$MACRO"
+else
+ printf '#define %s false\n' "$MACRO"
+fi
diff --git a/config/config.mk b/config/config.mk
index 5a6f8d2..5750b49 100644
--- a/config/config.mk
+++ b/config/config.mk
@@ -6,6 +6,10 @@
include config/prelude.mk
include config/exports.mk
+# All configuration steps
+config: ${CONFIG} ${GEN}/config.h
+.PHONY: config
+
# Makefile fragments generated by `make config`
MKS := \
${GEN}/vars.mk \
@@ -17,7 +21,7 @@ MKS := \
${CONFIG}: ${MKS}
${MSG} "[ GEN] ${TGT}"
@printf '# %s\n' "${TGT}" >$@
- @printf 'include $${GEN}/%s\n' ${.ALLSRC:${GEN}/%=%} >>$@
+ @printf 'include $${GEN}/%s\n' ${MKS:${GEN}/%=%} >>$@
${VCAT} ${CONFIG}
.PHONY: ${CONFIG}
@@ -67,3 +71,8 @@ ${GEN}/pkgs.mk: ${PKG_MKS}
${PKG_MKS}: ${GEN}/flags.mk
@+${MAKE} -sf config/pkg.mk TARGET=$@
.PHONY: ${PKG_MKS}
+
+# Compile-time feature detection
+${GEN}/config.h: ${CONFIG}
+ @+${MAKE} -sf config/header.mk $@
+.PHONY: ${GEN}/config.h
diff --git a/config/flags.mk b/config/flags.mk
index d02cc8b..9959d10 100644
--- a/config/flags.mk
+++ b/config/flags.mk
@@ -29,6 +29,7 @@ export XLDLIBS=${LDLIBS}
# Immutable flags
export BFS_CPPFLAGS= \
-Isrc \
+ -I${GEN} \
-D__EXTENSIONS__ \
-D_ATFILE_SOURCE \
-D_BSD_SOURCE \
diff --git a/config/getprogname-gnu.c b/config/getprogname-gnu.c
new file mode 100644
index 0000000..6b97c5e
--- /dev/null
+++ b/config/getprogname-gnu.c
@@ -0,0 +1,9 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <errno.h>
+
+int main(void) {
+ const char *str = program_invocation_short_name;
+ return str[0];
+}
diff --git a/config/getprogname.c b/config/getprogname.c
new file mode 100644
index 0000000..83dc8e8
--- /dev/null
+++ b/config/getprogname.c
@@ -0,0 +1,9 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <stdlib.h>
+
+int main(void) {
+ const char *str = getprogname();
+ return str[0];
+}
diff --git a/config/header.mk b/config/header.mk
new file mode 100644
index 0000000..3a1271e
--- /dev/null
+++ b/config/header.mk
@@ -0,0 +1,38 @@
+# Copyright © Tavian Barnes <tavianator@tavianator.com>
+# SPDX-License-Identifier: 0BSD
+
+# Makefile that generates gen/config.h
+
+include config/prelude.mk
+include ${GEN}/config.mk
+include config/exports.mk
+
+# All header fragments we generate
+HEADERS := \
+ ${GEN}/getprogname.h \
+ ${GEN}/getprogname-gnu.h
+
+${GEN}/config.h: ${HEADERS}
+ ${MSG} "[ GEN] ${TGT}"
+ printf '// %s\n' "${TGT}" >$@
+ printf '#ifndef BFS_CONFIG_H\n' >>$@
+ printf '#define BFS_CONFIG_H\n' >>$@
+ cat ${.ALLSRC} >>$@
+ printf '#endif // BFS_CONFIG_H\n' >>$@
+ cat ${.ALLSRC:%=%.log} >$@.log
+ ${RM} ${.ALLSRC} ${.ALLSRC:%=%.log}
+ ${VCAT} $@
+.PHONY: ${GEN}/config.h
+
+# The C source file to attempt to compile
+CSRC = ${@:${GEN}/%.h=config/%.c}
+
+${HEADERS}::
+ config/cc-define.sh ${CSRC} >$@ 2>$@.log
+ if ! [ "${IS_V}" ]; then \
+ if grep -q 'true$$' $@; then \
+ printf '[ CC ] %-${MSG_WIDTH}s ✔\n' ${CSRC}; \
+ else \
+ printf '[ CC ] %-${MSG_WIDTH}s ✘\n' ${CSRC}; \
+ fi; \
+ fi
diff --git a/config/pkg.mk b/config/pkg.mk
index 6f868be..fafe562 100644
--- a/config/pkg.mk
+++ b/config/pkg.mk
@@ -17,7 +17,7 @@ default::
@if [ "${IS_V}" ]; then \
cat ${TARGET}; \
elif grep -q PKGS ${TARGET}; then \
- printf '[ GEN] %-18s ✔\n' ${SHORT}; \
+ printf '[ GEN] %-${MSG_WIDTH}s ✔\n' ${SHORT}; \
else \
- printf '[ GEN] %-18s ✘\n' ${SHORT}; \
+ printf '[ GEN] %-${MSG_WIDTH}s ✘\n' ${SHORT}; \
fi
diff --git a/config/prelude.mk b/config/prelude.mk
index dbc6875..0ac5fde 100644
--- a/config/prelude.mk
+++ b/config/prelude.mk
@@ -109,6 +109,9 @@ MSG = @msg() { \
}; \
msg
+# Maximum width of a short message, to align the [X]
+MSG_WIDTH := 24
+
# cat a file if V=1
VCAT,y := @cat
VCAT, := @:
diff --git a/src/bfstd.c b/src/bfstd.c
index e1b4804..e8a927a 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -186,10 +186,10 @@ char *xgetdelim(FILE *file, char delim) {
const char *xgetprogname(void) {
const char *cmd = NULL;
-#if __GLIBC__
- cmd = program_invocation_short_name;
-#elif BSD
+#if BFS_HAS_GETPROGNAME
cmd = getprogname();
+#elif BFS_HAS_GETPROGNAME_GNU
+ cmd = program_invocation_short_name;
#endif
if (!cmd) {
diff --git a/src/prelude.h b/src/prelude.h
index c3a0752..a23b167 100644
--- a/src/prelude.h
+++ b/src/prelude.h
@@ -26,6 +26,8 @@
// bfs packaging configuration
+#include "config.h"
+
#ifndef BFS_COMMAND
# define BFS_COMMAND "bfs"
#endif