Skip to content

Support linker scripts in Cargo.toml / build.rs #432

Open
@xobs

Description

@xobs

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:

  1. It puts configuration data in a file that's ostensibly not going to be checked in
  2. 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:

  1. 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
...
$
  1. 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.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions