#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# APR script designed to allow easy command line access to APR configuration
# parameters.

APR_MAJOR_VERSION="@APR_MAJOR_VERSION@"
APR_DOTTED_VERSION="@APR_DOTTED_VERSION@"

prefix="@prefix@"
exec_prefix="@exec_prefix@"
bindir="@bindir@"
libdir="@libdir@"
datarootdir="@datadir@"
datadir="@datadir@"
installbuilddir="@installbuilddir@"
includedir="@includedir@"

CC="@CC@"
CPP="@CPP@"
SHELL="@SHELL@"
CPPFLAGS="@EXTRA_CPPFLAGS@"
CFLAGS="@EXTRA_CFLAGS@"
LDFLAGS="@EXTRA_LDFLAGS@"
LIBS="@EXTRA_LIBS@"
EXTRA_INCLUDES="@EXTRA_INCLUDES@"
SHLIBPATH_VAR="@shlibpath_var@"
APR_SOURCE_DIR="@apr_srcdir@"
APR_BUILD_DIR="@apr_builddir@"
APR_SO_EXT="@so_ext@"
APR_LIB_TARGET="@export_lib_target@"
APR_LIBNAME="@APR_LIBNAME@"

# NOTE: the following line is modified during 'make install': alter with care!
location=@APR_CONFIG_LOCATION@

# absolute path, but not installed path - we're cross compiling
case "$0" in
  "${bindir}/"*) ;;
  "/"*)         location=crosscompile;
                APR_TARGET_DIR=${0%${bindir}/apr-${APR_MAJOR_VERSION}-config} ;;
  *)            ;;
esac

show_usage()
{
    cat << EOF
Usage: apr-$APR_MAJOR_VERSION-config [OPTION]

Known values for OPTION are:
  --prefix[=DIR]    change prefix to DIR
  --bindir          print location where binaries are installed
  --includedir      print location where headers are installed
  --cc              print C compiler name
  --cpp             print C preprocessor name and any required options
  --cflags          print C compiler flags
  --cppflags        print C preprocessor flags
  --includes        print include information
  --ldflags         print linker flags
  --libs            print additional libraries to link against
  --srcdir          print APR source directory
  --installbuilddir print APR build helper directory
  --link-ld         print link switch(es) for linking to APR
  --link-libtool    print the libtool inputs for linking to APR
  --shlib-path-var  print the name of the shared library path env var
  --apr-la-file     print the path to the .la file, if available
  --apr-so-ext      print the extensions of shared objects on this platform
  --apr-lib-target  print the libtool target information
  --apr-libtool     print the path to APR's libtool
  --version         print the APR's version as a dotted triple
  --help            print this help

When linking with libtool, an application should do something like:
  APR_LIBS="\`apr-$APR_MAJOR_VERSION-config --link-libtool --libs\`"
or when linking directly:
  APR_LIBS="\`apr-$APR_MAJOR_VERSION-config --link-ld --libs\`"

An application should use the results of --cflags, --cppflags, --includes,
and --ldflags in their build process.
EOF
}

if test $# -eq 0; then
    show_usage
    exit 1
fi

if test "$location" = "installed"; then
    LA_FILE="$libdir/lib${APR_LIBNAME}.la"
elif test "$location" = "crosscompile"; then
    LA_FILE="$APR_TARGET_DIR/$libdir/lib${APR_LIBNAME}.la"
else
    LA_FILE="$APR_BUILD_DIR/lib${APR_LIBNAME}.la"
fi

flags=""

