Add a POSIX-shell configure step

This is to make the Makefile POSIX-compatible, which should mean that it
is portable everywhere.
signals
Gavin Howard 4 years ago
parent 38ddfc2bb2
commit 27fa9cd86a
Signed by untrusted user who does not match committer: gavin
GPG Key ID: C08038BDF280D33E
  1. 1
      .gitignore
  2. 153
      Makefile.in
  3. 362
      configure.sh
  4. 2
      link.sh

1
.gitignore vendored

@ -18,6 +18,7 @@ bc_help.c
dc_help.c
config.mak
timeconst.bc
Makefile
# Ignore the generated test files
parse.txt

@ -12,24 +12,28 @@
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
%%WARNING%%
.POSIX:
SRC = $(sort $(wildcard src/*.c))
OBJ = $(SRC:.c=.o)
GCDA = $(SRC:.c=.gcda)
GCNO = $(SRC:.c=.gcno)
SRC = %%SRC%%
OBJ = %%OBJ%%
GCDA = %%GCDA%%
GCNO = %%GCNO%%
BC_SRC = $(sort $(wildcard src/bc/*.c))
BC_OBJ = $(BC_SRC:.c=.o)
BC_GCDA = $(BC_SRC:.c=.gcda)
BC_GCNO = $(BC_SRC:.c=.gcno)
BC_SRC = %%BC_SRC%%
BC_OBJ = %%BC_OBJ%%
BC_GCDA = %%BC_GCDA%%
BC_GCNO = %%BC_GCNO%%
DC_SRC = $(sort $(wildcard src/dc/*.c))
DC_OBJ = $(DC_SRC:.c=.o)
DC_GCDA = $(DC_SRC:.c=.gcda)
DC_GCNO = $(DC_SRC:.c=.gcno)
DC_SRC = %%DC_SRC%%
DC_OBJ = %%DC_OBJ%%
DC_GCDA = %%DC_GCDA%%
DC_GCNO = %%DC_GCNO%%
BC_ENABLED = BC_ENABLED
DC_ENABLED = DC_ENABLED
BC_ENABLED_NAME = BC_ENABLED
BC_ENABLED = %%BC_ENABLED%%
DC_ENABLED_NAME = DC_ENABLED
DC_ENABLED = %%DC_ENABLED%%
VERSION = 1.1
@ -57,8 +61,10 @@ DC = dc
BC_EXEC = $(BIN)/$(BC)
DC_EXEC = $(BIN)/$(DC)
PREFIX ?= /usr/local
BC_ENABLE_SIGNALS ?= 1
PREFIX = %%PREFIX%%
DESTDIR = %%DESTDIR%%
BC_ENABLE_SIGNALS = %%SIGNALS%%
BC_ENABLE_HISTORY = %%HISTORY%%
INSTALL = ./install.sh
LINK = ./link.sh
@ -68,39 +74,38 @@ VALGRIND_ARGS = --error-exitcode=1 --leak-check=full --show-leak-kinds=all
-include config.mak
BC_NUM_KARATSUBA_LEN ?= 32
BC_NUM_KARATSUBA_LEN = %%KARATSUBA_LEN%%
CFLAGS += -Wall -Wextra -pedantic -std=c99 -funsigned-char
CPPFLAGS += -I./include/ -D_POSIX_C_SOURCE=200809L -DVERSION=$(VERSION)
CPPFLAGS += -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN)
CPPFLAGS += -DBC_ENABLE_SIGNALS=$(BC_ENABLE_SIGNALS)
CFLAGS1 = %%CFLAGS%%
CFLAGS = $(CFLAGS1) -Wall -Wextra -pedantic -std=c99 -funsigned-char
HOSTCC ?= $(CC)
CPPFLAGS1 = %%CPPFLAGS%%
CPPFLAGS2 = $(CPPFLAGS1) -D$(BC_ENABLED_NAME)=$(BC_ENABLED) -D$(DC_ENABLED_NAME)=$(DC_ENABLED)
CPPFLAGS3 = $(CPPFLAGS2) -I./include/ -D_POSIX_C_SOURCE=200809L -DVERSION=$(VERSION)
CPPFLAGS4 = $(CPPFLAGS3) -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN)
CPPFLAGS5 = $(CPPFLAGS4) -DBC_ENABLE_SIGNALS=$(BC_ENABLE_SIGNALS)
CPPFLAGS = $(CPPFLAGS5) -DBC_ENABLE_HISTORY=$(BC_ENABLE_HISTORY)
all: CPPFLAGS += -D$(BC_ENABLED)=1 -D$(DC_ENABLED)=1
all: make_bin clean_exe $(DC_HELP_O) $(BC_HELP_O) $(BC_LIB_O) $(BC_OBJ) $(DC_OBJ) $(OBJ)
LDFLAGS = %%LDFLAGS%%
CC = %%CC%%
HOSTCC = %%HOSTCC%%
all: make_bin $(DC_HELP_O) $(BC_HELP_O) $(BC_LIB_O) $(BC_OBJ) $(DC_OBJ) $(OBJ)
$(CC) $(CFLAGS) $(OBJ) $(DC_OBJ) $(BC_OBJ) $(BC_LIB_O) $(BC_HELP_O) $(DC_HELP_O) -o $(BC_EXEC)
$(LINK) $(BIN) $(DC)
%%LINK%%
$(GEN_EXEC):
$(HOSTCC) $(CFLAGS) -o $(GEN_EXEC) $(GEN_C)
$(BC_LIB_C): $(GEN_EXEC) $(BC_LIB)
$(GEN_EMU) $(GEN_EXEC) $(BC_LIB) $(BC_LIB_C) bc_lib bc_lib_name $(BC_ENABLED)
$(GEN_EMU) $(GEN_EXEC) $(BC_LIB) $(BC_LIB_C) bc_lib bc_lib_name $(BC_ENABLED_NAME)
$(BC_HELP_C): $(GEN_EXEC) $(BC_HELP)
$(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) bc_help "" $(BC_ENABLED)
$(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) bc_help "" $(BC_ENABLED_NAME)
$(DC_HELP_C): $(GEN_EXEC) $(DC_HELP)
$(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) dc_help "" $(DC_ENABLED)
$(DC): CPPFLAGS += -D$(BC_ENABLED)=0 -D$(DC_ENABLED)=1
$(DC): make_bin clean_exe $(DC_OBJ) $(DC_HELP_O) $(OBJ)
$(CC) $(CFLAGS) $(OBJ) $(DC_OBJ) $(DC_HELP_O) -o $(DC_EXEC)
$(BC): CPPFLAGS += -D$(BC_ENABLED)=1 -D$(DC_ENABLED)=0
$(BC): make_bin clean_exe $(BC_OBJ) $(BC_LIB_O) $(BC_HELP_O) $(OBJ)
$(CC) $(CFLAGS) $(OBJ) $(BC_OBJ) $(BC_LIB_O) $(BC_HELP_O) -o $(BC_EXEC)
$(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) dc_help "" $(DC_ENABLED_NAME)
make_bin:
mkdir -p $(BIN)
@ -110,78 +115,40 @@ help:
@echo ""
@echo "available targets:"
@echo ""
@echo " all (default) build bc and dc"
@echo " bc build bc only"
@echo " all (default) build the selected executable(s)"
@echo " clean remove all build files"
@echo " clean_tests remove all build files as well as generated tests"
@echo " dc build dc only"
@echo " install install to $(PREFIX)/bin"
@echo " uninstall uninstall from $(PREFIX)/bin"
@echo " test runs the test suite"
@echo " test_all runs the test suite as well as the Linux timeconst.bc test"
@echo " test_bc runs the bc test suite"
@echo " test_dc runs the dc test suite"
@echo " test_all runs the test suite as well as the Linux timeconst.bc test,"
@echo " if bc has been built"
@echo " timeconst runs the test on the Linux timeconst.bc script"
@echo " valgrind runs the test suite through valgrind"
@echo " valgrind_all runs the test suite, and the Linux timeconst.bc test,"
@echo " through valgrind"
@echo " valgrind_bc runs the bc test suite through valgrind"
@echo " valgrind_dc runs the dc test suite through valgrind"
@echo ""
@echo "useful environment variables:"
@echo ""
@echo " CC C compiler"
@echo " HOSTCC Host C compiler"
@echo " CFLAGS C compiler flags"
@echo " CPPFLAGS C preprocessor flags"
@echo " PREFIX the prefix to install to"
@echo " if PREFIX is \"/usr\", $(BC_EXEC) will be installed to \"/usr/bin\""
@echo " DESTDIR For package creation"
@echo " GEN_EMU Emulator to run $(GEN_EXEC) under (leave empty if not necessary)"
test_all: test timeconst
@echo " if bc has been built, through valgrind"
test: test_bc test_dc
test_all: test %%TIMECONST_TARGET%%
test_bc:
tests/all.sh bc
test:
%%BC_TEST%%
%%DC_TEST%%
test_bc_all: test_bc timeconst
%%TIMECONST%%
test_dc:
tests/all.sh dc
valgrind_all: valgrind %%TIMECONST_VG_TARGET%%
timeconst:
tests/bc/timeconst.sh
valgrind:
%%VG_BC_TEST%%
%%VG_DC_TEST%%
valgrind_all: valgrind valgrind_timeconst
%%TIMECONST_VG%%
valgrind: valgrind_bc valgrind_dc
%%KARATSUBA%%
valgrind_bc:
tests/all.sh bc valgrind $(VALGRIND_ARGS) $(BC_EXEC)
%%KARATSUBA_TEST%%
valgrind_bc_all: valgrind_bc valgrind_timeconst
valgrind_dc:
tests/all.sh dc valgrind $(VALGRIND_ARGS) $(DC_EXEC)
valgrind_timeconst:
echo "100" | valgrind $(VALGRIND_ARGS) $(BC_EXEC) tests/bc/scripts/timeconst.bc
karatsuba:
$(KARATSUBA)
karatsuba_test:
$(KARATSUBA) 100 $(BC_EXEC)
coverage: CC = gcc
coverage: CFLAGS = -fprofile-arcs -ftest-coverage -O0 -g
coverage: CPPFLAGS += -D$(DC_ENABLED) -D$(BC_ENABLED) -DNDEBUG
coverage: all test_all
gcov -pabcdf $(GCDA) $(BC_GCDA) $(DC_GCDA)
$(RM) -f $(GEN)*.gc*
gcovr --html-details --output index.html
%%COVERAGE%%
version:
@echo "$(VERSION)"
@ -189,7 +156,7 @@ version:
libcname:
@echo "$(BC_LIB_C)"
clean_exe:
clean:
$(RM) -f $(OBJ)
$(RM) -f $(BC_OBJ)
$(RM) -f $(DC_OBJ)
@ -200,8 +167,6 @@ clean_exe:
$(RM) -f $(DC_GCDA) $(DC_GCNO)
$(RM) -f *.gcov
$(RM) -f *.html
clean: clean_exe
$(RM) -f $(GEN_EXEC)
$(RM) -f $(BC_LIB_C)
$(RM) -f $(BC_LIB_O)

@ -0,0 +1,362 @@
#! /bin/sh
#
# Copyright 2018 Gavin D. Howard
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
usage() {
echo "usage: $0 [-b|-d|-c] [-chStn] [-m|-r] [-k KARATSUBA_LEN]"
echo ""
echo " -b"
echo " Build bc only. It is an error if \"-d\" is specified too."
echo " -c"
echo " Generate test coverage code. Requires gcov and regcovr."
echo " It is an error if only either \"-b\" or \"-d\" is specified"
echo " or if \"-n\" is not specified."
echo " -d"
echo " Build dc only. It is an error if \"-b\" is specified too."
echo " -h"
echo " Print this help message and exit."
echo " -k"
echo " Set the karatsuba length to KARATSUBA_LEN (default is 32)."
echo " It is an error if KARATSUBA_LEN is not a number or is less than 2."
echo " -m"
echo " Enable minimum-size release flags. It is an error if \"-r\" is"
echo " specified too."
echo " -n"
echo " Build in debug mode."
echo " -r"
echo " Enable default release flags (-O3 -DNDEBUG -s). On by default."
echo " If given with \"-n\", a debuggable release will be built."
echo " It is an error if \"-m\" is specified too."
echo " -S"
echo " Disable signal handling. On by default."
echo " -t"
echo " Enable history (currently not implemented)."
echo ""
echo "In addition, the following environment variables are used:"
echo ""
echo " CC C compiler. Must be either gcc or clang."
echo " HOSTCC Host C compiler."
echo " CFLAGS C compiler flags. You can use this for extra optimization flags."
echo " CPPFLAGS C preprocessor flags."
echo " LDFLAGS Linker flags."
echo " PREFIX the prefix to install to. Default is /usr/local."
echo " If PREFIX is \"/usr\", install path will be \"/usr/bin\"."
echo " DESTDIR For package creation."
echo " GEN_EMU Emulator to run string generator code under"
echo " (leave empty if not necessary)."
exit "$1"
}
err_exit() {
if [ "$#" -ne 1 ]; then
echo "Invalid number of args to err_exit"
exit 1
fi
echo "$1"
exit 1
}
replace_ext() {
if [ "$#" -ne 3 ]; then
err_exit "Invalid number of args to $0"
fi
file="$1"
ext1="$2"
ext2="$3"
result=$(echo "$file" | sed -e "s@\.$ext1@\.$ext2@")
echo "$result"
}
replace_exts() {
if [ "$#" -ne 3 ]; then
err_exit "Invalid number of args to $0"
fi
files="$1"
ext1="$2"
ext2="$3"
for file in $files; do
new_name=$(replace_ext "$file" "$ext1" "$ext2")
result="$result $new_name"
done
echo "$result"
}
replace() {
if [ "$#" -ne 3 ]; then
err_exit "Invalid number of args to $0"
fi
str="$1"
needle="$2"
replacement="$3"
result=$(printf '%s' "$str" | sed -e "s!%%$needle%%!$replacement!g")
echo "$result"
}
gen_file_lists() {
if [ "$#" -ne 3 ]; then
err_exit "Invalid number of args to $0"
fi
contents="$1"
filedir="$2"
typ="$3"
needle="${typ}SRC"
replacement=$(ls $filedir/*.c | tr '\n' ' ')
contents=$(replace "$contents" "$needle" "$replacement")
needle="${typ}OBJ"
replacement=$(replace_exts "$replacement" "c" "o")
contents=$(replace "$contents" "$needle" "$replacement")
needle="${typ}GCDA"
replacement=$(replace_exts "$replacement" "c" "gcda")
contents=$(replace "$contents" "$needle" "$replacement")
needle="${typ}GCNO"
replacement=$(replace_exts "$replacement" "c" "gcno")
contents=$(replace "$contents" "$needle" "$replacement")
echo "$contents"
}
bc_only=0
dc_only=0
coverage=0
karatsuba_len=32
min_size=0
debug=0
release=0
signals=1
hist=0
while getopts "bcdhk:mnrSt" opt; do
case "$opt" in
b) bc_only=1 ;;
c) coverage=1 ;;
d) dc_only=1 ;;
h) usage 0 ;;
k) karatsuba_len="$OPTARG" ;;
m) min_size=1 ;;
n) debug=1 ;;
r) release=1 ;;
S) signals=0 ;;
t) hist=1 ;;
?) usage 1 ;;
esac
done
if [ "$bc_only" -eq 1 -a "$dc_only" -eq 1 ]; then
usage 1
fi
case $karatsuba_len in
(*[!0-9]*|'') usage 1 ;;
(*) ;;
esac
if [ "$karatsuba_len" -lt 2 ]; then
usage 1
fi
if [ "$release" -eq 1 -a "$min_size" -eq 1 ]; then
usage 1
fi
set -e
script="$0"
scriptdir=$(dirname "$script")
contents=$(cat "$scriptdir/Makefile.in")
needle="WARNING"
replacement="# *** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***\n#"
contents=$(replace "$contents" "$needle" "$replacement")
contents=$(gen_file_lists "$contents" "$scriptdir/src" "")
contents=$(gen_file_lists "$contents" "$scriptdir/src/bc" "BC_")
contents=$(gen_file_lists "$contents" "$scriptdir/src/dc" "DC_")
link="@echo \"No link\""
bc_test="tests/all.sh bc"
dc_test="tests/all.sh dc"
vg_bc_test="tests/all.sh bc valgrind \$(VALGRIND_ARGS) \$(BC_EXEC)"
vg_dc_test="tests/all.sh dc valgrind \$(VALGRIND_ARGS) \$(DC_EXEC)"
timeconst_target="timeconst"
timeconst="$timeconst_target:\n\ttests/bc/timeconst.sh"
timeconst_vg_target="valgrind_timeconst"
timeconst_vg="$timeconst_vg_target:\n"
timeconst_vg="$timeconst_vg\techo \"0\" | valgrind \$(VALGRIND_ARGS) \$(BC_EXEC) tests/bc/scripts/timeconst.bc\n"
timeconst_vg="$timeconst_vg\techo \"100\" | valgrind \$(VALGRIND_ARGS) \$(BC_EXEC) tests/bc/scripts/timeconst.bc"
karatsuba=""
karatsuba_test=""
if [ "$bc_only" -eq 1 ]; then
bc=1
dc=0
dc_test="@echo \"No dc tests to run\""
vg_dc_test="@echo \"No dc tests to run\""
elif [ "$dc_only" -eq 1 ]; then
bc=0
dc=1
bc_test="@echo \"No bc tests to run\""
vg_bc_test="@echo \"No bc tests to run\""
timeconst_target=""
timeconst=""
timeconst_vg_target=""
timeconst_vg=""
else
bc=1
dc=1
link="\$(LINK) \$(BIN) \$(DC)"
karatsuba="karatsuba:\n\t\$(KARATSUBA)"
karatsuba_test="karatsuba_test:\n\t\$(KARATSUBA) 100 \$(BC_EXEC)"
fi
if [ "$debug" -eq 1 ]; then
CFLAGS="$CFLAGS -g -fno-omit-frame-pointer"
if [ "$release" -ne 1 -a "$min_size" -ne 1 ]; then
CFLAGS="$CFLAGS -O0"
fi
else
CPPFLAGS="$CPPFLAGS -DNDEBUG"
LDFLAGS="$LDFLAGS -s"
fi
if [ "$release" -eq 1 ]; then
CFLAGS="$CFLAGS -O3"
fi
if [ "$min_size" -eq 1 ]; then
CFLAGS="$CFLAGS -Os"
fi
if [ "$coverage" -eq 1 ]; then
if [ "$bc_only" -eq 1 -o "$dc_only" -eq 1 ]; then
usage 1
fi
CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
CPPFLAGS="$CPPFLAGS -DNDEBUG"
COVERAGE="coverage: all test_all\n"
COVERAGE="$COVERAGE\tgcov -pabcdf \$(GCDA) \$(BC_GCDA) \$(DC_GCDA)\n"
COVERAGE="$COVERAGE\t\$(RM) -f \$(GEN)*.gc*\n"
COVERAGE="$COVERAGE\tregcovr --html-details --output index.html"
fi
if [ "$PREFIX" = "" ]; then
PREFIX="/usr/local"
fi
gcc="gcc"
clang="clang"
if [ "${CC#*$gcc}" = "$CC" -a "${CC#*$clang}" = "$CC" ]; then
usage 1
fi
if [ "$HOSTCC" = "" ]; then
HOSTCC="$CC"
fi
if [ "${HOSTCC#*$gcc}" = "$CC" -a "${HOSTCC#*$clang}" = "$CC" ]; then
usage 1
fi
contents=$(replace "$contents" "BC_ENABLED" "$bc")
contents=$(replace "$contents" "DC_ENABLED" "$dc")
contents=$(replace "$contents" "LINK" "$link")
contents=$(replace "$contents" "SIGNALS" "$signals")
contents=$(replace "$contents" "HISTORY" "$hist")
contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len")
contents=$(replace "$contents" "PREFIX" "$PREFIX")
contents=$(replace "$contents" "DESTDIR" "$DESTDIR")
contents=$(replace "$contents" "CFLAGS" "$CFLAGS")
contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS")
contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS")
contents=$(replace "$contents" "CC" "$CC")
contents=$(replace "$contents" "HOSTCC" "$HOSTCC")
contents=$(replace "$contents" "COVERAGE" "$COVERAGE")
contents=$(replace "$contents" "BC_TEST" "$bc_test")
contents=$(replace "$contents" "DC_TEST" "$dc_test")
contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test")
contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test")
contents=$(replace "$contents" "TIMECONST_TARGET" "$timeconst_target")
contents=$(replace "$contents" "TIMECONST" "$timeconst")
contents=$(replace "$contents" "TIMECONST_VG_TARGET" "$timeconst_vg_target")
contents=$(replace "$contents" "TIMECONST_VG" "$timeconst_vg")
contents=$(replace "$contents" "KARATSUBA" "$karatsuba")
contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test")
contents=$(printf '%s' "$contents" | sed -e "s!\n\n!\n!g")
echo "$contents" > "$scriptdir/Makefile"
cd "$scriptdir"
make clean > /dev/null

@ -42,7 +42,7 @@ for exe in ./*; do
name="$link"
fi
ln -s "$exe" "./$name"
ln -fs "$exe" "./$name"
exit 0
fi

Loading…
Cancel
Save