Browse Source

Android support, part 1

rdb 13 years ago
parent
commit
c26c0e6a97

+ 378 - 0
dtool/Config.Android.pp

@@ -0,0 +1,378 @@
+//
+// Config.Android.pp
+//
+// This file defines some custom config variables for the Android
+// platform.  It makes some initial guesses about compiler features,
+// etc.
+//
+
+// *******************************************************************
+// NOTE: you should not attempt to copy this file verbatim as your own
+// personal Config.pp file.  Instead, you should start with an empty
+// Config.pp file, and add lines to it when you wish to override
+// settings given in here.  In the normal ppremake system, this file
+// will always be read first, and then your personal Config.pp file
+// will be read later, which gives you a chance to override the
+// default settings found in this file.  However, if you start by
+// copying the entire file, it will be difficult to tell which
+// settings you have customized, and it will be difficult to upgrade
+// to a subsequent version of Panda.
+// *******************************************************************
+
+// Android is a Linux distribution.
+#define IS_LINUX 1
+
+// These libraries are provided by the Android NDK.
+#define ZLIB_IPATH
+#define ZLIB_LPATH
+#define ZLIB_LIBS z
+#define HAVE_ZLIB 1
+
+#define GLES_IPATH
+#define GLES_LPATH
+#define GLES_LIBS GLESv1_CM
+#define HAVE_GLES 1
+
+#define GLES2_IPATH
+#define GLES2_LPATH
+#define GLES2_LIBS GLESv2
+#define HAVE_GLES2 1
+
+#define EGL_IPATH
+#define EGL_LPATH
+#define EGL_LIBS EGL
+#define HAVE_EGL 1
+
+// We don't have these, of course, so let's disable
+// them for convenience in case they were autodetected.
+#define HAVE_DX8
+#define HAVE_DX9
+#define HAVE_CG
+
+// Compiler flags
+#defer TOOLCHAIN_PATH $[ANDROID_NDK_HOME]/toolchains/$[ANDROID_TOOLCHAIN]/prebuilt/windows/bin
+#defer TOOLCHAIN_PREFIX $[if $[eq $[ANDROID_ABI],x86],i686-linux-android,$[ANDROID_ABI]]
+#defer CC $[TOOLCHAIN_PATH]/$[TOOLCHAIN_PREFIX]-gcc
+#defer CXX $[TOOLCHAIN_PATH]/$[TOOLCHAIN_PREFIX]-g++
+#defer AR $[TOOLCHAIN_PATH]/$[TOOLCHAIN_PREFIX]-ar
+#define C++FLAGS_GEN -fno-exceptions -fno-rtti
+
+#defer SYSROOT $[ANDROID_NDK_HOME]/platforms/$[ANDROID_PLATFORM]/arch-$[ANDROID_ARCH]
+#defer SYSROOT_FLAGS --sysroot=$[subst \,/,$[osfilename $[SYSROOT]]]
+
+#defer EXTRA_IPATH $[ANDROID_NDK_HOME]/sources/android/native_app_glue $[SYSROOT]/usr/include
+#defer EXTRA_LPATH $[SYSROOT]/usr/lib
+#defer EXTRA_LIBS $[if $[eq $[BUILD_TYPE],android],,c m]
+
+// Define the CFLAGS and LDFLAGS settings for the various architectures.
+#defer ANDROID_arm_CFLAGS\
+ -fpic\
+ -ffunction-sections\
+ -funwind-tables\
+ -fstack-protector\
+ -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__\
+ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__\
+ $[if $[eq $[ANDROID_ABI],armeabi-v7a],-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16,-march=armv5te -mtune=xscale -msoft-float]
+
+#defer ANDROID_arm_LDFLAGS -march=armv7-a -Wl,--fix-cortex-a8
+
+#define ANDROID_mips_CFLAGS\
+ -fpic\
+ -fno-strict-aliasing\
+ -finline-functions\
+ -ffunction-sections\
+ -funwind-tables\
+ -fmessage-length=0\
+ -fno-inline-functions-called-once\
+ -fgcse-after-reload\
+ -frerun-cse-after-loop\
+ -frename-registers
+
+#define ANDROID_mips_LDFLAGS
+
+#define ANDROID_x86_CFLAGS\
+ -ffunction-sections\
+ -funwind-tables\
+ -fstack-protector
+
+#define ANDROID_x86_LDFLAGS
+
+// Select the flags for our architecture and add some common ones.
+#defer ANDROID_CFLAGS $[ANDROID_$[ANDROID_ARCH]_CFLAGS] -DANDROID -Wa,$[if $[ANDROID_DISABLE_NX],--execstack,--noexecstack]
+#defer ANDROID_LDFLAGS -Wl,--no-undefined\
+ -Wl,-z,$[if $[ANDROID_DISABLE_NX],execstack,noexecstack]\
+ -Wl,-z,$[if $[ANDROID_DISABLE_RELRO],norelro,relro]\
+ -Wl,-z,$[if $[ANDROID_DISABLE_RELRO],lazy,now]
+
+// How to compile a C or C++ file into a .o file.  $[target] is the
+// name of the .o file, $[source] is the name of the source file,
+// $[ipath] is a space-separated list of directories to search for
+// include files, and $[flags] is a list of additional flags to pass
+// to the compiler.
+#defer os_ipath $[subst \,/,$[osfilename $[ipath]]]
+#defer COMPILE_C $[CC] $[SYSROOT_FLAGS] $[ANDROID_CFLAGS] $[CFLAGS_GEN] $[flags] $[os_ipath:%=-I%] -c $[source] -o $[target]
+#defer COMPILE_C++ $[CXX] $[SYSROOT_FLAGS] $[ANDROID_CFLAGS] $[C++FLAGS_GEN] $[flags] $[os_ipath:%=-I%] -c $[source] -o $[target]
+
+// What flags should be passed to both C and C++ compilers to enable
+// debug symbols?  This will be supplied when OPTIMIZE (above) is set
+// to 1, 2, or 3.
+#defer DEBUGFLAGS -g
+
+// What flags should be passed to both C and C++ compilers to enable
+// compiler optimizations?  This will be supplied when OPTIMIZE
+// (above) is set to 2, 3, or 4.
+#defer OPTFLAGS -O2
+
+// By convention, any source file that contains the string _no_opt_ in
+// its filename won't have the above compiler optimizations run for it.
+#defer no_opt $[findstring _no_opt_,$[source]]
+
+// What define variables should be passed to the compilers for each
+// value of OPTIMIZE?  We separate this so we can pass these same
+// options to interrogate, guaranteeing that the correct interfaces
+// are generated.  Do not include -D here; that will be supplied
+// automatically.
+#defer CDEFINES_OPT1 $[EXTRA_CDEFS]
+#defer CDEFINES_OPT2 $[EXTRA_CDEFS]
+#defer CDEFINES_OPT3 $[EXTRA_CDEFS]
+#defer CDEFINES_OPT4 $[EXTRA_CDEFS]
+
+// What additional flags should be passed for each value of OPTIMIZE
+// (above)?  We separate out the compiler-optimization flags, above,
+// so we can compile certain files that give optimizers trouble (like
+// the output of lex and yacc) without them, but with all the other
+// relevant flags.
+
+#define ANDROID_DEBUG_CFLAGS -fno-omit-frame-pointer -fno-strict-aliasing
+#define ANDROID_RELEASE_CFLAGS -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300
+
+#defer CFLAGS_OPT1 $[CDEFINES_OPT1:%=-D%] -Wall $[DEBUGFLAGS] $[ANDROID_DEBUG_FLAGS]
+#defer CFLAGS_OPT2 $[CDEFINES_OPT2:%=-D%] -Wall $[DEBUGFLAGS] $[if $[no_opt],,$[OPTFLAGS]] $[ANDROID_DEBUG_FLAGS]
+#defer CFLAGS_OPT3 $[CDEFINES_OPT3:%=-D%] $[DEBUGFLAGS] $[if $[no_opt],,$[OPTFLAGS]] $[ANDROID_RELEASE_FLAGS]
+#defer CFLAGS_OPT4 $[CDEFINES_OPT4:%=-D%] $[if $[no_opt],,$[OPTFLAGS]] $[ANDROID_RELEASE_FLAGS]
+
+// What additional flags should be passed to both compilers when
+// building shared (relocatable) sources?  Some architectures require
+// special support for this.
+#defer CFLAGS_SHARED -fPIC
+
+// How to generate a C or C++ executable from a collection of .o
+// files.  $[target] is the name of the binary to generate, and
+// $[sources] is the list of .o files.  $[libs] is a space-separated
+// list of dependent libraries, and $[lpath] is a space-separated list
+// of directories in which those libraries can be found.
+#defer os_lpath $[subst \,/,$[osfilename $[lpath]]]
+#defer LINK_BIN_C $[LINK_BIN_C++]
+#defer LINK_BIN_C++ $[cxx_ld]\
+ -Wl,--gc-sections\
+ -Wl,-z,nocopyreloc\
+ $[SYSROOT_FLAGS]\
+ $[sources]\
+ $[flags]\
+ $[os_lpath:%=-L%] $[libs:%=-l%]\
+ -o $[target]
+
+// How to generate a static C or C++ library.  $[target] is the
+// name of the library to generate, and $[sources] is the list of .o
+// files that will go into the library.
+#defer STATIC_LIB_C $[AR] cru $[target] $[sources]
+#defer STATIC_LIB_C++ $[AR] cru $[target] $[sources]
+
+// How to run ranlib, if necessary, after generating a static library.
+// $[target] is the name of the library.  Set this to the empty string
+// if ranlib is not necessary on your platform.
+#defer RANLIB ranlib $[target]
+
+// Where to put the so_locations file, used by an Irix MIPSPro
+// compiler, to generate a map of shared library memory locations.
+#defer SO_LOCATIONS $[DTOOL_INSTALL]/etc/so_locations
+
+
+// How to generate a shared C or C++ library.  $[source] and $[target]
+// as above, and $[libs] is a space-separated list of dependent
+// libraries, and $[lpath] is a space-separated list of directories in
+// which those libraries can be found.
+#defer SHARED_LIB_C $[SHARED_LIB_C++]
+#defer SHARED_LIB_C++ $[cxx_ld]\
+ -Wl,-soname,$[notdir $[target]]\
+ -shared\
+ $[SYSROOT_FLAGS]\
+ $[sources]\
+ $[flags]\
+ $[os_lpath:%=-L%] $[libs:%=-l%]\
+ -o $[target]
+#define BUNDLE_LIB_C++
+
+// How to install a data file or executable file.  $[local] is the
+// local name of the file to install, and $[dest] is the name of the
+// directory to put it in.
+
+// On Unix systems, we strongly prefer using the install program to
+// install files.  This has nice features like automatically setting
+// the permissions bits, and also is usually clever enough to install
+// a running program without crashing the running instance.  However,
+// it doesn't understanding installing a program from a subdirectory,
+// so we have to cd into the source directory first.
+#defer install_dash_p $[if $[KEEP_TIMESTAMPS],-p,]
+#defer INSTALL $[if $[ne $[dir $[local]], ./],cd ./$[dir $[local]] &&] install -m $[INSTALL_UMASK_DATA] $[install_dash_p] $[notdir $[local]] $[dest]/
+#defer INSTALL_PROG $[if $[ne $[dir $[local]], ./],cd ./$[dir $[local]] &&] install -m $[INSTALL_UMASK_PROG] $[install_dash_p] $[notdir $[local]] $[dest]/
+
+#define SYSTEM_IGATE_FLAGS -D__const=const -Dvolatile -Dmutable
+
+// Posix thread support is provided by the Android NDK.
+#define HAVE_POSIX_THREADS 1
+#define THREADS_LIBS
+
+// Is the platform big-endian (like an SGI workstation) or
+// little-endian (like a PC)?  Define this to the empty string to
+// indicate little-endian, or nonempty to indicate big-endian.
+#define WORDS_BIGENDIAN
+
+// Does the C++ compiler support namespaces?
+#define HAVE_NAMESPACE 1
+
+// Does the C++ compiler support ios::binary?
+#define HAVE_IOS_BINARY 1
+
+// How about the typename keyword?
+#define HAVE_TYPENAME 1
+
+// Will the compiler avoid inserting extra bytes in structs between a
+// base struct and its derived structs?  It is safe to define this
+// false if you don't know, but if you know that you can get away with
+// this you may gain a tiny performance gain by defining this true.
+// If you define this true incorrectly, you will get lots of
+// assertion failures on execution.
+#define SIMPLE_STRUCT_POINTERS
+
+// Do we have a gettimeofday() function?
+#define HAVE_GETTIMEOFDAY 1
+
+// Does gettimeofday() take only one parameter?
+#define GETTIMEOFDAY_ONE_PARAM
+
+// Do we have getopt() and/or getopt_long_only() built into the
+// system?
+#define HAVE_GETOPT 1
+#define HAVE_GETOPT_LONG_ONLY 1
+
+// Are the above getopt() functions defined in getopt.h, or somewhere else?
+#define PHAVE_GETOPT_H 1
+
+// Can we determine the terminal width by making an ioctl(TIOCGWINSZ) call?
+#define IOCTL_TERMINAL_WIDTH 1
+
+// Do the system headers define a "streamsize" typedef?  How about the
+// ios::binary enumerated value?  And other ios typedef symbols like
+// ios::openmode and ios::fmtflags?
+#define HAVE_STREAMSIZE 1
+#define HAVE_IOS_BINARY 1
+#define HAVE_IOS_TYPEDEFS 1
+
+// Can we safely call getenv() at static init time?
+#define STATIC_INIT_GETENV 1
+
+// Can we read the files /proc/self/* to determine our
+// environment variables at static init time?
+#define HAVE_PROC_SELF_EXE 1
+#define HAVE_PROC_SELF_MAPS 1
+#define HAVE_PROC_SELF_ENVIRON 1
+#define HAVE_PROC_SELF_CMDLINE 1
+
+// Do we have a global pair of argc/argv variables that we can read at
+// static init time?  Should we prototype them?  What are they called?
+#define HAVE_GLOBAL_ARGV
+#define PROTOTYPE_GLOBAL_ARGV
+#define GLOBAL_ARGV
+#define GLOBAL_ARGC
+
+// Should we include <iostream> or <iostream.h>?  Define PHAVE_IOSTREAM
+// to nonempty if we should use <iostream>, or empty if we should use
+// <iostream.h>.
+#define PHAVE_IOSTREAM 1
+
+// Do we have a true stringstream class defined in <sstream>?
+#define PHAVE_SSTREAM 1
+
+// Does fstream::open() require a third parameter, specifying the
+// umask?  Versions of gcc prior to 3.2 had this.
+#define HAVE_OPEN_MASK
+
+// Do we have the lockf() function available?
+#define HAVE_LOCKF
+
+// Do the compiler or system libraries define wchar_t for you?
+#define HAVE_WCHAR_T 1
+
+// Does <string> define the typedef wstring?  Most do, but for some
+// reason, versions of gcc before 3.0 didn't do this.
+#define HAVE_WSTRING 1
+
+// Do we have <new>?
+#define PHAVE_NEW 1
+
+// Do we have <io.h>?
+#define PHAVE_IO_H
+
+// Do we have <malloc.h>?
+#define PHAVE_MALLOC_H 1
+
+// Do we have <alloca.h>?
+#define PHAVE_ALLOCA_H 1
+
+// Do we have <locale.h>?
+#define PHAVE_LOCALE_H 1
+
+// Do we have <string.h>?
+#define PHAVE_STRING_H 1
+
+// Do we have <stdlib.h>?
+#define PHAVE_STDLIB_H 1
+
+// Do we have <limits.h>?
+#define PHAVE_LIMITS_H 1
+
+// Do we have <minmax.h>?
+#define PHAVE_MINMAX_H
+
+// Do we have <sys/types.h>?
+#define PHAVE_SYS_TYPES_H 1
+#define PHAVE_SYS_TIME_H 1
+
+// Do we have <unistd.h>?
+#define PHAVE_UNISTD_H 1
+
+// Do we have <utime.h>?
+#define PHAVE_UTIME_H 1
+
+// Do we have <dirent.h>?
+#define PHAVE_DIRENT_H 1
+
+// Do we have <glob.h> (and do we want to use it instead of dirent.h)?
+#define PHAVE_GLOB_H
+
+// Do we have <sys/soundcard.h> (and presumably a Linux-style audio
+// interface)?
+#define PHAVE_SYS_SOUNDCARD_H 1
+
+// Do we have <ucontext.h> (and therefore makecontext() / swapcontext())?
+#define PHAVE_UCONTEXT_H 1
+
+// Do we have <linux/input.h> ? This enables us to use raw mouse input.
+#define PHAVE_LINUX_INPUT_H 1
+
+// Do we have RTTI (and <typeinfo>)?
+// Technically, Android has RTTI support now,
+// but we keep it disabled for performance reasons.
+#define HAVE_RTTI
+
+// Do we have <stdint.h>?
+#define PHAVE_STDINT_H 1
+
+// We need 64-bit file i/o
+#define __USE_LARGEFILE64 1
+
+// The dynamic library file extension (usually .so .dll or .dylib):
+#define DYNAMIC_LIB_EXT .so
+#define STATIC_LIB_EXT .a
+#define BUNDLE_EXT

