aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-01-01 12:00:33 +0100
committerlemon <lsof@mailbox.org>2026-01-01 12:01:45 +0100
commit93194ef8447718ae78b345ce0a920bb5e6fdc090 (patch)
tree34551543dffff4b53e66ffb94839cddc70810568
parentd7203ea5f46fef1b41ba3b32c0b9313df3b3740c (diff)
Use a configure script, query system toolchain for default include paths
-rw-r--r--.gitignore1
-rw-r--r--README.md2
-rwxr-xr-xconfigure113
-rw-r--r--hostconfig.h27
-rw-r--r--main.c21
-rw-r--r--targ.c4
-rw-r--r--todo.txt2
7 files changed, 135 insertions, 35 deletions
diff --git a/.gitignore b/.gitignore
index 45ac1dc..3d6828c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+hostconfig.h
antcc
antcc0
antcc1
diff --git a/README.md b/README.md
index 895dd15..c3b552e 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,8 @@ experimental stage.
# Building
```
+./configure
+
make # outputs ./antcc executable
# or
make opt #compile with optimizations
diff --git a/configure b/configure
new file mode 100755
index 0000000..5097b39
--- /dev/null
+++ b/configure
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+die() {
+ echo "$0: Error: $@" >&2
+ exit 1
+}
+
+prihelp() {
+ host="[$(cc -dumpmachine)]"
+ : ${host:=""}
+ cat << EOF
+Usage: $0 [options]
+Options:
+ --help Print this help mesage
+ --host=target-triple $host
+ --cc=cc C compiler [cc]
+ --sysroot=/path System root [/usr]
+ --includedir="/a/b",... System include dirs
+EOF
+}
+
+sysroot=/usr
+host=
+
+for arg ; do
+ case "$arg" in
+ --host=*) host=${arg#*=} ;;
+ --sysroot=*) sysroot=${arg#*=} ;;
+ --includedir=*) host_include_dirs=${arg#*=} ;;
+ CC=*) CC=${arg#*=} ;;
+ --cc=*) CC=${arg#*=} ;;
+ --help) prihelp ; exit ;;
+ *) die "$0: unknown option '$arg'"
+ esac
+done
+
+: ${CC:=cc}
+: ${host:=$($CC -dumpmachine)}
+test -n "$host" || die "cannot determine host"
+
+host_arch=
+host_os=
+host_abi=
+
+echo "host: $host"
+case "$host" in
+x86_64-*) host_arch=x86_64 ;;
+aarch64-*) host_arch=aarch64 ;;
+*) host_arch=unk ;;
+esac
+
+case "$host" in
+*-linux-*) host_os=linux ;;
+*) host_os=unknown ;;
+esac
+
+case "$host" in
+*-gnu) host_abi=gnu ;;
+*-musl) host_abi=musl ;;
+*) host_abi=none ;;
+esac
+
+tryincldir() {
+ if stat "$1"/ >/dev/null 2>/dev/null; then
+ host_include_dirs="$host_include_dirs\"$1\","
+ fi
+}
+
+if ! test -n "$host_include_dirs"; then
+ # try to query host toolchain first
+ if hostccdirs=$($CC -E -v -xc /dev/null 2>&1 | sed -n '/#include <...> search starts here:/,/End of search list./{
+ s/^[[:space:]]*//
+ /^\/.*/p
+}') && test -n "$hostccdirs"; then
+ echo "Using $CC's system include paths:"
+ for d in $hostccdirs; do
+ dir=$(realpath "$d")
+ case "$dir" in
+ #exclude internal compiler headers, we have our own
+ */gcc/*) ;; */clang/*) ;;
+ *) echo " $dir"
+ tryincldir "$dir" ;;
+ esac
+ done
+ else
+ echo "Falling back to generic system include paths"
+ tryincldir "$sysroot/local/include/$host"
+ tryincldir "$sysroot/local/include"
+ tryincldir "$sysroot/include/$host"
+ tryincldir "$sysroot/include"
+ fi
+fi
+
+set -e
+
+echo using arch: "$host_arch"
+echo using os: "$host_os"
+echo using abi: "$host_abi"
+echo host include paths: "$host_include_dirs"
+
+echo "/** GENERATED WITH $0 $@ **/
+#ifndef HOSTCONFIG_H_
+#define HOSTCONFIG_H_
+
+#define HOST_TRIPLE \"$host\"
+#define HOST_ARCH IS$host_arch
+#define HOST_OS OS$host_os
+#define HOST_ABI ABI$host_abi
+#define HOST_INCLUDE_DIRS $host_include_dirs
+#define HOST_CC \"$CC\"
+
+#endif // HOSTCONFIG_H_" > hostconfig.h
+echo config written to hostconfig.h
diff --git a/hostconfig.h b/hostconfig.h
deleted file mode 100644
index b333ad2..0000000
--- a/hostconfig.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef HOST_CONFIG_H
-#define HOST_CONFIG_H
-
-#if defined __x86_64 || defined __x86_64__
-#define HOST_ARCH ISx86_64
-#else
-#define HOST_ARCH ISxxx
-#endif
-
-#if defined __linux__
-#define HOST_OS OSlinux
-#else
-#define HOST_OS OSunknown
-#endif
-
-#if defined __linux__
-#define HOST_ABI ABIgnu
-#else
-#define HOST_ABI ABInone
-#endif
-
-#ifndef HOST_INCLUDE_DIRS
-#define HOST_INCLUDE_DIRS "/usr/include", "/usr/local/include"
-#endif
-
-#endif
-
diff --git a/main.c b/main.c
index eacef15..a821baa 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
#include "common.h"
-#include "hostconfig.h"
+#include "hostconfig.h" /* run ./configure */
#include "obj/obj.h"
#include <errno.h>
#include <stdlib.h>
@@ -128,6 +128,9 @@ optparse(char **args)
if (!strcmp(arg, "help") || !strcmp(arg, "h") || !strcmp(arg, "-help")) {
prihelp();
exit(0);
+ } else if (!strcmp(arg, "dumpmachine")) {
+ pfmt("%s\n", HOST_TRIPLE);
+ exit(0);
} else if ((x = optval(arg, "std"))) {
if (!strcmp(x, "c89") || !strcmp(x, "c90")) ccopt.cstd = STDC89;
else if (!strcmp(x, "c99")) ccopt.cstd = STDC99;
@@ -367,12 +370,19 @@ hasprog(const char *prog)
return WEXITSTATUS(wstat) < 125;
}
+static bool
+iscrosscc(void)
+{
+ return target.os != HOST_OS || target.arch != HOST_ARCH || target.abi != HOST_ABI;
+}
+
struct cmdargs { vec_of(const char *); };
static void
findlinkcmd(struct cmdargs *cmd)
{
- if (task.targ && (target.os != HOST_OS || target.arch != HOST_ARCH || target.abi != HOST_ABI)) {
+ if (task.targ && iscrosscc()) {
+ /* try to find a cross compiling toolchain, e.g. aarch64-linux-gnu-gcc */
static const char *ccs[] = {"cc", "gcc", "clang"};
char cross[1024];
for (int i = 0; i < countof(ccs); ++i) {
@@ -385,6 +395,7 @@ findlinkcmd(struct cmdargs *cmd)
return;
}
}
+ /* zig cc fallback, which works great as cross compiler toolchain */
if (hasprog("zig")) {
vpush(cmd, "zig");
vpush(cmd, "cc");
@@ -394,7 +405,7 @@ findlinkcmd(struct cmdargs *cmd)
fatal(NULL, "cannot link to cross-compilation target: no appropiate toolchain installed");
}
} else {
- vpush(cmd, "cc");
+ vpush(cmd, HOST_CC);
}
}
@@ -489,7 +500,7 @@ driver(void)
{
void cpp(struct wbuf *, const char *);
if (task.verbose)
- efmt("# Target: %s\n", task.targ ? task.targ : "(host)");
+ efmt("# Target: %s\n", task.targ ? task.targ : HOST_TRIPLE);
if (task.syntaxonly)
task.out = "/dev/null"; // HACK
if (task.outft == OFTobj) {
@@ -627,7 +638,7 @@ main(int argc, char **argv)
/* global init */
targ_init(task.targ);
if (!target.arch)
- fatal(NULL, "unsupported target: %s", task.targ ? task.targ : "(host)");
+ fatal(NULL, "unsupported target: %s", task.targ ? task.targ : HOST_TRIPLE);
return driver();
}
diff --git a/targ.c b/targ.c
index 515bda3..4190b4f 100644
--- a/targ.c
+++ b/targ.c
@@ -62,7 +62,7 @@ parsetriple(struct targtriple *trg, const char *str)
return 1;
}
-#include "hostconfig.h"
+#include "hostconfig.h" /* run ./configure */
void
targ_init(const char *starg)
@@ -86,7 +86,7 @@ targ_init(const char *starg)
break;
}
}
- if (!t) fatal(NULL, "unsupported target: %s", starg ? starg : "(host)");
+ if (!t) fatal(NULL, "unsupported target: %s", starg ? starg : HOST_TRIPLE);
sizes[TYBOOL] = sizes[TYCHAR] = sizes[TYSCHAR] = sizes[TYUCHAR] = 1;
sizes[TYSHORT] = sizes[TYUSHORT] = 2;
diff --git a/todo.txt b/todo.txt
index 746d5c4..48deffe 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,6 @@
- aarch64 backend
- STDC: thread local, VLAs, complex, long double, atomics
-- test on non-GNU and non-linux POSIX systems (alpine, various BSDs). Maybe we'll need a configure script after all
+- test on non-GNU and non-linux POSIX systems (alpine, various BSDs)
- DWARF debug information
- implement GNU extensions: __attribute__, __builtin_*, ...
- compiler optimizations: