Cómo incorporar el archivo de hacer existente con Android NDK

Así que tengo un enorme proyecto C existente que he colocado en el directorio $PROJECT/jni . Este proyecto se realiza normalmente ejecutando un script de configuración que crea los Makefiles, lo que permite que el proyecto se compile mediante make .

Este proyecto es bastante grande y tiene muchos directorios que contienen archivos de origen y archivos de cabecera.

Supongo que me falta una comprensión fundamental aquí de cómo Android.mk se supone que funciona. ¿Se supone que debe reemplazar el configure y makefile que se utiliza actualmente para compilar el proyecto? ¿O estaría incorporando el makefile generado desde mi script de configuración en Android.mk ? Los ejemplos que proporcionan son bastante triviales con sólo unos pocos archivos de origen. Mi directorio jni parece más a:

 jni/ folder1/subfolder1 folder1/subfolder2 folder1/source folder2/source ..... foldern/source configure/ configure/configure.sh Makefile Android.mk 

Los makefiles generados son bastante extensos (buena cantidad de configuración y hay uno en cada directorio) por lo que estoy poco perdido en cuanto a cómo abordar esto.

EDITAR:

El problema principal es que los ejemplos que se envían con el NDK son ejemplos triviales. Tienen 3-5 archivos de origen en el directorio jni de nivel superior. Mi problema es que se trata de un enorme proyecto con una configuración compleja con 4 carpetas de nivel superior cada una con muchos subdirectorios. No puedo simplemente mover la fuente a la carpeta jni y ejecutar el compilador ndk.

3 Solutions collect form web for “Cómo incorporar el archivo de hacer existente con Android NDK”

Para responder a tu pregunta, sí Android.mk es el sistema de compilación de Android. Google apenas menciona que el "lenguaje" de este archivo se implementa como macros de GNU make. Los docs quieren que describas tu proyecto en términos de esas macros. Ellos manejan todos los detalles de la cruz-compilación grungy. Estoy bastante seguro de que Google ha adoptado este enfoque para mejorar la portabilidad hacia adelante de los archivos de Android.mk medida que evolucionan las herramientas de desarrollo.

El resultado es que (y sé que no querrá oír esto) la mejor respuesta es probablemente escribir correctamente un NDK Android.mk para su gran proyecto desde cero.

Este artículo establece las mismas observaciones que he hecho portar una biblioteca de unos 800 archivos y 300k SLOC. Desafortunadamente he quemado casi dos semanas llegando a la misma conclusión: La compilación cruzada hace que al menos algunos scripts de configure fallen (resultan en archivos config.h erróneos). Yo "inventó" prácticamente las mismas técnicas que usa en el artículo. Pero incluso después de tener una compilación limpia, la biblioteca estática resultante no funcionó completamente. Horas de depuración netted ninguna información útil. [Advertencia: No soy un experto en herramientas de configuración. Un gurú probablemente habría detectado mi error. Así que va.] Me tomó un par de días para crear un Android.mk limpio. La biblioteca resultante ejecutó todas las pruebas por primera vez. Y se ha portado de manera limpia a través de varias revoluciones de herramientas de desarrollo.

Desafortunadamente la construcción de una biblioteca que utiliza configure sin las herramientas automáticas significa construir su propio config.h a mano para el entorno de destino. Esto puede no ser tan malo como suena. Los sistemas IME tienden a definir mucho más en sus entornos de configure de lo que realmente utilizan. Obtener una idea clara de las dependencias reales puede compensar el tedioso esfuerzo durante la futura refactorización.

La declaración resumida del artículo lo dice todo:

Autotool es bueno sólo en los sistemas GNU y su uso para compilación cruzada puede ser realmente tedioso, confuso, propenso a errores o incluso imposible. El método descrito aquí es un hack y debe ser utilizado bajo su propio riesgo.

Lo siento, no tengo una sugerencia más positiva.

Mi respuesta funciona mejor en tándem con la respuesta de Gene .

La creación de ./configure del archivo de configuración se basa en la compilación (y posiblemente en la ejecución) de pequeños fragmentos de código C para cada prueba. Las pruebas de compilación sólo se pueden probar con éxito en un entorno de compilación cruzada. Sin embargo, las pruebas de compilación y ejecución son imposibles de ejecutar en un entorno de compilación cruzada. El éxito de cada prueba establece una variable correspondiente en la plantilla config.h.in para crear el config.h .

Por lo tanto, para iniciar el proceso de conversión, deberá configurar CPP , CC , LD y otras herramientas en el conjunto de herramientas de compilador cruzado (probablemente las del NDK ) y, a continuación, ejecutar ./configure . Una vez hecho esto, necesitará corregir el config.h para que coincida con su entorno de destino. Este es el paso más crítico y más propenso a errores.

En cuanto a Android.mk , sigue un formato muy cercano a Makefile.am que puede convertirse fácilmente en él. Puede ignorar el Makefile.in y el Makefile , ya que se generan desde Makefile.am .

Para tomar un ejemplo de archivo (versión 5.11), corrí configure con las siguientes opciones,

 ./configure --host arm-toshiba-linux-androideabi --build x86_64-linux-gnu \ --prefix=/data/local/ host_alias=arm-linux-androideabi \ "CFLAGS=--sysroot=~/ndk/platforms/android-8/arch-arm -Wall -Wextra" \ "CPPFLAGS=--sysroot=~/ndk/platforms/android-8/arch-arm" \ CPP=arm-linux-androideabi-cpp 

