"]
# o perfil usado para `cargo build`
[profile.dev]
panic = "abort" # desativar o unwinding do stack em caso de pânico
# o perfil usado para `cargo build --release`
[profile.release]
panic = "abort" # desativar o unwinding do stack em caso de pânico
```
Para construir este binário, precisamos compilar para um alvo bare metal como `thumbv7em-none-eabihf`:
```
cargo build --target thumbv7em-none-eabihf
```
Alternativamente, podemos compilá-lo para o sistema host passando argumentos adicionais de linker:
```bash
# Linux
cargo rustc -- -C link-arg=-nostartfiles
# Windows
cargo rustc -- -C link-args="/ENTRY:_start /SUBSYSTEM:console"
# macOS
cargo rustc -- -C link-args="-e __start -static -nostartfiles"
```
Note que isto é apenas um exemplo mínimo de um binário Rust independente. Este binário espera por várias coisas, por exemplo, que um stack seja inicializado quando a função `_start` é chamada. **Portanto para qualquer uso real de tal binário, mais passos são necessários**.
## Deixando `rust-analyzer` Feliz
O projeto [`rust-analyzer`](https://rust-analyzer.github.io/) é uma ótima forma de obter autocompletar e suporte "ir para definição" (e muitos outros recursos) para código Rust no seu editor.
Funciona muito bem para projetos `#![no_std]` também, então recomendo usá-lo para desenvolvimento de kernel!
Se você estiver usando a funcionalidade [`checkOnSave`](https://rust-analyzer.github.io/book/configuration.html#checkOnSave) de `rust-analyzer` (habilitada por padrão), ela pode relatar um erro para a função panic do nosso kernel:
```
found duplicate lang item `panic_impl`
```
A razão para este erro é que `rust-analyzer` invoca `cargo check --all-targets` por padrão, que também tenta construir o binário em modo [teste](https://doc.rust-lang.org/book/ch11-01-writing-tests.html) e [benchmark](https://doc.rust-lang.org/rustc/tests/index.html#benchmarks).
### Os dois significados de "target"
A flag `--all-targets` é completamente não relacionada ao argumento `--target`.
Há dois significados diferentes do termo "target" no `cargo`:
- A flag `--target` especifica o [_alvo de compilação_] que deve ser passado ao compilador `rustc`. Isso deve ser definido como o [target triple] da máquina que deve executar nosso código.
- A flag `--all-targets` referencia o [_alvo do package] do Cargo. Pacotes Cargo podem ser uma biblioteca e binário ao mesmo tempo, então você pode especificar de qual forma você gostaria de construir sua crate. Além disso, Cargo também tem alvos de package para [exemplos](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#examples), [testes](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#tests), e [benchmarks](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#benchmarks). Esses alvos de pacote podem coexistir, então você pode construir/verificar a mesma crate por exemplo em modo biblioteca ou modo teste.
[_alvo de compilação_]: https://doc.rust-lang.org/rustc/targets/index.html
[target triple]: https://clang.llvm.org/docs/CrossCompilation.html#target-triple
[_alvo do package]: https://doc.rust-lang.org/cargo/reference/cargo-targets.html
Por padrão, `cargo check` apenas constrói o _biblioteca_ e os alvos de pacote _binário_.
No entanto, `rust-analyzer` escolhe verificar todos os alvos de pacote por padrão quando [`checkOnSave`](https://rust-analyzer.github.io/book/configuration.html#checkOnSave) é habilitado.
Esta é a razão pela qual `rust-analyzer` relata o erro de `lang item` acima que não vemos em `cargo check`.
Se executarmos `cargo check --all-targets`, vemos o erro também:
```
error[E0152]: found duplicate lang item `panic_impl`
--> src/main.rs:13:1
|
13 | / fn panic(_info: &PanicInfo) -> ! {
14 | | loop {}
15 | | }
| |_^
|
= note: the lang item is first defined in crate `std` (which `test` depends on)
= note: first definition in `std` loaded from /home/[...]/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-8df6be531efb3fd0.rlib
= note: second definition in the local crate (`blog_os`)
```
A primeira `note` nos diz que o item de linguagem panic já está definido na crate `std`, que é uma dependência da crate `test`.
A crate `test` é automaticamente incluída ao construir uma crate em [modo teste](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#tests).
Isso não faz sentido para nosso kernel `#![no_std]` já que não há forma de suportar a biblioteca padrão em bare metal.
Então este erro não é relevante para nosso projeto e podemos seguramente ignorá-lo.
A forma apropriada de evitar este erro é especificar em nosso `Cargo.toml` que nosso binário não suporta construção em modos `test` e `bench`.
Podemos fazer isso adicionando uma seção `[[bin]]` em nosso `Cargo.toml` para [configurar a construção](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#configuring-a-target) do nosso binário:
```toml
# no Cargo.toml
[[bin]]
name = "blog_os"
test = false
bench = false
```
Os colchetes duplos ao redor de `bin` não é um erro, isto é como o formato TOML define chaves que podem aparecer múltiplas vezes.
Como uma crate pode ter múltiplos binários, a seção `[[bin]]` pode aparecer múltiplas vezes em `Cargo.toml` também.
Esta é também a razão para o campo `name` obrigatório, que precisa corresponder ao nome do binário (para que `cargo` saiba quais configurações devem ser aplicadas a qual binário).
Ao definir os campos [`test`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-test-field) e [`bench` ](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-bench-field) para `false`, instruímos `cargo` a não construir nosso binário em modo teste ou benchmark.
Agora `cargo check --all-targets` não deve lançar mais erros, e a implementação de `checkOnSave` de `rust-analyzer` também deve estar feliz.
## O que vem a seguir?
O [próximo post] explica os passos necessários para transformar nosso binário independente em um kernel mínimo do sistema operacional. Isso inclui criar um alvo customizado, combinar nosso executável com um bootloader, e aprender como imprimir algo na tela.
[próximo post]: @/edition-2/posts/02-minimal-rust-kernel/index.md