I'm trying to compile libnice (v0.18 to be specific) for Android, but have run into some troubles. How can I compile libnice for Android? I have listed my attempts so far below.
1st Attempt
My first try was using a custom Android.mk makefile but I got an error stating AI_NUMERICHOST undeclared (adding #include <netdb.h> did not resolve this and I'm out of ideas here). See my Android.mk below
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := glib LOCAL_SRC_FILES := lib/libglib-2.0.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := gobject LOCAL_SRC_FILES := lib/libgobject-2.0.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := gmodule LOCAL_SRC_FILES := lib/libgmodule-2.0.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := gio LOCAL_SRC_FILES := lib/libgio-2.0.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := gthread LOCAL_SRC_FILES := lib/libgthread-2.0.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := ffi LOCAL_SRC_FILES := lib/libffi.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := iconv LOCAL_SRC_FILES := lib/libiconv.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := intl LOCAL_SRC_FILES := lib/libintl.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := xml2 LOCAL_SRC_FILES := lib/libxml2.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := z LOCAL_SRC_FILES := lib/libz.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) NICE := libnice-0.1.8 LOCAL_MODULE := ice_jni LOCAL_LDLIBS := -llog LOCAL_STATIC_LIBRARIES := glib gobject gmodule gio gthread ffi iconv intl xml2 z NICE_INCLUDES := $(LOCAL_PATH)/include \ $(LOCAL_PATH)/lib/glib-2.0/include \ $(LOCAL_PATH)/lib/libffi-3.0.13/include \ $(wildcard $(LOCAL_PATH)/include/*) \ $(LOCAL_PATH)/$(NICE)/nice \ $(LOCAL_PATH)/$(NICE)/agent \ $(LOCAL_PATH)/$(NICE)/random \ $(LOCAL_PATH)/$(NICE)/socket \ $(LOCAL_PATH)/$(NICE)/stun NICE_SRC := $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/$(NICE)/agent/*.c)) \ $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/$(NICE)/random/*.c)) \ $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/$(NICE)/socket/*.c)) \ $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/$(NICE)/stun/*.c)) LOCAL_C_INCLUDES := $(LOCAL_PATH) \ $(NICE_INCLUDES) LOCAL_SRC_FILES := ICE.cpp \ $(NICE_SRC) include $(BUILD_SHARED_LIBRARY)
The static libraries are copied over from the gstreamer 1.4.1 debug version and are selected in accordance with the guide mentioned below.
2nd Attempt
I then tried to compile a static library referring to this guide, which is again causing trouble:
export PKG_CONFIG_PATH=`pwd`/../gstreamer/lib/pkgconfig export CFLAGS="--sysroot=`pwd`/../toolchain/sysroot" ./configure --prefix=`pwd`/../build --host=arm-linux-androideabi
This results in the error below. Adding -mthumb or -marm to CFLAGS yields a C compiler cannot create executables error during configure.
stunagent.c: Assembler messages: stunagent.c:160: Error: no such instruction: `rev %eax,%eax' stunagent.c:676: Error: no such instruction: `rev16 %ax,%ax'
The mentioned lines do not contain ASM but calls to htons and ntohl, so I guess I did something wrong...
I used make_standalone_toolchain from the NDK using various Android versions to create the toolchain.
Can anybody help? Thanks in advance! ~
FINALLY! This took me way too long. The problem was that libnice creates a config.h file during configure which defines some macros (HAVE_NETDB_H among others). Although I was not able to compile libnice with my toolchain I was able to generate a valid config.h which I could use. After this I had to make some additional adjustments to my Android.mk. I'll post both files below for others in search of answers.
(Note: you still need glib. As my project uses gstreamer I was able to use the shared library created by the gstreamer build script which contains glib.)
Cheers!
========================
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) NICE := libnice-0.1.8 LOCAL_MODULE := nice_jni LOCAL_LDLIBS := -llog LOCAL_SHARED_LIBRARIES := gstreamer_android LOCAL_CFLAGS += -DHAVE_CONFIG_H NICE_DIRS := $(LOCAL_PATH)/$(NICE)/ \ $(LOCAL_PATH)/$(NICE)/agent/ \ $(LOCAL_PATH)/$(NICE)/nice/ \ $(LOCAL_PATH)/$(NICE)/random/ \ $(LOCAL_PATH)/$(NICE)/socket/ \ $(LOCAL_PATH)/$(NICE)/stun/ \ $(LOCAL_PATH)/$(NICE)/stun/usages/ # $(LOCAL_PATH)/$(NICE)/stun/tools/ \ NICE_INCLUDES := $(NICE_DIRS) NICE_SRC := $(filter-out %test.c, $(foreach dir, $(NICE_DIRS), $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(addsuffix *.c, $(dir)))) )) LOCAL_C_INCLUDES := $(NICE_INCLUDES) #add your own headers if needed LOCAL_SRC_FILES := [YOUR_SRC_FILES] \ $(NICE_SRC) include $(BUILD_SHARED_LIBRARY)
config.h
(This should not differ across platforms and Android versions. I left the comments in it intentionally for future reference)
/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the <arpa/inet.h> header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if C supports variable-length arrays. */ #define HAVE_C_VARARRAYS 1 /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 /* Whether getifaddrs() is available on the system */ /* #undef HAVE_GETIFADDRS */ /* Have the GUPnP IGD library */ /* #undef HAVE_GUPNP */ /* Define to 1 if you have the <ifaddrs.h> header file. */ /* #undef HAVE_IFADDRS_H */ /* Define to 1 if you have the <inttypes.h> header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the <memory.h> header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the <netdb.h> header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the <net/in.h> header file. */ /* #undef HAVE_NET_IN_H */ /* Define to 1 if you have the `poll' function. */ #define HAVE_POLL 1 /* Define to 1 if the system has the type `size_t'. */ #define HAVE_SIZE_T 1 /* Define to 1 if the system has the type `ssize_t'. */ #define HAVE_SSIZE_T 1 /* Define to 1 if stdbool.h conforms to C99. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the <stdint.h> header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the <strings.h> header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the <string.h> header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the <sys/stat.h> header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the <sys/types.h> header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if the system has the type `_Bool'. */ #define HAVE__BOOL 1 /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if assertions should be disabled. */ /* #undef NDEBUG */ /* Public library function implementation */ #define NICEAPI_EXPORT /* Name of package */ #define PACKAGE "libnice" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "libnice" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "libnice 0.1.8" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libnice" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "0.1.8" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # define _ALL_SOURCE 1 #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # define _POSIX_PTHREAD_SEMANTICS 1 #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # define _TANDEM_SOURCE 1 #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # define __EXTENSIONS__ 1 #endif /* Version number of package */ #define VERSION "0.1.8" /* Define to `2' to get GNU/libc warnings. */ /* Only define if -O1 or more is enabled */ #if defined __OPTIMIZE__ && __OPTIMIZE__ > 0 # define _FORTIFY_SOURCE 2 #endif /* Define to 1 if on MINIX. */ /* #undef _MINIX */ /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ /* #undef _POSIX_1_SOURCE */ /* Define to 1 if you need to in order for `stat' and other things to work. */ /* #undef _POSIX_SOURCE */ /* Needed to get declarations for msg_control and msg_controllen on Solaris */ /* #undef _XOPEN_SOURCE */ /* Needed to get declarations for msg_control and msg_controllen on Solaris */ #define __EXTENSIONS__ 1 /* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported directly. */ #define restrict __restrict /* Work around a bug in Sun C++: it does not support _Restrict or __restrict__, even though the corresponding Sun C compiler ends up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. Perhaps some future version of Sun C++ will work with restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ #if defined __SUNPRO_CC && !defined __RESTRICT # define _Restrict # define __restrict__ #endif