+ 3 - 0
dtool/Config.FreeBSD.pp

@@ -220,6 +220,9 @@
 // umask?  Versions of gcc prior to 3.2 had this.
 // umask?  Versions of gcc prior to 3.2 had this.
 #define HAVE_OPEN_MASK
 #define HAVE_OPEN_MASK
 
 
+// Do we have the lockf() function available?
+#define HAVE_LOCKF 1
+
 // Do the compiler or system libraries define wchar_t for you?
 // Do the compiler or system libraries define wchar_t for you?
 #define HAVE_WCHAR_T 1
 #define HAVE_WCHAR_T 1
 
 

+ 3 - 0
dtool/Config.Irix.pp

@@ -95,6 +95,9 @@
 // umask?
 // umask?
 #define HAVE_OPEN_MASK 1
 #define HAVE_OPEN_MASK 1
 
 
+// Do we have the lockf() function available?
+#define HAVE_LOCKF 1
+
 // Do the compiler or system libraries define wchar_t for you?
 // Do the compiler or system libraries define wchar_t for you?
 #define HAVE_WCHAR_T 1
 #define HAVE_WCHAR_T 1
 
 

+ 4 - 0
dtool/Config.Linux.pp

@@ -263,6 +263,9 @@
 // umask?  Versions of gcc prior to 3.2 had this.
 // umask?  Versions of gcc prior to 3.2 had this.
 #define HAVE_OPEN_MASK
 #define HAVE_OPEN_MASK
 
 
