#1493

cxx-qt-build: panics writing .qmlls.ini into a read-only dependency checkout

Openjavagabaopened 1mo ago

What happens

CxxQtBuilder writes a .qmlls.ini into the manifest directory of every crate that declares a QML module, dependencies included. When that directory is read-only, the build script panics:

thread 'main' panicked at .../cxx-qt-build-0.10.0/src/lib.rs:1038:34:
Could not create qmlls.ini file: "/cargo/git/checkouts/<crate>-<hash>/<rev>/crates/theme/.qmlls.ini"

Where it comes from (crates/cxx-qt-build/src/lib.rs, the same on main today): the file is opened with create_new(true). AlreadyExists is ignored, but any other error, PermissionDenied/ReadOnlyFilesystem included, reaches panic!.

When it hits

A library crate with a QmlModule, used as a git or registry dependency from a cargo home or source tree that is read-only at build time. Setups that do this:

  • sandboxed builds that mount CARGO_HOME read-only after cargo fetch (ours: a container with --network none and a read-only cargo home);
  • vendored sources (cargo vendor) on a read-only checkout;
  • Nix and similar store-based builds.

When the checkout is writable (a normal ~/.cargo), the build succeeds but leaves a .qmlls.ini inside ~/.cargo/git/checkouts/… or ~/.cargo/registry/src/…. That's a build script writing into another package's sources, which Cargo asks build scripts not to do.

Reproduce

  1. Crate lib with CxxQtBuilder::new_qml_module(QmlModule::new("Lib"))…build().export(), pushed to a git repo.
  2. Crate app depending on it: lib = { git = "…", rev = "…" }.
  3. cargo fetch, then chmod -R a-w ~/.cargo/git/checkouts/lib-*, then cargo build: the panic above.

Suggested fix

Write .qmlls.ini only for crates being developed locally. For example, only when the package is not in a git or registry checkout: CARGO_MANIFEST_DIR outside CARGO_HOME, or behind an opt-in on the builder or an env var. Failing that, turn the non-AlreadyExists error into a cargo::warning= instead of a panic, since .qmlls.ini is tooling support, not something the build needs.

Workaround meanwhile: commit a .qmlls.ini in the library crate's directory. The AlreadyExists branch then skips the write.

Seen with cxx-qt-build 0.10.0, Qt 6.11.2, Rust 1.98.1, on Arch Linux.

Activity

1
ahayzen-kdab1mo ago

Pushed a fix #1494 which only warns instead of failing if it could not open the file for writing.