¿Cómo configurar automáticamente la ubicación local de Android.mk?
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))