Red de conocimiento informático - Conocimiento informático - ¿Cómo configurar automáticamente la ubicación local de Android.mk?

¿Cómo configurar automáticamente la ubicación local de Android.mk?

Al desarrollar juegos de Android con Cocos2d-x, debe especificar el código fuente que se compilará para la variable LOCAL_SRC_FILES en el archivo Android.mk y especificar el archivo de encabezado para la variable LOCAL_C_INCLUDES. Cuando hay cada vez más archivos de proyecto, este tipo de modificación manual es una pérdida de tiempo. Afortunadamente, Android.mk es en realidad un archivo MAKE y podemos usar la sintaxis del archivo MAKE para automatizar esta parte del trabajo.

Usar comandos externos

La forma más sencilla es llamar a un comando externo del shell. Primero, especificamos el directorio raíz de los archivos fuente que queremos buscar y lo configuramos en la variable SRC_ROOT. La variable LOCAL_C_INCLUDES usa buscar directamente

El código completo es el siguiente:

#Advertencia: Se usa el comando Shell, que solo es válido en sistemas operativos tipo UNIX.

# Si desea ejecutar en Windows, reemplácelo con reglas Makefile.

SRC_SUFFIX := *. cpp*. c

SRC_ROOT:= $(LOCAL_PATH)/../../Category

TODOS _ ARCHIVOS:= $(shell find $(SRC _ ROOT)-tipo f)

SRC_FILES:= $(filtro $(subst *,,$(SRC\_SUFFIX)),$(ALL_FILES))

LOCAL_SRC_FILES:= hola CPP/main

LOCAL _ SRC _ FILES = $(SRC \ _ FILES: $(LOCAL _ PATH)/ = )

SRC _ DIRS: = $(shell find $(SRC _ ROOT)-tipo d)

LOCAL_C_INCLUDES:= $(SRC_DIRS)

Usar sintaxis Makefile pura

Usar comandos externos es la solución más simple y práctica, pero como se menciona en el comentarios de código anteriores, este método solo se puede usar en sistemas Unix, y las aplicaciones multiplataforma aún requieren sintaxis pura de Makefile.

Sabemos que el comando comodín de Makefile puede implementar parcialmente funciones similares a las de búsqueda. Por ejemplo, se puede utilizar $(comodín *.c) para la búsqueda. c archivo en el directorio actual. Desafortunadamente, los comodines no son lo suficientemente potentes después de todo y no se incluyen en los resultados de este comando. c archivos en subdirectorios. Para lograr esta función, puede tomar prestado el comodín recursivo escrito por el maestro en StackOverflow usando la sintaxis pura de Makefile:

#Recursive wildcard

Rwildcard = $ (foreach d, $(wildcard $1 \ * ), $(call Rwildcard, $d/, $2) $ (filter $ (subst *,, $2), $d)) El comando rwildcard pasa dos parámetros, el primero. Este comando primero usa $(carácter comodín $1*) para obtener todos los archivos y subdirectorios de primer nivel en el directorio, y luego recorre nuevamente: para la situación actual donde la variable $d es un directorio, llame recursivamente a rwildcard al $d/ directorio; para $d es normal En el caso de archivos, la llamada recursiva finalizará porque $(comodín $d/*) no puede encontrar una coincidencia, y luego se llamará a la función de filtro para filtrar el patrón de $2.

El código completo es el siguiente:

SRC_SUFFIX:= *. cpp*.

c

SRC_ROOT:= $(LOCAL_PATH)/../../Category

#Comodín recursivo

rwildcard = $(foreach d, $(comodín $1\*), $(llamar rwildcard, $d/, $2) $(filtrar $(subst *,, $2), $d)))

SRC_FILES:= $(llamar rwildcard, $( SRC_ROOT)/,$(SRC_SUFFIX))

LOCAL _ SRC _ FILES: = hola CPP/main

LOCAL _ SRC _ FILES = $(SRC \ _ FILES: $. (LOCAL _ PATH)/ = )

Filtrar archivos de código fuente que no necesitan ser compilados.

El método descrito anteriormente tiene una premisa aplicable, es decir, cada archivo de código fuente en $SRC_ROOT debe compilarse. A veces esta condición no se cumple. Por ejemplo, en este proyecto se utilizan algunas bibliotecas externas y no es necesario compilar el código fuente de estas bibliotecas (por ejemplo, la biblioteca Asio está configurada en ASIO_HEADER_ONLY). En este momento debes excluir esta parte del código fuente de LOCAL_SRC_FILES.

El primer método: filtrado

El primer método es utilizar el comando de filtrado del Makefile:

# La biblioteca ASIO está configurada en ASIO _header_ único , por lo que será excluido del código fuente

EXCLUDE _ SRC _ FILES: = $(SRC _ ROOT)/3rd party/Asio/Asio/impl/. Card Print Processor (abreviatura de Card Print Processor)

EXCLUDE:= $(filter $(EXCLUDE _ SRC _ FILES), $(SRC_FILES))

src _ files:= $ (filtrado $(exclude _ src _ files), $ (src _ files)) Aunque este método funciona, el filtrado no se puede utilizar para la coincidencia de patrones de directorios de varios niveles, por lo que este método expone demasiado sobre bibliotecas externas. Detalles de la ruta del código fuente. ¿Es posible especificar nombres de bibliotecas o palabras clave para excluir y luego filtrar archivos de código fuente coincidentes en función de esta información?

Segundo método: mejorar rwildcard

El segundo método es agregar un criterio a rwildcard para filtrar: si el directorio/nombre de archivo actual coincide con la palabra clave que se va a filtrar, entonces no hacer nada. de lo contrario, continúe con la llamada recursiva y ejecute el comando de filtro.

# La biblioteca ASIO está configurada en ASIO_HEAD_ONLY, por lo que será excluida

EXCLUDE_LIB:= Asio

#Comodín recursivo

rwildcard = $(foreach d, $(comodín $1\*), $(if $(findstring $(EXCLUDE_LIB), $d),, $(call rwildcard, $d/, $2) $(filtro $ (subst *,, $2 ), $d)))

Src _ files: = $ (call rwildcard, $ (src _ root)/, $ (src _ suffix)) Este método es mejor, las búsquedas recursivas con comodines se excluyen directamente , pero rwildcard se vuelve más complicado y menos legible.

El tercer método: FILTER_OUT_PATTERN

El último método también proviene del filtrado modificado por StackOverflow usando la sintaxis pura de Makefile, pero es esencialmente similar a la implementación del segundo método. No lo explicaré en detalle aquí:

# La biblioteca ASIO está configurada en ASIO _header_only, por lo que será excluida del código fuente

EXCLUDE_SRC_PATTERN:= asio

FILTER_OUT_PATTERN = $(foreach v, $(2), $(if $(findstring $(1), $(v)), $(v))

SRC_FILES := $( Llamar filtrar \_OUT\_PATTERN, $(exclude_SRC_PATTERN), $(SRC_FILES))