Linking AVR programs with Cargo

懵懂的女人 提交于 2020-01-17 07:18:22

问题


I have a Rust project which I am currently compiling and linking by hand:

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

I would like to automate this with Cargo, so I started by setting avr-gcc as the linker, by adding the following to .cargo/config:

[build]
target = "avr-atmel-none"

[target.avr-atmel-none]
linker = "avr-gcc"

However, it seems cargo passes some extra arguments to the linker that avr-gcc cannot handle:

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

How do I remove these extra arguments from the avr-gcc invocation? Moreover, is there a way to integrate the third step, i.e. the avr-objcopy call, into the Cargo workflow?


回答1:


A word of warning: development on avr-rust can politely be said to be cutting edge. It's very likely something that works one day may not the next, so answers like this are likely to go out of date quickly. We welcome all contributors to the project to help make it more usable.


You need to specify a target JSON file and the full set of linker arguments. Here's an example from an older project of mine (some of the exact values may now be incorrect):

{
  "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
}

For a full example see my example repository. This project used to work (see my blog series). I have recently updated it so it compiles against the master branch of avr-rust, but haven't tested the compiled code on a real device.


There's an open RFC for having Cargo post build scripts, but it doesn't seem likely to be merged. I continue to use a Makefile. xargo might be an alternative. There were also rumbles about a cargo subcommand that could be created.



来源:https://stackoverflow.com/questions/43702724/linking-avr-programs-with-cargo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!