问题描述
我想使用 Rust 文件 main.rs
来绑定链接动态库(例如 src/c_ffi/myharfbuzz.c
和 hb.h
)的 C 文件 hb-ot.h
。当我用 cargo run
编译它时,它显示错误:
/usr/bin/ld: .../target/debug/build/uahji2-109ed7d174e31932/out/libmyharfbuzz.a(myharfbuzz.o): in function `example':
.../src/c_ffi/myharfbuzz.c:18: undefined reference to `hb_blob_create_from_file'
/usr/bin/ld: .../src/c_ffi/myharfbuzz.c:19: undefined reference to `hb_face_create'
/usr/bin/ld: .../src/c_ffi/myharfbuzz.c:21: undefined reference to `hb_ot_var_get_axis_count'
/usr/bin/ld: .../src/c_ffi/myharfbuzz.c:22: undefined reference to `hb_ot_var_get_axis_infos'
好像ld
找不到动态库hb.h
这是我的文件:
src/main.rs
use std::ffi::CString;
use std::os::raw::c_char;
#[link(name = "myharfbuzz")]
extern "C" {
fn example(s: *const std::os::raw::c_char,a: i32,b: i32);
}
fn main() {
let prompt = CString::new("Rust").unwrap();
unsafe {
example(prompt.as_ptr(),7,11);
}
}
src/c_ffi/myharfbuzz.c
#include <stdint.h>
#include <stdio.h>
#include <hb.h>
#include <hb-ot.h>
#include <stdint.h>
void example(int32_t a,int32_t b){
printf("%d + %d = %d\n",a,b,a + b);
char *filename = "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc";
printf("%s",filename);
hb_blob_t *blob = hb_blob_create_from_file(filename);
hb_face_t *face = hb_face_create(blob,0);
hb_ot_var_axis_info_t *axes_array;
int axes = hb_ot_var_get_axis_count(face);
hb_ot_var_get_axis_infos(face,&axes,axes_array);
printf("%d",axes_array);
}
在我的 build.rs
中设置了包含路径,但 ld
发出了链接错误:
use std::env;
use std::path::Path;
extern crate pkg_config;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
println!("OUT_DIR = {:?}",out_dir);
let harfbuzz_config = pkg_config::Config::new().probe("harfbuzz").unwrap();
println!("{:?}",harfbuzz_config);
let linked_path = harfbuzz_config.link_paths[0].clone();
let mut builder = cc::Build::new();
builder
.files(&["src/c_ffi/myharfbuzz.c"])
.includes(harfbuzz_config.include_paths)
.includes(harfbuzz_config.link_paths)
.flag(&format!("-lharfbuzz"))
.compile(&format!("myharfbuzz"));
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-link-search=native={:?}",linked_path);
println!("cargo:rustc-link-search=native={}",out_dir);
println!("cargo:rustc-link-lib=static=myharfbuzz");
}
解决方法
使用 #[link]
指令链接不太可能起作用,因为 Rust 不会努力搜索给定库的安装位置。
为了与 C/system 依赖项链接,您应该使用 sys crates。有harfbuzz-sys。