Should Cargo.lock be committed when the crate is both a rust library and an executable?
Asked Answered
O

2

32

I 've read https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

If I understand correctly, when I commit Cargo.lock into my crate (which is both a library and an executable)'s repository, and also, publish it to crates.io, downstream crates will ignore it and build it's own snap, right?

Otolith answered 12/7, 2020 at 13:20 Comment(0)
O
8

I found the best practice from the excellent project ripgrep, which split's itself into several crates. For the binary crate in the root, they track Cargo.lock, but for library crates that provide functionality for the application (for example, pcre2), they don't.

Otolith answered 3/9, 2020 at 16:3 Comment(2)
This is misleading because the pcre2 package in ripgrep is actually part of the workspace defined in the root Cargo.toml and a workspace always shares a single Cargo.lock in the root.Therefore
@Otolith please edit the answer. ripgrep uses workspaces and as such uses the same Cargo.lock for the binary as well as the libraries.Zedoary
V
29

Yes, crates that depend on your library will ignore your Cargo.lock. The Cargo FAQ provides more details:

Why do binaries have Cargo.lock in version control, but not libraries?

The purpose of a Cargo.lock is to describe the state of the world at the time of a successful build. It is then used to provide deterministic builds across whatever machine is building the package by ensuring that the exact same dependencies are being compiled.

This property is most desirable from applications and packages which are at the very end of the dependency chain (binaries). As a result, it is recommended that all binaries check in their Cargo.lock.

For libraries the situation is somewhat different. A library is not only used by the library developers, but also any downstream consumers of the library. Users dependent on the library will not inspect the library’s Cargo.lock (even if it exists). This is precisely because a library should not be deterministically recompiled for all users of the library.

If a library ends up being used transitively by several dependencies, it’s likely that just a single copy of the library is desired (based on semver compatibility). If Cargo used all of the dependencies' Cargo.lock files, then multiple copies of the library could be used, and perhaps even a version conflict.

In other words, libraries specify semver requirements for their dependencies but cannot see the full picture. Only end products like binaries have a full picture to decide what versions of dependencies should be used.

Venetis answered 19/9, 2020 at 10:44 Comment(0)
O
8

I found the best practice from the excellent project ripgrep, which split's itself into several crates. For the binary crate in the root, they track Cargo.lock, but for library crates that provide functionality for the application (for example, pcre2), they don't.

Otolith answered 3/9, 2020 at 16:3 Comment(2)
This is misleading because the pcre2 package in ripgrep is actually part of the workspace defined in the root Cargo.toml and a workspace always shares a single Cargo.lock in the root.Therefore
@Otolith please edit the answer. ripgrep uses workspaces and as such uses the same Cargo.lock for the binary as well as the libraries.Zedoary

© 2022 - 2024 — McMap. All rights reserved.