Cargo: How to build external static lib only when testing?


#1

Hello,

I am trying to use cargo to test and build a lib. My tests resides in tests/ sub folders. Some of my tests need to calls external c function which resides in file say foo.c . What I want is that before cargo build/run my test , it should first build libfoo.a from foo.c and link against these tests.

I can use build = “build.rs” for building external libs to be linked with main lib, but I do not know how to build external libs to be linked with tests.

Thx


#2

I think I have figured out how to do this , hope following steps will help some one.

Say I am building a lib crate called “system” and I have a test file check.rs in tests sub folder i.e tests/check.rs. This check.rs make use of external c functions which resides in “foo,c” . So now when test check.rs is built I want it to link with libfoo.a

Add link attribute to check.rs
#[link = "foo" , kind = "static"]

Create build.rs as given in http://doc.crates.io/build-script.html , except for last line and paths

use std::process::Command;
use std::env;
use std::path::Path;

fn main () {
  let out_dir = env::var("OUT_DIR").unwrap();
  
  Command::new("gcc").args(&["tests/foo.c", "-c", "-fPIC", "-o"])
    .arg(&format!("{}/foo.o", out_dir))
    .status().unwrap();
  
  Command::new("ar").args(&["crus", "libfoo.a", "foo.o"])
    .current_dir(&Path::new(&out_dir))
    .status().unwrap();

  println!("cargo:rustc-link-search=native={}", out_dir);
  //println!("cargo:rustc-link-lib=static=hello");

}

Add build.rs to Cargo.toml

[package]
name = "..."
build = "build.rs"

Now cargo build will not link against libfoo.a , but for cargo test , the test files which include the #[link = “foo” , kind = “static”] will now link against libfoo.a