#!/bin/sh
# $Id: pmkcfg.sh 1944 2006-12-24 15:01:09Z coudercd $
# Copyright (c) 2003-2004 Damien Couderc
# Copyright (c) 2004 Martin Reindl
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# - Neither the name of the copyright holder(s) nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# automatically detect and use posix shell
#
if test "$1" != "autodetected"; then
printf "Autodetecting POSIX shell\n"
posix_sh="/usr/bin/posix/sh"
if test ! -x $posix_sh; then
posix_sh="/usr/xpg4/bin/sh"
if test ! -x "$posix_sh"; then
posix_sh="/bin/sh"
fi
fi
printf "Using %s %s %s\n\n" "$posix_sh" "$0" "$*"
$posix_sh $0 "autodetected" "$@"
exit $?
else
# skip "autodetected"
shift
fi
###########
# defines #
########################################################################
usermode=0
privsep_user="nobody"
if [ -z "$PREFIX" ]; then
prefix="/usr/local"
else
prefix=$PREFIX
fi
if [ -z "$SYSCONFDIR" ]; then
sysdir="/etc"
else
sysdir=$SYSCONFDIR
fi
sconf="$sysdir/pmk"
um_prfx='$(HOME)'
testbin="./cfgtest"
testfile="$testbin.c"
testmake="./maketest.mk"
testmkvar="./test_mkvar"
testobj="$testbin.o"
temporary="./pmkcfg.tmp"
tmpl_list="Makefile.pmk compat/config.h.pmk tests/Makefile.pmk"
#############
# functions #
########################################################################
# display usage
usage() {
echo "\
usage: $0 [-hup]
-h usage
-p path prefix override
-u set usermode
-U privilege separation user (default: nobody)
"
}
# remove template suffix
# result in filename variable
get_file_name() {
basedir=`dirname $1`
case $1 in
*.in) sfx=".in";;
*.pmk) sfx=".pmk";;
esac
basename=`basename $1 $sfx`
filename="$basedir/$basename"
}
# create new files from templates
process_tmpl_list () {
newlist=""
for f in $*; do
get_file_name $f
newlist="$newlist $filename"
cp $f $filename
done
}
get_make_var() {
mkvar="$1"
printf "Getting '%s' value : " "$mkvar"
cat > $testmake << EOF
all:
@printf "%s\n" "\$($mkvar)" > $testmkvar
EOF
make -f $testmake >/dev/null 2>&1
rslt=`cat $testmkvar`
rm $testmake $testmkvar
printf "'%s'\n" "$rslt"
# mkf_sed "$mkvar" "$rslt"
make_var_value=$rslt
}
check_binary() {
binary="$1"
tname=`echo "$binary" | tr [a-z] [A-Z] | tr . _`
tval=""
printf "Checking binary '%s' : " "$binary"
plst=`echo $PATH | sed "s/:/ /g"`
r=1
for d in $plst; do
if test -x "$d/$binary"; then
tval="$d/$binary"
r=0
break
fi
done
if test "$r" -eq 0; then
printf "yes\n"
mkf_sed "$tname" "$tval"
else
printf "no\n"
fi
return $r
}
check_header() {
header="$1"
printf "Checking header '%s' : " "$header"
cat > $testfile <<EOF
#include <stdio.h>
#include <$header>
int main() {
return(0);
}
EOF
if $CC -o $testbin $testfile >/dev/null 2>&1; then
sed_define "def" "$header"
printf "yes\n"
r=0
else
sed_define "udef" "$header"
printf "no\n"
r=1
fi
rm -f $testfile $testbin
return $r
}
check_header_function() {
include="$1"
function="$2"
printf "Checking function '%s' in header '%s' : " "$function" "$include"
cat > $testfile <<EOF
#include <stdio.h>
#include <$include>
void (*pmk_funcp)() = $function;
int main() {
return(0);
}
EOF
if $CC -o $testobj -c $testfile >/dev/null 2>&1; then
sed_define "def" "$function"
printf "yes\n"
r=0
else
sed_define "udef" "$function"
printf "no\n"
r=1
fi
rm -f $testfile $testobj
return $r
}
check_lib_function() {
lib="$1"
function="$2"
printf "Checking function '%s' in library 'l%s' : " "$function" "$lib"
cat > $testfile <<EOF
#include <stdio.h>
int $function();
int main() {
printf("%p", $function);
return(0);
}
EOF
if $CC -o $testobj $testfile -l$lib >/dev/null 2>&1; then
sed_define "def" "$function"
printf "yes\n"
r=0
else
sed_define "udef" "$function"
printf "no\n"
r=1
fi
rm -f $testfile $testobj
return $r
}
check_type() {
type="$1"
printf "Checking type '%s' : " "$type"
cat > $testfile <<EOF
#include <stdio.h>
int main() {
if (($type *) 0)
return(0);
if (sizeof($type))
return(0);
return(0);
}
EOF
if $CC -o $testbin $testfile >/dev/null 2>&1; then
sed_define "def" "$type"
printf "yes\n"
r=0
else
sed_define "udef" "$type"
printf "no\n"
r=1
fi
rm -f $testfile $testbin
return $r
}
check_type_header() {
type="$1"
header="$2"
printf "Checking type '%s' in header '%s' : " "$type" "$header"
cat > $testfile <<EOF
#include <stdio.h>
#include <$header>
int main() {
if (($type *) 0)
return(0);
if (sizeof($type))
return(0);
return(0);
}
EOF
if $CC -o $testbin $testfile >/dev/null 2>&1; then
sed_define "def" "$type"
printf "yes\n"
r=0
else
sed_define "udef" "$type"
printf "no\n"
r=1
fi
rm -f $testfile $testbin
return $r
}
sed_define() {
sed_uc=`echo "$2" | tr [a-z] [A-Z] | tr . _ | tr " " _`
case $1 in
def) sed_str="#define HAVE_$sed_uc 1";;
udef) sed_str="#undef HAVE_$sed_uc";;
esac
sed_tag="@DEF__$sed_uc@"
for f in $file_list; do
cp $f $temporary
cat $temporary | sed "s/$sed_tag/$sed_str/" > $f
rm -f $temporary
done
}
mkf_sed() {
sed_var="$1"
sed_val="$2"
#printf "DEBUG: replace @%s@ by %s\n" "$sed_var" "$sed_val"
for f in $file_list; do
cp $f $temporary
cat $temporary | sed "s,@$sed_var@,$sed_val," > $f
rm -f $temporary
done
}
########
# init #
########################################################################
# parse options
while getopts "hp:uU:" arg; do
case $arg in
h) usage
exit 1
;;
p) printf "Setting prefix to '%s'\n" "$OPTARG"
base="$OPTARG"
;;
u) usermode=1
;;
U) printf "Setting privsep user tp '%s'\n" "$OPTARG"
privsep_user="$OPTARG"
;;
esac
done
shift `expr $OPTIND - 1`
# init templates
process_tmpl_list "$tmpl_list"
file_list=$newlist
if [ $usermode = 1 ]; then
echo 'USERMODE ON.'
mkf_sed 'USERMODE' '-DPMK_USERMODE'
if [ -z "$base" ]; then
mkf_sed 'PREFIX' "$um_prfx"
else
mkf_sed 'PREFIX' "$base"
fi
mkf_sed 'CONFDIR' '$(HOME)/.pmk'
mkf_sed 'SBINDIR' '$(PREFIX)/bin'
mkf_sed 'DATADIR' '$(CONFDIR)'
else
echo "USERMODE OFF."
mkf_sed 'USERMODE' ''
if [ -z "$base" ]; then
mkf_sed 'PREFIX' "$prefix"
else
mkf_sed 'PREFIX' "$base"
fi
mkf_sed 'CONFDIR' '$(SYSCONFDIR)/pmk'
mkf_sed 'SBINDIR' '$(PREFIX)/sbin'
mkf_sed 'DATADIR' '$(PREFIX)/share/$(PREMAKE)'
fi
mkf_sed 'BINDIR' '$(PREFIX)/bin'
mkf_sed 'MANDIR' '$(PREFIX)/man'
mkf_sed 'MAN1DIR' '$(MANDIR)/man1'
mkf_sed 'MAN5DIR' '$(MANDIR)/man5'
mkf_sed 'MAN8DIR' '$(MANDIR)/man8'
mkf_sed 'SYSCONFDIR' "$sysdir"
mkf_sed 'PRIVSEP_USER' "$privsep_user"
mkf_sed 'PACKAGE' "pmk"
mkf_sed 'VERSION' "0.9.3"
mkf_sed 'INSTALL' './pmkinstall'
#############
# get flags #
########################################################################
#
# gathering CFLAGS
#
if [ -z "$CFLAGS" ]; then
get_make_var CFLAGS
CFLAGS=$make_var_value
else
printf "CFLAGS defined, skipping detection.\n"
fi
#
# gathering CLDFLAGS
#
if [ -z "$CLDFLAGS" ]; then
get_make_var CLDFLAGS
CLDFLAGS=$make_var_value
else
printf "CLDFLAGS defined, skipping detection.\n"
fi
##################
# check binaries #
########################################################################
#
# cc check
#
if [ -z "$CC" ]; then
# check first for C99 then C89 compilers
if check_binary cc; then
CC="cc"
elif check_binary c99; then
CC="c99"
elif check_binary c89; then
CC="c89"
else
printf "Unable to find C compiler.\n"
exit 1
fi
else
printf "CC defined, skipping C compiler check.\n"
fi
mkf_sed 'CC' "$CC"
#
# cpp check
#
# 'cc -E' is the C99 standard for preprocessing C-language source files.
# See: http://www.opengroup.org/onlinepubs/009695399/utilities/c99.html
#
# However, the results are unspecified for assembler source files.
# Gcc has its own conventions for preprocessing assembler files, only the cpp
# binary preprocesses assembler files at any time. In gcc, 'cc -E' only
# processes assembler files which end in '.S'. To work around we first look
# for the cpp binary and fall back to 'cc -E' if not successful.
if [ -z "$CPP" ]; then
if check_binary cpp; then
CPP="cpp"
else
printf "Using '$CC -E'.\n"
CPP="$CC -E"
fi
else
printf "CPP defined, skipping C preprocessor check.\n"
fi
mkf_sed 'CPP' "$CPP"
#
# as check
#
if [ -z "$AS" ]; then
if ! check_binary as; then
printf "Unable to find assembler.\n"
exit 1
fi
else
printf "AS defined, skipping assembler.\n"
fi
mkf_sed 'AS' "$AS"
###############
# check types #
########################################################################
#
# _Bool type check
#
check_type _Bool
#
# blkcnt_t type check
#
check_type_header blkcnt_t sys/types.h
#
# long long type check
#
check_type "long long"
#
# unsigned long long type check
#
check_type "unsigned long long"
#
# long double type check
#
check_type "long double"
#
# intmax_t type check
#
check_type_header intmax_t stdint.h
#
# ptrdiff_t type check
#
check_type_header ptrdiff_t stddef.h
#
# wchar_t type check
#
check_type_header wchar_t wchar.h
#
# wint_t type check
#
check_type_header wint_t wchar.h
#################
# check headers #
########################################################################
#
# stdbool.h check
#
check_header stdbool.h
#
# libgen.h check
#
check_header libgen.h
###################
# check functions #
########################################################################
#
# strlcpy() check
#
check_header_function string.h strlcpy
#
# strlcat() check
#
check_header_function string.h strlcat
#
# strdup() check
#
check_header_function string.h strdup
#
# vsnprintf() check
#
check_header_function stdio.h vsnprintf
#
# snprintf() check
#
check_header_function stdio.h snprintf
#
# isblank() check
#
check_header_function ctype.h isblank
#
# mkstemps() check
#
check_header_function unistd.h mkstemps
#
# seteuid() check
#
if check_header_function unistd.h seteuid; then
PS_FLAGS=""
else
PS_FLAGS="-DWITHOUT_FORK"
fi
#
# dirname() check
#
if check_lib_function gen dirname; then
LGEN_FLAGS="-lgen"
else
LGEN_FLAGS=""
fi
#
# basename() check
#
check_lib_function gen basename
#
# isnan() check
#
if check_lib_function m isnan; then
LM_FLAGS="-lm"
else
LM_FLAGS=""
fi
#####################
# compilation flags #
########################################################################
mkf_sed 'CFLAGS' "$CFLAGS $PS_FLAGS"
mkf_sed 'CLDFLAGS' "$CLDFLAGS $LGEN_FLAGS $LM_FLAGS"
#
# end
#
exit 0
syntax highlighted by Code2HTML, v. 0.9.1