Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
xobs opened this issue Mar 10, 2020 · 4 comments
Open

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

xobs opened this issue Mar 10, 2020 · 4 comments

Comments

@xobs
Copy link

xobs commented Mar 10, 2020

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.

@xobs xobs changed the title Support linker scripts in Cargo.toml Support linker scripts in Cargo.toml / build.rs Mar 10, 2020
@jonas-schievink
Copy link
Contributor

Big 👍 from me, but this should probably be filed as a Cargo issue at https://github.com/rust-lang/cargo

@roblabla
Copy link

I'm probably misunderstanding something, but it's absolutely possible to check in .cargo/config, and cargo will read it just fine. Cargo walks the path from the current working directory upwards to find .cargo/config.

I'm 100% on board with a build-script mechanism to set linker flags though.

@cr1901
Copy link

cr1901 commented Mar 10, 2020

My understanding is that, you need to check in .cargo/config in a workspace targeting multiple architectures at once. Consider a workspace containing:

  • x86_64 testing application
  • An ARM micrcocontroller testing firmware
  • A serialization crate to send data back and forth, compiled for both x86_64 and ARM.

Setting the architecture to .cargo/config is required for the x86_64 testing application and firmware crate for cargo build, without an explicit target architecture to "do the right thing".

@xobs
Copy link
Author

xobs commented Mar 11, 2020

I created an issue in the cargo repository: rust-lang/cargo#7984

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants