-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathconfigure
executable file
·120 lines (103 loc) · 3.21 KB
/
configure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env bash
TMPL_MKFILE=scripts/tmpl.mk
DEPS_MKFILE=scripts/deps.mk
# This script generates the Makefile from $TMPL_MKFILE and $DEPS_MKFILE,
# the latter of which contains the rules to build the various object files.
#
# $DEPS_MKFILE imposes the following module rules:
#
# 1. Every directory in `/src` and its descendant directories, including
# `/src` itself, defines a module.
#
# 2. Every C file within a module can include headers from the
# `[root]/include` directory (if it exists) where `[root]` is the module
# root directory. E.g., `/src/main.c` and `/src/ast/expr.c` can both
# include headers from `/src/include`, but `/src/ast/expr.c` can also
# include from `/src/ast/include`.
#
# 3. Every C file is treated as its own translation unit.
#
# 4. Every `.c` and `.h` file in the directory is a Makefile-dependency of
# every other such file.
#
# 5. In keeping with [0], the -I include directories are ordered
# according to nearness to the file, so that if `x.h` is imported in
# `/src/abc` and there is both `/src/include/x.h` and
# `/src/abc/include/x.h` then the latter will be chosen.
#
# [0]: "Directories named in -I options shall be searched in the order
# specified".
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html
set +x
SRCDIR=src
BUILDDIR=build
# listincludes: output a list of the appropriate include directories from the
# given path, in keeping with rule (2.) above
function listincludes() {
path=$1
includedir=$path/include
if [ -d $includedir ]; then
echo $includedir
fi
parent=$(dirname $path)
if [[ $parent != "." ]]; then
listincludes $parent
fi
}
INCLUDEDIRS=$(find $SRCDIR -type d -name "include")
SRCDIRS=$(find $SRCDIR -type d ! -name "include")
# hack in Lex/Yacc files
PARSER_FILES="$SRCDIR/ast/lex.yy.c \
$SRCDIR/ast/gram.tab.c \
$SRCDIR/include/gram.tab.h"
touch $PARSER_FILES
exec > $DEPS_MKFILE
printf "# Generated by $(pwd)/$(basename $0) at $(date "+%s")\n\n"
# headers
printf "HEADERS ="
for dir in $INCLUDEDIRS; do
for f in $(find $dir -maxdepth 1 -type f -name "*.h"); do
printf " \\" # escape previous line
printf "\n\t$f"
done
done
printf "\n\n"
# objects
printf "OBJECTS ="
for dir in $SRCDIRS; do
build_dir=$(echo $dir | sed "s/^$SRCDIR/$BUILDDIR/")
for f in $(find $dir -maxdepth 1 -type f -name "*.c"); do
obj=$build_dir/$(basename $f | sed "s/.c$/.o/;")
printf " \\" # escape previous line
printf "\n\t$obj"
done
done
printf "\n"
# object build commands
for dir in $SRCDIRS; do
build_dir=$(echo $dir | sed "s/^$SRCDIR/$BUILDDIR/")
printf "\n# $dir with build dir /$build_dir\n"
includes=$(listincludes $dir)
for f in $(find $dir -maxdepth 1 -type f -name "*.c"); do
obj=$build_dir/$(basename $f | sed "s/.c$/.o/;")
printf "$obj: $build_dir parser\n"
printf "\t@printf \"CC\\\\t\$@\\\\n\"\n"
printf "\t@\$(CC) \$(CFLAGS) -o \$@ -c $f "
# the order of inclusions is important: see (5.) above.
for inc in $includes; do
printf -- '\\\n\t\t-I %s ' $inc
done
printf "\n"
done
done
# build dirs
printf "# build dirs\n"
for dir in $SRCDIRS; do
build_dir=$(echo $dir | sed "s/^$SRCDIR/$BUILDDIR/")
printf "$build_dir:\n"
printf "\t@mkdir -p \$@\n"
done
exec > /dev/tty
# hack in parser files
rm $PARSER_FILES
cp $TMPL_MKFILE Makefile