【发布时间】:2017-10-20 14:59:15
【问题描述】:
我正在尝试通过使用"linker-flavor":"gcc" 编写自定义目标.json 文件来使用this answer。我的完整目标.json 文件是:
{
"llvm-target": "avr-atmel-none",
"cpu": "atmega328p",
"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": ["-Os -mmcu=atmega328p"]
},
"exe-suffix": ".elf",
"post-link-args": {
"gcc": ["-Wl,--gc-sections"]
},
"no-default-libraries": false
}
运行 cargo build 并没有任何错误消息:
$ cargo build --release -v
Compiling core v0.1.0 (https://github.com/gergoerdi/rust-avr-libcore-mini?rev=adda44aa91ac517aab6915447592ee4cad26564c#adda44aa)
Running `rustc --crate-name core /home/cactus/.cargo/git/checkouts/rust-avr-libcore-mini-37e279d93a70b45a/adda44a/src/lib.rs --crate-type lib --emit=dep-info,link -C opt-level=3 -C metadata=655bb622dd229da9 -C extra-filename=-655bb622dd229da9 --out-dir /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps --target avr-atmega328p -L dependency=/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps -L dependency=/home/cactus/prog/rust/avr/chip8-avr/target/release/deps --cap-lints allow`
Compiling chip8-engine v0.1.0 (https://github.com/gergoerdi/rust-avr-chip8-engine?rev=c6f88737bae4dae0bd6c5c2bbc73737e6dfadfcd#c6f88737)
Running `rustc --crate-name chip8_engine /home/cactus/.cargo/git/checkouts/rust-avr-chip8-engine-4bce60f3f178d33a/c6f8873/src/lib.rs --crate-type lib --emit=dep-info,link -C opt-level=3 -C metadata=2197ff1f15f697c9 -C extra-filename=-2197ff1f15f697c9 --out-dir /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps --target avr-atmega328p -L dependency=/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps -L dependency=/home/cactus/prog/rust/avr/chip8-avr/target/release/deps --extern core=/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/libcore-655bb622dd229da9.rlib --cap-lints allow`
Compiling chip8-avr v0.1.0 (file:///home/cactus/prog/rust/avr/chip8-avr)
Running `rustc --crate-name chip8_avr src/main.rs --crate-type bin --emit=dep-info,link -C opt-level=3 -C metadata=014a8fed19cbc611 -C extra-filename=-014a8fed19cbc611 --out-dir /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps --target avr-atmega328p -L dependency=/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps -L dependency=/home/cactus/prog/rust/avr/chip8-avr/target/release/deps --extern chip8_engine=/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/libchip8_engine-2197ff1f15f697c9.rlib --extern core=/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/libcore-655bb622dd229da9.rlib`
Finished release [optimized] target(s) in 15.99 secs
但是,生成的 ELF 文件的 .text 部分是空的:
$ avr-objdump -h target/avr-atmega328p/release/chip8-avr.elf
target/avr-atmega328p/release/chip8-avr.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00800060 00000000 00000074 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .stab 0000012c 00000000 00000000 00000074 2**2
CONTENTS, READONLY, DEBUGGING
3 .stabstr 0000005d 00000000 00000000 000001a0 2**0
CONTENTS, READONLY, DEBUGGING
4 .comment 00000011 00000000 00000000 000001fd 2**0
CONTENTS, READONLY
所以为了弄清楚发生了什么,我想我会替换我的avr-gcc
用一个小的 shellscript 记录它的参数,然后再将它传递给
真正的avr-gcc 可执行文件。
这表明rustc/cargo 正在尝试运行以下命令
执行链接的命令行:
/usr/bin/avr-gcc -Os -mmcu=atmega328p \
-L /home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmega328p/lib \
/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/chip8_avr-014a8fed19cbc611.0.o \
-o /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/chip8_avr-014a8fed19cbc611.elf \
-Wl,--gc-sections \
-L /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps -L /home/cactus/prog/rust/avr/chip8-avr/target/release/deps -L /home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmega328p/lib \
-Wl,-Bstatic /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/libchip8_engine-2197ff1f15f697c9.rlib \
/home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/libcore-655bb622dd229da9.rlib \
-Wl,-Bdynamic -Wl,--gc-sections
如果我手动运行完全相同的命令,使用完全相同的环境变量,我会得到一个很好的 ELF 文件
正确的内容(注意它的.text 部分不为空):
$ /usr/bin/avr-gcc -Os -mmcu=atmega328p -L /home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmega328p/lib /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/chip8_avr-014a8fed19cbc611.0.o -o /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/chip8_avr-014a8fed19cbc611.elf -Wl,--gc-sections -L /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps -L /home/cactus/prog/rust/avr/chip8-avr/target/release/deps -L /home/cactus/prog/rust/rust-avr/build/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/avr-atmega328p/lib -Wl,-Bstatic /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/libchip8_engine-2197ff1f15f697c9.rlib /home/cactus/prog/rust/avr/chip8-avr/target/avr-atmega328p/release/deps/libcore-655bb622dd229da9.rlib -Wl,-Bdynamic -Wl,--gc-sections
$ avr-objdump -h target/avr-atmega328p/release/deps/chip8_avr-014a8fed19cbc611.elf
target/avr-atmega328p/release/deps/chip8_avr-014a8fed19cbc611.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 0000020e 00800100 00001a56 00001af0 2**4
CONTENTS, ALLOC, LOAD, DATA
1 .text 00001a56 00000000 00000000 00000094 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .bss 000001fa 0080030e 0080030e 00001cfe 2**0
ALLOC
3 .stab 000007ec 00000000 00000000 00001d00 2**2
CONTENTS, READONLY, DEBUGGING
4 .stabstr 000000b0 00000000 00000000 000024ec 2**0
CONTENTS, READONLY, DEBUGGING
5 .comment 00000011 00000000 00000000 0000259c 2**0
CONTENTS, READONLY
那么为什么cargo 会默默地生成一个无意义的空 ELF 文件,如果
从 shell 运行(假定)相同的命令会生成有效的 ELF 文件?
【问题讨论】:
标签: linker rust rust-cargo