As per #24 (comment)_, I'm opening a new issue.
The current recommendation for making custom linker scripts is to create a .cargo/config file and add a reference to the linker script there. The previous discussion identified a number of issues with this:
- It puts configuration data in a file that's ostensibly not going to be checked in
- It's difficult to change it on a per-device basis
Additionally, I would like to add some more issues I see with it, particularly with workspaces:
- The build depends on the directory you're in. For example, here the data section moved, which was a subtle bug to track down:
$ cargo build -p kernel --target riscv32imac-unknown-none-elf
$ riscv64-unknown-elf-readelf -S target/riscv32imac-unknown-none-elf/debug/kernel
There are 24 section headers, starting at offset 0x117724:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .rodata PROGBITS 000100e0 0000e0 002f38 00 AM 0 0 16
[ 2] .text PROGBITS 00014000 004000 00ebe2 00 AX 0 0 2
[ 3] .trap PROGBITS 00022be2 012be2 000104 00 AX 0 0 1
[ 4] .data PROGBITS 00023000 013000 002bc8 00 WA 0 0 4
[ 5] .sdata PROGBITS 00025bc8 015bc8 000004 00 WA 0 0 4
...
$ cd kernel
$ cargo build -p kernel --target riscv32imac-unknown-none-elf
$ riscv64-unknown-elf-readelf -S ../target/riscv32imac-unknown-none-elf/debug/kernel There are 21 section headers, starting at offset 0xfd404:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS ffd00000 001000 00c0c0 00 AX 0 0 4
[ 2] .rodata PROGBITS ffd0c0c0 00d0c0 002f34 00 AM 0 0 16
[ 3] .data PROGBITS ffd80000 010000 002bcc 00 WA 0 0 4096
[ 4] .bss NOBITS ffd82bcc 012bcc 000210 00 WA 0 0 4
...
$
- It is required to copy the linker args on a per-target basis. For example, duplicate arguments need to be made for
riscv32imac-unknown-none-elf and riscv32i-unknown-none-elf, even though they're identical.
- It isn't possible to do a
cargo build --target riscv32imac-unknown-none from the root, since cargo appears to ignore the .cargo/config setting.
Some of these could be fixed if cargo read .cargo/config from the crate root, which may be an acceptible workaround, however it seems to me that's just working around the problem.
I think it would be much better if cargo supported setting the linker flags from e.g. build.rs so they can be set on a per-crate basis, possibly based on the build environment in something like a CI infrastructure.
As per #24 (comment)_, I'm opening a new issue.
The current recommendation for making custom linker scripts is to create a
.cargo/configfile and add a reference to the linker script there. The previous discussion identified a number of issues with this:Additionally, I would like to add some more issues I see with it, particularly with workspaces:
$ cargo build -p kernel --target riscv32imac-unknown-none-elf $ riscv64-unknown-elf-readelf -S target/riscv32imac-unknown-none-elf/debug/kernel There are 24 section headers, starting at offset 0x117724: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .rodata PROGBITS 000100e0 0000e0 002f38 00 AM 0 0 16 [ 2] .text PROGBITS 00014000 004000 00ebe2 00 AX 0 0 2 [ 3] .trap PROGBITS 00022be2 012be2 000104 00 AX 0 0 1 [ 4] .data PROGBITS 00023000 013000 002bc8 00 WA 0 0 4 [ 5] .sdata PROGBITS 00025bc8 015bc8 000004 00 WA 0 0 4 ... $ cd kernel $ cargo build -p kernel --target riscv32imac-unknown-none-elf $ riscv64-unknown-elf-readelf -S ../target/riscv32imac-unknown-none-elf/debug/kernel There are 21 section headers, starting at offset 0xfd404: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS ffd00000 001000 00c0c0 00 AX 0 0 4 [ 2] .rodata PROGBITS ffd0c0c0 00d0c0 002f34 00 AM 0 0 16 [ 3] .data PROGBITS ffd80000 010000 002bcc 00 WA 0 0 4096 [ 4] .bss NOBITS ffd82bcc 012bcc 000210 00 WA 0 0 4 ... $riscv32imac-unknown-none-elfandriscv32i-unknown-none-elf, even though they're identical.cargo build --target riscv32imac-unknown-nonefrom the root, since cargo appears to ignore the.cargo/configsetting.Some of these could be fixed if cargo read
.cargo/configfrom the crate root, which may be an acceptible workaround, however it seems to me that's just working around the problem.I think it would be much better if cargo supported setting the linker flags from e.g.
build.rsso they can be set on a per-crate basis, possibly based on the build environment in something like a CI infrastructure.