#/bin/sh
#
# this script is used to rebuild SDL from sources in the current
# directory. It depends on the Android emulator build scripts
# that should normally be located in ../emulator/android/build
# but you can also use ANDROID_QEMU_PATH in your environment
# to point to the top of the Android emulator sources
#
#
# first, let's see which system we're running this on
cd `dirname $0`
# try to find the Android build directory automatically
if [ -z "$ANDROID_QEMU_PATH" ] ; then
if [ -f ../../android/build/common.sh ] ; then
ANDROID_QEMU_PATH=../..
else
echo "You must define ANDROID_QEMU_PATH in your environment to point"
echo "to the directory containing the Android emulator's sources."
exit 1
fi
fi
if [ ! -d $ANDROID_QEMU_PATH ] ; then
echo "Your ANDROID_QEMU_PATH does not point to a valid directory."
exit 1
fi
if [ ! -f $ANDROID_QEMU_PATH/android/build/common.sh ] ; then
echo "Your ANDROID_QEMU_PATH does not point to a directory that"
echo "contains the Android emulator build scripts."
exit 1
fi
# source common functions definitions
. $ANDROID_QEMU_PATH/android/build/common.sh
# Parse options
OPTION_TRY_64=no
OPTION_HELP=no
OPTION_TARGETS=
OPTION_FORCE_AUTODETECT=no
OPTION_NO_TIGER=no
if [ -z "$CC" ] ; then
CC=gcc
fi
for opt do
optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
case "$opt" in
--help|-h|-\?) OPTION_HELP=yes
;;
--verbose)
if [ "$VERBOSE" = "yes" ] ; then
VERBOSE2=yes
else
VERBOSE=yes
fi
;;
--cc=*) CC="$optarg" ; HOSTCC=$CC
;;
--try-64) OPTION_TRY_64=yes
;;
--prefix=*) OPTION_TARGETS="$OPTION_TARGETS $optarg"
;;
--force-autodetect) OPTION_FORCE_AUTODETECT=yes
;;
--no-tiger) OPTION_NO_TIGER=yes
;;
*)
echo "unknown option '$opt', use --help"
exit 1
esac
done
# Print the help message
#
if [ "$OPTION_HELP" = "yes" ] ; then
cat << EOF
Usage: rebuild.sh [options]
Options: [defaults in brackets after descriptions]
EOF
echo "Standard options:"
echo " --help print this message"
echo " --cc=PATH specify C compiler [$CC]"
echo " --try-64 try to build a 64-bit executable (may crash)"
echo " --verbose verbose configuration"
echo " --force-autodetect force feature auto-detection"
echo " --no-tiger do not generate Tiger-compatible binaries (OS X only)"
echo ""
exit 1
fi
# we only support generating 32-bit binaris on 64-bit systems.
# And we may need to add a -Wa,--32 to CFLAGS to let the assembler
# generate 32-bit binaries on Linux x86_64.
#
if [ "$OPTION_TRY_64" != "yes" ] ; then
force_32bit_binaries
fi
# default target
if [ -z "$OPTION_TARGETS" ] ; then
OPTION_TARGETS=out/$OS
fi
# we can build SDL with Cygwin, so enable it
enable_cygwin
setup_toolchain
###
### Special compiler and linker flags
###
case "$OS" in
linux-*)
BUILD_CFLAGS="-D_GNU_SOURCE=1 -fvisibility=hidden -DXTHREADS -D_REENTRANT"
# prevent -fstack-protector or the generated binaries will not link
BUILD_CFLAGS="$BUILD_CFLAGS -fno-stack-protector"
;;
darwin-*)
BUILD_CFLAGS="-D_GNU_SOURCE=1 -fvisibility=hidden -DTARGET_API_MAC_CARBON -DTARGET_API_MAC_OSX -D_THREAD_SAFE -force_cpusubtype_ALL -fpascal-strings"
# detect the 10.4 SDK and use it automatically
TIGER_SDK=/Developer/SDKs/MacOSX10.4u.sdk
if [ ! -d $TIGER_SDK -a $OPTION_NO_TIGER = no ] ; then
echo "Please install the 10.4 SDK at $TIGER_SDK to generate Tiger-compatible binaries."
echo "If you don't want compatibility, use --no-tiger option instead."
exit 1
fi
if [ -d $TIGER_SDK ] ; then
TIGER_OPTS="-isysroot $TIGER_SDK -mmacosx-version-min=10.4"
BUILD_CFLAGS="$BUILD_CFLAGS $TIGER_OPTS"
BUILD_LDFLAGS="$BUILD_LDFLAGS $TIGER_OPTS -Wl,-syslibroot,$(TIGER_SDK)"
echo "Using OS X 10.4 SDK to generate Tiger-compatible binaries."
else
echo "Warning: the generated binaries will not be compatible with Tiger."
fi
;;
windows)
BUILD_CFLAGS="-D_GNU_SOURCE=1"
;;
*)
BUILD_CFLAGS=
esac
# BUILD_CFLAGS are used to build SDL, but SDL_CFLAGS are used
# when clients want to use its facilities
#
case "$HOST_OS" in
linux)
SDL_CFLAGS="-D_GNU_SOURCE=1 -D_REENTRANT"
SDL_STATIC_LIBS="-lm -ldl -lpthread -lrt"
;;
darwin)
SDL_CFLAGS="-D_GNU_SOURCE=1 -D_THREAD_SAFE"
SDL_STATIC_LIBS="-Wl,-framework,OpenGL -Wl,-framework,Cocoa -Wl,-framework,QuickTime -Wl,-framework,ApplicationServices -Wl,-framework,Carbon -Wl,-framework,IOKit"
;;
windows)
SDL_CFLAGS="-D_GNU_SOURCE=1 -Dmain=SDL_main"
SDL_STATIC_LIBS="-luser32 -lgdi32 -lwinmm"
;;
*)
SDL_CFLAGS=
SDL_STATIC_LIBS=
esac
DOLLAR="$"
SDL_STATIC_LIBS="$DOLLAR{libdir}/libSDLmain.a $DOLLAR{libdir}/libSDL.a $SDL_STATIC_LIBS"
###
### Features probes
###
CONFIG_LIBC=yes
###
### Configuration files generation
###
# create the objs directory that is going to contain all generated files
# including the configuration ones
#
mkdir -p objs
config_add ()
{
echo "$1" >> $config_h
}
# used to add a macro define/undef line to the configuration
# $1: macro name
# $2: 1, 0, yes or no
# $3: optional log prefix
config_add_macro ()
{
local logname
logname="${3:-CfgMacro }"
case "$2" in
0|no|false)
config_add "/* #undef $1 */"
log "$logname: $1=0"
;;
1|yes|true)
config_add "#define $1 1"
log "$logname: $1=1"
;;
esac
}
# used to add host-os-specific driver macros to the config file
# $1 : driver prefix, e.g. DRIVERS_VIDEO
# $2 : macro prefix
# this will look for DRIVERS_VIDEO_${HOST_OS}, and, if it is not
# defined in DRIVERS_VIDEO_default
#
# then this will call 'config_add ${2}_${driver}' for each driver listed
#
config_add_driver_macros ()
{
local driver_list="`var_value ${1}_${HOST_OS}`"
local driver_name
if [ -z "$driver_list" ] ; then
driver_list="`var_value ${1}_default`"
fi
for driver_name in $driver_list; do
config_add_macro "${2}_${driver_name}" yes
done
}
config_h=objs/SDL_config.h
# a function used to check the availability of a given Standard C header
# $1 : header name, without the .h suffix nor enclosing brackets (e.g. 'memory' for <memory.h>)
# this will update the configuration with a relevant line
sdl_check_header ()
{
local result
local header
local macro
header="<$1.h>"
macro=`to_uppercase $1`
macro=`echo $macro | tr '/' '_'`
feature_check_header result "$header"
config_add_macro HAVE_${macro}_H $result "StdCHeader "
}
# call sdl_check_header with a list of header names
sdl_check_headers ()
{
for hh in $*; do
sdl_check_header "$hh"
done
}
# a function used to check that a given function is available in the C library
# this will update the configuration with a relevant line
# $1: function name
# $2: optional, libraries to link against
#
sdl_check_func ()
{
local result
local funcname
local macro
funcname="$1"
macro=`to_uppercase $1`
rm -f $TMPC
cat > $TMPC <<EOF
#undef $funcname
#define $funcname _innocuous_$funcname
#include <assert.h>
#undef $funcname
typedef void (*func_t)(void);
extern void $funcname(void);
func_t _dummy = $funcname;
int main(void)
{
return _dummy == $funcname;
}
EOF
EXTRA_LDFLAGS="$2"
feature_check_link result
config_add_macro HAVE_${macro} $result "StdCFunc "
}
# call sdl_check_func with a list of functions
sdl_check_funcs ()
{
for ff in $*; do
sdl_check_func "$ff"
done
}
# check endianess of the host platform
sdl_check_endianess ()
{
cat > $TMPC <<EOF
int main(void)
{
union {
unsigned short v;
unsigned char b[2];
} u;
u.v = 0x1234;
return (u.b[0] == 0x12);
}
EOF
feature_run_exec test_e
if [ "$test_e" = "1" ] ; then
eval $1=4321
else
eval $1=1234
fi
}
generate_SDL_config_h ()
{
echo "/* This file was autogenerated by '$PROGNAME' - do not edit */" > $config_h
config_add "#ifndef _SDL_config_h"
config_add "#define _SDL_config_h"
config_add ""
config_add "#include \"SDL_platform.h\""
config_add ""
# true for all architectures these days
config_add_macro SDL_HAS_64BIT_TYPE 1
sdl_check_endianess ENDIANESS
config_add "#define SDL_BYTEORDER $ENDIANESS"
config_add ""
config_add_macro HAVE_LIBC $CONFIG_LIBC
config_add "#if HAVE_LIBC"
config_add ""
config_add "/* Useful headers */"
sdl_check_headers alloca sys/types stdio
# just like configure - force it to 1
config_add "#define STDC_HEADERS 1"
sdl_check_headers stdlib stdarg malloc memory string strings inttypes stdint ctype math iconv signal altivec
config_add "/* C library functions */"
sdl_check_funcs malloc calloc realloc free alloc
config_add "#ifndef _WIN32 /* Don't use on Windows */"
sdl_check_funcs getenv putenv unsetenv
config_add "#endif"
sdl_check_funcs qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat
sdl_check_funcs strdup _strrev _strupr _strlwr index rindex strchr strrchr itoa _ltoa
sdl_check_funcs _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull
sdl_check_funcs strtod atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp
sdl_check_funcs vsnprintf iconv sigaction setjmp nanosleep
sdl_check_func clock_gettime -lrt
sdl_check_func dlvsym -ldl
sdl_check_funcs getpagesize
config_add "#else"
config_add "/* We may need some replacement for stdarg.h here */"
config_add "#include <stdarg.h>"
config_add "#endif /* HAVE_LIBC */"
config_add ""
config_add "/* Allow disabling of core subsystems */"
config_add_macro SDL_AUDIO_DISABLED yes
config_add_macro SDL_CDROM_DISABLED yes
config_add_macro SDL_CPUINFO_DISABLED no
config_add_macro SDL_EVENTS_DISABLED no
config_add_macro SDL_FILE_DISABLED yes
config_add_macro SDL_JOYSTICK_DISABLED yes
config_add_macro SDL_LOADSO_DISABLED no
config_add_macro SDL_THREADS_DISABLED no
config_add_macro SDL_TIMERS_DISABLED no
config_add_macro SDL_VIDEO_DISABLED no
config_add ""
config_add "/* Enable various shared object loading systems */"
config_add_driver_macros DRIVERS_LOADSO SDL_LOADSO
config_add ""
config_add "/* Enable various threading systems */"
config_add_driver_macros DRIVERS_THREAD SDL_THREAD
config_add ""
config_add "/* Enable various timer systems */"
config_add_driver_macros DRIVERS_TIMER SDL_TIMER
config_add ""
config_add "/* Enable various video drivers */"
config_add_driver_macros DRIVERS_VIDEO SDL_VIDEO_DRIVER
config_add_driver_macros DRIVERS_MAIN SDL_MAIN
# the following defines are good enough for all recent Unix distributions
config_add "#define SDL_VIDEO_DRIVER_X11_DYNAMIC \"libX11.so.6\""
config_add "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT \"libXext.so.6\""
config_add "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR \"libXrandr.so.2\""
config_add "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER \"libXrender.so.1\""
# todo: OpenGL support ?
# todo: Assembly routines support ?
config_add "#endif /* _SDL_config_h */"
}
### Build the config sub-makefile
###
make_add ()
{
echo "$1" >> $config_mk
}
make_add_driver_macros ()
{
local driver_list="`var_value ${1}_${HOST_OS}`"
local driver_name
if [ -z "$driver_list" ] ; then
driver_list="`var_value ${1}_default`"
fi
for driver_name in $driver_list; do
make_add "SDL_$2_${driver_name} := yes"
done
}
generate_sdl_config_mk ()
{
CFLAGS="$CFLAGS $BUILD_CFLAGS"
LDFLAGS="$LDFLAGS $BUILD_LDFLAGS"
create_config_mk
make_add ""
PWD=`pwd`
make_add "SRC_PATH=$PWD"
make_add "BUILD_SYSTEM=$ANDROID_QEMU_PATH/android/build"
make_add "SDL_CONFIG_LIBC := $CONFIG_LIBC"
make_add "SDL_CONFIG_CPUINFO := yes"
make_add_driver_macros DRIVERS_LOADSO CONFIG_LOADSO
make_add_driver_macros DRIVERS_THREAD CONFIG_THREAD
make_add_driver_macros DRIVERS_TIMER CONFIG_TIMER
make_add_driver_macros DRIVERS_VIDEO CONFIG_VIDEO
make_add_driver_macros DRIVERS_MAIN CONFIG_MAIN
make_add "INSTALL_TARGETS := $OPTION_TARGETS"
}
### Build the final sdl-config script from the template
###
generate_sdl_config ()
{
# build a sed script that will replace all @VARIABLES@ in the template
# with appropriate values
rm -f $TMPC
# replace @exec_prefix@ with "{prefix}", and @libdir@ with "{libdir}"
cat > $TMPC <<EOF
s!@exec_prefix@!\$\{prefix\}!g
s!@libdir@!\$\{exec_prefix\}/libs!g
s!@includedir@!\$\{prefix\}/include!g
EOF
# we want to enable static linking, do @ENABLE_STATIC_FALSE@ and @ENABLE_STATIC_TRUE@
cat >> $TMPC <<EOF
s!@ENABLE_STATIC_FALSE@!\#!g
s!@ENABLE_STATIC_TRUE@!!g
s!@ENABLE_SHARED_TRUE@!\#!g
s!@ENABLE_SHARED_FALSE@!!g
EOF
# set the version to 1.2.12
cat >> $TMPC <<EOF
s!@SDL_VERSION@!1.2.12!g
EOF
#
cat >> $TMPC <<EOF
s!@SDL_CFLAGS@!$SDL_CFLAGS!g
s!@SDL_STATIC_LIBS@!$SDL_STATIC_LIBS!g
EOF
cat sdl-config.in | sed -f $TMPC > objs/sdl-config
chmod +x objs/sdl-config
}
# copy a configuration file or perform auto-detection if one is not available
# or the --force-autodetect option was used
# $1: basename of config file
# $2: command to run to perform auto-detection/generation
#
copy_or_autodetect ()
{
if [ "$OPTION_FORCE_AUTODETECT" != "yes" -a -f android/build/$OS/$1 ] ; then
log "Setup : Copying $1 from android/build/$OS"
cp -f android/build/$OS/$1 objs/$1
else
log "Setup : Auto-generating $1"
eval $2
fi
}
generate_all ()
{
copy_or_autodetect SDL_config.h generate_SDL_config_h
generate_sdl_config_mk
copy_or_autodetect sdl-config generate_sdl_config
}
DRIVERS_LOADSO_default=DLOPEN
DRIVERS_LOADSO_darwin=DLCOMPAT
DRIVERS_LOADSO_windows=WIN32
# TODO: determine if PTHREAD_RECURSIVE or PTHREAD_RECURSIVE_NP is valid for the platform
DRIVERS_THREAD_default="PTHREAD PTHREAD_RECURSIVE_MUTEX"
DRIVERS_THREAD_linux="PTHREAD PTHREAD_RECURSIVE_MUTEX_NP"
DRIVERS_THREAD_windows=WIN32
DRIVERS_TIMER_default=UNIX
DRIVERS_TIMER_windows=WIN32
# TODO: actually compute this properly for X11 and dynamic loading !!
DRIVERS_VIDEO_default="X11 X11_DPMS X11_XINERAMA X11_XME"
DRIVERS_VIDEO_darwin="QUARTZ"
DRIVERS_VIDEO_windows="WINDIB"
DRIVERS_MAIN_default=DUMMY
DRIVERS_MAIN_darwin=MACOSX
DRIVERS_MAIN_windows=WIN32
generate_all