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"
106 cf_cflags_gcc="${cf_cflags_gcc} $@"
109 cf_ldflags_gcc="${cf_ldflags_gcc} $@"
112 cf_libs_gcc="${cf_libs_gcc} $@"
115 # Let's figure out where we are...
117 cf_dir="$(readlink -f "${progname}")"
118 # or should we use the hopefully more reliable basename command?
119 cf_dir="${cf_dir%/*}"
121 if [ "x${cf_dir}" = "x${cf_wd}" ]; then
122 echo "Please run this script in a different directory \
123 to not overwrite the git working tree."
127 # execute a command inside $cf_dir
129 # do it in a subshell so we don't change directory ourselves
130 ( cd "${cf_dir}" && "$@" ) || false
137 has_cmd "${CC}" || CC=clang
138 has_cmd "${CC}" || CC=gcc
139 has_cmd "${CC}" || CC=cc
140 has_cmd "${CC}" || CC=tcc
141 has_cmd "${CC}" || die "No compiler found"
143 # We might add support for different compilers with a different CLI
146 if [ "x${CC}" != "xclang" -a "x${CC}" != "gcc" -a "x${CC}" != "g++" ]; then
147 cf_ccver="$(${CC} -v 2>&1)"
148 [ $? -eq 0 ] || die "Failed to retrieve compiler version info"
149 if (echo "${cf_ccver}" | grep -q '\<clang\|gcc\>'); then
150 msg "found compatible compiler"
152 die "don't know how to use this compiler..."
156 # Git information - that is, if git is available
159 # And provided we're in a git repo:
160 if [ -d "${cf_dir}/.git" ]; then
162 msg "reading git info"
163 cf_gitinfo_text="$(indir git describe --always)"
169 has_cmd valgrind && cf_valgrind=1
171 # compiler specific flags:
172 [ "x${CC}" != "xg++" ] && \
173 cflags_gcc -Wmissing-prototypes -Wstrict-prototypes
175 if [ "x${CC}" = "xclang" ]; then
176 cflags_gcc -Weverything
177 cflags_gcc -Wno-padded
178 cflags_gcc -Wno-format-nonliteral
179 cflags_gcc -Wno-disabled-macro-expansion
180 cflags_gcc -Wno-conversion
181 cflags_gcc -Wno-float-equal
182 cflags_gcc -Wno-unknown-warning-option
183 cflags_gcc -Wno-cast-align
186 if [ "x${CC}" != "xtcc" ]; then
187 cflags_gcc -pedantic-errors
189 cflags_gcc -Wno-pointer-sign -fno-common
194 if [ ${cf_gitinfo} -ne 0 ]; then
195 cflags_gcc '-DGMQCC_GITINFO="${cf_gitinfo_text}"'
198 if [ ${cf_valgrind} -eq 0 ]; then
199 cflags_gcc -DNVALGRIND
203 # Put the cflags/ldflags/libs we use into cf_cflags/ldflags/libs
205 case "${cf_cctype}" in
207 cf_cflags="${cf_cflags_gcc}"
208 cf_ldflags="${cf_ldflags_gcc}"
209 cf_libs="${cf_libs_gcc}"
212 die "compiler type '%s' not handled here!" "${cf_cctype}"
216 # Makefile generation routines
219 # executables is an array of variable names used in the makefile to
220 # name an executable; the list of objects is assumed to be
222 executables="GMQCC QCVM TESTSUITE PAK"
225 all_c_obj="${all_c_obj} $@"
230 for i in ${executables}; do
231 printf ' $(%s)' "${i}"
236 # create all the object variables:
238 common="ansi.o util.o hash.o stat.o fs.o opts.o conout.o"
241 gmqcc="main.o utf8.o lexer.o parser.o ftepp.o fold.o"
242 gmqcc="${gmqcc} intrin.o correct.o ast.o ir.o code.o"
249 add_c_obj ${testsuite}
255 GMQCC = gmqcc${cf_exesuffix}
256 QCVM = qcvm${cf_exesuffix}
257 TESTSUITE = testsuite${cf_exesuffix}
258 PAK = pak${cf_exesuffix}
260 QCVM_OBJ := ${common} ${qcvm}
261 GMQCC_OBJ := ${common} ${gmqcc}
262 TESTSUITE_OBJ := ${common} ${testsuite}
263 PAK_OBJ := ${common} ${pak}
266 printf 'ALL_PROGRAMS ='
267 for i in ${executables}; do
268 printf ' $(%s)' "${i}"
273 # generate the commands used to build objects and executables
274 # in a way that works with both BSD make and gmake by not relying
275 # on special vars like - also generate the .d files
277 # generate object rules to get the right path: $cf_dir
278 for obj in ${all_c_obj}; do
279 local c_src="${cf_dir}/${obj%.o}.c"
280 local d_inc="${obj}.d"
281 echo "${obj}: ${c_src}"
282 printf '\t$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ "%s"' "${c_src}"
283 if [ "x$cf_cctype" == "xgcc" ]; then
284 printf ' -MMD -MF "%s" -MT $@\n' "${d_inc}"
290 for exe in ${executables}; do
291 echo "\$(${exe}): \$(${exe}_OBJ)"
292 printf '\t$(CC) $(LDFLAGS) -o $(%s) $(%s_OBJ) $(LIBS)\n' "${exe}" "${exe}"
297 # Now generate our output file
299 echo "Generating Makefile"
302 # First: cflags and directories
307 CFLAGS = ${CFLAGS} ${cf_cflags}
308 LDFLAGS = ${LDFLAGS} ${cf_ldflags}
309 LIBS = ${LIBS} ${cf_libs}
314 PREFIX = ${cf_prefix}
315 BINDIR = ${cf_bindir}
316 DATADIR = ${cf_datadir}
317 MANDIR = ${cf_mandir}
318 MAN1DIR = ${cf_man1dir}
322 # now all object variables
326 # the all rule to include all executables
329 # Now the Makefile.in
330 echo "# Makefile.in contents:"
335 # all the targets and how to build them
338 # include dependency files too
339 echo "-include *.o.d"
340 ) > "${cf_wd}/Makefile"