CONFIG_DEFINES='' INCLUDE_DIRS='' LIBRARY_DIRS='' MAKEFILE_DEFINES='' PKG_CONF_USED='' ASFLAGS="${ASFLAGS:-}" CFLAGS="${CFLAGS:-}" CXXFLAGS="${CXXFLAGS:-}" LDFLAGS="${LDFLAGS:-}" PREFIX="${PREFIX:-/usr/local}" SHARE_DIR="${SHARE_DIR:-${PREFIX}/share}" # add_define: # $1 = MAKEFILE or CONFIG # $2 = define # $3 = value add_define() { eval "${1}_DEFINES=\"\${${1}_DEFINES} $2=$3\""; } # add_dirs: # $1 = INCLUDE or LIBRARY # $@ = include or library paths add_dirs() { ADD="$1"; LINK="${1%"${1#?}"}"; shift while [ $# -gt 0 ]; do eval "${ADD}_DIRS=\"\${${ADD}_DIRS} -${LINK}${1}\"" shift done eval "${ADD}_DIRS=\"\${${ADD}_DIRS# }\"" BUILD_DIRS="$INCLUDE_DIRS $LIBRARY_DIRS" } # check_compiler: # $1 = language # $2 = function in lib check_compiler() { if [ "$1" = cxx ]; then COMPILER="$CXX" FLAGS="$CXXFLAGS" TEMP_CODE="$TEMP_CXX" TEST_C="extern \"C\" { void $2(void); } int main() { $2(); }" else COMPILER="$CC" FLAGS="$CFLAGS" TEMP_CODE="$TEMP_C" TEST_C="void $2(void); int main(void) { $2(); return 0; }" fi } # check_enabled: # $1 = HAVE_$1 [Disabled 'feature' or 'feature feature1 feature2', $1 = name] # $2 = USER_$2 [Enabled feature] # $3 = lib # $4 = feature # $5 = enable lib when true, disable errors with 'user' [checked only if non-empty] # if any HAVE_$1 is true, HAVE_$2 is enabled # if USER_$2 is false, HAVE_$2 is disabled # if neither of the above, it's an error check_enabled() { add_opt "$2" setval="$(eval "printf %s \"\$HAVE_$2\"")" for val in $(printf %s "$1"); do tmpvar="$(eval "printf %s \"\$HAVE_$val\"")" if [ "$tmpvar" != 'no' ]; then if [ "$setval" != 'no' ] && match "${5:-}" true user; then eval "HAVE_$2=yes" fi return 0 fi done tmpval="$(eval "printf %s \"\$USER_$2\"")" if [ "$tmpval" != 'yes' ]; then if [ "$setval" != 'no' ]; then eval "HAVE_$2=no" if ! match "${5:-}" true user; then die : "Notice: $4 disabled, $3 support will also be disabled." fi fi return 0 fi if [ "${5:-}" != 'user' ]; then die 1 "Error: $4 disabled and forced to build with $3 support." fi } # check_platform: # $1 = OS ['OS' or 'OS OS2 OS3', $1 = name] # $2 = HAVE_$2 # $3 = feature # $4 = enable feature when 'true', disable errors with 'user' [checked only if non-empty] check_platform() { add_opt "$2" tmpval="$(eval "printf %s \"\$HAVE_$2\"")" [ "$tmpval" = 'no' ] && return 0 error= newval= setval="$(eval "printf %s \"\$USER_$2\"")" for platform in $(printf %s "$1"); do if [ "$setval" = 'yes' ]; then if [ "$error" != 'no' ] && [ "${4:-}" != 'user' ] && { { [ "$platform" != "$OS" ] && match "${4:-}" true user; } || { [ "$platform" = "$OS" ] && ! match "${4:-}" true user; }; }; then error='yes' elif match "${4:-}" true user; then error='no' fi elif [ "$platform" = "$OS" ]; then if match "${4:-}" true user; then newval=yes break else newval=no fi elif match "${4:-}" true user; then newval=auto fi done if [ "${error}" = 'yes' ]; then die 1 "Error: $3 not supported for $OS." else eval "HAVE_$2=\"${newval:-$tmpval}\"" fi } # check_lib: # Compiles a simple test program to check if a library is available. # $1 = language # $2 = HAVE_$2 # $3 = lib # $4 = function in lib [checked only if non-empty] # $5 = extralibs [checked only if non-empty] # $6 = headers [checked only if non-empty] # $7 = include directory [checked only if non-empty] # $8 = critical error message [checked only if non-empty] check_lib() { add_opt "$2" tmpval="$(eval "printf %s \"\$HAVE_$2\"")" [ "$tmpval" = 'no' ] && return 0 check_compiler "$1" "$4" if [ "$4" ]; then MSG="Checking function $4 in" if [ "$6" ]; then printf %s\\n "$6" "int main(void) { void *p = (void*)$4; return 0; }" > "$TEMP_CODE" else printf %s\\n "$TEST_C" > "$TEMP_CODE" fi else MSG='Checking existence of' printf %s\\n 'int main(void) { return 0; }' > "$TEMP_CODE" fi lib="${3% }" include="${7:-}" error="${8:-}" answer='no' printf %s "$MSG $lib ... " $(printf %s "$COMPILER") -o "$TEMP_EXE" "$TEMP_CODE" \ $(printf %s "$BUILD_DIRS $5 $FLAGS $LDFLAGS $lib") \ >>config.log 2>&1 && answer='yes' printf %s\\n "$answer" if [ "$answer" = 'yes' ] && [ "$include" ]; then answer='no' for dir in $(printf %s "$INCLUDES"); do [ "$answer" = 'yes' ] && break printf %s "Checking existence of /$dir/$include ... " if [ -d "/$dir/$include" ]; then eval "${2}_CFLAGS=\"-I/$dir/$include\"" answer='yes' fi printf %s\\n "$answer" done fi eval "HAVE_$2=\"$answer\"" rm -f -- "$TEMP_CODE" "$TEMP_EXE" if [ "$answer" = 'no' ]; then [ "$error" ] && die 1 "$error" setval="$(eval "printf %s \"\$USER_$2\"")" if [ "$setval" = 'yes' ]; then die 1 "Forced to build with library $lib, but cannot locate. Exiting ..." fi else eval "${2}_LIBS=\"$lib\"" PKG_CONF_USED="$PKG_CONF_USED $2" fi return 0 } # check_pkgconf: # If available uses $PKG_CONF_PATH to find a library. # $1 = HAVE_$1 # $2 = package ['package' or 'package package1 package2', $1 = name] # $3 = version [checked only if non-empty] # $4 = critical error message [checked only if non-empty] # $5 = force check_lib when true [checked only if non-empty, set by check_val] check_pkgconf() { add_opt "$1" tmpval="$(eval "printf %s \"\$HAVE_$1\"")" eval "TMP_$1=\$tmpval" [ "$tmpval" = 'no' ] && return 0 ECHOBUF='' [ "${3:-}" ] && ECHOBUF=" >= ${3##* }" pkg="${2%% *}" MSG='Checking presence of package' [ "$PKG_CONF_PATH" = "none" ] && { eval "HAVE_$1=no" eval "${1#HAVE_}_VERSION=0.0" printf %s\\n "$MSG $pkg$ECHOBUF ... no" return 0 } ver="${3:-0.0}" err="${4:-}" lib="${5:-}" answer='no' version='no' for pkgnam in $(printf %s "${2#* }"); do [ "$answer" = 'yes' ] && break printf %s "$MSG $pkgnam$ECHOBUF ... " for pkgver in $(printf %s "$ver"); do if "$PKG_CONF_PATH" --atleast-version="$pkgver" "$pkgnam"; then answer='yes' version="$("$PKG_CONF_PATH" --modversion "$pkgnam")" eval "${1}_CFLAGS=\"$("$PKG_CONF_PATH" --cflags "$pkgnam")\"" eval "${1}_LIBS=\"$("$PKG_CONF_PATH" --libs "$pkgnam")\"" eval "${1}_VERSION=\"$pkgver\"" break fi done printf %s\\n "$version" done eval "HAVE_$1=\"$answer\"" if [ "$answer" = 'no' ]; then [ "$lib" != 'true' ] || return 0 [ "$err" ] && die 1 "$err" setval="$(eval "printf %s \"\$USER_$1\"")" if [ "$setval" = 'yes' ]; then die 1 "Forced to build with package $pkg, but cannot locate. Exiting ..." fi else PKG_CONF_USED="$PKG_CONF_USED $1" fi } # check_header: # $1 = language # $2 = HAVE_$2 # $@ = header files check_header() { add_opt "$2" check_compiler "$1" '' tmpval="$(eval "printf %s \"\$HAVE_$2\"")" [ "$tmpval" = 'no' ] && return 0 rm -f -- "$TEMP_C" val="$2" header="$3" shift 2 for head do CHECKHEADER="$head" printf %s\\n "#include <$head>" >> "$TEMP_CODE" done printf %s\\n "int main(void) { return 0; }" >> "$TEMP_CODE" answer='no' printf %s "Checking presence of header file $CHECKHEADER ... " $(printf %s "$COMPILER") -o "$TEMP_EXE" "$TEMP_CODE" \ $(printf %s "$BUILD_DIRS $FLAGS $LDFLAGS") >>config.log 2>&1 && answer='yes' eval "HAVE_$val=\"$answer\"" printf %s\\n "$answer" rm -f -- "$TEMP_C" "$TEMP_EXE" setval="$(eval "printf %s \"\$USER_$val\"")" if [ "$setval" = 'yes' ] && [ "$answer" = 'no' ]; then die 1 "Build assumed that $header exists, but cannot locate. Exiting ..." fi } # check_macro: # $1 = HAVE_$1 # $2 = macro name # $3 = header name [included only if non-empty] check_macro() { add_opt "$1" tmpval="$(eval "printf %s \"\$HAVE_$1\"")" [ "$tmpval" = 'no' ] && return 0 header_include='' ECHOBUF='' if [ "${3:-}" ]; then header_include="#include <$3>" ECHOBUF=" in $3" fi cat << EOF > "$TEMP_C" $header_include #ifndef $2 #error $2 is not defined #endif int main(void) { return 0; } EOF answer='no' val="$1" macro="$2" printf %s "Checking presence of predefined macro $macro$ECHOBUF ... " $(printf %s "$CC") -o "$TEMP_EXE" "$TEMP_C" \ $(printf %s "$BUILD_DIRS $CFLAGS $LDFLAGS") >>config.log 2>&1 && answer='yes' eval "HAVE_$val=\"$answer\"" printf %s\\n "$answer" rm -f -- "$TEMP_C" "$TEMP_EXE" setval="$(eval "printf %s \"\$USER_$val\"")" if [ "$setval" = 'yes' ] && [ "$answer" = 'no' ]; then die 1 "Build assumed that $macro is defined, but it's not. Exiting ..." fi } # check_switch: # $1 = language # $2 = HAVE_$2 # $3 = switch # $4 = critical error message [checked only if non-empty] check_switch() { add_opt "$2" check_compiler "$1" '' printf %s\\n 'int main(void) { return 0; }' > "$TEMP_CODE" answer='no' printf %s "Checking for availability of switch $3 in $COMPILER ... " $(printf %s "$COMPILER") -o "$TEMP_EXE" "$TEMP_CODE" \ $(printf %s "$BUILD_DIRS $CFLAGS $3 -Werror $LDFLAGS") \ >>config.log 2>&1 && answer='yes' eval "HAVE_$2=\"$answer\"" printf %s\\n "$answer" rm -f -- "$TEMP_CODE" "$TEMP_EXE" if [ "$answer" = 'yes' ]; then eval "${2}_CFLAGS=\"$3\"" PKG_CONF_USED="$PKG_CONF_USED $2" elif [ "${4:-}" ]; then die 1 "$4" fi } # check_val: # Uses check_pkgconf to find a library and falls back to check_lib if false. # $1 = language # $2 = HAVE_$2 # $3 = lib # $4 = include directory [checked only if non-empty] # $5 = package # $6 = version [checked only if non-empty] # $7 = critical error message [checked only if non-empty] # $8 = force check_lib when true [checked only if non-empty] check_val() { check_pkgconf "$2" "$5" "${6:-}" "${7:-}" "${8:-}" [ "$PKG_CONF_PATH" = "none" ] || [ "${8:-}" = true ] || return 0 tmpval="$(eval "printf %s \"\$HAVE_$2\"")" oldval="$(eval "printf %s \"\$TMP_$2\"")" if [ "$tmpval" = 'no' ] && [ "$oldval" != 'no' ]; then eval "HAVE_$2=auto" check_lib "$1" "$2" "$3" '' '' '' "${4:-}" "${7:-}" fi } create_config_header() { outfile="$1"; shift printf %s\\n "Creating config header: $outfile" name="$(printf %s "QB_${outfile}__" | tr '.[a-z]' '_[A-Z]')" { printf %s\\n "#ifndef $name" "#define $name" '' \ "#define PACKAGE_NAME \"$PACKAGE_NAME\"" while [ $# -gt 0 ]; do case "$(eval "printf %s \"\$HAVE_$1\"")" in 'yes') n='0' c89_build="$(eval "printf %s \"\$C89_$1\"")" cxx_build="$(eval "printf %s \"\$CXX_$1\"")" if [ "$c89_build" = 'no' ]; then n=$(($n+1)) printf %s\\n '#if __cplusplus || __STDC_VERSION__ >= 199901L' fi if [ "$cxx_build" = 'no' ]; then n=$(($n+1)) printf %s\\n '#ifndef CXX_BUILD' fi printf %s\\n "#define HAVE_$1 1" while [ $n != '0' ]; do n=$(($n-1)) printf %s\\n '#endif' done ;; 'no') printf %s\\n "/* #undef HAVE_$1 */";; esac shift done for VAR in $(printf %s "$CONFIG_DEFINES"); do printf %s\\n "#define ${VAR%%=*} ${VAR#*=}" done printf %s\\n '#endif' } > "$outfile" } create_config_make() { outfile="$1"; shift printf %s\\n "Creating make config: $outfile" { if [ "$HAVE_CC" = 'yes' ]; then printf %s\\n "CC = $CC" if [ "${CFLAGS}" ]; then printf %s\\n "CFLAGS = $CFLAGS" fi fi if [ "$HAVE_CXX" = 'yes' ]; then printf %s\\n "CXX = $CXX" if [ "${CXXFLAGS}" ]; then printf %s\\n "CXXFLAGS = $CXXFLAGS" fi fi printf %s\\n "WINDRES = $WINDRES" \ "MOC = $MOC" \ "ASFLAGS = $ASFLAGS" \ "LDFLAGS = $LDFLAGS" \ "INCLUDE_DIRS = $INCLUDE_DIRS" \ "LIBRARY_DIRS = $LIBRARY_DIRS" \ "PACKAGE_NAME = $PACKAGE_NAME" \ "BUILD = $BUILD" \ "PREFIX = $PREFIX" while [ $# -gt 0 ]; do case "$(eval "printf %s \"\$HAVE_$1\"")" in 'yes') n='0' c89_build="C89_$1" cxx_build="CXX_$1" for build in "$c89_build" "$cxx_build"; do if [ "$(eval "printf %s \"\$$build\"")" = 'no' ]; then n=$(($n+1)) printf %s\\n "ifneq (\$(${build%%_*}_BUILD),1)" fi done printf %s\\n "HAVE_$1 = 1" while [ $n != '0' ]; do n=$(($n-1)) printf %s\\n 'endif' done ;; 'no') printf %s\\n "HAVE_$1 = 0";; esac case "$PKG_CONF_USED" in *$1*) FLAG="$(eval "printf %s \"\$$1_CFLAGS\"")" LIBS="$(eval "printf %s \"\$$1_LIBS\"")" [ "${FLAG}" ] && printf %s\\n "$1_CFLAGS = ${FLAG%"${FLAG##*[! ]}"}" [ "${LIBS}" ] && printf %s\\n "$1_LIBS = ${LIBS%"${LIBS##*[! ]}"}" ;; esac shift done for VAR in $(printf %s "$MAKEFILE_DEFINES"); do printf %s\\n "${VAR%%=*} = ${VAR#*=}" done } > "$outfile" } . qb/config.libs.sh