Description
Problem
When building a lib crate that has a dependency on a proc_macro crate, and where both crates depend on a common dependency with different feature sets:
The features required by the lib and proc_macro crates get unified when the whole workspace is built together, even with resolver = 2 set.
When building the lib crate in isolation, or excluding the proc-macro crate from the virtual workspace, the features required by the lib and proc_macro creates are decoupled and do not impact each other. Note that the proc-macro crate is a dependency of the lib crate so it still gets built.
Steps
The code base below experiences this issue.
-
git clone https://github.com/stellar/rs-stellar-contract-sdk
-
cd rs-stellar-contract-sdk
-
git fetch origin pull/163/head:pr163
-
git checkout pr163
-
cargo build --target wasm32-unknown-unknown
🔴The following error will display:
error: duplicate lang item in crate `std` (which `stellar_xdr` depends on): `panic_impl`. | = note: the lang item is first defined in crate `stellar_contract_env_panic_handler_wasm32_unreachable` (which `stellar_contract_sdk` depends on) = note: first definition in `stellar_contract_env_panic_handler_wasm32_unreachable` loaded from /Users/leighmcculloch/Code/rs-stellar-contract-sdk/target/wasm32-unknown-unknown/debug/deps/libstellar_contract_env_panic_handler_wasm32_unreachable-392062a7cb65bdce.rlib = note: second definition in `std` loaded from /Users/leighmcculloch/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/wasm32-unknown-unknown/lib/libstd-c25950e70fb23c19.rlib
The error is occurring because the libs in the workspace provide their own panic handler, and the proc-macro is dependent on rs-stellar-xdr's std feature, which pulls in the std panic handler, and Cargo resolves rs-stellar-xdr with the std feature for all the other libs too.
-
cargo build --target wasm32-unknown-unknown --workspace --exclude stellar-contract-macros
🟢This command will succeed because the proc-macro package has been excluded from the build, and so it is not influencing the main lib dependencies, even though the package is still compiled because it is a dependency of the other libs. A similar affect can be achieved by making this change to the workspace
Cargo.toml
:+ exclude=["macros"]
Possible Solution(s)
I think proc-macro features and dependencies should be decoupled from other builds, not only when they are dependencies, but also when they are built as part of a workspace.
Notes
No response
Version
cargo 1.62.0 (a748cf5a3 2022-06-08)