#!/bin/sh
#
#  Copyright (c) 2008-2026 Jonathan Schleifer <js@nil.im>
#
#  All rights reserved.
#
#  This program is free software: you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License version 3.0 only,
#  as published by the Free Software Foundation.
#
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
#  version 3.0 for more details.
#
#  You should have received a copy of the GNU Lesser General Public License
#  version 3.0 along with this program. If not, see
#  <https://www.gnu.org/licenses/>.
#

prefix="/usr/local"
exec_prefix="${prefix}"
libdir="${exec_prefix}/lib"
packagesdir="$libdir/objfw-config"
CFLAGS=""
CPPFLAGS=" -I${prefix}/include"
CXXFLAGS=""
OBJC="clang"
OBJCFLAGS=" -fexceptions -fobjc-exceptions -funwind-tables -fconstant-string-class=OFConstantString -Xclang -fno-constant-cfstrings -Xclang -fobjc-runtime=objfw-1.5 -Xclang -fblocks"
LIB_CFLAGS="-fPIC -DPIC"
LIB_LDFLAGS="-shared"
LIB_PREFIX="lib"
LIB_SUFFIX=".so.${LIB_MAJOR}.${LIB_MINOR}"
LDFLAGS=" -fexceptions -fstack-protector-strong -Wl,-z,relro,-z,now"
LDFLAGS_REEXPORT=""
LDFLAGS_RPATH="-Wl,-rpath,${libdir}"
LIBS="-lobjfw -lobjfwrt -lpthread -lm -lpthread "
FRAMEWORK_LIBS="-framework ObjFW"
FRAMEWORK_LIBS="$FRAMEWORK_LIBS  -lpthread -lm -lpthread "
PLUGIN_CFLAGS="-fPIC -DPIC"
PLUGIN_LDFLAGS="-shared"
PLUGIN_SUFFIX=".so"
PROG_SUFFIX=""
STATIC_LIBS="${libdir}/libobjfw.a ${libdir}/libobjfwrt.a -lpthread -lm -lpthread "
VERSION="1.5.7"

show_help() {
	cat >&2 <<__EOF__
objfw-config: Available arguments are:

    --all             Outputs all flags + libs
    --arc             Outputs the required OBJCFLAGS to use ARC
    --cflags          Outputs the required CFLAGS
    --cppflags        Outputs the required CPPFLAGS
    --cxxflags        Outputs the required CXXFLAGS
    --framework-libs  Outputs the required LIBS, preferring frameworks
    --help            Prints the help
    --ldflags         Outputs the required LDFLAGS
    --libs            Outputs the required LIBS
    --lib-cflags      Outputs CFLAGS for building a library
    --lib-ldflags     Outputs LDFLAGS for building a library
    --lib-prefix      Outputs the prefix for libraries
    --lib-suffix      Outputs the suffix for libraries
    --objc            Outputs the OBJC used to compile ObjFW
    --objcflags       Outputs the required OBJCFLAGS
    --package         Additionally outputs the flags for the specified package
    --packages-dir    Outputs the directory where flags for packages are stored
    --plugin-cflags   Outputs CFLAGS for building a plugin
    --plugin-ldflags  Outputs LDFLAGS for building a plugin
    --plugin-suffix   Outputs the suffix for plugins
    --prog-suffix     Outputs the suffix for binaries
    --reexport        Outputs LDFLAGS to reexport ObjFW
    --rpath           Outputs LDFLAGS for using rpath
    --static-libs     Outputs the required LIBS to link ObjFW statically
    --version         Outputs the installed ObjFW version
__EOF__
	exit $1
}

test -z "$1" && show_help 1

package_format() {
	if test "$1" != "1"; then
		echo "Unsupported package format version: $1" 1>&2
		exit 1
	fi
}

package_depends_on() {
	if ! test -f "$packagesdir/$1.oc"; then
		echo "No such package: $1" 1>&2
		exit 1
	fi

	set -e
	. "$packagesdir/$1.oc"
	set +e
}

