Rust Admin

Cargo: Gerenciador de Pacotes e Build System do Rust: Do Básico ao Avançado Já leu

Introdução ao Cargo: O Coração do Rust Cargo é o gerenciador de pacotes e sistema de build oficial do Rust, responsável por compilar código, gerenciar dependências, executar testes e publicar bibliotecas. Se você vem de linguagens como Python (pip) ou JavaScript (npm), Cargo funciona de forma similar, mas com integração profunda na toolchain do Rust. Nesta aula, você aprenderá desde conceitos fundamentais até práticas avançadas que o tornarão capaz de gerenciar projetos profissionais com confiança. Estrutura do Projeto e Configuração Básica Criando um Projeto Todo projeto Rust começa com Cargo. Use para gerar a estrutura padrão: Isso cria uma estrutura como: O Arquivo Cargo.toml O é um arquivo TOML que define metadados e dependências. Aqui está um exemplo real: Cada dependência pode especificar versão, features (características opcionais) e fonte personalizada. O garante reprodutibilidade, fixando versões exatas usadas na última compilação bem-sucedida. Gerenciamento de Dependências Adicionando e Atualizando Dependências Use para instalar pacotes diretamente: Ou edite manualmente. Para atualizar, execute: Entendendo

Introdução ao Cargo: O Coração do Rust

Cargo é o gerenciador de pacotes e sistema de build oficial do Rust, responsável por compilar código, gerenciar dependências, executar testes e publicar bibliotecas. Se você vem de linguagens como Python (pip) ou JavaScript (npm), Cargo funciona de forma similar, mas com integração profunda na toolchain do Rust. Nesta aula, você aprenderá desde conceitos fundamentais até práticas avançadas que o tornarão capaz de gerenciar projetos profissionais com confiança.

Estrutura do Projeto e Configuração Básica

Criando um Projeto

Todo projeto Rust começa com Cargo. Use cargo new para gerar a estrutura padrão:

cargo new meu_projeto
cd meu_projeto

Isso cria uma estrutura como:

meu_projeto/
├── Cargo.toml          # Manifesto do projeto
├── Cargo.lock          # Lock file (gerado automaticamente)
└── src/
    └── main.rs         # Ponto de entrada

O Arquivo Cargo.toml

O Cargo.toml é um arquivo TOML que define metadados e dependências. Aqui está um exemplo real:

[package]
name = "meu_projeto"
version = "0.1.0"
edition = "2021"
authors = ["seu_nome <seu_email@example.com>"]

[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.35", features = ["full"] }
reqwest = "0.11"

[dev-dependencies]
criterion = "0.5"

[[bin]]
name = "app"
path = "src/main.rs"

[profile.release]
opt-level = 3
lto = true

Cada dependência pode especificar versão, features (características opcionais) e fonte personalizada. O Cargo.lock garante reprodutibilidade, fixando versões exatas usadas na última compilação bem-sucedida.

Gerenciamento de Dependências

Adicionando e Atualizando Dependências

Use cargo add para instalar pacotes diretamente:

cargo add serde --features derive
cargo add tokio --features full

Ou edite Cargo.toml manualmente. Para atualizar, execute:

cargo update                    # Atualiza respeitando Cargo.toml
cargo update serde --precise 1.0.200  # Versão específica

Entendendo Versionamento Semântico

Rust segue semver (Semantic Versioning). Na especificação "1.2.3":

  • "1.2.3" — exatamente esta versão
  • "^1.2.3" — compatível (1.2.3 até <2.0.0)
  • "~1.2" — patch flexível (1.2.x até <1.3.0)
  • "*" — qualquer versão (evite em produção)

Exemplo prático em Cargo.toml:

[dependencies]
serde = "1.0"           # ^1.0 implícito
log = "~0.4"            # 0.4.x apenas
uuid = { version = "1.0", optional = true }

[features]
with_uuid = ["uuid"]    # Feature que ativa uuid

Sistema de Build e Compilação

Perfis de Compilação

Cargo fornece perfis pré-configurados para diferentes cenários:

cargo build                    # Debug (padrão, desenvolvimento)
cargo build --release          # Release (otimizado, produção)
cargo build --profile custom   # Perfil customizado

O exemplo abaixo mostra um Cargo.toml com perfis personalizados:

[profile.dev]
opt-level = 0           # Sem otimizações
debug = true            # Informações de debug

[profile.release]
opt-level = 3           # Máxima otimização
lto = true              # Link Time Optimization
codegen-units = 1       # Otimização agressiva (compilação mais lenta)
strip = true            # Remove símbolos de debug

[profile.bench]
inherits = "release"    # Herda configurações de release

Compilando e Executando

cargo build --release              # Compila em release
cargo run                           # Compila (se necessário) e executa
cargo run --release -- arg1 arg2   # Executa com argumentos
cargo check                         # Verifica sem gerar binário

Testes, Documentação e Publicação

Executando Testes

cargo test                  # Executa todos os testes
cargo test --release        # Em modo release
cargo test -- --nocapture   # Mostra println! durante testes

Exemplo de teste em Rust:

// src/lib.rs
pub fn soma(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn testa_soma() {
        assert_eq!(soma(2, 2), 4);
    }

    #[test]
    #[should_panic]
    fn testa_panic() {
        panic!("Esta função deve falhar");
    }
}

Documentação

Gere documentação automática com comentários ///:

/// Calcula a soma de dois números.
///
/// # Exemplos
///
/// ```
/// let resultado = soma(2, 3);
/// assert_eq!(resultado, 5);
/// ```
pub fn soma(a: i32, b: i32) -> i32 {
    a + b
}
cargo doc --open  # Gera e abre documentação no navegador

Publicando no crates.io

Para publicar sua biblioteca em https://crates.io, registre-se e obtenha um token. Depois:

cargo login <seu_token>
cargo publish

Seu Cargo.toml deve incluir descrição e licença:

[package]
name = "minha_lib"
version = "0.1.0"
description = "Uma biblioteca incrível"
license = "MIT"
repository = "https://github.com/usuario/minha_lib"

Conclusão

Dominado Cargo, você controla toda a ciclo de vida de projetos Rust: desde a criação até publicação. Os três pilares essenciais são: (1) Cargo.toml como fonte única de verdade sobre dependências e configuração, (2) gerenciamento de versões usando semver para evitar conflitos, e (3) perfis de build para otimizar conforme o contexto (desenvolvimento vs. produção). Pratique criando projetos pequenos e publique uma biblioteca para solidificar o aprendizado.

Referências


Artigos relacionados