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

per-package-target looks in project root for memory.x rather then crate specific directories #9537

Closed
FrankvdStam opened this issue Jun 3, 2021 · 5 comments
Labels
A-linkage Area: linker issues, dylib, cdylib, shared libraries, so A-rustflags Area: rustflags C-bug Category: bug S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. Z-per-package-target Nightly: per-package-target

Comments

@FrankvdStam
Copy link

Unsure if bug or asking for a feature.

Problem

When using the new per-package-target feature in nightly builds, any linker scripts that you might need in a specific crate will not be found when using a workspace. The linker script is expected in root.

Given the following project structure and manifest files:

root (directory)
	cargo.toml
		
                [workspace]
		members = ["cli", "hardware"]
	
	cli (directory)
		cargo.toml
			[package]
			name = "cli"
			version = "0.1.0"
			authors = ["redacted"]
			edition = "2018"
		
		main.rs
			code omitted, not important
	
	hardware (directory)
		cargo.toml
			cargo-features = ["per-package-target"]
			
			[package]
			name = "hardware"
			version = "0.1.0"
			authors = ["redacted"]
			edition = "2018"
			forced-target = "thumbv7em-none-eabihf"

			[dependencies]
			cortex-m = "0.7.2"
			cortex-m-rt = "0.6.13"
			cortex-m-semihosting = "0.3.7"
			alloc-cortex-m = "0.4.1"
			stm32h7xx-hal = {version = "0.9.0", features = ["stm32h7a3","rt"]}
			embedded-hal = "0.2.5"

		memory.x
			script ommitted, contents not important
	
		.cargo (directory)
			config.toml
				[target.thumbv7em-none-eabihf]
				runner = 'arm-none-eabi-gdb'
				rustflags = [
					# LLD (shipped with the Rust toolchain) is used as the default linker
					"-C", "link-arg=-Tlink.x",
				]

				[build]
				target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

cargo build will eventually fail during linking:

note: rust-lld: error: C:\projects\embedded\stm6502\target\thumbv7em-none-eabihf\debug\build\cortex-m-rt-3e6b4c679f86541e\out\link.x:23: cannot find linker script memory.x
          >>> INCLUDE memory.x
          >>>         ^

Even though the script is right there in the crate's subdirectory.

After copying memory.x to the root directory, cargo build runs without problems (except for all those warnings I should really look at)

I would expect the script (memory.x) in the crate directory itself to be picked up.
The way that this is setup, I wouldn't be able to target multiple microcontrollers requiring a different memory.x script from the same workspace. I can't specify the name either; "link-arg=-Tlink.x" just looks for memory.x and that's it. In order to target different microcontrollers, you'd have to swap the file in the root directory during build or some crazy shenanigans like that.

Steps

  1. Create above project structure or clone this minimal reproduction repository that I set up for this issue (names of directories slightly different): https://github.com/FrankvdStam/PerPackageTargetIssue
  2. Run cargo build, note linker error
  3. Move memory.x to project root
  4. Run cargo build, note linker error disappearing

Possible Solution(s)

Maybe the best would not be to just make it pick up memory.x from the specific crate, but allow users to explicitly tell cargo where to find memory.x in Cargo.toml - the first time I saw memory.x I was confused how/where it was used/what it was, an explicit setting might help users find the documentation for it on their own. Then again I have no idea as to the complexities of implementing any of this.

Notes

Output of cargo version:

cargo 1.54.0-nightly (e931e4796 2021-05-24)

Output of rustup show:

Default host: x86_64-pc-windows-gnu
rustup home:  C:\Users\Frank\.rustup

installed toolchains
--------------------

stable-x86_64-pc-windows-gnu
stable-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-gnu
nightly-x86_64-pc-windows-msvc (default)

installed targets for active toolchain
--------------------------------------

thumbv6m-none-eabi
thumbv7em-none-eabihf
thumbv7m-none-eabi
x86_64-pc-windows-msvc

active toolchain
----------------

nightly-x86_64-pc-windows-msvc (default)
rustc 1.54.0-nightly (dbe459ded 2021-06-02)
@FrankvdStam FrankvdStam added the C-bug Category: bug label Jun 3, 2021
@FrankvdStam FrankvdStam changed the title per-package-target looks in project root for memory.x rather then crate specific per-package-target looks in project root for memory.x rather then crate specific directories Jun 3, 2021
@mattiekat
Copy link

mattiekat commented Jun 13, 2021

My understanding is it is a missing feature that other have been asking for in different forms. Found #7004 first which is simmilar.

I am also running into the same issue (more or less). I am trying to change the rustflags to link against opengl and a few other libs which has to happen at the end in my case because I am also working with cxx but I don't want the rustflags to get modified for all crates in my workspace. At this time the subdirectories' configs in the workspace are ignored and only the main config is used.

The current workaround seems to be running cargo from within the crate's workspace which some people have been creating makefiles for.

Also just found this which seems it might be a solution (but it does require a build script):
#8441

@ehuss ehuss added Z-per-package-target Nightly: per-package-target A-linkage Area: linker issues, dylib, cdylib, shared libraries, so A-rustflags Area: rustflags labels Jul 1, 2021
@Nikita240
Copy link

+1 encountered the same issue setting up a workspace that targets different microcontrollers

@weihanglo weihanglo added the S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. label Mar 9, 2024
@weihanglo
Copy link
Member

I feel like this is less an issue of Z-per-package-target, as the feature doesn't really change anything for configuration probing or where a process is spawned.
This is more an issue of people confused by how Cargo's configuration files are discovered (not to be confused with Cargo.toml), and supporting config-relative or variable expansions in Cargo configuration. See some relevant issues:

I am going to close this in favor of the issues above. Do let us know if there is a reason to keep this issue separately!

@weihanglo weihanglo closed this as not planned Won't fix, can't repro, duplicate, stale Nov 22, 2024
@FrankvdStam
Copy link
Author

I don't see any confusion over cargo's configuration nor relevance in the mentioned issues. None of them really solve my problem.

@weihanglo
Copy link
Member

The linked example project is gone so I have no way to reproduce. Since how rustflags is handled is relatively sensitive to where cargo is invoked, do you remember where you ran cargo build from?

The current workaround seems to be running cargo from within the crate's workspace which some people have been creating makefiles for.

The other folk has mentioned this. Did that work for you?

None of them really solve my problem.

Sorry. I close this as duplicate because per-package-target doesn't seem to affect the behavior from my understanding. Unfortunately GitHub has a bad UI and shows it as “not planned”.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linker issues, dylib, cdylib, shared libraries, so A-rustflags Area: rustflags C-bug Category: bug S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. Z-per-package-target Nightly: per-package-target
Projects
None yet
Development

No branches or pull requests

5 participants