while test $# -gt 0; do
    # Normalize the prefix.
    case "$1" in
    -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
    *) optarg= ;;
    esac

    case "$1" in
    # It is possible for the user to override our prefix.
    --prefix=*)
    prefix=$optarg
    ;;
    --prefix)
    echo $prefix
    exit 0
    ;;
    --bindir)
    echo $bindir
    exit 0
    ;;
    --includedir)
    if test "$location" = "installed"; then
        flags="$includedir"
    elif test "$location" = "crosscompile"; then
        flags="$APR_TARGET_DIR/$includedir"
    elif test "$location" = "source"; then
        flags="$APR_SOURCE_DIR/include"
    else
        # this is for VPATH builds
        flags="$APR_BUILD_DIR/include $APR_SOURCE_DIR/include"
    fi
    echo $flags
    exit 0
    ;;
    --cc)
    echo $CC
    exit 0
    ;;
    --cpp)
    echo $CPP
    exit 0
    ;;
    --cflags)
    flags="$flags $CFLAGS"
    ;;
    --cppflags)
    flags="$flags $CPPFLAGS"
    ;;
    --libs)
    flags="$flags $LIBS"
    ;;
    --ldflags)
    flags="$flags $LDFLAGS"
    ;;
    --includes)
    if test "$location" = "installed"; then
        flags="$flags -I$includedir $EXTRA_INCLUDES"
    elif test "$location" = "crosscompile"; then
        flags="$flags -I$APR_TARGET_DIR/$includedir $EXTRA_INCLUDES"
    elif test "$location" = "source"; then
        flags="$flags -I$APR_SOURCE_DIR/include $EXTRA_INCLUDES"
    else
        # this is for VPATH builds
        flags="$flags -I$APR_BUILD_DIR/include -I$APR_SOURCE_DIR/include $EXTRA_INCLUDES"
    fi
    ;;
    --srcdir)
    echo $APR_SOURCE_DIR
    exit 0
    ;;
    --installbuilddir)
    if test "$location" = "installed"; then
        echo "${installbuilddir}"
    elif test "$location" = "crosscompile"; then
        echo "$APR_TARGET_DIR/${installbuilddir}"
    elif test "$location" = "source"; then
        echo "$APR_SOURCE_DIR/build"
    else
        # this is for VPATH builds
        echo "$APR_BUILD_DIR/build"
    fi
    exit 0
    ;;
    --version)
    echo $APR_DOTTED_VERSION
    exit 0
    ;;
    --link-ld)
    if test "$location" = "installed"; then
        ### avoid using -L if libdir is a "standard" location like /usr/lib
        flags="$flags -L$libdir -l${APR_LIBNAME}"
    elif test "$location" = "crosscompile"; then
        flags="$flags -L$APR_TARGET_DIR/$libdir -l${APR_LIBNAME}"
    else
        ### this surely can't work since the library is in .libs?
        flags="$flags -L$APR_BUILD_DIR -l${APR_LIBNAME}"
    fi
    ;;
    --link-libtool)
    # If the LA_FILE exists where we think it should be, use it.  If we're
    # installed and the LA_FILE does not exist, assume to use -L/-l
    # (the LA_FILE may not have been installed).  If we're building ourselves,
    # we'll assume that at some point the .la file be created.
    if test -f "$LA_FILE"; then
        flags="$flags $LA_FILE"
    elif test "$location" = "installed"; then
        ### avoid using -L if libdir is a "standard" location like /usr/lib
        # Since the user is specifying they are linking with libtool, we
        # *know* that -R will be recognized by libtool.
        flags="$flags -L$libdir -R$libdir -l${APR_LIBNAME}"
    elif test "$location" = "crosscompile"; then
        flags="$flags  -L${APR_TARGET_DIR}/$libdir  -l${APR_LIBNAME}"
    else
        flags="$flags $LA_FILE"
    fi
    ;;
    --shlib-path-var)
    echo "$SHLIBPATH_VAR"
    exit 0
    ;;
    --apr-la-file)
    if test -f "$LA_FILE"; then
        flags="$flags $LA_FILE"
    fi
    ;;
    --apr-so-ext)
    echo "$APR_SO_EXT"
    exit 0
    ;;
    --apr-lib-target)
    echo "$APR_LIB_TARGET"
    exit 0
    ;;
    --apr-libtool)
    if test "$location" = "installed"; then
        echo "${installbuilddir}/libtool"
    elif test "$location" = "crosscompile"; then
        echo "$APR_TARGET_DIR/${installbuilddir}/libtool"
    else
        echo "$APR_BUILD_DIR/libtool"
    fi
    exit 0
    ;;
    --help)
    show_usage
    exit 0
    ;;
    *)
    show_usage
    exit 1
    ;;
    esac

    # Next please.
    shift
done

if test -n "$flags"; then
  echo "$flags"
fi

exit 0
