Compilando libnice para Android
android-ndk stun (1)
Estoy intentando compilar libnice (v0.18 para ser específico) para Android, pero me he encontrado con algunos problemas. ¿Cómo puedo compilar libnice para Android? He enumerado mis intentos hasta ahora a continuación.
Primer intento
Mi primer intento fue usar un archivo personalizado de Android.mk, pero recibí un error al declarar AI_NUMERICHOST undeclared
(agregar #include <netdb.h>
no resolvió esto y me he #include <netdb.h>
sin ideas aquí). Ver mi Android.mk a continuación
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)
Las bibliotecas estáticas se copian de la versión de depuración gstreamer 1.4.1 y se seleccionan de acuerdo con la guía que se menciona a continuación.
Segundo intento
Luego traté de compilar una biblioteca estática que hace referencia a esta guía , que nuevamente está causando problemas:
export PKG_CONFIG_PATH=`pwd`/../gstreamer/lib/pkgconfig
export CFLAGS="--sysroot=`pwd`/../toolchain/sysroot"
./configure --prefix=`pwd`/../build --host=arm-linux-androideabi
Esto produce el error a continuación. Agregar -mthumb
o -marm
a CFLAGS produce un C compiler cannot create executables
errores C compiler cannot create executables
durante la configuración.
stunagent.c: Assembler messages:
stunagent.c:160: Error: no such instruction: `rev %eax,%eax''
stunagent.c:676: Error: no such instruction: `rev16 %ax,%ax''
Las líneas mencionadas no contienen ASM, pero las llamadas a htons
y ntohl
, así que supongo que hice algo mal ...
Utilicé make_standalone_toolchain
del NDK usando varias versiones de Android para crear la cadena de herramientas.
¿Alguien puede ayudar? ¡Gracias por adelantado! ~
¡FINALMENTE! Esto me llevó demasiado tiempo. El problema fue que libnice crea un archivo config.h
durante la configuración que define algunas macros ( HAVE_NETDB_H
entre otras). Aunque no pude compilar libnice con mi toolchain, pude generar una config.h válida que podría usar. Después de esto tuve que hacer algunos ajustes adicionales a mi Android.mk
. Publicaré los dos archivos a continuación para otros en busca de respuestas.
(Nota: todavía necesitas glib. Como mi proyecto usa gstreamer, pude usar la biblioteca compartida creada por el script de construcción gstreamer que contiene glib).
¡Aclamaciones!
========================
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
(Esto no debería diferir entre plataformas y versiones de Android. Dejé los comentarios en él intencionalmente para referencia futura)
/* 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