Problem linking 2 C libraries into Rust codebase


#1

Hi all,

I am trying to use rust with two C libraries but I am stuck at the very last step of the compilation pipeline, the linking.

I start generating the archive file of the two libraries using gcc:

gcc::Config::new()
    .file("src/CDeps/Redis/redismodule.c")
    .include("src/CDeps/Redis/include")
    .out_dir(&Path::new("target/"))
    .compile("libredismodule.a");

gcc::Config::new()
    .file("src/CDeps/SQLite/sqlite3.c")
    .include("src/CDeps/SQLite/include")
    .out_dir(&Path::new("target/"))
    .compile("libsqlite3.a");

At this point I move one generating the binds from both SQLite and Redis:

let bindings = bindgen::Builder::default()
    .no_unstable_rust()
    .parse_callbacks(Box::new(SqliteTypeChooser))
    .header("wrapper.h")
    .generate()
    .expect("Unable to generate bindings");

let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings.write_to_file(out_path.join("bindings.rs"))
    .expect("Couldn't write bindings!");

Where:

$ cat wrapper.h 
#include "src/CDeps/SQLite/include/sqlite3.h"
#include "src/CDeps/Redis/include/redismodule.h"

Unfortunately this whole process doesn’t finish correctly:

simo@simo:~/rediSQL-rst$ cargo build -v 
   Compiling rediSQL-rst v0.1.0 (file:///home/simo/rediSQL-rst)
     Running `rustc --crate-name rediSQL_rst src/main.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=6d9320ab56bfd8ec -C extra-filename=-6d9320ab56bfd8ec --out-dir /home/simo/rediSQL-rst/target/debug/deps -L dependency=/home/simo/rediSQL-rst/target/debug/deps --extern libsqlite3_sys=/home/simo/rediSQL-rst/target/debug/deps/liblibsqlite3_sys-b8e4928ec755e1ae.rlib --extern rusqlite=/home/simo/rediSQL-rst/target/debug/deps/librusqlite-f341497b58e69856.rlib --extern rediSQL_rst=/home/simo/rediSQL-rst/target/debug/deps/librediSQL_rst-06e2198da6112b67.rlib -L native=/home/simo/rediSQL-rst/target/debug/build/rediSQL-rst-196441589fefb3b1/out -L native=/home/simo/rediSQL-rst/target/debug/build/rediSQL-rst-196441589fefb3b1/out`

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/simo/rediSQL-rst/target/debug/deps/rediSQL_rst-6d9320ab56bfd8ec.0.o" "-o" "/home/simo/rediSQL-rst/target/debug/deps/rediSQL_rst-6d9320ab56bfd8ec" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/home/simo/rediSQL-rst/target/debug/deps" "-L" "/home/simo/rediSQL-rst/target/debug/build/rediSQL-rst-196441589fefb3b1/out" "-L" "/home/simo/rediSQL-rst/target/debug/build/rediSQL-rst-196441589fefb3b1/out" "-L" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-13f36e2630c2d79b.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-a2ef7979b4b3e1d5.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-d22754c8c52de3a1.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_unicode-1cc5fcd37568ebc4.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-3b9d178f1de89528.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-93bb403c9fc56f72.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-c53f99154bf815c4.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_jemalloc-f1bb04f5989dcb98.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-739908a2e215dd88.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-3f4289353c600297.rlib" "/home/simo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-07bfb3bcb2a51da0.rlib" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "gcc_s" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "util"
  = note: /home/simo/rediSQL-rst/target/debug/deps/rediSQL_rst-6d9320ab56bfd8ec.0.o: In function `rediSQL_rst::{{impl}}::drop':
          /home/simo/rediSQL-rst/src/main.rs:32: undefined reference to `sqlite3_finalize'
          /home/simo/rediSQL-rst/src/main.rs:40: undefined reference to `sqlite3_close'
          /home/simo/rediSQL-rst/target/debug/deps/rediSQL_rst-6d9320ab56bfd8ec.0.o: In function `rediSQL_rst::create_statement':
          /home/simo/rediSQL-rst/src/main.rs:51: undefined reference to `sqlite3_prepare_v2'
          /home/simo/rediSQL-rst/target/debug/deps/rediSQL_rst-6d9320ab56bfd8ec.0.o: In function `rediSQL_rst::open_connection':
          /home/simo/rediSQL-rst/src/main.rs:70: undefined reference to `sqlite3_open_v2'
          /home/simo/rediSQL-rst/target/debug/deps/rediSQL_rst-6d9320ab56bfd8ec.0.o: In function `rediSQL_rst::execute_statement':
          /home/simo/rediSQL-rst/src/main.rs:97: undefined reference to `sqlite3_step'
          /home/simo/rediSQL-rst/src/main.rs:101: undefined reference to `sqlite3_column_count'
          /home/simo/rediSQL-rst/src/main.rs:104: undefined reference to `sqlite3_column_type'
          /home/simo/rediSQL-rst/target/debug/deps/rediSQL_rst-6d9320ab56bfd8ec.0.o: In function `rediSQL_rst::{{impl}}::next':
          /home/simo/rediSQL-rst/src/main.rs:191: undefined reference to `sqlite3_step'
          /home/simo/rediSQL-rst/src/main.rs:165: undefined reference to `sqlite3_column_int'
          /home/simo/rediSQL-rst/src/main.rs:169: undefined reference to `sqlite3_column_double'
          /home/simo/rediSQL-rst/src/main.rs:175: undefined reference to `sqlite3_column_text'
          /home/simo/rediSQL-rst/src/main.rs:182: undefined reference to `sqlite3_column_blob'
          collect2: error: ld returned 1 exit status
          

error: aborting due to previous error

error: Could not compile `rediSQL-rst`.

Caused by:
  process didn't exit successfully: `rustc --crate-name rediSQL_rst src/main.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=6d9320ab56bfd8ec -C extra-filename=-6d9320ab56bfd8ec --out-dir /home/simo/rediSQL-rst/target/debug/deps -L dependency=/home/simo/rediSQL-rst/target/debug/deps --extern libsqlite3_sys=/home/simo/rediSQL-rst/target/debug/deps/liblibsqlite3_sys-b8e4928ec755e1ae.rlib --extern rusqlite=/home/simo/rediSQL-rst/target/debug/deps/librusqlite-f341497b58e69856.rlib --extern rediSQL_rst=/home/simo/rediSQL-rst/target/debug/deps/librediSQL_rst-06e2198da6112b67.rlib -L native=/home/simo/rediSQL-rst/target/debug/build/rediSQL-rst-196441589fefb3b1/out -L native=/home/simo/rediSQL-rst/target/debug/build/rediSQL-rst-196441589fefb3b1/out` (exit code: 101)

It is clear that I am missing something, but I can’t quite figure out what I am missing, it is definitely a flag passed to the linker but I have tried several combination and none worked.

Do you see the problem?

For reference the whole code is here: https://github.com/siscia/rediSQL-rs


#2

In your build.rs you should point out rustc/cargo to link resulted binaries,
for example this is how I link skia library to my code (from build.rs ):

fn main() {
...
    println!("cargo:rustc-link-search=native={}", dst.join("lib").to_str().unwrap());
    println!("cargo:rustc-link-lib=static=skia");
...
}

another variant (I suppose it is possible):
you can point out bindgen to generate link instructions,
similar to example from the book:

#[link(name = "extlib")]
extern {
   fn register_callback(cb: extern fn(i32)) -> i32;
   fn trigger_callback();
}

#3

Quite.

The problem was that I also had a lib.rs files and it was having some problem with that.

I removed that file and I now compile without problems.

Your suggestion was completely right, however I am using GCC (the crate) and it was setting those flags by itself.

Thanks,

Simone