Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choosing shared or static library with Cargo

I am attempting to modify Racer to emit a shared library instead of an rlib.

To do this, I added crate-type = ["dylib"] to the [lib] section of the Cargo manifest, then ran cargo build --lib. This worked great, and libracer.so was emitted.

Unfortunately, now I could not build the Racer binary, which depends on a static version of the library. Running cargo build complains:

   Compiling racer v1.0.0 (file:///home/georgev/dotfiles/vim/bundle/racer)
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 `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 `rand` only shows up once
help: having upstream crates all available in one format will likely make this go away
error: aborting due to 7 previous errors
Could not compile `racer`.

I changed the crate-type to ["dylib", "bin"], which allowed the compilation to succeed. However, cargo build --lib will not emit a shared library anymore (only an rlib).

How can I specify which type of library I would like to build, while still allowing said library to be built statically for inclusion in an executable?

like image 566
George Hilliard Avatar asked Aug 12 '15 22:08

George Hilliard


People also ask

When use static library vs shared library?

Shared libraries are added during linking process when executable file and libraries are added to the memory. Static libraries are much bigger in size, because external programs are built in the executable file.

What are the advantages of static library over shared library?

For static libraries recompilation is required if any changes were applied to external files. On other hand for Shared libraries there is no need to recompile the executable. Static libraries take longer to execute, because loading into the memory happens every time while executing.

When should I use static library?

If you have a lot of files, multiple copies of a static library means an increase in the executable file's size. If, however, the benefits of execution time outweigh the need to save space, the static library is the way to go.

Why do we need static library?

Static libraries increase the size of the code in your binary. They're always loaded and whatever version of the code you compiled with is the version of the code that will run. Dynamic libraries are stored and versioned separately.


1 Answers

bin is not a valid crate-type value. The valid values are rlib, lib, staticlib, and dylib. Changing the crate type to

crate-type = ["dylib", "rlib"]

will cause the behavior you're after.

The reason that only an rlib is emitted with ["dylib", "bin"] is because there is currently a Cargo bug that causes invalid values for crate-type to only produce an rlib. I've filed a pull request to fix the issue.

like image 111
George Hilliard Avatar answered Oct 03 '22 11:10

George Hilliard