+// Do we have the lockf() function available?
+#define HAVE_LOCKF 1
+
 // Do the compiler or system libraries define wchar_t for you?
 // Do the compiler or system libraries define wchar_t for you?
 #define HAVE_WCHAR_T 1
 #define HAVE_WCHAR_T 1
 
 
@@ -273,6 +276,7 @@
 // Do we have <new>?
 // Do we have <new>?
 #define PHAVE_NEW 1
 #define PHAVE_NEW 1
 
 
+
 // Do we have <io.h>?
 // Do we have <io.h>?
 #define PHAVE_IO_H
 #define PHAVE_IO_H
 
 

+ 3 - 0
dtool/Config.OSX.pp

@@ -222,6 +222,9 @@
 // umask?  Versions of gcc prior to 3.2 had this.
 // umask?  Versions of gcc prior to 3.2 had this.
 #define HAVE_OPEN_MASK
 #define HAVE_OPEN_MASK
 
 
+// Do we have the lockf() function available?
+#define HAVE_LOCKF 1
+
 // Do the compiler or system libraries define wchar_t for you?
 // Do the compiler or system libraries define wchar_t for you?
 #define HAVE_WCHAR_T 1
 #define HAVE_WCHAR_T 1
 
 

+ 3 - 0
dtool/Config.Win32.pp

@@ -100,6 +100,9 @@
 // umask?
 // umask?
 #define HAVE_OPEN_MASK
 #define HAVE_OPEN_MASK
 
 
+// Do we have the lockf() function available?
+#define HAVE_LOCKF 1
+
 // Do the compiler or system libraries define wchar_t for you?
 // Do the compiler or system libraries define wchar_t for you?
 #define HAVE_WCHAR_T 1
 #define HAVE_WCHAR_T 1
 
 

+ 3 - 0
dtool/Config.Win64.pp

@@ -100,6 +100,9 @@
 // umask?
 // umask?
 #define HAVE_OPEN_MASK
 #define HAVE_OPEN_MASK
 
 
+// Do we have the lockf() function available?
+#define HAVE_LOCKF 1
+
 // Do the compiler or system libraries define wchar_t for you?
 // Do the compiler or system libraries define wchar_t for you?
 #define HAVE_WCHAR_T 1
 #define HAVE_WCHAR_T 1
 
 

+ 14 - 0
dtool/Config.pp

@@ -402,6 +402,20 @@
 // Don't enable this unless you know what you're doing!
 // Don't enable this unless you know what you're doing!
 #define BUILD_IPHONE
 #define BUILD_IPHONE
 
 
+// Panda contains some experimental code to compile for Android.  This
+// requires the Google Android NDK.
+// Besides BUILD_ANDROID, you'll also have to set ANDROID_NDK_HOME
+// to the location of the Android NDK directory.  ANDROID_NDK_HOME may
+// not contain any spaces.
+// Furthermore, ANDROID_ABI can be set to armeabi, armeabi-v7a, x86,
+// or mips, depending on which architecture should be targeted.
+#define ANDROID_NDK_HOME
+#define ANDROID_ABI armeabi
+#define ANDROID_STL gnustl_shared
+#define ANDROID_PLATFORM android-9
+#define ANDROID_ARCH arm
+#defer ANDROID_TOOLCHAIN $[if $[eq $[ANDROID_ARCH],arm],arm-linux-androideabi]
+
 // Do you want to use one of the alternative malloc implementations?
 // Do you want to use one of the alternative malloc implementations?
 // This is almost always a good idea on Windows, where the standard
 // This is almost always a good idea on Windows, where the standard
 // malloc implementation appears to be pretty poor, but probably
 // malloc implementation appears to be pretty poor, but probably

