Skip to content

cargo new sometimes generates invalid Cargo.toml when new crate is in a subdirectory of a workspace with Cargo 1.71 #12360

Closed as not planned
@Be-ing

Description

@Be-ing

Problem

A crate in a subdirectory of a workspace opting out of being in the workspace via an empty [workspace] table or specifying its path in workspace.exclude in the workspace root's Cargo.toml fails on Windows with Cargo 1.71 whereas it worked with previous versions of Cargo.

Steps

Create a crate in a subdirectory of a workspace with the following Cargo.toml:

[package]
name = "required_libs"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
[lib]
crate-type=["staticlib"]
[workspace]

Running cargo commands fail:

 'C:/Program Files/Microsoft Visual Studio/2022/Enterprise/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe' '-E' 'env' 'CARGO_BUILD_RUSTC=C:/Users/runneradmin/.rustup/toolchains/stable-x86_64-pc-windows-msvc/bin/rustc.exe' 'C:/Users/runneradmin/.rustup/toolchains/stable-x86_64-pc-windows-msvc/bin/cargo.exe' 'rustc' '--verbose' '--color' 'never' '--target=x86_64-pc-windows-msvc' '--' '--print=native-static-libs'
error: failed to parse manifest at `C:\cxx-qt\build\corrosion\required_libs\Cargo.toml`
Caused by:
  error inheriting `version` from workspace root manifest's `workspace.package.version`
Caused by:
  `workspace.package.version` was not defined

Removing the empty [workspace] table from Cargo.toml fails with a different error. This error is also shown when specifying workspace.exclude = [ "path/to/subdir" ] in the workspace root's Cargo.toml:

'C:/Program Files/Microsoft Visual Studio/2022/Enterprise/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe' '-E' 'env' 'CARGO_BUILD_RUSTC=C:/Users/runneradmin/.rustup/toolchains/stable-x86_64-pc-windows-msvc/bin/rustc.exe' 'C:/Users/runneradmin/.rustup/toolchains/stable-x86_64-pc-windows-msvc/bin/cargo.exe' 'rustc' '--verbose' '--color' 'never' '--target=x86_64-pc-windows-msvc' '--' '--print=native-static-libs'
error: current package believes it's in a workspace when it's not:
current:   C:\cxx-qt\build\corrosion\required_libs\Cargo.toml
workspace: C:\cxx-qt\Cargo.toml
this may be fixable by adding `build\corrosion\required_libs` to the `workspace.members` array of the manifest located at: C:\cxx-qt\Cargo.toml
Alternatively, to keep it out of the workspace, add the package to the `workspace.exclude` array, or add an empty `[workspace]` table to the package's manifest.

Possible Solution(s)

I encounter this when using Corrosion to invoke Cargo via CMake as part of building a C++ application. At CMake configure time, Corrosion autogenerates a dummy staticlib crate with the above Cargo.toml to run cargo rustc -- --print=native-static-libs, which is used to tell CMake what system libraries need to be linked whenever linking a staticlib into a C/C++ build. The generated dummy crate is put in the CMake build directory, which conventionally is inside the code repository, which also contains the workspace's virtual Cargo.toml manifest.

A workaround for this particular scenario is to create the CMake build directory outside of the code repository.

If rustc had some way to get the list of native-static-libs needed for every staticlib crate without needing to generate a dummy crate, this situation could be avoided.

Notes

Downstream Corrosion bug: corrosion-rs/corrosion#418

Somehow this bug is only occurring on Windows. Linux and macOS builds still work fine with Rust 1.71.

The root Cargo.toml for the workspace is:

[workspace]
members = [
    "crates/cxx-qt",
    "crates/cxx-qt-build",
    "crates/cxx-qt-gen",
    "crates/cxx-qt-lib",
    "crates/cxx-qt-lib-headers",
    "crates/qt-build-utils",

    "examples/cargo_without_cmake",
    "examples/demo_threading/rust",
    "examples/qml_extension_plugin/plugin/rust",
    "examples/qml_features/rust",
    "examples/qml_minimal/rust",

    "tests/basic_cxx_only/rust",
    "tests/basic_cxx_qt/rust",
    "tests/qt_types_standalone/rust",
]

[workspace.package]
edition = "2021"
license = "MIT OR Apache-2.0"
repository = "https://github.com/KDAB/cxx-qt/"
version = "0.5.3"

# Note a version needs to be specified on dependencies of packages
# we publish, otherwise crates.io complains as it doesn't know the version.
[workspace.dependencies]
cxx-qt = { path = "crates/cxx-qt" }
cxx-qt-macro = { path = "crates/cxx-qt-macro" }
cxx-qt-build = { path = "crates/cxx-qt-build" }
cxx-qt-gen = { path = "crates/cxx-qt-gen", version = "0.5.3" }
cxx-qt-lib = { path = "crates/cxx-qt-lib" }
cxx-qt-lib-headers = { path = "crates/cxx-qt-lib-headers", version = "0.5.3" }
qt-build-utils = { path = "crates/qt-build-utils", version = "0.5.3" }

# Ensure that the example comments are kept in sync
# examples/cargo_without_cmake/Cargo.toml
# examples/qml_minimal/rust/Cargo.toml
cxx = "1.0.95"
cxx-build = { version = "1.0.95", features = [ "parallel" ] }
cxx-gen = "0.7.95"
convert_case = "0.6"
proc-macro2 = "1.0"
syn = { version = "2.0", features = ["extra-traits", "full"] }
quote = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

Version

1.71

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions