Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot link to --crate-type dylib #34909

Open
alexcrichton opened this issue Jul 18, 2016 · 6 comments
Open

Cannot link to --crate-type dylib #34909

alexcrichton opened this issue Jul 18, 2016 · 6 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@alexcrichton
Copy link
Member

alexcrichton commented Jul 18, 2016

cd $(mktemp -d)
cat <<EOF > foo.rs
pub fn foo() {}
EOF
cat <<EOF > bar.rs
extern crate foo;

fn main() {
    foo::foo();
}
EOF
rustc foo.rs --crate-type dylib
rustc bar.rs -L .
error: cannot satisfy dependencies so `std` only shows up once
help: having upstream crates all available in one format will likely make this go away
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 `collections` 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_unicode` 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 `rand` only shows up once
help: having upstream crates all available in one format will likely make this go away
error: cannot satisfy dependencies so `libc` 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 `panic_unwind` only shows up once
help: having upstream crates all available in one format will likely make this go away
error: cannot link together two allocators: alloc_jemalloc and alloc_system
error: aborting due to 10 previous errors

I believe that there's no reason this executable couldn't be created, it should just use all dependencies through the dylib that was created in the previous step.

@alexcrichton alexcrichton added the A-linkage Area: linking into static, shared libraries and binaries label Jul 18, 2016
@MarkSwanson
Copy link

The workaround for us was to define a process where all git repos have zero tests, and all tests are moved into another git repo.

It's critical for us that we can build a Rust DSO.
It would be nice if the test cases for a DSO could be included with the git repo that contains the DSO code.

@alexcrichton
Copy link
Member Author

@MarkSwanson note that the crate type "cdylib" is most appropriate for creating a Rust DSO. If you're trying to use a dylib linking to other Rust dylibs it'll be a nonstop world of pain right now unfortunately, but cdylib should be quite smooth.

@jsgf
Copy link
Contributor

jsgf commented Jan 23, 2017

I believe that there's no reason this executable couldn't be created, it should just use all dependencies through the dylib that was created in the previous step.

If this were a diamond dependency, where D depends on B and C which in turn both depend on A:

  A
 / \
B   C
 \ /
  D

would you also expect this to work?

Currently if you build B and C as dynamic, then they will each link their own static copy of A. When you try to link both into A, it will fail with error: cannot satisfy dependencies so 'A' only shows up once. In principle, if A is stateless then it doesn't matter which version gets used, or even a mix and match. But if A has state (eg lazy_static) then there's a semantic question of whether B and C should each get separate state or share the same state (and if so, how to make sure they do).

The simplest thing is if A is dynamically linked to both B and C, so a single instance is shared between B and C, and there's no need to disambiguate them.

(Edit: swapped A and D to match the answer below)

@alexcrichton
Copy link
Member Author

@jsgf it depends on how all the linkages work out, we've got a test for this in tree for the various versions though. The gist is:

A B C D links?
rlib rlib rlib rlib
dylib rlib rlib rlib
rlib dylib rlib rlib
dylib dylib rlib rlib
rlib rlib dylib rlib
dylib rlib dylib rlib
rlib dylib dylib rlib
dylib dylib dylib rlib
rlib rlib rlib dylib
dylib rlib rlib dylib
rlib dylib rlib dylib
dylib dylib rlib dylib
rlib rlib dylib dylib
dylib rlib dylib dylib
rlib dylib dylib dylib
dylib dylib dylib dylib

The only failure mode is when B/C are both dylibs, statically linking A, so D can't be guaranteed one copy of A. In other cases A is only included once as it's statically linked into only one dylib.

The compiler isn't very smart about this today, though. It has a very simple heuristic where if it doesn't work on the first try it emits an error.

@zicklag
Copy link

zicklag commented Jun 5, 2019

Compiling it like this does work:

> rustc foo.rs --crate-type dylib -C prefer-dynamic
> rustc bar.rs -L .

But then you have to dynamically link to libstd because it won't get statically linked into libfoo.

@jonas-schievink jonas-schievink added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Feb 9, 2020
@clouds56
Copy link

clouds56 commented Sep 7, 2020

Is there any plan for the fix?
I'm creating a large application and now the linkage took more than 2 minutes.

Should I make every module cdylib? That would change all the interface IIRC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants