Cargo build error: cannot satisfy dependencies so only shows up once (dylib)

I'm encountering a frustrating issue while trying to build my Rust project that uses a dynamic library (dylib). I keep getting the error message: 'cannot satisfy dependencies so engine only shows up once', and 'engine was unavailable as a static crate, preventing fully static linking'.

Engine

Cargo.toml


[package]
name = "engine"
version = "0.1.0"
edition = "2024"

[dependencies]
mlua = {version = "*", features = ["lua54", "vendored"]}

[lib]

crate-type = ["dylib"]

lib.rs


use mlua::*;
use std::fs;
use std::env;

pub fn run() -> Result<()> {
    let exe_path = env::current_exe().expect("Failed to get current exe path");
    let exe_dir = exe_path.parent().expect("Failed to get exe directory");
    let lua_path = exe_dir.join("main.lua"); // ไฟล์ main.lua

    let lua_code = fs::read_to_string(&lua_path)
        .expect("Failed to read main.lua");

    let lua = Lua::new();

    lua.load(&lua_code).exec()?;

    println!("Hello from engine");

    Ok(())
}

Editor

Cargo.toml

[package]
name = "editor"
version = "0.1.0"
edition = "2024"

[dependencies]
engine = {path = "../engine"}

main.rs

use engine::run;

fn main() {
    match run() {
        Ok(_) => println!("Parsing successful!"),
        Err(e) => eprintln!("Parsing error: {}", e),
    }

    println!("Hello from editor!");
}

Output

PS C:\Users\{}\Documents\Rust\Demo> cargo run dev
   Compiling engine v0.1.0 (C:\Users\compl\Documents\Rust\Demo\engine)
   Compiling editor v0.1.0 (C:\Users\compl\Documents\Rust\Demo\editor)
error: cannot satisfy dependencies so `engine` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away
  = note: `engine` was unavailable as a static crate, preventing fully static linking     

error: cannot satisfy dependencies so `core` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `compiler_builtins` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `rustc_std_workspace_core` only shows up once       
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `alloc` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `unwind` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `cfg_if` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `hashbrown` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `rustc_std_workspace_alloc` only shows up once      
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `std_detect` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `rustc_demangle` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `windows_targets` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: cannot satisfy dependencies so `panic_unwind` only shows up once
  |
  = help: having upstream crates all available in one format will likely make this go away

error: could not compile `editor` (bin "editor") due to 13 previous errors

which version of the toolchain are you using? I'm on nightly, and your code builds successfully on my machine.

maybe related to #90539, possibly a regression?

btw, do you really mean to use dylib?

dylib is only useful in very specific scenarios, most of the time, you probably want either the default lib crate type, if your crate is used as dependency for other rust crates; or the cdylib crate type, if your crate is also meant to be loaded at runtime, e.g. with dlopen.

I changed my toolchain to nightly, but the issue persists. I just need a .dll for my project—I don’t want to bundle everything into an .exe.

can you give me your project files that's working? I want to try maybe issue is my setup

so you are on Windows, maybe the windows linker works differently, or some of the dependencies had different build instructions for Windows and Linux.

I don't have a Windows environment at the moment to test though. someone who's familiar with the Windows toolchain should know better.

at mean time, you may try to work around this issue by forcing dynamic link to the standard library. just keep in mind, this will tie your program to a specific version of rust.

you can do so by setting the prefer-dynamic codegen option for rustc, either via the RUSTFLAGS environment variable:

> rem with env variable
> set RUSTFLAGS="-C prefer-dynamic"
> cargo build

or a cargo configuration:

# .cargo/config.toml
[build]
rustflags = "-C prefer-dynamic"

I literally just copied the code from your post, there's nothing special here.

Why? Rust strongly prefers statically linking over dynamically linking. The only reasons you may want to use rust dylibs (as opposed to cdylibs exporting only a C ABI) with rust would be if you want to allow plugins that will be loaded by your executable to link against your library. And to save disk space. The latter however only applies if you have a ton of executables. Using dylibs prevents removing dead code, so a dylib is almost certainly going to be a fair bit larger than the entire executable if you statically link. Rust dylibs don't help with updating as rust doesn't have a stable ABI and requires all dependent dylibs and executables to be recompiled when a rust dylib changes.

As for the reason why -Cprefer-dynamic helps: This prevents the dylib from statically linking libstd. When you try to link against the dylib rustc will notice that it can't statically link against everything and as such attempts to dynamically link everything that can be dynamically linked. When it does so however it will end up with two copies of libstd. One in the form of std.dll and one statically linked into your dylib. This is not allowed, so rustc emits an error. It is not capable of figuring out that it can change the linkage of libstd to IncludedFromDylib to only use the copy that was statically linked into the dylib.

Edit: Looks like you opened an issue at dylib crate fails to compile · Issue #138339 · rust-lang/rust · GitHub. In the future please reference discussion in one place when posting something in another place again to avoid duplicate work.