+ 3 - 0
dtool/LocalSetup.pp

@@ -578,6 +578,9 @@ $[cdefine HAVE_NAMESPACE]
 /* Define if fstream::open() accepts a third parameter for umask. */
 /* Define if fstream::open() accepts a third parameter for umask. */
 $[cdefine HAVE_OPEN_MASK]
 $[cdefine HAVE_OPEN_MASK]
 
 
+/* Define if we have a lockf() function. */
+$[cdefine HAVE_LOCKF]
+
 /* Define if some header file defines wchar_t. */
 /* Define if some header file defines wchar_t. */
 $[cdefine HAVE_WCHAR_T]
 $[cdefine HAVE_WCHAR_T]
 
 

+ 2 - 0
dtool/pptempl/Global.pp

@@ -790,6 +790,8 @@
     #set alt_libs $[alt_libs] $[WIN_SYS_LIBS] $[components $[WIN_SYS_LIBS],$[active_libs] $[transitive_link]]
     #set alt_libs $[alt_libs] $[WIN_SYS_LIBS] $[components $[WIN_SYS_LIBS],$[active_libs] $[transitive_link]]
   #elif $[OSX_PLATFORM]
   #elif $[OSX_PLATFORM]
     #set alt_libs $[alt_libs] $[OSX_SYS_LIBS] $[components $[OSX_SYS_LIBS],$[active_libs] $[transitive_link]]
     #set alt_libs $[alt_libs] $[OSX_SYS_LIBS] $[components $[OSX_SYS_LIBS],$[active_libs] $[transitive_link]]
