Introducción
¿Es la primera vez que usas Bazel? Estás en el lugar correcto. Sigue este tutorial de primera compilación para ver una introducción simplificada al uso de Bazel. En este instructivo, se definen los términos clave según se usan en el contexto de Bazel y se explican los conceptos básicos del flujo de trabajo de Bazel. Comenzando con las herramientas que necesitas, compilarás y ejecutarás tres proyectos cada vez más complejos y aprenderás cómo y por qué se vuelven más complejos.
Por otro lado, Bazel es un sistema de compilación que admite compilaciones de varios lenguajes. En este instructivo, se usa un proyecto de C++ como ejemplo. y proporciona las pautas generales y el flujo que se aplican a la mayoría de los lenguajes.
Tiempo estimado de finalización: 30 minutos
Requisitos previos
Primero, instala Bazel si aún no lo has hecho. que ya existe. En este instructivo, se usa Git para controlar el código fuente, por lo que obtendrás mejores resultados Instalar Git como en la nube.
A continuación, recupera el proyecto de ejemplo del repositorio de GitHub de Bazel ejecutando el siguiente en la herramienta de línea de comandos que prefieras:
git clone https://github.com/bazelbuild/examples
El proyecto de muestra para este instructivo se encuentra en el directorio examples/cpp-tutorial
.
A continuación, puedes ver cómo está estructurada:
examples
└── cpp-tutorial
├──stage1
│ ├── main
│ │ ├── BUILD
│ │ └── hello-world.cc
│ └── WORKSPACE
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── WORKSPACE
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
Hay tres conjuntos de archivos, y cada uno representa una etapa en este instructivo. En la primera etapa, compilarás un solo destino que resida en un solo paquete. En la segunda etapa, compilar un objeto binario y una biblioteca a partir de un solo paquete. En En la tercera y última etapa, crearás un proyecto con varios paquetes y compilarla con varios destinos.
Resumen: Introducción
Cuando instalas Bazel (y Git) y clonas el repositorio para este instructivo, puedes ya que sentaste las bases para tu primera compilación con Bazel. Continuar al siguiente para definir algunos términos y configurar tu lugar de trabajo.
Cómo comenzar
Configura el espacio de trabajo
Antes de compilar un proyecto, debes configurar su lugar de trabajo. Un espacio de trabajo es un directorio que contiene los archivos fuente de tu proyecto y los resultados de la compilación de Bazel. Integra también contiene estos archivos significativos:
- El
, que identifica el directorio y su contenido como un espacio de trabajo de Bazel y se encuentra en la raíz de la estructura de directorios del proyecto.WORKSPACE
file - Uno o más
, que le indican a Bazel cómo compilar diferentes partes del proyecto. R dentro del espacio de trabajo que contenga un archivoBUILD
filesBUILD
package. (Más información sobre los paquetes más adelante en este instructivo).
En proyectos futuros, para designar un directorio como lugar de trabajo de Bazel, crea un
archivo vacío llamado WORKSPACE
en ese directorio. A los efectos de este instructivo,
ya hay un archivo WORKSPACE
en cada etapa.
NOTA: Cuando Bazel compila el proyecto, todas las entradas deben estar en el mismo lugar de trabajo. Los archivos que residen en diferentes espacios de trabajo son independientes entre sí, a menos que estén vinculados. Puedes encontrar información más detallada sobre las reglas de los lugares de trabajo en esta guía.
Comprende el archivo BUILD
Un archivo BUILD
contiene varios tipos diferentes de instrucciones para Bazel. Cada
El archivo BUILD
requiere al menos una regla
como un conjunto de instrucciones, que le indica a Bazel cómo compilar los resultados deseados.
como objetos binarios o bibliotecas ejecutables. Cada instancia de una regla de compilación del
El archivo BUILD
se denomina destino
y apunta a un conjunto específico de archivos de origen y dependencies.
Un objetivo también puede dirigir a otros destinos.
Consulta el archivo BUILD
en el directorio cpp-tutorial/stage1/main
:
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
En nuestro ejemplo, el objetivo hello-world
crea una instancia de cc_binary rule
integrado de Bazel.
La regla le indica a Bazel que compile un ejecutable binario independiente a partir del archivo fuente hello-world.cc
sin dependencias.
Resumen: Cómo comenzar
Ahora conoces algunos términos clave y lo que significan en el contexto de este proyecto y Bazel en general. En la próxima sección, compilarás y probarás Etapa 1 del proyecto.
Etapa 1: Un solo objetivo y un solo paquete
Es hora de construir la primera parte del proyecto. Para tener una referencia visual, el estructura de la sección de la Etapa 1 del proyecto es:
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── WORKSPACE
Ejecuta el siguiente comando para moverte al directorio cpp-tutorial/stage1
:
cd cpp-tutorial/stage1
Luego, ejecute el siguiente comando:
bazel build //main:hello-world
En la etiqueta de destino, la parte //main:
es la ubicación del archivo BUILD
.
relativa a la raíz del lugar de trabajo, y hello-world
es el nombre del destino en
el archivo BUILD
.
Bazel produce algo que se ve de la siguiente manera:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.267s, Critical Path: 0.25s
Acabas de compilar tu primer objetivo de Bazel. Bazel coloca los resultados de la compilación en el
directorio bazel-bin
en la raíz del
espacio de trabajo.
Ahora, prueba el objeto binario recién compilado, que es el siguiente:
bazel-bin/main/hello-world
Esto genera un mensaje “Hello world
” impreso.
Este es el gráfico de dependencias de la etapa 1:
Resumen: etapa 1
Ahora que has completado tu primera construcción, tienes una idea básica de cómo está estructurado. En la siguiente etapa, agregarás complejidad agregando otra objetivo.
Etapa 2: múltiples destinos de compilación
Si bien un solo objetivo es suficiente para los proyectos pequeños, proyectos más grandes en múltiples objetivos y paquetes. Esto permite compilaciones incrementales rápidas (es decir, Bazel solo vuelve a compilar lo que cambió) y acelera las compilaciones compilando varias partes de un proyecto a la vez. En esta etapa del instructivo, se agrega un destino y, en la siguiente, un paquete.
Este es el directorio con el que estás trabajando para la etapa 2:
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── WORKSPACE
Observa a continuación el archivo BUILD
en el directorio cpp-tutorial/stage2/main
:
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
],
)
Con este archivo BUILD
, Bazel primero compila la biblioteca hello-greet
.
(con cc_library rule
integrado de Bazel),
y, luego, el objeto binario hello-world
. El atributo deps
en
el destino hello-world
le indica a Bazel que el hello-greet
se requiere para compilar el objeto binario hello-world
.
Antes de compilar esta nueva versión del proyecto, debes cambiar de directorio y, para ello, ejecuta el siguiente comando para cambiar al directorio cpp-tutorial/stage2
:
cd ../stage2
Ahora puedes compilar el nuevo objeto binario con el siguiente comando que ya conoces:
bazel build //main:hello-world
Una vez más, Bazel produce algo que se ve de la siguiente manera:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.399s, Critical Path: 0.30s
Ahora puedes probar el objeto binario recién compilado, que muestra otro "Hello world
":
bazel-bin/main/hello-world
Si ahora modificas hello-greet.cc
y vuelves a compilar el proyecto, Bazel solo vuelve a compilar
ese archivo.
Si observas el gráfico de dependencia, puedes ver que hello-world
depende de una entrada adicional.
llamado hello-greet
:
Resumen: etapa 2
Ahora, compilaste el proyecto con dos destinos. El destino hello-world
compila un archivo fuente y depende de otro destino (//main:hello-greet
), que compila dos archivos fuente adicionales. En la siguiente sección, irás un paso más allá y agregarás otro paquete.
Etapa 3: varios paquetes
En la siguiente etapa, se agrega
otra capa de complicación y se compila un proyecto
varios paquetes. Observa la estructura y el contenido de las
cpp-tutorial/stage3
:
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
Puedes ver que ahora hay dos subdirectorios, y cada uno contiene un archivo BUILD
. Por lo tanto, para Bazel, el espacio de trabajo ahora contiene dos paquetes: lib
y
main
.
Observa el archivo lib/BUILD
:
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
Y en el archivo main/BUILD
:
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
"//lib:hello-time",
],
)
El destino hello-world
en el paquete principal depende del objetivo hello-time
en el paquete lib
(de ahí la etiqueta de destino //lib:hello-time
). Bazel sabe
esto a través del atributo deps
. Puedes ver esto reflejado en el gráfico de dependencias:
Para que la compilación se realice correctamente, debes hacer que el destino //lib:hello-time
en lib/BUILD
sea visible de forma explícita para los destinos en main/BUILD
con el atributo de visibilidad.
Esto se debe a que, de forma predeterminada, los objetivos solo son visibles para otros objetivos del mismo
BUILD
. Bazel usa la visibilidad de destino para evitar problemas, como las bibliotecas.
que contienen detalles de implementación que se filtran en APIs públicas.
Ahora, compila esta versión final del proyecto. Para cambiar al directorio cpp-tutorial/stage3
, ejecuta lo siguiente:
cd ../stage3
Vuelve a ejecutar el siguiente comando:
bazel build //main:hello-world
Bazel produce algo que se ve de la siguiente manera:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s
Ahora prueba el último objeto binario de este instructivo para obtener un mensaje Hello world
final:
bazel-bin/main/hello-world
Resumen: etapa 3
Ya compilaste el proyecto como dos paquetes con tres objetivos y comprendiste las dependencias entre ellos, lo que te equipa para avanzar y construir proyectos con Bazel. En la siguiente sección, veamos cómo continuar con el viaje de Bazel.
Próximos pasos
Ya completaste tu primera compilación básica con Bazel, pero esta es solo la comenzar. Estos son algunos recursos más para seguir aprendiendo con Bazel:
- Para seguir enfocándote en C++, lee sobre los casos de uso comunes de compilación de C++.
- Para comenzar a compilar otras aplicaciones con Bazel, consulta los instructivos. para Java, aplicaciones para Android, o la aplicación para iOS).
- Para obtener más información sobre cómo trabajar con repositorios locales y remotos, consulta el artículo sobre dependencias externas.
- Para obtener más información sobre las otras reglas de Bazel, consulta esta guía de referencia.
¡Feliz compilación!