Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I compile a C++ library statically with Bazel to use in Rust?

My goal is to get a .a static library on linux from the MediaPipe project, which is built with Bazel. To my knowledge, there is no bazel rule for doing so. I really don't want to integrate with Bazel - I want it to produce what I need, and use it in other non-Bazel-managed things.

I'm trying to integrate MediaPipe (https://github.com/google/mediapipe) which uses the google build system Bazel, with a personal project written in Rust. I'm trying to figure out how to get a static library (.a) out of the bazel build system. I've searched around and found people saying they've tried it and done it, but nobody has posted what they've done.

My attempt thus far has been to make bazel verbose (run with -s) and then see what commands it passes to compiling the final binary so I could take it and modify it to build a static library. I've tried parsing the compiler command args to pick out all the object files (.o) and link them with ar like so ar rcs gpu.a $(grep -E '\.o' bazel-bin/custom/run_gpu-2.params)

That command works, but when I try to link it to Rust with rust fails.

Here's my build.rs

fn main() {
    println!("cargo:rustc-link-search=/home/me/dev/mediapipe");
}

And here's my main

#[link(name = "gpu")]
extern "C" {
    fn square(val: i32) -> i32;
}

fn main() {
    let r = unsafe { square(3) };
    println!("3 squared is {}", r);
}

And here's the error I get:

   Compiling my-mediapipe-project v0.1.0 (/home/me/dev/my-mediapipe-project)
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.1fmokwdndpsbxaxm.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.2j9fb5mr4wpkcnpp.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.3bpsevdikgyu7tj9.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.48fsbok7dmpjlo4o.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.4ezfxccf1xedvrna.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.577bi7s5mtonhdwp.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.qpj0hauia5ocv8m.rcgu.o" "-o" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c" "/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.22pad9p4rf6ea56q.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "/home/me/dev/my-mediapipe-project/target/debug/deps" "-L" "/home/me/dev/mediapipe" "-L" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-lgpu" "-Wl,--start-group" "-Wl,-Bstatic" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-c32b051c3aafd36c.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-eabf8b29c0a244dd.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-5c336cc1b5ec2048.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-c7631f762b1ba6d9.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-db0f6c539591c951.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-32c2dc6fbc292c9c.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-84e9c510dc249620.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-13bc027534de0b4c.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-b3c13ecda1794c6c.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-72dc11de859645e9.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-a78b04f112feb31a.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-29469f6c53ac35f8.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-0eb3c513c640c4a6.rlib" "-Wl,--end-group" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-0b278345638bce90.rlib" "-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: /usr/bin/ld: cannot find -lgpu
          collect2: error: ld returned 1 exit status

Here it is manually line-wrapped:

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/me/.rustup/toolchains
/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/me/dev/my-
mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.1fmokwdndpsbxaxm.rcgu.o" 
"/home/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-
a37e83e58c99436c.2j9fb5mr4wpkcnpp.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug
/deps/rust_whiteboard-a37e83e58c99436c.3bpsevdikgyu7tj9.rcgu.o" "/home/me/dev/my-mediapipe-
project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.48fsbok7dmpjlo4o.rcgu.o" "/home
/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-
a37e83e58c99436c.4ezfxccf1xedvrna.rcgu.o" "/home/me/dev/my-mediapipe-project/target/debug
/deps/rust_whiteboard-a37e83e58c99436c.577bi7s5mtonhdwp.rcgu.o" "/home/me/dev/my-mediapipe-
project/target/debug/deps/rust_whiteboard-a37e83e58c99436c.qpj0hauia5ocv8m.rcgu.o" "-o" "/home
/me/dev/my-mediapipe-project/target/debug/deps/rust_whiteboard-a37e83e58c99436c" "/home/me/dev
/my-mediapipe-project/target/debug/deps/rust_whiteboard-
a37e83e58c99436c.22pad9p4rf6ea56q.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" 
"-nodefaultlibs" "-L" "/home/me/dev/my-mediapipe-project/target/debug/deps" "-L" "/home/me/dev
/mediapipe" "-L" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
/x86_64-unknown-linux-gnu/lib" "-lgpu" "-Wl,--start-group" "-Wl,-Bstatic" "/home/me/.rustup
/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-
c32b051c3aafd36c.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
/x86_64-unknown-linux-gnu/lib/libpanic_unwind-eabf8b29c0a244dd.rlib" "/home/me/.rustup
/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib
/libhashbrown-5c336cc1b5ec2048.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-
gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-
c7631f762b1ba6d9.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
/x86_64-unknown-linux-gnu/lib/libbacktrace-db0f6c539591c951.rlib" "/home/me/.rustup/toolchains
/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-
32c2dc6fbc292c9c.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
/x86_64-unknown-linux-gnu/lib/librustc_demangle-84e9c510dc249620.rlib" "/home/me/.rustup
/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-
13bc027534de0b4c.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
/x86_64-unknown-linux-gnu/lib/libcfg_if-b3c13ecda1794c6c.rlib" "/home/me/.rustup/toolchains
/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-
72dc11de859645e9.rlib" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
/x86_64-unknown-linux-gnu/lib/liballoc-a78b04f112feb31a.rlib" "/home/me/.rustup/toolchains
/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib
/librustc_std_workspace_core-29469f6c53ac35f8.rlib" "/home/me/.rustup/toolchains/stable-x86_64-
unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-0eb3c513c640c4a6.rlib" 
"-Wl,--end-group" "/home/me/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-0b278345638bce90.rlib" "-Wl,-Bdynamic" 
"-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: /usr/bin/ld: cannot find -lgpu
          collect2: error: ld returned 1 exit status

I'm on Arch Linux if it helps. MediaPipe does compile correctly for me - I had to modify a few definitions relating to OpenCV to get it to work properly, I found that documented in a GitHub issue.

I really don't want to have to manage my Rust code through Bazel. I'd really like to just be able to produce a static binary, and then consume it through Rust/Cargo.

I'd really love it if there was a cross platform solution for this too...

like image 277
Sam Sieber Avatar asked Mar 24 '20 02:03

Sam Sieber


Video Answer


1 Answers

When you build a cc_library in Bazel it will compile a both a target_name.{a|so}, with other shared lib extensions on windows/mac, though that doesn't seem to be important in this case. e.g. running;

$ bazel build //mediapipe/gpu:gpu_service
INFO: Analyzed target //mediapipe/gpu:gpu_service (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //mediapipe/gpu:gpu_service up-to-date:
  bazel-bin/mediapipe/gpu/libgpu_service.a
  bazel-bin/mediapipe/gpu/libgpu_service.so
INFO: Elapsed time: 0.102s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action

NOTE: Tested on GitHub codespaces default environment i.e. Ubuntu Linux.

Note here that the path to the library that you built is printed to stdout. i.e. bazel-bin/mediapipe/gpu/libgpu_service.a. You can copy this anywhere you need to integrate that into your cargo build.

like image 54
silvergasp Avatar answered Oct 14 '22 18:10

silvergasp