+  #elif $[eq $[PLATFORM], Android]
+    #set alt_libs $[alt_libs] $[ANDROID_SYS_LIBS] $[components $[ANDROID_SYS_LIBS],$[active_libs] $[transitive_link]]
   #else
   #else
     #set alt_libs $[alt_libs] $[UNIX_SYS_LIBS] $[components $[UNIX_SYS_LIBS],$[active_libs] $[transitive_link]]
     #set alt_libs $[alt_libs] $[UNIX_SYS_LIBS] $[components $[UNIX_SYS_LIBS],$[active_libs] $[transitive_link]]
   #endif
   #endif

+ 53 - 0
dtool/pptempl/PostConfig.pp

@@ -28,5 +28,58 @@
   #define OSX_CFLAGS -isysroot $[dev]/SDKs/$[IPH_PLATFORM]$[IPH_VERSION].sdk $[osflags]
   #define OSX_CFLAGS -isysroot $[dev]/SDKs/$[IPH_PLATFORM]$[IPH_VERSION].sdk $[osflags]
 
 
   #defer ODIR_SUFFIX -$[IPH_PLATFORM]
   #defer ODIR_SUFFIX -$[IPH_PLATFORM]
+#endif
+
+#if $[eq $[PLATFORM], Android]
+
+// These are the flags also used by Android's own ndk-build.
+#if $[eq $[ANDROID_ARCH],arm]
+#define target_cflags\
+ -fpic\
+ -ffunction-sections\
+ -funwind-tables\
+ -fstack-protector\
+ -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__\
+ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__
+
+#elif $[eq $[ANDROID_ARCH],mips]
+#define target_cflags\
+ -fpic\
+ -fno-strict-aliasing\
+ -finline-functions\
+ -ffunction-sections\
+ -funwind-tables\
+ -fmessage-length=0\
+ -fno-inline-functions-called-once\
+ -fgcse-after-reload\
+ -frerun-cse-after-loop\
+ -frename-registers
+
+#elif $[eq $[ANDROID_ABI],x86]
+#define target_cflags\
+ -ffunction-sections\
+ -funwind-tables\
+ -fstack-protector
+#endif
+
+#if $[eq $[ANDROID_ABI],armeabi-v7a]
+#define target_cflags $[target_cflags]\
+ -march=armv7-a \
+ -mfloat-abi=softfp \
+ -mfpu=vfpv3-d16
+
+#define target_ldflags $[target_ldflags]\
+ -march=armv7-a \
+ -Wl,--fix-cortex-a8
+
+#elif $[eq $[ANDROID_ABI],armeabi]
+#define target_cflags $[target_cflags]\
+ -march=armv5te \
+ -mtune=xscale \
+ -msoft-float
+#endif
+
+#define ANDROID_CFLAGS $[target_cflags] $[ANDROID_CFLAGS]
+#define ANDROID_LDFLAGS $[target_ldflags] $[ANDROID_LDFLAGS]
 
 
 #endif
 #endif

+ 11 - 0
dtool/src/dtoolbase/dtool_platform.h

@@ -49,6 +49,17 @@
 #define DTOOL_PLATFORM "freebsd_i386"
 #define DTOOL_PLATFORM "freebsd_i386"
 #endif
 #endif
 
 
+#elif defined(__ANDROID__)
+#if defined(__ARM_ARCH_7A__)
+#define DTOOL_PLATFORM "android_armv7a"
+#elif defined(__arm__)
+#define DTOOL_PLATFORM "android_arm"
+#elif defined(__mips__)
+#define DTOOL_PLATFORM "android_mips"
+#elif defined(__i386__)
+#define DTOOL_PLATFORM "android_i386"
+#endif
+
 #elif defined(__x86_64)
 #elif defined(__x86_64)
 #define DTOOL_PLATFORM "linux_amd64"
 #define DTOOL_PLATFORM "linux_amd64"
 
 

+ 8 - 0
dtool/src/dtoolutil/filename.cxx

