diff options
| author | Jakob Kaivo <jkk@ung.org> | 2019-01-27 18:36:58 -0500 |
|---|---|---|
| committer | Jakob Kaivo <jkk@ung.org> | 2019-01-27 18:36:58 -0500 |
| commit | 0ca793b65069d8ba9a61f48228ffb982ef233c1a (patch) | |
| tree | ea462b4de8ba616ee4a6cd6ba2034df857807a7c | |
| parent | 0bd12f61b7a0213775a0e3d5fbc32bd4213c76e8 (diff) | |
new utility to generate makefiles with dependencies
| -rwxr-xr-x | mkmf.sh | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/mkmf.sh b/mkmf.sh new file mode 100755 index 00000000..8861a7ad --- /dev/null +++ b/mkmf.sh @@ -0,0 +1,109 @@ +#!/bin/sh + +classify_source () { + NAME=$(basename $1 .c) + + if grep -q "define ${NAME}[ (]" $1; then + echo MACRO + elif grep -q "typedef.* ${NAME};" $1; then + echo TYPE + elif grep -q "typedef.*{$" $1; then + echo TYPE_LONG + elif grep -q "struct.*${NAME} {" $1; then + echo STRUCT + elif grep -q "union.* ${NAME} {" $1; then + echo UNION + elif grep -q "^[A-Za-z_].* ${NAME};" $1; then + echo EXTERN + else + echo FUNCTION + fi +} + +STANDARD=${1-9899-1990} +#STANDARD=${1-POSIX.1-1990} + +if [ ! -f .dep/to-build ]; then + rm -rf .dep Makefile header.mk + mkdir -p .dep + echo ${STANDARD} > .dep/to-build +fi + +if [ ! -d std/${STANDARD} ]; then + printf "Standard %s not found.\n" "${STANDARD}" + exit 1 +fi + +if [ -f std/${STANDARD}/INCLUDE ]; then + for i in $(cat std/${STANDARD}/INCLUDE); do + $0 $i + done +fi + +rm -f .dep/${STANDARD}.* + +for i in $(find std/${STANDARD} -name \*.c); do + NAME=$(basename $i .c) + TYPE=$(classify_source $i) + HEADER=$(sed -ne 's/.*<\(.*\.h\)>.*/\1/p' $i) + LIB=$(grep '^LINK(' $i | m4 -DLINK='lib$1') + LIB=${LIB:-libc} + + if [ ! -f .dep/${HEADER}.mk ]; then + mkdir -p $(dirname .dep/${HEADER}.mk) + printf '$(INCDIR)/%s:' "${HEADER}" > .dep/${HEADER}.mk + fi + printf ' \\\n\t%s' "$i" >> .dep/${HEADER}.mk + + if [ ${TYPE} = EXTERN -o ${TYPE} = FUNCTION ]; then + printf '$(OBJDIR)/%s.o: %s $(INCDIR)/%s' ${NAME} $i ${HEADER}> .dep/${NAME}.o.mk + for j in $(grep include $i); do + : # TODO: add each header to depends file here + done + printf '\n\t-@mkdir -p $(OBJDIR)\n\t$(CC) $(CFLAGS) -c %s -o $@\n\n' $i >> .dep/${NAME}.o.mk + + if [ ! -f .dep/${LIB}.a.mk ]; then + printf '%s_OBJS =' ${LIB} > .dep/${LIB}.a.mk + if [ ${LIB} = libc ]; then + printf ' $(OBJDIR)/libc.o $(OBJDIR)/x86-64.o' >> .dep/${LIB}.a.mk + fi + fi + printf ' \\\n\t$(OBJDIR)/%s.o' ${NAME} >> .dep/${LIB}.a.mk + fi + +done + +if [ $(cat .dep/to-build) = ${STANDARD} ]; then + printf '.POSIX:\n\n' > Makefile + printf 'default: all\n\n' >> Makefile + printf 'include config.mk\n\n' >> Makefile + printf 'INCLUDES=-I$(INCDIR) -I. -Inonstd/stubs\n' >> Makefile + printf 'CFLAGS=$(INCLUDES) -g -fno-builtin -nostdinc -nostdlib -nodefaultlibs -Werror -Wall -Wextra -fPIC\n\n' >> Makefile + + for i in .dep/lib*.a.mk; do + LIB=$(basename $i .a.mk) + cat $i >> Makefile + printf '\n\n%s.a: $(%s_OBJS)\n\t$(AR) r $@ $?\n\n' $LIB $LIB >> Makefile + done + + printf '.POSIX:\n\ninclude config.mk\n\n' > headers.mk + for i in $(find .dep -name \*.h.mk); do + cat $i >> headers.mk + printf '\n\t./gen-header $@\n\n' >> headers.mk + done + + cat .dep/*.o.mk >> Makefile + + printf '$(OBJDIR)/libc.o: nonstd/libc.c\n\t$(CC) $(CFLAGS) -c $? -o $@\n\n' >> Makefile + printf '$(OBJDIR)/x86-64.o: nonstd/x86-64.s\n\t$(CC) $(CFLAGS) -c $? -o $@\n\n' >> Makefile + + printf 'all:' >> Makefile + for i in .dep/lib*.a.mk; do + printf ' %s' $(basename $i .mk) >> Makefile + done + printf '\n\n' >> Makefile + + printf 'clean:\n\trm -rf $(OBJDIR) *.a\n\n' >> Makefile + printf 'git-clean: clean\n\trm -rf .dep header.mk Makefile\n\n' >> Makefile + +fi |
