Closed jonblack closed 3 years ago
Are you setting the target with a .cargo/config
file in the second crate?
If I add a .cargo/config
in the first crate with the contents:
[build]
target = "asmjs-unknown-emscripten"
And then run cargo build
from the root crate, I get the same compilation failure. It seems cargo ignores this.
I have a similar problem, where I want to build some parts of my workspace as an SGX enclave (using the x86_64-fortanix-unknown-sgx target) and other parts as a regular binary.
Is there a hack-ish way to do this right now, that is simpler than writing a bash script that invokes cargo build in every crate of the workspace?
@kaimast I'm doing this currently: https://github.com/smartcontractkit/chainlink/blob/develop/sgx/Makefile
If I add a
.cargo/config
in the first crate with the contents:[build] target = "asmjs-unknown-emscripten"
And then run
cargo build
from the root crate, I get the same compilation failure. It seems cargo ignores this.
I have this exact same problem. Cargo is ignoring the .cargo/config
files when I build, which makes it difficult to set up a CI build.
I'm experiencing this problem a lot because my workspace has wasms and non-wasms crates...
I ran into this problem too and it cost me 4 hours before I understood what was going on.
My situation: I'm have an embedded project. My binary is in one workspace member and there are two no_std libraries in the workspace as well. The libraries are made for specific chips that are on board of the hardware.
The solution would be that every member can have its own .Cargo/config and when that isn't found, it will then go look in the parent directories.
The solution would be that every member can have its own .Cargo/config and when that isn't found, it will then go look in the parent directories.
Yeah, one would logically think that is the current case... General common config in the topdir.. specialized config in the subdirs.
Yeah, one would logically think that is the current case... General common config in the topdir.. specialized config in the subdirs.
They do work if you call cargo build
in the workspace member itself. But when building from the workspace root, they get ignored.
I have no idea if it's trivial to fix that. It may also break existing workspaces.
I also just run into this problem trying to set up a WASM sub crate. I think I will just use a Makefile to manually run the build per crate instead. But it is a bit inconvenient to do so.
I have faced this issue today. I want to compile one crate with musl
and the other crates with glibc
. Now I am compiling with using separate cargo commands.
I also faced this issue with a workspace of mostly normal crates and 2 wasm crates. It would be very convenient if the .cargo/config
target setting was respected by the workspace.
So, today and I have stumbled with the same issue with wasm and non-wasm crates in one project.
Just ran into this. This seems pretty key as long as rust considers wasm a first class target.
Same problem. Any workaround? I really need it since I build stuff around efi and bios.
Use case:
One workaround, albeit not a great one, but one we do use is to divide up the workspace into multiple workspaces, one per target, have them in different folders and have a .cargo/config
in each that picks the target to build for.
It is not great though, you don't have a single workspace to build anymore. but doing cargo build
inside each separate folder and workspace does build and run on the right target.
I've decided to go with rust-make and remove Cargo.toml workspace file and use rust-make's internal one. So I have Makefile.toml and just execute "cargo make" to build them all, it goes to each folder and executes "cargo build"
I have looked into this. cargo completely ignores config files in member directories if cargo is called from the workspace root. I came up with 3 different options to implement per-crate build targets but sadly none of them are trivial:
.cargo/config.toml
Not a good idea. While this would work for some keys like build.target
it is not a good idea for others like build.jobs
. cargo could ignore such definitions in workspace members of course but it seems very hacky.
.cargo/member.toml
configurationSpecial configuration file with a scope limited to a single member crate and a limited set of configuration values like build.target
. Reusing config file parsing code from cargo would be difficult though since it all pretty much depends on Config
(e.g. ConfigRelativePath::resolve_path
takes &Config
as its argument).
# workspace/foo/.cargo/member.toml
[build]
target = "wasm32-unknown-unknown"
[member.'name']
table in toplevel .cargo/config.toml
Similar to .cargo/member.toml proposal but all information goes into the toplevel .cargo config.toml
# workspace/.cargo/config.toml
[build]
# Default target
target = "x86_64-unknown-linux-gnu"
[member.foo]
# Override default target for `foo`
target = "wasm32-unknown-unknown"
I have implemented proposal 3 (here) and it seems to work fine (all tests pass). It's not an elegant implementation though and it feels pretty "wedged in".
IMHO much better idea would be to allow use of the workspace’s config as a base, where each package have the ability to overwrite properties in context of a package.
I am not aware how it works internally but if there is only once „Config” instance, maybe building „Config” for each package and switching it would also be an option?
IMHO much better idea would be to allow use of the workspace’s config as a base, where each package have the ability to overwrite properties in context of a package.
I am not aware how it works internally but if there is only once „Config” instance, maybe building „Config” for each package and switching it would also be an option?
I started work on this with a similar approach but I had to abandon it. The current configuration system in cargo is just not designed to deal with multiple configs in one run. Changing this would be a major refactoring and would probably lead to backwards-compatibility problems too.
Using [member.'crate']
tables just circumvents the problem by not challenging cargo's assumption that there is only one configuration per run.
It is great that progress is made on this issue :)
I started work on this with a similar approach but I had to abandon it. The current configuration system in cargo is just not designed to deal with multiple configs in one run. Changing this would be a major refactoring and would probably lead to backwards-compatibility problems too.
I think eventually this refactor needs to happen or the Rust community has to decide on a meta build tool that is used on top of cargo. Many projects (especially those involving WASM or SGX) use Makefiles right now to circumvent these limitations, which is somewhat ugly and does not work on all platform.
This thread has a proposal on a fix to this, discussed by the cargo team (was linked on #8797): https://internals.rust-lang.org/t/proposal-move-some-cargo-config-settings-to-cargo-toml/13336
It appears the current status is that PRs are welcome for adding the properties discussed there to Cargo.toml
.
Hey! In case people are interested, I've just submitted https://github.com/rust-lang/cargo/pull/9030 which should implement the solution discussed in the irlo thread listed just above.
Additionally would be awesome to have in Cargo.toml possibility to define triplets for each [[bin]] :) Just an idea.
@kaimast I'm doing this currently: https://github.com/smartcontractkit/chainlink/blob/develop/sgx/Makefile
This link is broken.
Thanks for your work @Ekleog, this was very helpful in a project I'm working on!
In case any newbies (like me) come across this in the future, and are confused about how to use the fix, it's documented here: https://doc.rust-lang.org/cargo/reference/unstable.html#per-package-target
Google is still showing this issue as the 1st result, so the doc link may be helpful.
@ryanc-me are there any solutions for stable rust?
I would also love to know which solution is recommended for stable rust.
Describe the problem you are trying to solve
I have a project with two crates in a workspace. The first crate should compile to asmjs with
--target asmjs-unknown-emscripten
and the result is used in the second crate, which should compile to the native binary format (default target).When I run
cargo build
in the root crate that contains the workspace configuration inCargo.toml
, it builds both crates using the default target.Describe the solution you'd like
I'd like to be able to specify the target for each crate. I'm not sure if this belongs in each crates'
Cargo.toml
or in the root crate'sCargo.toml
.