【问题标题】:Linking AVR programs with Cargo将 AVR 程序与 Cargo 链接
【发布时间】:2017-09-27 21:38:20
【问题描述】:

我有一个 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 工作流程中?

【问题讨论】:

    标签: linker rust avr rust-cargo


    【解决方案1】:

    一句警告: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。这个项目曾经工作(见我的blog series)。我最近更新了它,使它可以针对 avr-rust 的 master 分支进行编译,但尚未在真实设备上测试编译后的代码。


    Cargo post build scripts 有一个开放的 RFC,但它似乎不太可能被合并。我继续使用 Makefile。 xargo 可能是另一种选择。还有关于可以创建货物子命令的隆隆声。

    【讨论】:

    • 使用您的 .json 文件(删除我不需要的 interrupt_vector.S 依赖项),cargo build 完成没有错误,但生成的 .elf 文件只有 701 个字节,与一个手动链接的.elf,它是 4002 字节。 avr-objdump -S 显示短 .elf 文件不包含任何代码。
    • @Cactus 请再次检查。编译器总是添加-Wl,--gc-sections,这会删除所有内容。 post-link-args 应该可以撤消它,但是之前它的结构是错误的,我现在已经更改了它。
    猜你喜欢
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    相关资源
    最近更新 更多