Mutual dependencies and linking in Cargo

I have a question about compiling / linking using Cargo. Looking at the diagrams below, say a library (A) depends on two libraries (B and C) that have a mutual dependency (D) with a static (but mutable) variable. Under Outcome 1, lib B and lib C always see the same state for the global in lib D. Under Outcome 2, lib B and lib C link with separate copies of lib D, and so the static variable can have two different values.

My question is under what circumstances will compiling with Cargo result in Outcome 1 vs Outcome 2? Is there a way to force Cargo to output the non-default outcome?

Some considerations:

  • What if lib B requires v1 of lib D and lib C requires v2 of lib D?
  • What if I compile lib B and lib C manually (at which point Cargo would not know about the mutual dependency) and then subsequently compile lib A?
  • What about static and dynamic linking? E.g. what if lib B links to lib D dynamically but lib C links to lib D statically?
  • I'm running Linux, so I'm mostly interested in that perspective, but are other operating systems different?

Outcome 1:

  B
 / \
A   D
 \ /
  C

Outcome 2:

  B--D
 /
A
 \
  C--D

Cargo will choose outcome 1 if the version numbers in B and C's dependencies are semver compatible, otherwise outcome 2.

3 Likes

Thanks for the link--that's quite helpful and addresses the main point.