En este instructivo, se explica cómo compilar una app para Android simple con Bazel.
Bazel admite la compilación de apps para Android con las reglas para Android.
Este instructivo está dirigido a usuarios de Windows, macOS y Linux, y no requiere experiencia con el desarrollo de apps para Android o Bazel. No es necesario que escribas ningún código de Android en este instructivo.
Qué aprenderás
En este instructivo, aprenderás a realizar las siguientes acciones:
- Instala Bazel y Android Studio, y descarga el proyecto de muestra para configurar el entorno.
- Configura un lugar de trabajo de Bazel que contenga el código fuente
de la app y un archivo
WORKSPACE
que identifique el nivel superior del directorio del lugar de trabajo. - Actualiza el archivo
WORKSPACE
para que contenga referencias a las dependencias externas requeridas, como el SDK de Android. - Crea un archivo
BUILD
. - Compila la app con Bazel.
- Implementa y ejecuta la app en un emulador o dispositivo físico de Android.
Antes de comenzar
Instala Bazel
Antes de comenzar el instructivo, instala el siguiente software:
- Bazel Para instalarla, sigue las instrucciones de instalación.
- Android Studio. Para ello, sigue los pasos para descargar Android Studio. Ejecute el asistente de configuración para descargar el SDK y configurar su entorno.
- (Opcional) Git. Usa
git
para descargar el proyecto de la app para Android.
Obtén el proyecto de muestra
Para el proyecto de muestra, usa un proyecto básico de app para Android en el repositorio de ejemplos de Bazel.
Esta app tiene un solo botón que imprime un saludo cuando haces clic en él:
Figura 1: Saludo para el botón de la app para Android.
Clona el repositorio con git
(o descarga el archivo ZIP directamente):
git clone https://github.com/bazelbuild/examples
El proyecto de muestra de este instructivo se encuentra en examples/android/tutorial
. Para el resto del instructivo, ejecutarás comandos en este directorio.
Revisa los archivos fuente
Observa los archivos de origen de la app.
.
├── README.md
└── src
└── main
├── AndroidManifest.xml
└── java
└── com
└── example
└── bazel
├── AndroidManifest.xml
├── Greeter.java
├── MainActivity.java
└── res
├── layout
│ └── activity_main.xml
└── values
├── colors.xml
└── strings.xml
Los archivos y directorios clave son:
Nombre | Ubicación |
---|---|
Archivos de manifiesto de Android | src/main/AndroidManifest.xml y src/main/java/com/example/bazel/AndroidManifest.xml |
Archivos de origen de Android | src/main/java/com/example/bazel/MainActivity.java y Greeter.java |
Directorio de archivos de recursos | src/main/java/com/example/bazel/res/ |
Compila con Bazel
Configure el lugar de trabajo
Un lugar de trabajo es un directorio que contiene los archivos fuente para uno o más proyectos de software y tiene un archivo WORKSPACE
en su raíz.
Es posible que el archivo WORKSPACE
esté vacío o contenga referencias a dependencias externas que se requieren para compilar tu proyecto.
Primero, ejecuta el siguiente comando para crear un archivo WORKSPACE
vacío:
SO | Comando |
---|---|
Linux y macOS | touch WORKSPACE |
Windows (Símbolo del sistema) | type nul > WORKSPACE |
Windows (PowerShell) | New-Item WORKSPACE -ItemType file |
Ejecuta Bazel
Ahora, puede verificar si Bazel se está ejecutando correctamente con el siguiente comando:
bazel info workspace
Si Bazel imprime la ruta del directorio actual, estás listo para comenzar. Si el archivo WORKSPACE
no existe, es posible que veas un mensaje de error como el siguiente:
ERROR: The 'info' command is only supported from within a workspace.
Cómo realizar la integración con el SDK de Android
Bazel necesita ejecutar las herramientas de compilación del SDK de Android para compilar la app. Esto significa que debes agregar información a tu archivo WORKSPACE
para que Bazel sepa dónde encontrarlas.
Agrega la siguiente línea a tu archivo WORKSPACE
:
android_sdk_repository(name = "androidsdk")
Se usará el SDK de Android en la ruta de acceso a la que hace referencia la variable de entorno ANDROID_HOME
, y se detectará automáticamente el nivel de API más alto y la última versión de las herramientas de compilación instaladas en esa ubicación.
Puedes establecer la variable ANDROID_HOME
en la ubicación del SDK de Android. Encuentra la ruta de acceso al SDK instalado con SDK Manager de Android Studio.
Si el SDK está instalado en ubicaciones predeterminadas, puedes usar los siguientes comandos para configurar la variable ANDROID_HOME
:
SO | Comando |
---|---|
Linux | export ANDROID_HOME=$HOME/Android/Sdk/ |
macOS | export ANDROID_HOME=$HOME/Library/Android/sdk |
Windows (Símbolo del sistema) | set ANDROID_HOME=%LOCALAPPDATA%\Android\Sdk |
Windows (PowerShell) | $env:ANDROID_HOME="$env:LOCALAPPDATA\Android\Sdk" |
Los comandos anteriores establecen la variable solo para la sesión de shell actual. Para hacerlo de forma permanente, ejecuta los siguientes comandos:
SO | Comando |
---|---|
Linux | echo "export ANDROID_HOME=$HOME/Android/Sdk/" >> ~/.bashrc |
macOS | echo "export ANDROID_HOME=$HOME/Library/Android/Sdk/" >> ~/.bashrc |
Windows (Símbolo del sistema) | setx ANDROID_HOME "%LOCALAPPDATA%\Android\Sdk" |
Windows (PowerShell) | [System.Environment]::SetEnvironmentVariable('ANDROID_HOME', "$env:LOCALAPPDATA\Android\Sdk", [System.EnvironmentVariableTarget]::User) |
También puedes especificar de forma explícita la ruta de acceso absoluta del SDK de Android, el nivel de API y la versión de las herramientas de compilación que se incluirán si incluyes los atributos path
, api_level
y build_tools_version
. Si no se especifican api_level
y build_tools_version
, la regla android_sdk_repository
usará la versión más reciente correspondiente en el SDK. Puedes especificar cualquier combinación de estos atributos, siempre que estén presentes en el SDK, por ejemplo:
android_sdk_repository(
name = "androidsdk",
path = "/path/to/Android/sdk",
api_level = 25,
build_tools_version = "30.0.3"
)
En Windows, ten en cuenta que el atributo path
debe usar la ruta de acceso de estilo mixto, es decir, una ruta de Windows con barras diagonales:
android_sdk_repository(
name = "androidsdk",
path = "c:/path/to/Android/sdk",
)
Opcional: Si deseas compilar código nativo en tu app para Android, también debes descargar el NDK de Android y agregar la siguiente línea a tu archivo WORKSPACE
a fin de indicarle a Bazel dónde encontrarlo:
android_ndk_repository(name = "androidndk")
Al igual que android_sdk_repository
, la ruta de acceso al NDK de Android se infiere de manera predeterminada en la variable de entorno ANDROID_NDK_HOME
. La ruta también se puede especificar de forma explícita con un atributo path
en android_ndk_repository
.
Para obtener más información, consulta Cómo usar el kit de desarrollo nativo de Android con Bazel.
api_level
es la versión de la API de Android a la que se orientan el SDK y el NDK; por ejemplo, 23 para Android 6.0 y 25 para Android 7.1. Si no se establece de forma explícita, api_level
se establece de forma predeterminada en el nivel de API más alto disponible para android_sdk_repository
y android_ndk_repository
.
No es necesario configurar los niveles de API en el mismo valor para el SDK y el NDK. Esta página contiene un mapa de las versiones de Android para los niveles de API admitidos por el NDK.
Crear un archivo BUILD
Un archivo BUILD
describe la relación entre un conjunto de resultados de compilación, como recursos de Android compilados de aapt
o archivos de clase de javac
, y sus dependencias. Estas dependencias pueden ser archivos de origen (Java, C++) en el lugar de trabajo o en otros resultados de compilación. Los archivos BUILD
están escritos en un lenguaje llamado Starlark.
Los archivos BUILD
forman parte de un concepto en Bazel, conocido como jerarquía de paquetes.
La jerarquía de paquetes es una estructura lógica que se superpone a la estructura de directorios en tu lugar de trabajo. Cada paquete es un directorio (y sus subdirectorios) que contiene un conjunto relacionado de archivos de origen y un archivo BUILD
. El paquete también incluye cualquier subdirectorio, excepto los que contienen su propio archivo BUILD
. El nombre del paquete es la ruta al archivo BUILD
en relación con el WORKSPACE
.
Ten en cuenta que la jerarquía de paquetes de Bazel es conceptualmente diferente de la jerarquía de paquetes de Java del directorio de tu app para Android en la que se encuentra el archivo BUILD
, aunque los directorios pueden estar organizados de forma idéntica.
Para la app simple de Android en este instructivo, los archivos de origen en src/main/
compone un solo paquete de Bazel. Un proyecto más complejo puede tener muchos paquetes anidados.
Cómo agregar una regla android_library
Un archivo BUILD
contiene varios tipos diferentes de declaraciones para Bazel. El tipo más importante es la regla de compilación, que le indica a Bazel cómo compilar un resultado de software intermedio o final a partir de un conjunto de archivos de origen, o bien otras dependencias. Bazel proporciona dos reglas de compilación, android_library
y android_binary
, que puedes usar a fin de compilar una app para Android.
En este instructivo, primero usarás la regla android_library
para indicarle a Bazel que compile un módulo de biblioteca de Android a partir del código fuente de la app y los archivos de recursos. Luego, usarás la
regla android_binary
a fin de indicarle a Bazel cómo compilar el paquete de aplicaciones para Android.
Crea un archivo BUILD
nuevo en el directorio src/main/java/com/example/bazel
y declara un nuevo destino android_library
:
src/main/java/com/example/bazel/BUILD
:
package(
default_visibility = ["//src:__subpackages__"],
)
android_library(
name = "greeter_activity",
srcs = [
"Greeter.java",
"MainActivity.java",
],
manifest = "AndroidManifest.xml",
resource_files = glob(["res/**"]),
)
La regla de compilación android_library
contiene un conjunto de atributos que especifican la información
que Bazel necesita para compilar un módulo de biblioteca a partir de los archivos de origen.
Además, ten en cuenta que el nombre de la regla es greeter_activity
. Haz referencia a la regla con este nombre como una dependencia en la regla android_binary
.
Cómo agregar una regla android_binary
La regla android_binary
compila el paquete de aplicación para Android (archivo .apk
) de tu app.
Crea un archivo BUILD
nuevo en el directorio src/main/
y declara un nuevo destino android_binary
:
src/main/BUILD
:
android_binary(
name = "app",
manifest = "AndroidManifest.xml",
deps = ["//src/main/java/com/example/bazel:greeter_activity"],
)
Aquí, el atributo deps
hace referencia al resultado de la regla greeter_activity
que agregaste al archivo BUILD
anterior. Esto significa que, cuando Bazel compila el resultado de esta regla, primero verifica si el resultado de la regla de biblioteca greeter_activity
se compiló y está actualizado. De lo contrario, Bazel
la compila y, luego, usa ese resultado para compilar el archivo de paquete de la aplicación.
Ahora guarde y cierre el archivo.
Compila la app
Intenta compilar la app. Ejecuta el siguiente comando para compilar el destino android_binary
:
bazel build //src/main:app
El subcomando build
le indica a Bazel que compile el
destino que sigue. El destino se especifica como el nombre de una regla de compilación dentro de un archivo BUILD
, junto con la ruta de acceso del paquete en relación con tu directorio de espacio de trabajo. En este ejemplo, el destino es app
y la ruta del paquete es //src/main/
.
Ten en cuenta que, a veces, puedes omitir la ruta del paquete o el nombre del destino, según el directorio de trabajo actual en la línea de comandos y el nombre del destino. Para obtener más detalles sobre etiquetas y rutas de destino, consulta Etiquetas.
Bazel comenzará a compilar la app de muestra. Durante el proceso de compilación, su resultado será similar al siguiente:
INFO: Analysed target //src/main:app (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //src/main:app up-to-date:
bazel-bin/src/main/app_deploy.jar
bazel-bin/src/main/app_unsigned.apk
bazel-bin/src/main/app.apk
Cómo encontrar los resultados de la compilación
Bazel coloca los resultados de las operaciones de compilación intermedias y finales en un conjunto
de directorios de salida por usuario y por lugar de trabajo. Estos directorios están simbólicos desde las siguientes ubicaciones en el nivel superior del directorio del proyecto, en el que WORKSPACE
es:
bazel-bin
almacena ejecutables binarios y otros resultados de compilación ejecutablesbazel-genfiles
almacena los archivos de origen intermedios que generan las reglas de Bazelbazel-out
almacena otros tipos de resultados de compilación
Bazel almacena el archivo .apk
de Android generado mediante la regla android_binary
en el directorio bazel-bin/src/main
, en el que el nombre del subdirectorio src/main
se deriva del nombre del paquete de Bazel.
En un símbolo del sistema, enumera el contenido de este directorio y busca el archivo app.apk
:
SO | Comando |
---|---|
Linux y macOS | ls bazel-bin/src/main |
Windows (Símbolo del sistema) | dir bazel-bin\src\main |
Windows (PowerShell) | ls bazel-bin\src\main |
Ejecuta la app
Ahora puedes implementar la app en un emulador o dispositivo Android conectado desde la línea de comandos con el comando bazel
mobile-install
. Este comando usa Android Debug Bridge (adb
) para comunicarse con el dispositivo. Antes de la implementación, debes configurar el dispositivo para usar adb
según las instrucciones de Android Debug Bridge. También puedes instalar la app en el emulador de Android incluido en Android Studio. Asegúrate de que el emulador esté en ejecución antes de ejecutar el siguiente comando.
Ingrese el siguiente comando:
bazel mobile-install //src/main:app
A continuación, busca e inicia la "app de instructivo de Bazel":
Figura 2: App del instructivo de Bazel
¡Felicitaciones! Acabas de instalar tu primera app para Android creada con Bazel.
Ten en cuenta que el subcomando mobile-install
también admite la marca --incremental
que se puede usar para implementar solo aquellas partes de la app que cambiaron desde la última implementación.
También admite la marca --start_app
para iniciar la app de inmediato después de instalarla.
Lecturas adicionales
Para obtener más información, consulta las siguientes páginas:
- Problemas abiertos en GitHub
- Más información sobre la instalación en dispositivos móviles
- Integrar dependencias externas como AppCompat, Guava y JUnit desde repositorios de Maven con rules_jvm_external
- Ejecuta pruebas Robolectric con la integración de robolectric-bazel.
- Cómo probar tu app con las pruebas de instrumentación de Android
- Cómo integrar el código C y C++ a tu app para Android con el NDK
- Consulta más proyectos de ejemplo de Bazel sobre lo siguiente:
¡Feliz edificio!