El siguiente paso era tomar el src/Makefile.am como se muestra a continuación:

 MAGIC = $(pkgdatadir)/magic lib_LTLIBRARIES = libmagic.la include_HEADERS = magic.h bin_PROGRAMS = file AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"' AM_CFLAGS = $(CFLAG_VISIBILITY) @WARNINGS@ libmagic_la_SOURCES = magic.c apprentice.c softmagic.c ascmagic.c \ encoding.c compress.c is_tar.c readelf.c print.c fsmagic.c \ funcs.c file.h readelf.h tar.h apptype.c \ file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h libmagic_la_LDFLAGS = -no-undefined -version-info 1:0:0 if MINGW MINGWLIBS = -lgnurx -lshlwapi else MINGWLIBS = endif libmagic_la_LIBADD = $(LTLIBOBJS) $(MINGWLIBS) file_SOURCES = file.c file_LDADD = libmagic.la CLEANFILES = magic.h EXTRA_DIST = magic.h.in HDR= $(top_srcdir)/src/magic.h.in BUILT_SOURCES = magic.h magic.h: ${HDR} sed -e "s/X.YY/$$(echo @VERSION@ | tr -d .)/" < ${HDR} > $@ 

Y crear el Android.mk de esto.

El último y más importante paso fue modificar el config.h para reflejar con precisión el estado del sistema de destino. Este será un proceso manual que no puedo dar una solución para, principalmente involucrando la mirada en el configure.log, mirando en los encabezados y "invocando" Google. Los frutos de este trabajo están disponibles en XDA .

He aquí una solución para hacer las cosas al revés: la construcción de la biblioteca externa y el paquete de Android de Makefiles estándar.

Como requisito previo, es necesario instalar todo lo necesario para hacer el desarrollo de la línea de comandos de Android:

  • Una cadena de herramientas independiente, consulte la documentación incluida en el Android NDK;
  • hormiga.

La estructura del ejemplo es: un directorio para la biblioteca externa y un directorio para las fuentes de Android al mismo nivel con un Makefile en cada directorio y un Makefile recursivo de nivel superior:

 Makefile mylib/ Makefile android/ Makefile 

El mylib/Makefile genera una biblioteca estática:

 AR=/path/to/standalone/bin/arm-linux-androideabi-ar CC=/path/to/standalone/bin/arm-linux-androideabi-gcc libmylib.a: mylib.o $(AR) rcs libmylib.a mylib.o mylib.o: mylib.c $(CC) -c mylib.c -o mylib.o 

El android/Makefile está proporcionando reglas para construir el paquete de Android:

  • Necesitamos una dependencia para copiar mylib cuando es modificado;
  • Estamos utilizando un archivo jni/ndkmake.c para envolver las llamadas a mylib y proporcionar material específico de android;
  • El paquete android depende de las fuentes Java y de la biblioteca compartida.

El Makefile proporciona dos target: release (el valor por defecto) y debug para construir un paquete de lanzamiento o uno de depuración.

 NDK_BUILD=/path/to/ndk-build JAVASRC=src/com/example/ndkmake/NdkMake.java release: bin/NdkMake-release-unsigned.apk debug: bin/NdkMake-debug.apk bin/NdkMake-release-unsigned.apk: libs/armeabi/libndkmake.so $(JAVASRC) ant release bin/NdkMake-debug.apk: libs/armeabi/libndkmake.so $(JAVASRC) ant debug libs/armeabi/libndkmake.so: jni/ndkmake.c jni/libmylib.a $(NDK_BUILD) jni/libmylib.a: ../mylib/libmylib.a cp ../mylib/libmylib.a jni/libmylib.a 

El archivo Android.mk proporciona reglas para incluir la biblioteca estática en la compilación, como un precompuesto. Estamos incluyendo encabezados de la biblioteca LOCAL_EXPORT_C_INCLUDES usando LOCAL_EXPORT_C_INCLUDES .

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ndkmake LOCAL_SRC_FILES := ndkmake.c LOCAL_STATIC_LIBRARIES := mylib-prebuilt include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := mylib-prebuilt LOCAL_SRC_FILES := libmylib.a LOCAL_EXPORT_C_INCLUDES := ../mylib/ include $(PREBUILT_STATIC_LIBRARY) 

Ahora solo necesitamos un Makefile de nivel superior para construir los dos subdirectorios:

 all: libmylib package libmylib: cd mylib && $(MAKE) package: cd android && $(MAKE) 

Cualquier cambio en la biblioteca, en las fuentes jni o en las fuentes Java activará una reconstrucción del paquete.

  • Construyendo Android desde fuentes: unsupported reloc 43
  • Macro de preprocesador en Android.mk se ignora, pero funciona en Application.mk
  • Gnu Makefile para gdc
  • La ejecución falló para la tarea ': app: compileDebugNdk' no pudo ejecutar este comando ndk-build.cmd
  • Android.mk wilcard extra 'jni' en el camino?
  • Cómo especificar el directorio para NDK_MODULE_PATH
  • Construya la aplicación del sistema gradle como parte de la compilación de AOSP
  • Condiciones de Android.mk
  • Construcción de proyecto android produce error 2
  • Cada compilación NDK es una reconstrucción completa
  • Los cambios en el makefile importado no activan la reconstrucción en android-ndk
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.