parse_packages() {
	while test x"$1" != "x"; do
		case "$1" in
		--package)
			shift
			package_depends_on "$1"
			;;
		esac
		shift
	done
}
parse_packages "$@"

# Add search directories after all packages have been processed so that they
# always come first.
LIBS="-L${libdir} $LIBS"
FRAMEWORK_LIBS="-F${prefix}/Library/Frameworks $FRAMEWORK_LIBS"

flag_printed="no"
output_flag() {
	if test x"$flag_printed" = x"yes"; then
		printf " %s" "$1"
	else
		printf "%s" "$1"
		flag_printed="yes"
	fi
}

while test x"$1" != "x"; do
	case "$1" in
	--all)
		output_flag "$CFLAGS $CPPFLAGS $CXXFLAGS $OBJCFLAGS"
		output_flag "$LDFLAGS $LDFLAGS_REEXPORT $LDFLAGS_RPATH $LIBS"
		;;
	--arc)
		output_flag "-fobjc-arc -fobjc-arc-exceptions"
		;;
	--cflags)
		output_flag "$CFLAGS"
		;;
	--cppflags)
		output_flag "$CPPFLAGS"
		;;
	--cxxflags)
		output_flag "$CXXFLAGS"
		;;
	--framework-libs)
		output_flag "$FRAMEWORK_LIBS"
		;;
	--help)
		show_help 0
		;;
	--objc)
		output_flag "$OBJC"
		;;
	--objcflags)
		output_flag "$OBJCFLAGS"
		;;
	--libs)
		output_flag "$LIBS"
		;;
	--lib-cflags)
		if test x"$LIB_MAJOR" = x"" -o x"$LIB_MINOR" = x""; then
			echo "LIB_MAJOR and LIB_MINOR need to be set!" 1>&2
			exit 1
		fi

		output_flag "$LIB_CFLAGS"
		;;
	--lib-ldflags)
		if test x"$SHARED_LIB" = x"" -o x"$LIB_MAJOR" = x"" \
		    -o x"$LIB_MINOR" = x""; then
			printf "SHARED_LIB, LIB_MAJOR and " 2>&1
			echo "LIB_MINOR need to be set!" 1>&2
			exit 1
		fi

		output_flag "$LIB_LDFLAGS"
		;;
	--lib-prefix)
		if test x"$LIB_MAJOR" = x"" -o x"$LIB_MINOR" = x""; then
			echo "LIB_MAJOR and LIB_MINOR need to be set!" 1>&2
			exit 1
		fi

		output_flag "$LIB_PREFIX"
		;;
	--lib-suffix)
		if test x"$LIB_MAJOR" = x"" -o x"$LIB_MINOR" = x""; then
			echo "LIB_MAJOR and LIB_MINOR need to be set!" 1>&2
			exit 1
		fi

		output_flag "$LIB_SUFFIX"
		;;
	--ldflags)
		output_flag "$LDFLAGS"
		;;
	--reexport)
		output_flag "$LDFLAGS_REEXPORT"
		;;
	--rpath)
		output_flag "$LDFLAGS_RPATH"
		;;
	--package)
		# Already included into the flags.
		shift
		;;
	--packages-dir)
		output_flag "$packagesdir"
		;;
	--plugin-cflags)
		output_flag "$PLUGIN_CFLAGS"
		;;
	--plugin-ldflags)
		output_flag "$PLUGIN_LDFLAGS"
		;;
	--plugin-suffix)
		output_flag "$PLUGIN_SUFFIX"
		;;
	--prog-suffix)
		output_flag "$PROG_SUFFIX"
		;;
	--static-libs)
		output_flag "$STATIC_LIBS"
		;;
	--version)
		output_flag "$VERSION"
		;;
	*)
		echo "Invalid option: $1" 1>&2
		exit 1
		;;
	esac
	shift
done

test x"$flag_printed" = x"yes" && echo
exit 0
