vkdot/badwolf/configure
2025-03-02 03:05:35 -05:00

455 lines
11 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# SPDX-FileCopyrightText: 2019-2023 Badwolf Authors <https://hacktivis.me/projects/badwolf>
# SPDX-License-Identifier: BSD-3-Clause
VERSION=1.3.0
VERSION_FULL=${VERSION}$(./version.sh)
DEPS="gtk+-3.0 libxml-2.0"
SRCS="bookmarks.c userscripts.c fmt.c fmt_test.c uri.c uri_test.c keybindings.c downloads.c badwolf.c"
OBJS="bookmarks.o userscripts.o fmt.o uri.o keybindings.o downloads.o badwolf.o"
OBJS_test="fmt_test.o uri_test.o bookmarks_test.o"
EXE=badwolf
EXE_test="fmt_test uri_test bookmarks_test"
DOCS="usr.bin.badwolf README.md KnowledgeBase.md interface.md"
TRANS="fr pt_BR tr de vi"
TRANS_MAN="de fr tr vi"
lint_targets=""
min_webkitgtk=2.32.0
min_glib_guri=2.66.0
arg0="$0"
args="$@"
usage() {
cat <<END
Usage: [variables] configure [variables]
Variables:
PREFIX=DIR
BINDIR=DIR
MANDIR=DIR
DOCDIR=DIR
DATADIR=DIR
APPSDIR=DIR
PKGCONFIG=BIN
MSGFMT=BIN
INKSCAPE=BIN
CC=BIN
CFLAGS=OPTIONS
ED=BIN
LDFLAGS=OPTIONS
EXTRA_CFLAGS=OPTIONS
XGETTEXT=BIN
MSGMERGE=BIN
MANDOC=BIN
SHELLCHECK=BIN
FLAWFINDER=BIN
REUSE=BIN
WITH_WEBKITGTK=(4.0|4.1)
WITH_URI_PARSER=(guri|libsoup2)
Variables are set in the following order: Default, Environment, Arguments
Dependencies: See README.md
END
}
is_ok() {
status="$?"
if test $status -eq 0; then
printf " OK\n"
else
printf " FAIL\n"
fi
return $status
}
required() {
is_ok || exit 1
}
pkg_config_check() {
printf 'Checking: %s %s ...' "${PKGCONFIG}" "$*"
"${PKGCONFIG}" "$@"
is_ok
}
## User configuration
# defaults
PREFIX="${PREFIX:-/usr/local}"
PKGCONFIG="${PKGCONFIG:-pkg-config}"
MSGFMT="${MSGFMT:-msgfmt}"
INKSCAPE="${INKSCAPE:-inkscape}"
CC="${CC:-cc}"
CFLAGS="${CFLAGS:--g -O2 -D_FORTIFY_SOURCE=2}"
ED="${ED:-ed}"
XGETTEXT="${XGETTEXT:-xgettext}"
MSGMERGE="${MSGMERGE:-msgmerge}"
MANDOC="${MANDOC:-mandoc}"
SHELLCHECK="${SHELLCHECK:-shellcheck}"
FLAWFINDER="${FLAWFINDER:-flawfinder}"
REUSE="${REUSE:-reuse}"
# Also allow variables through arguments
for i; do
case "$i" in
-h|--help)
usage
exit 1
;;
-*)
printf "Unknown argument %s\n" "${i}"
usage
exit 1
;;
*=*)
# shellcheck disable=SC2163
export "$i"
shift
;;
*)
printf "Unknown argument %s\n" "${i}"
usage
exit 1
;;
esac
done
# Fallback definitions for dirs, based on $PREFIX
BINDIR="${BINDIR:-${PREFIX}/bin}"
MANDIR="${MANDIR:-${PREFIX}/share/man}"
DOCDIR="${DOCDIR:-${PREFIX}/share/doc/badwolf-${VERSION}}"
DATADIR="${DATADIR:-${PREFIX}/share/badwolf}"
APPSDIR="${APPSDIR:-${PREFIX}/share/applications}"
# Add some extra CFLAGS
CFLAGS="${CFLAGS} -Wall -Wextra -Wconversion -Wsign-conversion -Werror=implicit-function-declaration -Werror=implicit-int -Werror=vla ${EXTRA_CFLAGS}"
## System checks
# commands
printf 'Checking %s command existance ...' "${PKGCONFIG}"
command -v "${PKGCONFIG}" >/dev/null ; required
printf 'Checking %s command existance ...' "${CC}"
command -v "${CC}" >/dev/null ; required
printf 'Checking %s command existance ...' "${ED}"
if command -v "${ED}" >/dev/null ; is_ok
then
:
else
echo 'Warning: Fixing copyright in po/*.pot files via ed(1) disabled'
ED="false"
fi
printf 'Checking %s command existance ...' "${MANDOC}"
if command -v "${MANDOC}" >/dev/null ; is_ok
then
lint_targets="${lint_targets} lint_mandoc"
else
echo 'Warning: manpage linting via mandoc(1) disabled'
MANDOC="true"
fi
printf 'Checking %s command existance ...' "${XGETTEXT}"
if command -v "${XGETTEXT}" >/dev/null ; is_ok
then
if [ "${XGETTEXT}" != "true" ]
then
# This is due to NetBSD base system having a very old version of gettext (0.16)
printf 'Checking if %s --help lists --package-name= option ...' "${XGETTEXT}"
if "${XGETTEXT}" --help 2>&1 | grep -q package-name=; is_ok
then
:
else
echo 'Warning: translation updates disabled, you may want to set XGETTEXT'
XGETTEXT="true"
fi
else
echo 'Warning: translation updates disabled'
fi
else
echo 'Warning: translation updates disabled'
XGETTEXT="true"
fi
printf 'Checking %s command existance ...' "${MSGMERGE}"
if command -v "${MSGMERGE}" >/dev/null ; is_ok
then
:
else
echo 'Warning: translation updates disabled'
MSGMERGE="true"
fi
printf 'Checking %s command existance ...' "${SHELLCHECK}"
if command -v "${SHELLCHECK}" >/dev/null ; is_ok
then
lint_targets="${lint_targets} lint_shellcheck"
else
echo 'Warning: shell linting via shellcheck(1) disabled'
SHELLCHECK="true"
fi
printf 'Checking %s command existance ...' "${FLAWFINDER}"
if command -v "${FLAWFINDER}" >/dev/null ; is_ok
then
lint_targets="${lint_targets} lint_flawfinder"
else
echo 'Warning: C analysis via flawfinder(1) disabled'
FLAWFINDER="true"
fi
printf 'Checking %s command existance ...' "${REUSE}"
if command -v "${REUSE}" >/dev/null ; is_ok
then
lint_targets="${lint_targets} lint_reuse"
else
echo 'Warning: License linting via reuse(1) disabled'
REUSE="true"
fi
echo
# pkg-config
for dep in ${DEPS}
do
pkg_config_check --exists "$dep" || exit 1
done
case "${WITH_WEBKITGTK}n" in
4.1n)
pkg_config_check --atleast-version="${min_webkitgtk}" webkit2gtk-4.1 || exit 1
DEPS="${DEPS} webkit2gtk-4.1"
;;
4.0n)
pkg_config_check --atleast-version="${min_webkitgtk}" webkit2gtk-4.0 || exit 1
DEPS="${DEPS} webkit2gtk-4.0"
;;
n)
echo "notice: Packagers should consider setting the ABI version (4.0 or 4.1) in WITH_WEBKITGTK" >&2
if pkg_config_check --atleast-version="${min_webkitgtk}" webkit2gtk-4.1
then
DEPS="${DEPS} webkit2gtk-4.1"
else
pkg_config_check --atleast-version="${min_webkitgtk}" webkit2gtk-4.0 || exit 1
DEPS="${DEPS} webkit2gtk-4.0"
fi
;;
*)
echo "error: invalid webkit2gtk version in WITH_WEBKITGTK environment variable, must be 4.0 or 4.1" >&2
exit 1
;;
esac
case "${WITH_URI_PARSER}n" in
gurin)
echo "URI parser selected: GUri from glib-2.0"
pkg_config_check --atleast-version="${min_glib_guri}" glib-2.0 || exit 1
DEPS="${DEPS} glib-2.0"
;;
libsoup2n)
echo "URI parser selected: libsoup-2.4"
pkg_config_check libsoup-2.4 || exit 1
DEPS="${DEPS} libsoup-2.4"
CFLAGS="${CFLAGS} -DUSE_LIBSOUP2"
if echo "${DEPS}" | grep -q 'webkit2gtk-4.1'
then
echo 'warning: libsoup2 selected while WebKitGTK with libsoup3 API is used' >&2
fi
;;
n)
echo "notice: Packagers should consider setting the URI parsing library (guri or libsoup2) in WITH_URI_PARSER" >&2
if echo "${DEPS}" | grep -q 'webkit2gtk-4.0'
then
pkg_config_check libsoup-2.4 || exit 1
echo "URI parser selected: libsoup-2.4"
DEPS="${DEPS} libsoup-2.4"
CFLAGS="${CFLAGS} -DUSE_LIBSOUP2"
else
pkg_config_check --atleast-version="${min_glib_guri}" glib-2.0 || exit 1
echo "URI parser selected: GUri from glib-2.0"
DEPS="${DEPS} glib-2.0"
fi
;;
*)
echo "error: invalid uri provider in WITH_URI_PARSER environment variable, must be guri or libsoup2" >&2
;;
esac
printf 'Using pkg-config to get CFLAGS for %s ...' "${DEPS}"
get_cflags() { "${PKGCONFIG}" --cflags "${DEPS}"; }
DEPS_cflags="$(get_cflags)"
required
printf 'Using pkg-config to get LIBS for %s ...' "${DEPS}"
get_libs() { "${PKGCONFIG}" --libs "${DEPS}"; }
DEPS_libs="$(get_libs)"
required
echo
printf 'Writing to configure.h ...'
cat >configure.h <<EOF
#define DATADIR "${DATADIR}"
#define PACKAGE "Badwolf"
#define _XOPEN_SOURCE 700
#define _POSIX_C_SOURCE 200809L
#define VERSION "${VERSION_FULL}"
EOF
is_ok
## Configuration write
printf 'Writing to config.ninja ...'
cat >config.ninja <<EOF
# Autogenerated by $arg0 $args
rule gen_config
command = $arg0 "$args"
generator = 1
build config.ninja: gen_config configure
PREFIX = ${PREFIX}
PKGCONFIG = ${PKGCONFIG}
MSGFMT = ${MSGFMT}
INKSCAPE = ${INKSCAPE}
CC = ${CC}
CFLAGS = ${CFLAGS}
LDFLAGS = ${LDFLAGS}
ED = ${ED}
MANDOC = ${MANDOC}
XGETTEXT = ${XGETTEXT}
MSGMERGE = ${MSGMERGE}
SHELLCHECK = ${SHELLCHECK}
FLAWFINDER = ${FLAWFINDER}
REUSE = ${REUSE}
DEPS_cflags = ${DEPS_cflags}
DEPS_libs = ${DEPS_libs}
GETTEXT_OPTS = --copyright-holder="Badwolf Authors <https://hacktivis.me/projects/badwolf>" --package-name="Badwolf" --package-version="${VERSION_FULL}" --msgid-bugs-address="contact+badwolf-msgid@hacktivis.me"
rule xgettext
command = \$XGETTEXT --keyword=_ --language=C --from-code=UTF-8 -o \$out --add-comments --sort-output --foreign-user --no-location --no-wrap \$GETTEXT_OPTS \$in && ed -s \$out <po/pot_license.ed
rule msgmerge
# touch: msgmerge doesn't always updates timestamps
command = \$MSGMERGE --update --backup=off \$out \$in && touch \$out
rule xgettext_man
command = if test -e \$out; $
then po4a-updatepo --format man -M utf-8 --master \$in \$GETTEXT_OPTS --po \$out && ed -s \$out <po/pot_license.ed;$
else po4a-gettextize --format man -M utf-8 --master \$in \$GETTEXT_OPTS --po \$out && ed -s \$out <po/pot_license.ed;$
fi
rule cc_exe
command = \$CC -std=c11 \$CFLAGS -include configure.h \$DEPS_cflags -o \$out \$in \$LDFLAGS \$DEPS_libs
rule cc_obj
command = \$CC -std=c11 \$CFLAGS -include configure.h \$DEPS_cflags -c -o \$out \$in
build po/messages.pot: xgettext ${SRCS} | po/pot_license.ed
build badwolf: cc_exe ${OBJS}
EOF
all="badwolf"
for obj in ${OBJS}; do
obj_c="$(echo "$obj" | sed -e 's;\.o;.c;g')"
echo -n "build ${obj}: cc_obj ${obj_c} | "
grep '#include "' "${obj_c}" | sed -e 's;#include ";;' -e 's;";;' | tr '\n' ' '
echo
done >>config.ninja
for trans in ${TRANS}; do
echo "build po/${trans}.po: msgmerge po/messages.pot"
echo "build locale/${trans}/LC_MESSAGES/Badwolf.mo: po2mo po/${trans}.po"
all="${all} locale/${trans}/LC_MESSAGES/Badwolf.mo"
done >>config.ninja
for man in ${TRANS_MAN}; do
echo "build po/${man}_man.po: xgettext_man badwolf.1"
echo "build badwolf.${man}.1: translate_manpage po/${man}_man.po"
bundled="${bundled} badwolf.${man}.1"
trans_man="${trans_man} badwolf.${man}.1"
done >>config.ninja
for i in 24 32 48 64 128 256; do
echo "build icons/hicolor/${i}x${i}/apps/badwolf.png: gen_icon icons/hicolor/scalable/apps/badwolf.svg
width = $i
height = $i"
bundled="${bundled} icons/hicolor/${i}x${i}"
icons_list="${icons_list} icons/hicolor/${i}x${i}/apps/badwolf.png"
done >>config.ninja
cat >>config.ninja <<EOF
build icons: phony | ${icons_list}
build trans_man: phony | ${trans_man}
build bundled: phony | icons trans_man
default ${all}
rule remove
command = rm -fr \${in} \${foo}
build install: install | ${all}
build clean: remove
foo = ${all} ${OBJS} ${OBJS_test}
build distclean: remove | clean
foo = config.ninja configure.h install.sh
build fullclean: remove | distclean
foo = ${bundled}
EOF
is_ok
printf 'Writing to ./install.sh ...'
cat >install.sh <<EOF
# Autogenerated by $arg0 $args
# doins <DIR> <filename ...>
doins() {
dir="\${DESTDIR}/\$1"; shift
mkdir -p "\${dir}/" || exit 1
echo "\$@ → \${dir}/"
cp -pr "\$@" "\${dir}/"
}
# newins <DIR> <orig-filename> <dest-filename>
newins() {
dir="\${DESTDIR}/\$1"
mkdir -p "\${dir}/" || exit 1
echo "\$2 → \${dir}/\$3"
cp -pr "\$2" "\${dir}/\$3"
}
doins "${BINDIR}" ./badwolf
doins "${MANDIR}/man1" ./badwolf.1
for man in ${TRANS_MAN}; do
newins "${MANDIR}/\${man}/man1" "./badwolf.\${man}.1" "badwolf.1"
done
doins "${DATADIR}" ./locale
doins "${DATADIR}" ./interface.css
doins "${APPSDIR}" badwolf.desktop
doins "${DOCDIR}" ${DOCS}
doins "${PREFIX}/share" icons
printf "\nNote: An example AppArmor profile has been installed at '${DOCDIR}/usr.bin.badwolf'\n"
EOF
is_ok
echo 'Done, you can now run ninja or samu'