Cargo: El administrador de compilación y paquetes de Rust

Intermediate

This tutorial is from open-source community. Access the source code

Introducción

Bienvenido a Hello, Cargo. Esta práctica es parte del Rust Book. Puedes practicar tus habilidades de Rust en LabEx.

En esta práctica, aprenderemos sobre Cargo, el sistema de compilación y administrador de paquetes de Rust, que simplifica tareas como la compilación de código, la gestión de dependencias y la descarga de bibliotecas para proyectos de Rust.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel intermedio con una tasa de finalización del 80%. Ha recibido una tasa de reseñas positivas del 100% por parte de los estudiantes.

Hello, Cargo

Cargo es el sistema de compilación y administrador de paquetes de Rust. La mayoría de los rustianos utilizan esta herramienta para administrar sus proyectos de Rust porque Cargo se encarga de muchas tareas para ti, como compilar tu código, descargar las bibliotecas en las que tu código depende y compilar esas bibliotecas. (Llamamos dependencias a las bibliotecas que necesita tu código.)

Los programas de Rust más simples, como el que hemos escrito hasta ahora, no tienen ninguna dependencia. Si hubiéramos compilado el proyecto "Hello, world!" con Cargo, solo usaría la parte de Cargo que se encarga de compilar tu código. A medida que escribas programas de Rust más complejos, agregará dependencias, y si empiezas un proyecto usando Cargo, agregarlas será mucho más fácil de hacer.

Debido a que la gran mayoría de los proyectos de Rust usan Cargo, el resto de este libro asume que también estás usando Cargo. Cargo viene instalado con Rust si usaste los instaladores oficiales discutidos en "Instalación". Si instalaste Rust de alguna otra manera, verifica si Cargo está instalado ingresando lo siguiente en tu terminal:

cargo --version

Si ves un número de versión, ¡lo tienes! Si ves un error, como command not found, consulta la documentación de tu método de instalación para determinar cómo instalar Cargo por separado.

Creando un proyecto con Cargo

Vamos a crear un nuevo proyecto usando Cargo y ver cómo difiere de nuestro original proyecto "Hello, world!". Navega de vuelta a tu directorio project (o dondequiera que hayas decidido almacenar tu código). Luego, en cualquier sistema operativo, ejecuta lo siguiente:

cd ~/project
cargo new hello_cargo
cd hello_cargo

El primer comando crea un nuevo directorio y proyecto llamado hello_cargo. Hemos nombrado nuestro proyecto hello_cargo, y Cargo crea sus archivos en un directorio con el mismo nombre.

Ingresa al directorio hello_cargo y lista los archivos. Verás que Cargo ha generado dos archivos y un directorio para nosotros: un archivo Cargo.toml y un directorio src con un archivo main.rs dentro.

También ha inicializado un nuevo repositorio Git junto con un archivo .gitignore. Los archivos de Git no se generarán si ejecutas cargo new dentro de un repositorio Git existente; puedes anular este comportamiento usando cargo new --vcs=git.

Nota: Git es un sistema de control de versiones común. Puedes cambiar cargo new para usar un sistema de control de versiones diferente o ningún sistema de control de versiones usando la bandera --vcs. Ejecuta cargo new --help para ver las opciones disponibles.

Abre Cargo.toml en tu editor de texto preferido. Debería verse similar al código de la Lista 1-2.

Nombre de archivo: Cargo.toml

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"

[dependencies]

Lista 1-2: Contenido de Cargo.toml generado por cargo new