@@ -3010,7 +3010,11 @@ atomic_compare_and_exchange_contents(string &orig_contents,
 
 
   orig_contents = string();
   orig_contents = string();
 
 
+#ifdef HAVE_LOCKF
   if (lockf(fd, F_LOCK, 0) != 0) {
   if (lockf(fd, F_LOCK, 0) != 0) {
+#else
+  if (flock(fd, LOCK_EX) != 0) {
+#endif
     perror(os_specific.c_str());
     perror(os_specific.c_str());
     close(fd);
     close(fd);
     return false;
     return false;
@@ -3127,7 +3131,11 @@ atomic_read_contents(string &contents) const {
 
 
   contents = string();
   contents = string();
 
 
+#ifdef HAVE_LOCKF
   if (lockf(fd, F_LOCK, 0) != 0) {
   if (lockf(fd, F_LOCK, 0) != 0) {
+#else
+  if (flock(fd, LOCK_EX) != 0) {
+#endif
     perror(os_specific.c_str());
     perror(os_specific.c_str());
     close(fd);
     close(fd);
     return false;
     return false;

+ 2 - 0
dtool/src/prc/Sources.pp

@@ -4,6 +4,8 @@
 #begin lib_target
 #begin lib_target
   #define TARGET p3prc
   #define TARGET p3prc
 
 
+  #define ANDROID_SYS_LIBS log
+
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx  $[TARGET]_composite2.cxx
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx  $[TARGET]_composite2.cxx
   
   
   #define SOURCES \
   #define SOURCES \

+ 157 - 0
dtool/src/prc/androidLogStream.cxx

@@ -0,0 +1,157 @@
+// Filename: androidLogStream.cxx
+// Created by:  rdb (12Jan13)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "androidLogStream.h"
+#include "configVariableString.h"
+
+#ifdef ANDROID
+
+#include <android/log.h>
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStreamBuf::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+AndroidLogStream::AndroidLogStreamBuf::
+AndroidLogStreamBuf(int priority) :
+  _priority(priority) {
+
+  static ConfigVariableString android_log_tag
+  ("android-log-tag", "Panda3D",
+   PRC_DESC("This defines the tag that Panda3D will use when writing to the "
+            "Android log.  The default is \"Panda3D\"."));
+
+  if (_tag.empty()) {
+    _tag = android_log_tag.get_value();
+  }
+
+  // The AndroidLogStreamBuf doesn't actually need a buffer--it's happy
+  // writing characters one at a time, since they're just getting
+  // stuffed into a string.  (Although the code is written portably
+  // enough to use a buffer correctly, if we had one.)
+  setg(0, 0, 0);
+  setp(0, 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStreamBuf::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+AndroidLogStream::AndroidLogStreamBuf::
+~AndroidLogStreamBuf() {
+  sync();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStreamBuf::sync
+//       Access: Public, Virtual
+//  Description: Called by the system ostream implementation when the
+//               buffer should be flushed to output (for instance, on
+//               destruction).
+////////////////////////////////////////////////////////////////////
+int AndroidLogStream::AndroidLogStreamBuf::
+sync() {
+  streamsize n = pptr() - pbase();
+
+  // Write the characters that remain in the buffer.
+  for (char *p = pbase(); p < pptr(); ++p) {
+    write_char(*p);
+  }
+
+  pbump(-n);  // Reset pptr().
+  return 0;  // EOF to indicate write full.
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStreamBuf::overflow
+//       Access: Public, Virtual
+//  Description: Called by the system ostream implementation when its
+//               internal buffer is filled, plus one character.
+////////////////////////////////////////////////////////////////////
+int AndroidLogStream::AndroidLogStreamBuf::
+overflow(int ch) {
+  streamsize n = pptr() - pbase();
+
+  if (n != 0 && sync() != 0) {
+    return EOF;
+  }
+
+  if (ch != EOF) {
+    // Write one more character.
+    write_char(ch);
+  }
+
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStreamBuf::write_char
+//       Access: Private
+//  Description: Stores a single character.
+////////////////////////////////////////////////////////////////////
+void AndroidLogStream::AndroidLogStreamBuf::
+write_char(char c) {
+  if (c == '\n') {
+    // Write a line to the log file.
+    __android_log_write(_priority, _tag.c_str(), _data.c_str());
+    _data.clear();
+  } else {
+    _data += c;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStream::Constructor
+//       Access: Private
+//  Description:
+////////////////////////////////////////////////////////////////////
+AndroidLogStream::
+AndroidLogStream(int priority) :
+  ostream(new AndroidLogStreamBuf(priority)) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStream::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+AndroidLogStream::
+~AndroidLogStream() {
+  delete rdbuf();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AndroidLogStream::out
+//       Access: Public, Static
+//  Description: Returns an AndroidLogStream suitable for writing
+//               log messages with the indicated severity.
+////////////////////////////////////////////////////////////////////
+ostream &AndroidLogStream::
+out(NotifySeverity severity) {
+  static AndroidLogStream* streams[NS_fatal + 1] = {NULL};
+
+  if (streams[severity] == NULL) {
+    int priority = ANDROID_LOG_UNKNOWN;
+    if (severity != NS_unspecified) {
+      priority = ((int)severity) + 1;
+    }
+    streams[severity] = new AndroidLogStream(priority);
+  }
+
+  return *streams[severity];
+}
+
+#endif  // ANDROID

+ 59 - 0
dtool/src/prc/androidLogStream.h

@@ -0,0 +1,59 @@
+// Filename: androidLogStream.h
+// Created by:  rdb (12Jan13)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef ANDROIDLOGSTREAM_H
+#define ANDROIDLOGSTREAM_H
+
+#ifdef ANDROID
+
+#include "dtoolbase.h"
+#include "notifySeverity.h"
+
+#include <string>
+#include <iostream>
+
+////////////////////////////////////////////////////////////////////
+//       Class : AndroidLogStream
+// Description : This is a type of ostream that writes each line
+//               to the Android log.
+///////////////////////////////////////////////////////////////////
+class AndroidLogStream : public ostream {
+private:
+  class AndroidLogStreamBuf : public streambuf {
+  public:
+    AndroidLogStreamBuf(int priority);
+    virtual ~AndroidLogStreamBuf();
+
+  protected:
+    virtual int overflow(int c);
+    virtual int sync();
+
+  private:
+    void write_char(char c);
+
+    int _priority;
+    string _tag;
+    string _data;
+  };
+
+  AndroidLogStream(int priority);
+
+public:
+  virtual ~AndroidLogStream();
+  static ostream &out(NotifySeverity severity);
+};
+
+#endif  // ANDROID
+
+#endif

+ 8 - 0
dtool/src/prc/notify.cxx

@@ -26,6 +26,10 @@
 #include <fcntl.h>
 #include <fcntl.h>
 #endif
 #endif
 
 
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
 Notify *Notify::_global_ptr = (Notify *)NULL;
 Notify *Notify::_global_ptr = (Notify *)NULL;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -439,7 +443,11 @@ assert_failure(const char *expression, int line,
     return (*_assert_handler)(expression, line, source_file);
     return (*_assert_handler)(expression, line, source_file);
   }
   }
 
 
+#ifdef ANDROID
+  __android_log_assert("assert", "Panda3D", "Assertion failed: %s", message.c_str());
+#else
   nout << "Assertion failed: " << message << "\n";
   nout << "Assertion failed: " << message << "\n";
+#endif
 
 
   // This is redefined here, shadowing the defining in config_prc.h,
   // This is redefined here, shadowing the defining in config_prc.h,
   // so we can guarantee it has already been constructed.
   // so we can guarantee it has already been constructed.

+ 17 - 0
dtool/src/prc/notifyCategory.cxx

@@ -19,6 +19,10 @@
 #include "configVariableBool.h"
 #include "configVariableBool.h"
 #include "config_prc.h"
 #include "config_prc.h"
 
 
+#ifdef ANDROID
+#include "androidLogStream.h"
+#endif
+
 #include <time.h>  // for strftime().
 #include <time.h>  // for strftime().
 #include <assert.h>
 #include <assert.h>
 
 
@@ -61,6 +65,18 @@ NotifyCategory(const string &fullname, const string &basename,
 ostream &NotifyCategory::
 ostream &NotifyCategory::
 out(NotifySeverity severity, bool prefix) const {
 out(NotifySeverity severity, bool prefix) const {
   if (is_on(severity)) {
   if (is_on(severity)) {
+
+#ifdef ANDROID
+    // Android redirects stdio and stderr to /dev/null,
+    // but does provide its own logging system.  We use a special
+    // type of stream that redirects it to Android's log system.
+    if (prefix) {
+      return AndroidLogStream::out(severity) << *this << ": ";
+    } else {
+      return AndroidLogStream::out(severity);
+    }
+#else
+
     if (prefix) {
     if (prefix) {
       if (get_notify_timestamp()) {
       if (get_notify_timestamp()) {
         // Format a timestamp to include as a prefix as well.
         // Format a timestamp to include as a prefix as well.
@@ -80,6 +96,7 @@ out(NotifySeverity severity, bool prefix) const {
     } else {
     } else {
       return nout;
       return nout;
     }
     }
+#endif
 
 
   } else if (severity <= NS_debug && get_check_debug_notify_protect()) {
   } else if (severity <= NS_debug && get_check_debug_notify_protect()) {
     // Someone issued a debug Notify output statement without
     // Someone issued a debug Notify output statement without

+ 1 - 1
dtool/src/prc/p3prc_composite1.cxx

@@ -1,3 +1,4 @@
+#include "androidLogStream.cxx"
 #include "config_prc.cxx"
 #include "config_prc.cxx"
 #include "configDeclaration.cxx"
 #include "configDeclaration.cxx"
 #include "configFlags.cxx"
 #include "configFlags.cxx"
@@ -12,4 +13,3 @@
 #include "configVariableFilename.cxx"
 #include "configVariableFilename.cxx"
 #include "configVariableInt.cxx"
 #include "configVariableInt.cxx"
 #include "configVariableInt64.cxx"
 #include "configVariableInt64.cxx"
-#include "configVariableList.cxx"

+ 1 - 0
dtool/src/prc/p3prc_composite2.cxx

@@ -1,3 +1,4 @@
+#include "configVariableList.cxx"
 #include "configVariableManager.cxx"
 #include "configVariableManager.cxx"
 #include "configVariableSearchPath.cxx"
 #include "configVariableSearchPath.cxx"
 #include "configVariableString.cxx"
 #include "configVariableString.cxx"