#!/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 #include 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 #include int main() { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif return 0; }" then WORDS_BIGENDIAN=y fi # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). elif try_compile_link " #include 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 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 #include #include 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 }