How to link against Rust crate from integration tests in 'tests' folder when building static library?
Asked Answered
R

1

18

I'm building a library in Rust that will be called from C/C++ code. Cargo.toml is configured to output the crate as a static library:

[lib]
crate-type = ["staticlib"]

I have a test in tests/integration_test.rs:

extern crate mylibrary;

#[test]
fn it_works() {
    hello_world();   // Defined in 'mylibrary'.
}

However, when running the tests with cargo test, the following error is output:

error[E0463]: can't find crate for `mylibrary`
 --> tests\integration_test.rs:1:1
  |
1 | extern crate mylibrary;
  | ^^^^^^^^^^^^^^^^^^^^^ can't find crate

If I remove the staticlib config line from Cargo.toml then the tests build and run fine.

Two possibilities occur to me:

  1. Do I need to configure the building of the crate when running tests differently (i.e. so that it doesn't build a static library)?

  2. Do I need to link the static library crate differently in the test (i.e. as if it were a system C library)?

It's not clear from the docs what the correct way to configure this setup is, or how to go about it.

Rountree answered 20/12, 2016 at 11:44 Comment(2)
I'd suggest that this isn't really the right organization. An integration test is supposed to use your code as a real user would. However, your real user isn't going to be Rust code. I'd advocate that you reorganize your code to have one crate that is pure Rust and contains the majority of your business logic. Integration tests of that would work like you are trying. Then, create a second crate that uses the first, exposes the FFI bindings that you want, and is built as staticlib. Integration tests for that should be written in C and basically ensure that the proper bindings exist.Oppugn
Potentially relevant: A static system library will be produced. This is different from other library outputs in that the Rust compiler will never attempt to link to staticlib outputs.Oppugn
P
1
[lib]    
crate-type = ["lib", "staticlib"]

Just use this then you will have no worries.

https://doc.rust-lang.org/reference/linkage.html says that "these outputs are stackable in the sense that if multiple are specified, then the compiler will produce each form of output without having to recompile."

Predisposition answered 3/8, 2023 at 8:7 Comment(1)
I think this is the correct answer. In the section linked above: > A static system library will be produced. This is different from other library outputs in that the compiler will never attempt to link to staticlib outputs. Which is why integration tests, which are external to your crate, can't link with it.Piapiacenza

© 2022 - 2024 — McMap. All rights reserved.