#!/bin/bash BINARY=${1:-cc} COMPILER=${2:-gcc} MODE=${3:-freestanding} LEVEL=${4:-d} DEBUG=0 declare -a MODULES MODULES+=("libc-${MODE}.c") MODULES+=("$BINARY.c") case "${COMPILER}" in gcc) CFLAGS="-m32 -march=i386 -Wall -pedantic -Werror -std=c89 -x c" ;; clang) CFLAGS="-m32 -march=i386 -Werror -Wall -pedantic -std=c89 -x c" ;; pcc) CFLAGS="-march=i386 -Werror -Wall -std=c89 -x c" ;; tcc) CFLAGS="-m32 -march=i386 -Werror -Wall -std=c89" ;; *) echo "ERROR: Unknown compiler '${COMPILER}' (use gcc, clang, pcc or tcc)" 1>&2 exit 1 ;; esac case "${COMPILER}:${LEVEL}" in *:0|*:1|*:2|*:3|*:s) CFLAGS+=" -O${LEVEL}" ;; pcc:d) CFLAGS+=" -g -O0" DEBUG=1 ;; *:d) CFLAGS+=" -g -Og" DEBUG=1 ;; *) echo "ERROR: Unknown compilation level '${LEVEL}' (use one of 0123s for -O, or d for '-Og -g' and debugging)" 1>&2 exit 1 ;; esac case "${MODE}" in freestanding) CFLAGS+=" -D__FREESTANDING__" ;; hosted) CFLAGS+=" -D__HOSTED__" ;; *) echo "ERROR: Unknown environment '${MODE}' (use 'freestanding' or 'hosted')" 1>&2 exit 1 ;; esac case "${COMPILER}:${MODE}" in gcc:freestanding) CFLAGS+=" -ffreestanding -fno-stack-protector -nostdlib -emain -fno-omit-frame-pointer" ;; clang:freestanding) CFLAGS+=" -ffreestanding -fno-stack-protector -nostdlib -Wl,-emain -fno-omit-frame-pointer" ;; pcc:freestanding) CFLAGS+=" -ffreestanding -nostdlib -Wl,-emain" ;; tcc:freestanding) CFLAGS+=" -fno-bultin -nostdlib" MODULES+=("_start-stub.c") ;; pcc:hosted) CFLAGS+=" -Wl,-emain" ;; esac case "${COMPILER}:${MODE}" in *:hosted) CFLAGS+=" -lbsd" ;; esac echo "${COMPILER} ${CFLAGS} -o ${BINARY} ${MODULES[@]}" if [ "${DEBUG}" = 1 ]; then cat ${MODULES[@]} > "${BINARY}_tmp.c" ${COMPILER} ${CFLAGS} -o ${BINARY} "${BINARY}_tmp.c" else cat ${MODULES[@]} | ${COMPILER} ${CFLAGS} -o ${BINARY} - fi