2 # vim: ts=2 sts=2 sw=2 et:
11 --prefix=PREFIX change the install prefix [/usr/local]
12 --bindir=BINDIR target of executables [PREFIX/bin]
13 --datadir=DATADIR target of additional data [PREFIX/share]
14 --mandir=MANDIR target of manpages [DATADIR/man]
15 --man1dir=MAN1DIR manual section 1 [MANDIR/man1]
16 Environment variables:
23 while [ $# -ge 1 ]; do
25 --prefix=*) cf_prefix="${1#--prefix=}" ;;
26 --bindir=*) cf_bindir="${1#--bindir=}" ;;
27 --datadir=*) cf_datadir="${1#--datadir=}" ;;
28 --mandir=*) cf_mandir="${1#--mandir=}" ;;
29 --man1dir=*) cf_man1dir="${1#--man1dir=}" ;;
32 echo "Unknown parameter: $1"
42 local mesg="$1"; shift
43 printf "fatal: ${mesg}\n" "$@"
48 local mesg="$1"; shift
49 printf "configure: ${mesg}\n" "$@"
53 # Some library functions
56 if which $1 >/dev/null 2>&1
62 # so we don't have to repeat the >/dev/null all the time
64 # strip parameters (ie, 'need_cmd $CC' with CC="gcc -m32" should work)
71 # Well we can expect those to exist, no?
78 # default host specific values:
80 host="$(uname -s | tr A-Z a-z)"
83 cf_prefix="${cf_prefix:-/usr/local}"
84 cf_bindir="${cf_bindir:-${cf_prefix}/bin}"
85 cf_datadir="${cf_datadir:-${cf_prefix}/share}"
86 cf_mandir="${cf_mandir:-${cf_datadir}/man}"
87 cf_man1dir="${cf_man1dir:-${cf_mandir}/man1}"
91 cf_prefix="${cf_prefix:-}"
92 cf_bindir="${cf_bindir:-}"
93 cf_datadir="${cf_datadir:-}"
94 cf_mandir="${cf_mandir:-}"
95 cf_man1dir="${cf_man1dir:-}"
100 # for the default-supported compilers:
101 cf_cflags_gcc=(-Wall -Wextra -Werror -Wstrict-aliasing -Wno-attributes)
105 # Let's figure out where we are...
107 cf_dir="$(readlink -f "${progname}")"
108 # or should we use the hopefully more reliable basename command?
109 cf_dir="${cf_dir%/*}"
111 if [[ $cf_dir == $cf_wd ]]; then
112 echo "Please run this script in a different directory \
113 to not overwrite the git working tree."
117 # execute a command inside $cf_dir
119 # do it in a subshell so we don't change directory ourselves
120 ( cd "${cf_dir}" && "$@" ) || false
127 has_cmd "${CC}" || CC=clang
128 has_cmd "${CC}" || CC=gcc
129 has_cmd "${CC}" || CC=cc
130 has_cmd "${CC}" || CC=tcc
131 has_cmd "${CC}" || die "No compiler found"
133 # We might add support for different compilers with a different CLI
136 if [[ $CC != clang && $CC != gcc && $CC != g++ ]]; then
137 cf_ccver="$(${CC} -v 2>&1)"
138 (( $? )) && die "Failed to retrieve compiler version info"
139 if (echo "${cf_ccver}" | grep -q '\<clang\|gcc\>'); then
140 msg "found compatible compiler"
142 die "don't know how to use this compiler..."
146 # Git information - that is, if git is available
149 # And provided we're in a git repo:
150 if [[ -d "${cf_dir}/.git" ]]; then
152 msg "reading git info"
153 cf_gitinfo_text="$(indir git describe --always)"
159 has_cmd valgrind && cf_valgrind=1
161 # compiler specific flags:
162 [[ $CC != g++ ]] && cf_cflags_gcc+=(-Wmissing-prototypes -Wstrict-prototypes)
163 [[ $CC = clang ]] && \
167 -Wno-format-nonliteral
168 -Wno-disabled-macro-expansion
171 -Wno-unknown-warning-option
174 if [[ $CC != tcc ]]; then
175 cf_cflags_gcc+=(-pedantic-errors)
177 cf_cflags_gcc+=(-Wno-pointer-sign -fno-common)
182 if (( cf_gitinfo )); then
183 cf_cflags_gcc+=(-DGMQCC_GITINFO="\"${cf_gitinfo_text}\"")
186 if (( ! cf_valgrind )); then
187 cf_cflags_gcc+=(-DNVALGRIND)
191 # Put the cflags/ldflags/libs we use into cf_cflags/ldflags/libs
193 case "${cf_cctype}" in
195 cf_cflags=("${cf_cflags_gcc[@]}")
196 cf_ldflags=("${cf_ldflags_gcc[@]}")
197 cf_libs=("${cf_libs_gcc[@]}")
200 die "compiler type '%s' not handled here!" "${cf_cctype}"
204 # Makefile generation routines
207 # executables is an array of variable names used in the makefile to
208 # name an executable; the list of objects is assumed to be
210 executables=(GMQCC QCVM TESTSUITE PAK)
211 all_c_obj=() # filled by print_objects
214 for i in "${executables[@]}"; do
220 # create all the object variables:
222 local common=(ansi.o util.o hash.o stat.o fs.o opts.o conout.o)
223 all_c_obj+=("${common[@]}")
224 local gmqcc=(main.o utf8.o
225 lexer.o parser.o ftepp.o
226 fold.o intrin.o correct.o
228 all_c_obj+=("${gmqcc[@]}")
230 all_c_obj+=("${qcvm[@]}")
231 local testsuite=(test.o)
232 all_c_obj+=("${testsuite[@]}")
234 all_c_obj+=("${pak[@]}")
236 GMQCC = gmqcc${cf_exesuffix}
237 QCVM = qcvm${cf_exesuffix}
238 TESTSUITE = testsuite${cf_exesuffix}
239 PAK = pak${cf_exesuffix}
241 QCVM_OBJ := ${common[@]} ${qcvm[@]}
242 GMQCC_OBJ := ${common[@]} ${gmqcc[@]}
243 TESTSUITE_OBJ := ${common[@]} ${testsuite[@]}
244 PAK_OBJ := ${common[@]} ${pak[@]}
247 printf 'ALL_PROGRAMS ='
248 for i in "${executables[@]}"; do
254 # generate the commands used to build objects and executables
255 # in a way that works with both BSD make and gmake by not relying
256 # on special vars like - also generate the .d files
258 # generate object rules to get the right path: $cf_dir
259 for obj in "${all_c_obj[@]}"; do
260 local c_src="${cf_dir}/${obj%.o}.c"
261 local d_inc="${obj}.d"
262 echo "${obj}: ${c_src}"
263 echo $'\t'"\$(CC) \$(CFLAGS) \$(CPPFLAGS) -c -o \$@ \"${c_src}\" -MMD -MF \"${d_inc}\" -MT \$@"
266 for exe in "${executables[@]}"; do
267 echo "\$(${exe}): \$(${exe}_OBJ)"
268 echo $'\t'"\$(CC) \$(LDFLAGS) -o \$(${exe}) \$(${exe}_OBJ) \$(LIBS)"
273 # Now generate our output file
275 echo "Generating Makefile"
278 # First: cflags and directories
283 CFLAGS = ${CFLAGS} ${cf_cflags[@]}
284 LDFLAGS = ${LDFLAGS} ${cf_ldflags[@]}
285 LIBS = ${LIBS} ${cf_libs[@]}
290 PREFIX = ${cf_prefix}
291 BINDIR = ${cf_bindir}
292 DATADIR = ${cf_datadir}
293 MANDIR = ${cf_mandir}
294 MAN1DIR = ${cf_man1dir}
298 # now all object variables
302 # the all rule to include all executables
305 # Now the Makefile.in
306 echo "# Makefile.in contents:"
311 # all the targets and how to build them
314 # include dependency files too
315 echo "-include *.o.d"
316 ) > "${cf_wd}/Makefile"