Introducción
¿Es la primera vez que usas Bazel? Está en el lugar correcto. Sigue este tutorial de primera compilación para ver una introducción simplificada al uso de Bazel. En este tutorial, se definen los términos clave, ya que se usan en el contexto de Bazel y te guía a través de los conceptos básicos de Bazel en el flujo de trabajo. 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 si deseas obtener mejores resultados, instala la herramienta Git también.
A continuación, recupera el proyecto de ejemplo del repositorio de GitHub de Bazel ejecutando el siguiente en tu herramienta de línea de comandos preferida:
git clone https://github.com/bazelbuild/examples
El proyecto de muestra para este instructivo se encuentra en examples/cpp-tutorial
.
Observa cómo está estructurada:
examples
└── cpp-tutorial
├──stage1
│ ├── main
│ │ ├── BUILD
│ │ └── hello-world.cc
│ └── MODULE.bazel
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
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 la tercera y última compilarás un proyecto con varios paquetes y lo compilarás con múltiples 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 lugar de trabajo.
Cómo comenzar
Antes de compilar un proyecto, debes configurar su lugar de trabajo. Un espacio de trabajo que contiene los archivos fuente de tu proyecto y los resultados de la compilación de Bazel. También contiene estos archivos significativos:
- El archivo
MODULE.bazel
, que identifica el directorio y su contenido como un espacio de trabajo de Bazel y se encuentra en la raíz del directorio del proyecto en la nube. También es donde especificas tus dependencias externas. - Uno o más
BUILD
archivos, que le indican a Bazel cómo construir las diferentes partes del proyecto. Un directorio dentro del que contiene un archivoBUILD
es package. (Más información sobre 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 MODULE.bazel
en ese directorio. A los efectos de este documento,
, ya hay un archivo MODULE.bazel
en cada etapa.
Comprende el archivo BUILD
Un archivo BUILD
contiene varios tipos diferentes de instrucciones para Bazel. Cada
BUILD
archivo requiere al menos uno
regla como un conjunto de instrucciones
que le indica a Bazel cómo compilar los resultados que deseas, como los objetos binarios ejecutables
o bibliotecas. Cada instancia de una regla de compilación en el archivo BUILD
se denomina
objetivo y apunta a un
conjunto de archivos de origen y
dependencias. Un objetivo puede
también apuntan a otros objetivos.
Observa el archivo BUILD
en el directorio cpp-tutorial/stage1/main
:
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
En nuestro ejemplo, el destino hello-world
crea una instancia de la interfaz
Regla cc_binary
. La regla
le indica a Bazel que compile un binario ejecutable independiente desde el
hello-world.cc
> un archivo fuente sin dependencias.
Resumen: cómo empezar
Ya conoces algunos términos clave y lo que significan en el contexto este proyecto y Bazel en general. En la próxima sección, compilarás y probarás Etapa 1 del proyecto.
Etapa 1: destino único, paquete único
Es hora de crear 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
└── MODULE.bazel
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 destino de Bazel. Bazel coloca las salidas de compilación en el
bazel-bin
en la raíz del lugar de trabajo.
Ahora, prueba el objeto binario recién compilado, que es el siguiente:
bazel-bin/main/hello-world
Como resultado, se imprime "Hello world
" mensaje.
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 cómo está estructurada la compilación. En la siguiente etapa, agregarás complejidad al agregar otro objetivo.
Etapa 2: múltiples destinos de compilación
Si bien un solo objetivo es suficiente para los proyectos pequeños, puede proyectos más grandes en múltiples objetivos y paquetes. Esto permite una rápida compilaciones incrementales (es decir, Bazel solo reconstruye lo que cambió) y acelera tus compilaciones construyendo varias partes de un proyecto a la vez. Esta etapa del instructivo agrega un destino y el 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
│ └── MODULE.bazel
Observa 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
de Bazel integrado
), luego el
Objeto binario hello-world
. El atributo deps
en el destino hello-world
le indica
Bazel indica que se requiere la biblioteca hello-greet
para compilar hello-world
.
binario.
Antes de compilar esta nueva versión del proyecto, debes cambiar
directorios y pasar al directorio cpp-tutorial/stage2
ejecutando lo siguiente:
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, solo Bazel
vuelve a compilar ese archivo.
Si observas el gráfico de dependencias, puedes ver que hello-world
depende de un
Entrada adicional llamada hello-greet
:
Resumen: etapa 2
Ahora, compilaste el proyecto con dos destinos. Las compilaciones de destino hello-world
un archivo fuente y depende de otro destino (//main:hello-greet
), que
compila dos archivos fuente adicionales. En la siguiente sección, ve más allá
y agregar otro paquete.
Etapa 3: varios paquetes
En la siguiente etapa, se agrega
otra capa de complicación y se compila un proyecto
varios paquetes. Echa un vistazo a la estructura y el contenido
cpp-tutorial/stage3
:
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
Puedes ver que ahora hay dos subdirectorios y cada uno contiene un 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 modelo de dependencia
gráfico:
Para que la compilación se realice correctamente, debes establecer el objetivo //lib:hello-time
en lib/BUILD
visibles de forma explícita para los destinos en main/BUILD
mediante el atributo de visibilidad.
Esto se debe a que, de forma predeterminada, los destinos 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. Cambiar a cpp-tutorial/stage3
con lo siguiente:
cd ../stage3
Una vez más, ejecuta 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 ver un mensaje Hello world
final:
bazel-bin/main/hello-world
Resumen: etapa 3
Ya compilaste el proyecto como dos paquetes con tres objetivos y comprendes las dependencias entre ellos, lo que te equipa para avanzar y construir proyectos con Bazel. En la siguiente sección, descubra 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 los usos comunes de la compilación de C++. casos.
- Para comenzar a compilar otras aplicaciones con Bazel, consulta la instructivos para Java y Android aplicación o iOS aplicación.
- Para obtener más información sobre cómo trabajar con repositorios locales y remotos, consulta lo siguiente: dependencias externas.
- Para obtener más información sobre las otras reglas de Bazel, consulta esta referencia .
¡Feliz compilación!