1#!/usr/bin/env bash
2#
3# Configure script for pqiv. Running this script is optional if you only want
4# gdk-pixbuf support, but still recommended.
5#
6
7tempdir() {
8	NAME=tmp_${RANDOM}
9	while ! mkdir "${NAME}" 2>/dev/null; do
10		NAME=tmp_${RANDOM}
11	done
12	echo ${NAME}
13}
14
15PREFIX=/usr
16DESTDIR=
17GTK_VERSION=0
18CROSS=
19BINARY_EXTENSION=
20BINDIR=
21LIBDIR=
22MANDIR=
23BACKENDS=
24ENFORCED_BACKENDS=
25DISABLED_BACKENDS=
26EXTRA_DEFS=
27BACKENDS_BUILD=static
28DEBUG_DEFS=
29
30# Check if configure was called from another directory;
31# support for out-of-source-tree builds
32STARTUP_DIR="$(pwd)"
33SOURCE_DIR="$( (cd "$(dirname "$0")"; pwd -P) )"
34cd "$SOURCE_DIR"
35
36# For development, you can set default settings here
37[ -x ./configure-dev ] && . ./configure-dev
38
39# Help and options
40help() {
41	cat >&2 <<EOF
42pqiv configuration
43
44general options:
45  --prefix=..           Set the prefix for installed files [/usr]
46  --destdir=..          Set the destination prefix for "make install" [/]
47  --libdir=..           Set the directory for shared libraries [\$PREFIX/lib]
48  --gtk-version=2       Use GTK+-2.0 even if GTK+-3.0 is available
49  --cross=..            Set a cross-compiler prefix (e.g. \`i686-pc-mingw32-')
50
51  Some of the usual autotools options are supported as well for advanced users.
52  See the source code of the configure script.
53
54options to select pqiv's backends:
55  --backends=..         Select which backends to include in pqiv
56                        (autodetermined by default)
57                        Available:
58                          archive (generic archive file support),
59                          archive_cbx (*.cb? comic book archive support),
60                          libav (Video support, works with ffmpeg as well),
61                          gdkpixbuf (images),
62                          poppler (PDF),
63                          spectre (PS/EPS),
64                          wand (ImageMagick, various formats)
65                          webp (WebP format)
66  --with[out]-<backend> Alternative syntax for backend selection. Non-specified backends are
67                        autodetermined.
68  --backends-build=..   Either \`shared' to compile the backends as shared libraries,
69                        or \`static' to compile them into pqiv. \`shared' is only of use if you
70                        plan to package pqiv and want to get rid of the run-time dependencies,
71                        so this defaults to \`static'.
72
73options to remove features from pqiv:
74EOF
75
76	awk 'BEGIN { FS="ifndef|ifdef|option|:|/\\*|\\*/" } /ifn?def .+ option / { print $2 " " $4 " " $5 }' pqiv.c | while read DEFNAME OPTFLAG DESCRIPTION; do
77		if [ ${#DESCRIPTION} -gt 50 ]; then
78			printf "  %-22s\n  %-22s%s\n" $OPTFLAG "" "$DESCRIPTION" >&2
79		else
80			printf "  %-22s%s\n" $OPTFLAG "$DESCRIPTION" >&2
81		fi
82	done
83	echo >&2
84}
85
86while [ $# -gt 0 ]; do
87	PARAMETER=${1%=*}
88	VALUE=${1#*=}
89
90	case $PARAMETER in
91		--prefix)
92			PREFIX=$VALUE
93			;;
94		--destdir)
95			DESTDIR=$VALUE
96			;;
97		--libdir)
98			LIBDIR=${VALUE}
99			LIBDIR="${LIBDIR//\{/(}"
100			LIBDIR="${LIBDIR//\}/)}"
101			LIBDIR="${LIBDIR//prefix/PREFIX}"
102			;;
103		--gtk-version)
104			GTK_VERSION=$VALUE
105			;;
106		-h)
107			help
108			exit 0
109			;;
110		--help)
111			help
112			exit 0
113			;;
114		--cross)
115			CROSS=$VALUE
116			if [ "${CROSS: -1}" != "-" ]; then
117				CROSS="$CROSS-"
118			fi
119			;;
120		--backends-build)
121			BACKENDS_BUILD=$VALUE
122			if [ "$BACKENDS_BUILD" != "static" -a "$BACKENDS_BUILD" != "shared" ]; then
123				echo "Invalid argument to --backends-build: Value must be either \`static' or \`shared'." >&2
124				exit 1
125			fi
126			;;
127		--backends)
128			BACKENDS="${VALUE//,/ }"
129			for NAME in ${BACKENDS}; do
130				[ -e backends/${NAME}.c ] && continue
131				echo "Invalid argument to --backends: Backend ${NAME} was not found" >&2
132				exit 1
133			done
134			;;
135		# Undocumented options for autoconf (esp. dh_auto_configure)
136		# compatibility Note to maintainers: These options are here to make it
137		# simpler to package pqiv, because they allow to run autotools wrappers
138		# against this package.  I will maintain them, but I'd recommend
139		# against using them if you can avoid it.
140		--host)
141			CROSS=${VALUE}-
142			;;
143		--bindir)
144			BINDIR=${VALUE}
145			BINDIR="${BINDIR//\{/(}"
146			BINDIR="${BINDIR//\}/)}"
147			BINDIR="${BINDIR//prefix/PREFIX}"
148			echo "Use of autoconf option --bindir is discouraged, because support is incomplete. Rewrote \`$VALUE' to \`$BINDIR' and used that as the BINDIR Make variable." >&2
149			;;
150		--mandir)
151			MANDIR=${VALUE}
152			MANDIR="${MANDIR//\{/(}"
153			MANDIR="${MANDIR//\}/)}"
154			MANDIR="${MANDIR//prefix/PREFIX}"
155			echo "Use of autoconf option --mandir is discouraged, because support is incomplete. Rewrote \`$VALUE' to \`$MANDIR' and used that as the MANDIR Make variable." >&2
156			;;
157		--disable-silent-rules)
158			VERBOSE=1
159			;;
160		--infodir | --sysconfdir | --includedir | --localstatedir | --libexecdir | --disable-maintainer-mode | --disable-dependency-tracking | --build | --sbindir | --includedir | --oldincludedir | --localedir | --docdir)
161			echo "autoconf option ${PARAMETER} ignored" >&2
162			;;
163		--no-sorting | --no-compositing | --no-fading | --no-commands | --no-config-file | --no-inotify | --no-animations | --binary-name)
164			echo "obsolete 1.0 option ${PARAMETER} ignored" >&2
165			;;
166		*)
167			# Check for disableable feature flag
168			DEF=$(
169				awk 'BEGIN { FS="ifndef|ifdef|option|:|/\\*|\\*/" } /ifn?def .+ option / { print $2 " " $4 " " $5 }' pqiv.c | while read DEFNAME OPTFLAG DESCRIPTION; do
170					if [ "${PARAMETER}" = "${OPTFLAG}" ]; then
171						echo "-D${DEFNAME}"
172					fi
173				done
174			)
175			if [ -n "${DEF}" ]; then
176				EXTRA_DEFS="${EXTRA_DEFS} ${DEF}"
177			else
178				# Check for dynamic backend en-/dis-abling flag
179				if [ "${PARAMETER#--without-}" != "${PARAMETER}" ]; then
180					NAME="${PARAMETER#--without-}"
181					if ! [ -e backends/${NAME}.c ]; then
182						echo "Unknown option: $1" >&2
183						exit 1
184					fi
185					DISABLED_BACKENDS="${PARAMETER#--without-} ${DISABLED_BACKENDS}"
186				elif [ "${PARAMETER#--with-}" != "${PARAMETER}" ]; then
187					NAME="${PARAMETER#--with-}"
188					if ! [ -e backends/${NAME}.c ]; then
189						echo "Unknown option: $1" >&2
190						exit 1
191					fi
192					ENFORCED_BACKENDS="${NAME} ${ENFORCED_BACKENDS}"
193				else
194					echo "Unknown option: $1" >&2
195					help
196					exit 1
197				fi
198			fi
199	esac
200	shift
201done
202
203# The makefile is for GNU make
204if [ -z $MAKE ]; then
205	MAKE=make
206	if ! (${MAKE} -v 2>&1 | grep -q "GNU Make"); then
207		MAKE=gmake
208		if ! which $MAKE 2>&1 >/dev/null; then
209			echo "GNU make is required for building pqiv" >&2
210			exit 1
211		fi
212	fi
213fi
214
215# If cross-compiling, check if cc is present (usually it is not)
216if [ -n "$CROSS" -a -z "$CC" ]; then
217	echo -n "Checking for cross-compiler cc..              "
218	if ! which ${CROSS}cc >/dev/null 2>&1; then
219		if which ${CROSS}clang >/dev/null 2>&1; then
220			export CC=clang
221		elif which ${CROSS}gcc >/dev/null 2>&1; then
222			export CC=gcc
223		else
224			echo
225			echo
226			echo "No compiler found. Please set the appropriate CC environment variable." >&2
227			exit 1
228		fi
229		echo "using ${CROSS}${CC}"
230	else
231		echo "ok"
232	fi
233fi
234
235# Determine binary extension (for Windows)
236echo -n "Determining executable extension..            "
237DIR=`tempdir`
238cd $DIR
239echo 'int main(int argc, char *argv[]) { return 0; }' > test.c
240${CROSS}${CC:-cc} ${CFLAGS} test.c ${LDFLAGS}
241RV=$?
242rm -f test.c
243EXECUTABLE=`ls`
244rm -f $EXECUTABLE
245cd ..
246rmdir $DIR
247if [ "$RV" != 0 ]; then
248	echo
249	echo
250	echo "The compiler can't compile executables!?" >&2
251	exit 1
252fi
253EXECUTABLE_EXTENSION=${EXECUTABLE#a}
254if [ "$EXECUTABLE_EXTENSION" = ".out" ]; then
255	EXECUTABLE_EXTENSION=
256fi
257echo ${EXECUTABLE_EXTENSION:-(none)}
258
259# Do a rudimental prerequisites check to have user-friendlier error messages
260if [ -n "${CROSS}" -a -z "${PKG_CONFIG}" ]; then
261	echo -n "Checking for pkg-config..                     "
262	PKG_CONFIG=${CROSS}pkg-config
263	if ! which ${PKG_CONFIG} >/dev/null 2>&1; then
264		echo
265		echo
266		echo "Did not find a specialized tool ${CROSS}pkg-config, defaulting to pkg-config" >&2
267		echo "If you really ARE cross-compiling, the build might therefore fail!" >&2
268		echo
269		PKG_CONFIG=pkg-config
270	else
271		echo "${PKG_CONFIG}"
272	fi
273fi
274
275# Auto-determine available backends
276if [ -z "$BACKENDS" ]; then
277	echo -n "Checking for supported backends..             "
278	BACKENDS="$($MAKE get_available_backends ${PKG_CONFIG:+PKG_CONFIG="$PKG_CONFIG"} | awk '/^BACKENDS:/ {print substr($0, 11);}') "
279	echo "${BACKENDS:-(none)}"
280fi
281
282# Disable explicitly disabled and enable explicitly enabled backends
283for BACKEND in ${DISABLED_BACKENDS}; do
284	BACKENDS="${BACKENDS/${BACKEND}/}"
285done
286for BACKEND in ${ENFORCED_BACKENDS}; do
287	BACKENDS="${BACKEND} ${BACKENDS/${BACKEND} /}"
288done
289
290echo "Building with backends:                       ${BACKENDS:-(none)}"
291if [ -z "$BACKENDS" ]; then
292	echo "WARNING: Building without backends! You won't be able to see _any_ images." >&2
293fi
294
295echo -n "Checking if the prerequisites are installed.. "
296LIBS_GTK3="`$MAKE get_libs GTK_VERSION=3 EXECUTABLE_EXTENSION=$EXECUTABLE_EXTENSION ${PKG_CONFIG:+PKG_CONFIG="$PKG_CONFIG"} ${BACKENDS:+BACKENDS="$BACKENDS"} | awk '/^LIBS:/ {print substr($0, 7);}'`"
297LIBS_GTK2="`$MAKE get_libs GTK_VERSION=2 EXECUTABLE_EXTENSION=$EXECUTABLE_EXTENSION ${PKG_CONFIG:+PKG_CONFIG="$PKG_CONFIG"} ${BACKENDS:+BACKENDS="$BACKENDS"} | awk '/^LIBS:/ {print substr($0, 7);}'`"
298
299if [ $? != 0 ]; then
300	echo "failed."
301	echo
302	echo
303	echo "Failed to run make. Is your make command compatible to GNU make?" >&2
304	exit 1
305fi
306
307if ${PKG_CONFIG:-pkg-config} --exists "$LIBS_GTK3"; then
308	LIBS="${LIBS_GTK3}"
309	echo "ok"
310else
311	if ${PKG_CONFIG:-pkg-config} --exists "$LIBS_GTK2"; then
312		if [ "$GTK_VERSION" = 3 ]; then
313			echo "failed."
314			echo
315			echo
316			echo "GTK 2 was found, but you manually specified --gtk-version=3, which was not found." >&2
317			echo "If you want GTK3, install the development packages for" >&2
318			echo " ${LIBS_GTK3}" >&2
319			exit 1
320		fi
321		echo "ok, found GTK 2"
322		GTK_VERSION=2
323		LIBS="${LIBS_GTK2}"
324	else
325		echo "failed."
326		echo
327		echo
328		echo "Please install either the development packages for " >&2
329		echo " ${LIBS_GTK3}" >&2
330		echo "or for" >&2
331		echo " ${LIBS_GTK2}" >&2
332		exit 1
333	fi
334fi
335
336if [ "$SOURCE_DIR" != "$STARTUP_DIR" ]; then
337	if ! [ -e $STARTUP_DIR/GNUmakefile ]; then
338		echo "Writing GNUmakefile."
339		echo "include $SOURCE_DIR/GNUmakefile" > $STARTUP_DIR/GNUmakefile
340	else
341		echo "Not touching existing GNUmakefile."
342	fi
343fi
344
345
346echo "Writing config.make."
347cat > $STARTUP_DIR/config.make <<EOF
348DESTDIR=$DESTDIR
349PREFIX=$PREFIX
350GTK_VERSION=$GTK_VERSION
351CROSS=$CROSS
352EXECUTABLE_EXTENSION=$EXECUTABLE_EXTENSION
353${PKG_CONFIG:+PKG_CONFIG=$PKG_CONFIG}
354EXTRA_DEFS=${EXTRA_DEFS}
355BACKENDS_BUILD=$BACKENDS_BUILD
356${CFLAGS:+CFLAGS=$CFLAGS}
357${LDFLAGS:+LDFLAGS=$LDFLAGS}
358${CPPFLAGS:+CPPFLAGS=$CPPFLAGS}
359${MANDIR:+MANDIR=$MANDIR}
360${LIBDIR:+LIBDIR=$LIBDIR}
361${BINDIR:+BINDIR=$BINDIR}
362${BACKENDS:+BACKENDS=$BACKENDS}
363${CC:+CC=$CC}
364${VERBOSE:+VERBOSE=$VERBOSE}
365${EXTRA_CFLAGS_SHARED_OBJECTS:+EXTRA_CFLAGS_SHARED_OBJECTS=$EXTRA_CFLAGS_SHARED_OBJECTS}
366${EXTRA_CFLAGS_BINARY:+EXTRA_CFLAGS_BINARY=$EXTRA_CFLAGS_BINARY}
367${EXTRA_LDFLAGS_SHARED_OBJECTS:+EXTRA_LDFLAGS_SHARED_OBJECTS=$EXTRA_LDFLAGS_SHARED_OBJECTS}
368${EXTRA_LDFLAGS_BINARY:+EXTRA_LDFLAGS_BINARY=$EXTRA_LDFLAGS_BINARY}
369${DEBUG_DEFS}
370EOF
371
372# Check for lcms bug
373#
374if [ "${BACKENDS_BUILD}" = "static" -a "${BACKENDS/poppler//}" != "${BACKENDS}" -a "${BACKENDS/spectre//}" != "${BACKENDS}" -a -n "$(which ldd 2>/dev/null)" ]; then
375	echo -n "Checking if affected by liblcms bug..         "
376	DIR=`tempdir`
377	cd $DIR
378	echo -e "#include <poppler.h>\n#include <libspectre/spectre.h>\nint main() { poppler_get_version(); spectre_status_to_string(SPECTRE_STATUS_SUCCESS); }" > test.c
379	${CROSS}${CC:-cc} ${CFLAGS} test.c ${LDFLAGS} $(${PKG_CONFIG:-pkg-config} --libs --cflags ${LIBS}) -o test >/dev/null 2>&1
380	if [ -e test ]; then
381		if [ "$(ldd test | grep -E "liblcms[0-9]?.so" | wc -l)" -gt 1 ]; then
382			echo "yes"
383			echo 2>&1
384			echo "WARNING: You enabled both the spectre and poppler backends, and chose static linking." >&2
385			echo "Your system uses two different versions of liblcms that are known to interfere:" 2>&1
386			ldd test | grep -E "liblcms[0-9]?.so" >&2
387			echo "Recompile using --backends-build=shared if you experience problems." 2>&1
388			echo 2>&1
389		else
390			echo "no"
391		fi
392	else
393		echo "test failed"
394	fi
395	rm -f test.c test
396	cd ..
397	rmdir $DIR
398fi
399
400echo
401echo "Done. Run \`$MAKE install' to install pqiv."
402exit 0
403