将 AVR 程序与 Cargo 链接
Linking AVR programs with Cargo
我有一个 Rust 项目,目前正在手动编译和链接:
rustc --target=avr-atmel-none src/main.rs --emit=obj -o _build/main.rs.o -C opt-level=3
avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o _build/image.elf _build/main.rs.o
avr-objcopy -Oihex -R.eeprom _build/image.elf _build/image.hex
我想用 Cargo 自动执行此操作,所以我首先将 avr-gcc
设置为链接器,将以下内容添加到 .cargo/config
:
[build]
target = "avr-atmel-none"
[target.avr-atmel-none]
linker = "avr-gcc"
但是,似乎 cargo
向链接器传递了一些 avr-gcc
无法处理的额外参数:
11:47:10 [cactus@galaxy interrupt-bug]$ cargo build --release
Compiling hello-avr v0.1.0 (file:///home/cactus/prog/rust/avr/interrupt-bug)
error: linking with `avr-gcc` failed: exit code: 1
|
= note: "avr-gcc" "-Wl,--as-needed" "-L" "/home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmel-none/lib" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps/hello_avr-8bce8eb24807f5a8.0.o" "-o" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps/hello_avr-8bce8eb24807f5a8" "-Wl,--gc-sections" "-pie" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps" "-L" "/home/cactus/prog/rust/avr/interrupt-bug/target/release/deps" "-L" "/home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmel-none/lib"
= note: /usr/lib/gcc/avr/4.8.2/../../../avr/bin/ld: -pie not supported
collect2: error: ld returned 1 exit status
如何从 avr-gcc
调用中删除这些额外参数?此外,有没有办法将第三步,即 avr-objcopy
调用集成到 Cargo 工作流程中?
一句警告:avr-rust 的开发可以礼貌地说是 前沿 。很可能有一天有用的东西可能不会在下一天起作用,所以像这样的答案很可能很快就会过时。我们欢迎该项目的所有贡献者,以帮助提高它的可用性。
您需要指定目标 JSON 文件和完整的链接器参数集。这是我的一个旧项目的示例(一些确切的值现在可能不正确):
{
"llvm-target": "avr-atmel-none",
"target-endian": "little",
"target-pointer-width": "16",
"os": "none",
"target-env": "gnu",
"target-vendor": "unknown",
"arch": "avr",
"data-layout": "e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n8",
"executables": true,
"linker": "avr-gcc",
"linker-flavor": "gcc",
"pre-link-args": {
"gcc": ["-mmcu=atmega328p", "-nostartfiles", "../interrupt_vector.S"]
},
"exe-suffix": ".elf",
"post-link-args": {
"gcc": ["-Wl,--no-gc-sections"]
},
"no-compiler-rt": true
}
有关完整示例,请参阅 my example repository. This project used to work (see my blog series)。我最近更新了它,因此它可以针对 avr-rust 的主分支进行编译,但尚未在真实设备上测试编译后的代码。
有一个开放的 RFC 可以让 Cargo post build scripts, but it doesn't seem likely to be merged. I continue to use a Makefile. xargo 成为替代方案。还有关于可以创建的 cargo 子命令的传言。
我有一个 Rust 项目,目前正在手动编译和链接:
rustc --target=avr-atmel-none src/main.rs --emit=obj -o _build/main.rs.o -C opt-level=3
avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o _build/image.elf _build/main.rs.o
avr-objcopy -Oihex -R.eeprom _build/image.elf _build/image.hex
我想用 Cargo 自动执行此操作,所以我首先将 avr-gcc
设置为链接器,将以下内容添加到 .cargo/config
:
[build]
target = "avr-atmel-none"
[target.avr-atmel-none]
linker = "avr-gcc"
但是,似乎 cargo
向链接器传递了一些 avr-gcc
无法处理的额外参数:
11:47:10 [cactus@galaxy interrupt-bug]$ cargo build --release
Compiling hello-avr v0.1.0 (file:///home/cactus/prog/rust/avr/interrupt-bug)
error: linking with `avr-gcc` failed: exit code: 1
|
= note: "avr-gcc" "-Wl,--as-needed" "-L" "/home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmel-none/lib" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps/hello_avr-8bce8eb24807f5a8.0.o" "-o" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps/hello_avr-8bce8eb24807f5a8" "-Wl,--gc-sections" "-pie" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/cactus/prog/rust/avr/interrupt-bug/target/avr-atmel-none/release/deps" "-L" "/home/cactus/prog/rust/avr/interrupt-bug/target/release/deps" "-L" "/home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmel-none/lib"
= note: /usr/lib/gcc/avr/4.8.2/../../../avr/bin/ld: -pie not supported
collect2: error: ld returned 1 exit status
如何从 avr-gcc
调用中删除这些额外参数?此外,有没有办法将第三步,即 avr-objcopy
调用集成到 Cargo 工作流程中?
一句警告:avr-rust 的开发可以礼貌地说是 前沿 。很可能有一天有用的东西可能不会在下一天起作用,所以像这样的答案很可能很快就会过时。我们欢迎该项目的所有贡献者,以帮助提高它的可用性。
您需要指定目标 JSON 文件和完整的链接器参数集。这是我的一个旧项目的示例(一些确切的值现在可能不正确):
{
"llvm-target": "avr-atmel-none",
"target-endian": "little",
"target-pointer-width": "16",
"os": "none",
"target-env": "gnu",
"target-vendor": "unknown",
"arch": "avr",
"data-layout": "e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n8",
"executables": true,
"linker": "avr-gcc",
"linker-flavor": "gcc",
"pre-link-args": {
"gcc": ["-mmcu=atmega328p", "-nostartfiles", "../interrupt_vector.S"]
},
"exe-suffix": ".elf",
"post-link-args": {
"gcc": ["-Wl,--no-gc-sections"]
},
"no-compiler-rt": true
}
有关完整示例,请参阅 my example repository. This project used to work (see my blog series)。我最近更新了它,因此它可以针对 avr-rust 的主分支进行编译,但尚未在真实设备上测试编译后的代码。
有一个开放的 RFC 可以让 Cargo post build scripts, but it doesn't seem likely to be merged. I continue to use a Makefile. xargo 成为替代方案。还有关于可以创建的 cargo 子命令的传言。