2 # vim: ts=2 sts=2 sw=2 et:
12 --prefix=PREFIX change the install prefix [/usr/local]
13 --bindir=BINDIR target of executables [PREFIX/bin]
14 --datadir=DATADIR target of additional data [PREFIX/share]
15 --mandir=MANDIR target of manpages [DATADIR/man]
16 --man1dir=MAN1DIR manual section 1 [MANDIR/man1]
17 Environment variables:
18 CC, CPP, CFLAGS, CPPFLAGS
24 while [ $# -ge 1 ]; do
26 --prefix=*) cf_prefix="${1#--prefix=}" ;;
27 --bindir=*) cf_bindir="${1#--bindir=}" ;;
28 --datadir=*) cf_datadir="${1#--datadir=}" ;;
29 --mandir=*) cf_mandir="${1#--mandir=}" ;;
30 --man1dir=*) cf_man1dir="${1#--man1dir=}" ;;
33 echo "Unknown parameter: $1"
43 local mesg="$1"; shift
44 printf "fatal: ${mesg}\n" "$@" >> "${cf_log}"
45 printf "fatal: ${mesg}\n" "$@"
50 local mesg="$1"; shift
51 printf "configure: ${mesg}\n" "$@" >> "${cf_log}"
52 printf "configure: ${mesg}\n" "$@"
56 local mesg="$1"; shift
57 printf "${mesg}\n" "$@" >> "${cf_log}"
61 echo "$@" >> "${cf_log}"
66 # Some library functions
69 if which $1 >/dev/null 2>&1
75 # so we don't have to repeat the >/dev/null all the time
77 # strip parameters (ie, 'need_cmd $CC' with CC="gcc -m32" should work)
79 which $1 >/dev/null 2>&1
84 # Well we can expect those to exist, no?
92 # default host specific values:
94 host="$(uname -s | tr A-Z a-z)"
97 cf_prefix="${cf_prefix:-/usr/local}"
98 cf_bindir="${cf_bindir:-${cf_prefix}/bin}"
99 cf_datadir="${cf_datadir:-${cf_prefix}/share}"
100 cf_mandir="${cf_mandir:-${cf_datadir}/man}"
101 cf_man1dir="${cf_man1dir:-${cf_mandir}/man1}"
105 cf_prefix="${cf_prefix:-}"
106 cf_bindir="${cf_bindir:-}"
107 cf_datadir="${cf_datadir:-}"
108 cf_mandir="${cf_mandir:-}"
109 cf_man1dir="${cf_man1dir:-}"
114 # will be set to one if the compiler can generate .d files
117 # for the default-supported compilers:
118 cf_cflags_gcc="-Wall -Wextra -Werror -Wstrict-aliasing -Wno-attributes"
123 cf_cflags_gcc="${cf_cflags_gcc} $@"
126 cf_ldflags_gcc="${cf_ldflags_gcc} $@"
129 cf_libs_gcc="${cf_libs_gcc} $@"
132 # Let's figure out where we are...
134 cf_log="${cf_wd}/config.log"
135 cf_dir="$(readlink -f "${progname}")"
136 # or should we use the hopefully more reliable basename command?
137 cf_dir="${cf_dir%/*}"
139 if [ "x${cf_dir}" = "x${cf_wd}" ]; then
140 echo "Please run this script in a different directory \
141 to not overwrite the git working tree."
145 # execute a command inside $cf_dir
147 # do it in a subshell so we don't change directory ourselves
148 ( cd "${cf_dir}" && "$@" ) || false
154 msg "looking for C compiler..."
156 has_cmd "${CC}" || CC=clang
157 has_cmd "${CC}" || CC=gcc
158 has_cmd "${CC}" || CC=cc
159 has_cmd "${CC}" || CC=tcc
160 has_cmd "${CC}" || die "no compiler found"
161 msg 'using CC = %s' "${CC}"
163 # We might add support for different compilers with a different CLI
166 if [ "x${CC}" != "xclang" -a "x${CC}" != "gcc" -a "x${CC}" != "g++" ]; then
167 msg "checking compiler type"
168 cf_ccver="$(${CC} -v 2>&1)"
169 [ $? -eq 0 ] || die "Failed to retrieve compiler version info"
170 if (echo "${cf_ccver}" | grep -q '\<clang\|gcc\>'); then
171 msg "found compatible compiler"
173 die "don't know how to use this compiler..."
177 # Find a preprocessor too
178 msg "looking for a C preprocessor..."
179 CPP=${CPP:-clang-cpp}
180 has_cmd "${CPP}" || CPP=cpp
181 if ! has_cmd "${CPP}"; then
182 msg "no C preprocessor found, trying -E"
183 logprint 'executing the following program with %s' "$CC -E"
184 prog="#define SHOW(X) :X:\nSHOW(THIS WORKS)\n"
185 logprint '%s' "${prog}"
186 if echo "${prog}" | $CC -E - 2>&1 \
187 | awk '/^:THIS WORKS:$/{ exit(0); } END {exit(1);}'; then
188 msg 'using preprocessor: %s' "$CC -E"
191 fatal "cannot find a working C preprocessor"
194 msg 'using CPP = %s' "${CPP}"
197 # Git information - that is, if git is available
200 # And provided we're in a git repo:
201 if [ -d "${cf_dir}/.git" ]; then
203 msg "reading git info"
204 cf_gitinfo_text="$(indir git describe --always)"
210 has_cmd valgrind && cf_valgrind=1
212 # compiler specific flags:
213 [ "x${CC}" != "xg++" ] && \
214 cflags_gcc -Wmissing-prototypes -Wstrict-prototypes
216 if [ "x${CC}" = "xclang" ]; then
217 cflags_gcc -Weverything
218 cflags_gcc -Wno-padded
219 cflags_gcc -Wno-format-nonliteral
220 cflags_gcc -Wno-disabled-macro-expansion
221 cflags_gcc -Wno-conversion
222 cflags_gcc -Wno-float-equal
223 cflags_gcc -Wno-unknown-warning-option
224 cflags_gcc -Wno-cast-align
227 if [ "x${CC}" != "xtcc" ]; then
228 cflags_gcc -pedantic-errors
230 cflags_gcc -Wno-pointer-sign -fno-common
235 if [ ${cf_gitinfo} -ne 0 ]; then
236 cflags_gcc '-DGMQCC_GITINFO="${cf_gitinfo_text}"'
239 if [ ${cf_valgrind} -eq 0 ]; then
240 cflags_gcc -DNVALGRIND
244 # Put the cflags/ldflags/libs we use into cf_cflags/ldflags/libs
246 case "${cf_cctype}" in
248 cf_cflags="${cf_cflags_gcc}"
249 cf_ldflags="${cf_ldflags_gcc}"
250 cf_libs="${cf_libs_gcc}"
253 die "compiler type '%s' not handled here!" "${cf_cctype}"
257 # Dependency generation
260 (echo "${cf_dir}"; $CPP "$@") | awk \
263 cf_len=length(cf_dir);
267 if (substr($3,1,cf_len) == cf_dir)
275 # Makefile generation routines
278 # executables is an array of variable names used in the makefile to
279 # name an executable; the list of objects is assumed to be
281 executables="GMQCC QCVM TESTSUITE PAK"
284 all_c_obj="${all_c_obj} $@"
289 for i in ${executables}; do
290 printf ' $(%s)' "${i}"
295 # create all the object variables:
297 common="ansi.o util.o hash.o stat.o fs.o opts.o conout.o"
300 gmqcc="main.o utf8.o lexer.o parser.o ftepp.o fold.o"
301 gmqcc="${gmqcc} intrin.o correct.o ast.o ir.o code.o"
308 add_c_obj ${testsuite}
314 GMQCC = gmqcc${cf_exesuffix}
315 QCVM = qcvm${cf_exesuffix}
316 TESTSUITE = testsuite${cf_exesuffix}
317 PAK = pak${cf_exesuffix}
319 QCVM_OBJ := ${common} ${qcvm}
320 GMQCC_OBJ := ${common} ${gmqcc}
321 TESTSUITE_OBJ := ${common} ${testsuite}
322 PAK_OBJ := ${common} ${pak}
325 printf 'ALL_PROGRAMS ='
326 for i in ${executables}; do
327 printf ' $(%s)' "${i}"
332 # generate the commands used to build objects and executables
333 # in a way that works with both BSD make and gmake by not relying
334 # on special vars like - also generate the .d files
336 # generate object rules to get the right path: $cf_dir
337 for obj in ${all_c_obj}; do
338 local c_src="${cf_dir}/${obj%.o}.c"
339 local d_inc="${obj}.d"
340 echo "${obj}: ${c_src}"
341 printf '\t$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ "%s"' "${c_src}"
342 if [ "x$cf_cctype" == "xgcc" ]; then
344 printf ' -MMD -MF "%s" -MT $@\n' "${d_inc}"
350 for exe in ${executables}; do
351 echo "\$(${exe}): \$(${exe}_OBJ)"
352 printf '\t$(CC) $(LDFLAGS) -o $(%s) $(%s_OBJ) $(LIBS)\n' "${exe}" "${exe}"
357 # Now generate our output file
359 echo "Generating Makefile"
362 # First: cflags and directories
367 CFLAGS = ${CFLAGS} ${cf_cflags}
368 LDFLAGS = ${LDFLAGS} ${cf_ldflags}
369 LIBS = ${LIBS} ${cf_libs}
374 PREFIX = ${cf_prefix}
375 BINDIR = ${cf_bindir}
376 DATADIR = ${cf_datadir}
377 MANDIR = ${cf_mandir}
378 MAN1DIR = ${cf_man1dir}
382 # now all object variables
386 # the all rule to include all executables
389 # Now the Makefile.in
390 echo "# Makefile.in contents:"
395 # all the targets and how to build them
398 # include dependency files too
400 echo '# Dependency rules'
401 if [ ${cf_dynamic_depends} -ne 0 ]; then
402 echo "-include *.o.d"
404 for obj in ${all_c_obj}; do
406 logprint 'generating dependencies for: %s' "${src}"
407 deps=$(depgrep "${cf_dir}/${src}" | tr "\n" " ")
408 logprint 'found: %s' "${deps}"
409 printf '%s: %s\n' "${obj}" "${cf_dir}/${src} ${deps}"
412 ) > "${cf_wd}/Makefile"