Files
cmus/scripts/checks.sh
2026-03-29 14:01:52 +03:00

709 lines
14 KiB
Bash

#!/bin/sh
#
# Copyright 2005-2006 Timo Hirvonen
#
# This file is licensed under the GPLv2.
# C compiler
# ----------
# CC default gcc
# LD default $CC
# LDFLAGS common linker flags for CC
#
# C++ Compiler
# ------------
# CXX default g++
# CXXLD default $CXX
# CXXLDFLAGS common linker flags for CXX
#
# Common for C and C++
# --------------------
# SOFLAGS flags for compiling position independent code (-fPIC)
# LDSOFLAGS flags for linking shared libraries
# LDDLFLAGS flags for linking dynamically loadable modules
msg_checking()
{
printf "checking $@... "
}
msg_result()
{
echo "$@"
}
msg_error()
{
echo "*** $@"
}
# @program: program to check
# @name: name of variable where to store the full program name (optional)
#
# returns 0 on success and 1 on failure
check_program()
{
argc check_program $# 1 2
msg_checking "for program $1"
__cp_file=`path_find "$1"`
if test $? -eq 0
then
msg_result $__cp_file
test $# -eq 2 && set_var $2 "$__cp_file"
return 0
else
msg_result "no"
return 1
fi
}
cc_supports()
{
$CC $CPPFLAGS $CFLAGS "$@" -S -o /dev/null -x c /dev/null 2> /dev/null
return $?
}
cxx_supports()
{
$CXX $CPPFLAGS $CXXFLAGS "$@" -S -o /dev/null -x c /dev/null 2> /dev/null
return $?
}
# @flag: option flag(s) to check
#
# add @flag to EXTRA_CFLAGS if CC accepts it
# EXTRA_CFLAGS are added to CFLAGS in the end of configuration
check_cc_flag()
{
argc check_cc_flag $# 1
test -z "$CC" && die "check_cc_flag: CC not set"
msg_checking "for CFLAGS $*"
if cc_supports $*
then
EXTRA_CFLAGS="$EXTRA_CFLAGS $*"
msg_result "yes"
return 0
else
msg_result "no"
return 1
fi
}
# @flag: option flag(s) to check
#
# add @flag to EXTRA_CXXFLAGS if CXX accepts it
# EXTRA_CXXFLAGS are added to CXXFLAGS in the end of configuration
check_cxx_flag()
{
argc check_cxx_flag $# 1
test -z "$CXX" && die "check_cxx_flag: CXX not set"
msg_checking "for CXXFLAGS $*"
if cxx_supports $*
then
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $*"
msg_result "yes"
return 0
else
msg_result "no"
return 1
fi
}
cc_cxx_common()
{
test "$cc_cxx_common_done" && return 0
cc_cxx_common_done=yes
var_default SOFLAGS "-fPIC"
var_default LDSOFLAGS "-shared"
var_default LDDLFLAGS "-shared"
common_cf=
common_lf=
case `uname -s` in
*BSD)
common_cf="$common_cf -I/usr/local/include"
common_lf="$common_lf -L/usr/local/lib"
;;
Darwin)
# fink
if test -d /sw/lib
then
common_cf="$common_cf -I/sw/include"
common_lf="$common_lf -L/sw/lib"
fi
# darwinports
if test -d /opt/local/lib
then
common_cf="$common_cf -I/opt/local/include"
common_lf="$common_lf -L/opt/local/lib"
fi
LDSOFLAGS="-dynamic"
case ${MACOSX_DEPLOYMENT_TARGET} in
10.[012])
LDDLFLAGS="-bundle -flat_namespace -undefined suppress"
;;
10.*)
LDDLFLAGS="-bundle -undefined dynamic_lookup"
;;
*)
LDDLFLAGS="-bundle -flat_namespace -undefined suppress"
;;
esac
;;
SunOS)
common_cf="$common_cf -D__EXTENSIONS__ -I/usr/local/include"
common_lf="$common_lf -R/usr/local/lib -L/usr/local/lib"
;;
esac
makefile_vars SOFLAGS LDSOFLAGS LDDLFLAGS
}
# CC, LD, CFLAGS, LDFLAGS, SOFLAGS, LDSOFLAGS, LDDLFLAGS
check_cc()
{
var_default CC ${CROSS}gcc
var_default LD $CC
var_default CFLAGS "-g -O2 -Wall"
var_default LDFLAGS ""
check_program $CC || return 1
cc_cxx_common
CFLAGS="$CFLAGS $common_cf"
LDFLAGS="$LDFLAGS $common_lf"
makefile_vars CC LD CFLAGS LDFLAGS
__check_lang=c
return 0
}
# HOSTCC, HOSTLD, HOST_CFLAGS, HOST_LDFLAGS
check_host_cc()
{
var_default HOSTCC gcc
var_default HOSTLD $HOSTCC
var_default HOST_CFLAGS "-g -O2 -Wall"
var_default HOST_LDFLAGS ""
check_program $HOSTCC || return 1
makefile_vars HOSTCC HOSTLD HOST_CFLAGS HOST_LDFLAGS
__check_lang=c
return 0
}
# CXX, CXXLD, CXXFLAGS, CXXLDFLAGS, SOFLAGS, LDSOFLAGS, LDDLFLAGS
check_cxx()
{
var_default CXX ${CROSS}g++
var_default CXXLD $CXX
var_default CXXFLAGS "-g -O2 -Wall"
var_default CXXLDFLAGS ""
check_program $CXX || return 1
cc_cxx_common
CXXFLAGS="$CXXFLAGS $common_cf"
CXXLDFLAGS="$CXXLDFLAGS $common_lf"
makefile_vars CXX CXXLD CXXFLAGS CXXLDFLAGS
__check_lang=cxx
return 0
}
# check if CC can generate dependencies (.dep-*.o files)
# always succeeds
check_cc_depgen()
{
msg_checking "if CC can generate dependency information"
if cc_supports -MMD -MP -MF /dev/null
then
EXTRA_CFLAGS="$EXTRA_CFLAGS -MMD -MP -MF .dep-\$(subst /,-,\$@)"
msg_result yes
else
msg_result no
fi
return 0
}
# check if CXX can generate dependencies (.dep-*.o files)
# always succeeds
check_cxx_depgen()
{
msg_checking "if CXX can generate dependency information"
if cxx_supports -MMD -MP -MF /dev/null
then
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -MMD -MP -MF .dep-\$(subst /,-,\$@)"
msg_result yes
else
msg_result no
fi
return 0
}
# adds AR to config.mk
check_ar()
{
var_default AR ${CROSS}ar
var_default ARFLAGS "-cr"
if check_program $AR
then
makefile_vars AR ARFLAGS
return 0
fi
return 1
}
# adds AS to config.mk
check_as()
{
var_default AS ${CROSS}gcc
if check_program $AS
then
makefile_vars AS
return 0
fi
return 1
}
check_pkgconfig()
{
if test -z "$PKG_CONFIG"
then
if check_program pkg-config PKG_CONFIG
then
makefile_vars PKG_CONFIG
else
# don't check again
PKG_CONFIG="no"
return 1
fi
fi
return 0
}
# check for library FOO and add FOO_CFLAGS and FOO_LIBS to config.mk
#
# @name: variable prefix (e.g. CURSES -> CURSES_CFLAGS, CURSES_LIBS)
# @cflags: CFLAGS for the lib
# @libs: LIBS to check
#
# adds @name_CFLAGS and @name_LIBS to config.mk
# CFLAGS are not checked, they are assumed to be correct
check_library()
{
argc check_library $# 3 3
msg_checking "for ${1}_LIBS ($3)"
if try_link $3
then
msg_result yes
makefile_var ${1}_CFLAGS "$2"
makefile_var ${1}_LIBS "$3"
return 0
else
msg_result no
return 1
fi
}
# run pkg-config
#
# @prefix: variable prefix (e.g. GLIB -> GLIB_CFLAGS, GLIB_LIBS)
# @modules: the argument for pkg-config
# @cflags: CFLAGS to use if pkg-config failed (optional)
# @libs: LIBS to use if pkg-config failed (optional)
#
# if pkg-config fails and @libs are given check_library is called
#
# example:
# ---
# check_glib()
# {
# pkg_config GLIB "glib-2.0 >= 2.2"
# return $?
# }
#
# check check_cc
# check check_glib
# ---
# GLIB_CFLAGS and GLIB_LIBS are automatically added to Makefile
pkg_config()
{
argc pkg_config $# 2 4
# optional
__pc_cflags="$3"
__pc_libs="$4"
check_pkgconfig
msg_checking "for ${1}_LIBS (pkg-config)"
if test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists "$2" >/dev/null 2>&1
then
# pkg-config is installed and the .pc file exists
__pc_libs="`$PKG_CONFIG --libs ""$2""`"
msg_result "$__pc_libs"
msg_checking "for ${1}_CFLAGS (pkg-config)"
__pc_cflags="`$PKG_CONFIG --cflags ""$2""`"
msg_result "$__pc_cflags"
makefile_var ${1}_CFLAGS "$__pc_cflags"
makefile_var ${1}_LIBS "$__pc_libs"
return 0
fi
# no pkg-config or .pc file
msg_result "no"
if test -z "$__pc_libs"
then
if test "$PKG_CONFIG" = "no"
then
# pkg-config not installed and no libs to check were given
msg_error "pkg-config required for $1"
else
# pkg-config is installed but the required .pc file wasn't found
$PKG_CONFIG --errors-to-stdout --print-errors "$2" | sed 's:^:*** :'
fi
return 1
fi
check_library "$1" "$__pc_cflags" "$__pc_libs"
return $?
}
# old name
pkg_check_modules()
{
pkg_config "$@"
}
# run *-config
#
# @prefix: variable prefix (e.g. ARTS -> ARTS_CFLAGS, ARTS_LIBS)
# @program: the -config program
#
# example:
# ---
# check_arts()
# {
# app_config ARTS artsc-config
# return $?
# }
#
# check check_cc
# check check_arts
# ---
# ARTS_CFLAGS and ARTS_LIBS are automatically added to config.mk
app_config()
{
argc app_config $# 2 2
check_program $2 || return 1
msg_checking "for ${1}_CFLAGS"
__ac_cflags="`$2 --cflags`"
msg_result "$__ac_cflags"
msg_checking "for ${1}_LIBS"
__ac_libs="`$2 --libs`"
msg_result "$__ac_libs"
makefile_var ${1}_CFLAGS "$__ac_cflags"
makefile_var ${1}_LIBS "$__ac_libs"
return 0
}
# @contents: file contents to compile
# @cflags: extra cflags (optional)
try_compile()
{
argc try_compile $# 1
case $__check_lang in
c)
__src=`tmp_file prog.c`
__obj=`tmp_file prog.o`
echo "$1" > $__src || exit 1
shift
__cmd="$CC -c $CPPFLAGS $CFLAGS $@ $__src -o $__obj"
$CC -c $CPPFLAGS $CFLAGS "$@" $__src -o $__obj 2>/dev/null
;;
cxx)
__src=`tmp_file prog.cc`
__obj=`tmp_file prog.o`
echo "$1" > $__src || exit 1
shift
__cmd="$CXX -c $CPPFLAGS $CXXFLAGS $@ $__src -o $__obj"
$CXX -c $CPPFLAGS $CXXFLAGS "$@" $__src -o $__obj 2>/dev/null
;;
esac
return $?
}
# @contents: file contents to compile and link
# @flags: extra flags (optional)
try_compile_link()
{
argc try_compile $# 1
case $__check_lang in
c)
__src=`tmp_file prog.c`
__exe=`tmp_file prog`
echo "$1" > $__src || exit 1
shift
__cmd="$CC $__src -o $__exe $CPPFLAGS $CFLAGS $LDFLAGS $@"
$CC $__src -o $__exe $CPPFLAGS $CFLAGS $LDFLAGS "$@" 2>/dev/null
;;
cxx)
__src=`tmp_file prog.cc`
__exe=`tmp_file prog`
echo "$1" > $__src || exit 1
shift
__cmd="$CXX $__src -o $__exe $CPPFLAGS $CXXFLAGS $CXXLDFLAGS $@"
$CXX $__src -o $__exe $CPPFLAGS $CXXFLAGS $CXXLDFLAGS "$@" 2>/dev/null
;;
esac
return $?
}
# optionally used after try_compile or try_compile_link
__compile_failed()
{
warn
warn "Failed to compile simple program:"
warn "---"
cat $__src >&2
warn "---"
warn "Command: $__cmd"
case $__check_lang in
c)
warn "Make sure your CC and CFLAGS are sane."
;;
cxx)
warn "Make sure your CXX and CXXFLAGS are sane."
;;
esac
exit 1
}
# tries to link against a lib
#
# @function: some function
# @flags: extra flags (optional)
check_function()
{
argc check_function $# 1
__func="$1"
shift
msg_checking "for function $__func"
if try_compile_link "extern int $__func(); int (*ptr)() = &$__func; int main() { return 0; }" "$@"
then
msg_result yes
return 0
fi
msg_result no
return 1
}
# tries to link against a lib
#
# @ldadd: something like -L/usr/X11R6/lib -lX11
try_link()
{
try_compile_link "int main(int argc, char *argv[]) { return 0; }" "$@"
return $?
}
# compile and run
#
# @code: simple program code to run
run_code()
{
if test $CROSS
then
msg_error "cannot run code when cross compiling"
exit 1
fi
try_compile_link "$1" || __compile_failed
./$__exe
return $?
}
# check if the architecture is big-endian
# parts are from autoconf 2.67
#
# defines WORDS_BIGENDIAN=y/n
check_endianness()
{
msg_checking "byte order"
WORDS_BIGENDIAN=n
# See if sys/param.h defines the BYTE_ORDER macro.
if try_compile_link "
#include <sys/types.h>
#include <sys/param.h>
int main() {
#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
&& defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
&& LITTLE_ENDIAN)
bogus endian macros
#endif
return 0;
}"
then
# It does; now see whether it defined to BIG_ENDIAN or not.
if try_compile_link "
#include <sys/types.h>
#include <sys/param.h>
int main() {
#if BYTE_ORDER != BIG_ENDIAN
not big endian
#endif
return 0;
}"
then
WORDS_BIGENDIAN=y
fi
# See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
elif try_compile_link "
#include <limits.h>
int main() {
#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
bogus endian macros
#endif
return 0;
}"
then
# It does; now see whether it defined to _BIG_ENDIAN or not.
if try_compile_link "
#include <limits.h>
int main() {
#ifndef _BIG_ENDIAN
not big endian
#endif
return 0;
}"
then
WORDS_BIGENDIAN=y
fi
elif run_code "
int main(int argc, char *argv[])
{
unsigned int i = 1;
return *(char *)&i;
}"
then
WORDS_BIGENDIAN=y
fi
if test "$WORDS_BIGENDIAN" = y
then
msg_result "big-endian"
else
msg_result "little-endian"
fi
return 0
}
# check if @header can be included
#
# @header
# @cflags -I/some/path (optional)
check_header()
{
argc check_header $# 1
__header="$1"
shift
msg_checking "for header <$__header>"
if try_compile "#include <$__header>" "$@"
then
msg_result yes
return 0
fi
msg_result no
return 1
}
# check X11 libs
#
# adds X11_LIBS (and empty X11_CFLAGS) to config.mk
check_x11()
{
for __libs in "-lX11" "-L/usr/X11R6/lib -lX11"
do
check_library X11 "" "$__libs" && return 0
done
return 1
}
# check posix threads
#
# adds PTHREAD_CFLAGS and PTHREAD_LIBS to config.mk
check_pthread()
{
for __libs in "$PTHREAD_LIBS" -lpthread -lc_r -lkse
do
test -z "$__libs" && continue
check_library PTHREAD "-D_REENTRANT" "$__libs" && return 0
done
echo "using -pthread gcc option"
makefile_var PTHREAD_CFLAGS "-pthread -D_THREAD_SAFE"
makefile_var PTHREAD_LIBS "-pthread"
return 0
}
# check dynamic linking loader
#
# adds DL_LIBS to config.mk
check_dl()
{
for DL_LIBS in "-ldl -Wl,--export-dynamic" "-ldl -rdynamic" "-Wl,--export-dynamic" "-rdynamic" "-ldl"
do
check_library DL "" "$DL_LIBS" && return 0
done
echo "assuming -ldl is not needed"
DL_LIBS=
makefile_vars DL_LIBS DL_CFLAGS
return 0
}
# check for iconv
#
# adds ICONV_CFLAGS and ICONV_LIBS to config.mk
check_iconv()
{
HAVE_ICONV=n
if check_library ICONV "" "-liconv"
then
echo "taking iconv from libiconv"
else
echo "assuming libc contains iconv"
makefile_var ICONV_CFLAGS ""
makefile_var ICONV_LIBS ""
fi
msg_checking "for working iconv"
if try_compile_link '
#include <stdio.h>
#include <string.h>
#include <iconv.h>
int main(int argc, char *argv[]) {
char buf[128], *out = buf, *in = argv[1];
size_t outleft = 127, inleft = strlen(in);
iconv_t cd = iconv_open("UTF-8", "ISO-8859-1");
iconv(cd, &in, &inleft, &out, &outleft);
*out = 0;
printf("%s", buf);
iconv_close(cd);
return 0;
}' $ICONV_CFLAGS $ICONV_LIBS
then
msg_result "yes"
HAVE_ICONV=y
else
msg_result "no"
msg_error "Your system doesn't have iconv!"
msg_error "This means that no charset conversion can be done, so all"
msg_error "your tracks need to be encoded in your system charset!"
fi
return 0
}