Este archivo está en el formato TOML (Tom's Obvious, Minimal Language), que es el formato de configuración de Cargo.

La primera línea, [package], es un encabezado de sección que indica que las siguientes declaraciones están configurando un paquete. A medida que agregamos más información a este archivo, agregaremos otras secciones.

Las siguientes tres líneas establecen la información de configuración que Cargo necesita para compilar tu programa: el nombre, la versión y la edición de Rust a usar. Hablaremos de la clave edition en el Apéndice E.

La última línea, [dependencies], es el comienzo de una sección para que puedas listar cualquier dependencia de tu proyecto. En Rust, los paquetes de código se denominan crates. No necesitaremos ningún otro crate para este proyecto, pero sí en el primer proyecto del Capítulo 2, así que usaremos esta sección de dependencias entonces.

Ahora abre src/main.rs y echa un vistazo:

Nombre de archivo: src/main.rs

fn main() {
    println!("Hello, world!");
}

Cargo ha generado un programa "Hello, world!" para ti, ¡al igual que el que escribimos en la Lista 1-1! Hasta ahora, las diferencias entre nuestro proyecto y el proyecto generado por Cargo son que Cargo colocó el código en el directorio src y tenemos un archivo de configuración Cargo.toml en el directorio principal.

Cargo espera que tus archivos fuente estén dentro del directorio src. El directorio principal del proyecto es solo para archivos README, información de licencia, archivos de configuración y cualquier otra cosa no relacionada con tu código. Usar Cargo te ayuda a organizar tus proyectos. Hay un lugar para todo, y todo está en su lugar.

Si comenzaste un proyecto que no usa Cargo, como lo hicimos con el proyecto "Hello, world!", puedes convertirlo en un proyecto que sí use Cargo. Mueve el código del proyecto al directorio src y crea un archivo Cargo.toml adecuado.

Compilando y ejecutando un proyecto con Cargo

Ahora veamos qué es lo diferente cuando compilamos y ejecutamos el programa "Hello, world!" con Cargo. Desde tu directorio hello_cargo, compila tu proyecto ingresando el siguiente comando:

$ cargo build
   Compilando hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Terminada la compilación en modo desarrollo [no optimizada + información de depuración] de los target(s) en 2.85 segundos

Este comando crea un archivo ejecutable en target/debug/hello_cargo en lugar de en tu directorio actual. Debido a que la compilación predeterminada es una compilación de depuración, Cargo coloca el binario en un directorio llamado debug. Puedes ejecutar el ejecutable con este comando:

$./target/debug/hello_cargo
Hello, world!

Si todo sale bien, Hello, world! debería imprimirse en la terminal. Ejecutar cargo build por primera vez también hace que Cargo cree un nuevo archivo en el nivel superior: Cargo.lock. Este archivo lleva un registro de las versiones exactas de las dependencias en tu proyecto. Este proyecto no tiene dependencias, por lo que el archivo es un poco esparso. Nunca tendrás que cambiar este archivo manualmente; Cargo se encarga de su contenido para ti.

Acabamos de compilar un proyecto con cargo build y lo ejecutamos con ./target/debug/hello_cargo, pero también podemos usar cargo run para compilar el código y luego ejecutar el ejecutable resultante todo en un solo comando:

$ cargo run
    Terminada la compilación en modo desarrollo [no optimizada + información de depuración] de los target(s) en 0.0 segundos
     Ejecutando `target/debug/hello_cargo`
Hello, world!

Usar cargo run es más conveniente que tener que recordar ejecutar cargo build y luego usar la ruta completa al binario, por lo que la mayoría de los desarrolladores usan cargo run.

Observa que esta vez no vimos salida que indique que Cargo estaba compilando hello_cargo. Cargo se dio cuenta de que los archivos no habían cambiado, por lo que no los recompiló sino que simplemente ejecutó el binario. Si hubieras modificado tu código fuente, Cargo habría recompilado el proyecto antes de ejecutarlo, y habrías visto esta salida:

$ cargo run
   Compilando hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Terminada la compilación en modo desarrollo [no optimizada + información de depuración] de los target(s) en 0.33 segundos
     Ejecutando `target/debug/hello_cargo`
Hello, world!

Cargo también proporciona un comando llamado cargo check. Este comando revisa rápidamente tu código para asegurarse de que se compile pero no produce un ejecutable:

$ cargo check
   Revisando hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Terminada la compilación en modo desarrollo [no optimizada + información de depuración] de los target(s) en 0.32 segundos

¿Por qué no querrías un ejecutable? A menudo, cargo check es mucho más rápido que cargo build porque salta el paso de producir un ejecutable. Si estás revisando constantemente tu trabajo mientras escribes el código, usar cargo check acelerará el proceso de saber si tu proyecto todavía se compila. Por lo tanto, muchos rustianos ejecutan cargo check periódicamente mientras escriben su programa para asegurarse de que se compile. Luego ejecutan cargo build cuando están listos para usar el ejecutable.

Repasemos lo que hemos aprendido hasta ahora sobre Cargo:

  • Podemos crear un proyecto usando cargo new.
  • Podemos compilar un proyecto usando cargo build.
  • Podemos compilar y ejecutar un proyecto en un solo paso usando cargo run.
  • Podemos compilar un proyecto sin producir un binario para revisar errores usando cargo check.
  • En lugar de guardar el resultado de la compilación en el mismo directorio que nuestro código, Cargo lo almacena en el directorio target/debug.

Una ventaja adicional de usar Cargo es que los comandos son los mismos independientemente del sistema operativo en el que estés trabajando. Entonces, en este punto, ya no proporcionaremos instrucciones específicas para Linux y macOS en comparación con Windows.

Compilando para la versión de lanzamiento

Cuando tu proyecto está finalmente listo para ser lanzado, puedes usar cargo build --release para compilarlo con optimizaciones.

cargo build --release

Este comando creará un ejecutable en target/release en lugar de target/debug. Las optimizaciones hacen que tu código de Rust se ejecute más rápido, pero activarlas aumenta el tiempo que tarda en compilarse tu programa. Por eso hay dos perfiles diferentes: uno para el desarrollo, cuando quieres recompilar rápidamente y con frecuencia, y otro para compilar el programa final que darás a un usuario que no se recompilará repetidamente y que se ejecutará lo más rápido posible. Si estás benchmarkeando el tiempo de ejecución de tu código, asegúrate de ejecutar cargo build --release y benchmarkear con el ejecutable en target/release.

Cargo como convención

Con proyectos simples, Cargo no ofrece mucha más ventaja que simplemente usar rustc, pero demostrará su valor a medida que tus programas se vuelvan más complejos. Una vez que los programas crecen a múltiples archivos o necesitan una dependencia, es mucho más fácil dejar que Cargo coordine la compilación.

Aunque el proyecto hello_cargo es simple, ahora utiliza gran parte de la herramienta real que usarás en el resto de tu carrera de Rust. De hecho, para trabajar en cualquier proyecto existente, puedes usar los siguientes comandos para descargar el código usando Git, cambiar al directorio de ese proyecto y compilar:

git clone example.org/someproject
cd someproject
cargo build

Para obtener más información sobre Cargo, consulta su documentación en https://doc.rust-lang.org/cargo.

Resumen

¡Felicitaciones! Has completado el laboratorio Hello, Cargo. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.