首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rust bindgen找不到特定于平台的库?

Rust bindgen找不到特定于平台的库?
EN

Stack Overflow用户
提问于 2020-09-28 04:04:23
回答 1查看 367关注 0票数 0

我正在尝试将我的简单应用程序从C移植到Rust。它只在我的Mac上运行,只在Mac上有一个库。以下是C代码中失败部分的简化版本

代码语言:javascript
复制
// myLog.h
#include <os/log.h> // macOS header

void debug(const char *str);

//************************************

// myLog.c
#include "myLog.h"

void debug(const char* str) {
    // call the macOS log function
    os_log_debug(OS_LOG_DEFAULT, "%{public}s", str);
}

只需调用gcc debug.c即可编译此代码,并且运行良好。

然后,我将.h和.c添加到我的rust项目中,并指定如下所示的bindgen

代码语言:javascript
复制
fn main() {
    println!("cargo:rerun-if-changed=myLog.h");

    let bindings = bindgen::Builder::default()
        .header("myLog.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()
        .expect("Unable to build bindgen");
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("mylog_bindings.rs"))
        .expect("Couldn't write bindings!");
}

并且main函数没有其他函数,但现在测试日志:

代码语言:javascript
复制
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

use std::ffi::CString;
include!(concat!(env!("OUT_DIR"), "/mylog_bindings.rs"));

fn main() {
    let log_infomation = CString::new("Log from Rust").expect("Failed to create c string");
    let c_pointer = log_infomation.as_ptr();
    unsafe {
        debug(c_pointer);
    }
}

程序失败,出现以下错误:

代码语言:javascript
复制
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-m64" "-arch" "x86_64" "-L" ......
  = note: Undefined symbols for architecture x86_64:
            "_debug", referenced from:
                bindgen_test::main::hc0e5702b90adf92c in bindgen_test.3ccmhz8adio5obzw.rcgu.o
          ld: symbol(s) not found for architecture x86_64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)
          

error: aborting due to previous error; 2 warnings emitted

error: could not compile `bindgen_test`.

我不确定这失败的原因,但我发现如果我删除整个不安全的块(不调用函数),编译就会工作。但是谁能给我解释一下我做错了什么?我需要添加什么才能编译它吗?

非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-28 04:32:09

问题是您在任何地方都没有包含myLog.c文件,只包含了myLog.h头文件。这就是bindgen所做的:它将C头文件转换为Rust代码,但它本身并不编译C代码。

为此,您需要cc板条箱。您必须在build.rs文件中同时使用ccbindgen

代码语言:javascript
复制
use std::env;
use std::path::PathBuf;

fn main() {
    println!("cargo:rerun-if-changed=myLog.h");
    println!("cargo:rerun-if-changed=myLog.c");  // new line here!!

    let bindings = bindgen::Builder::default()
        .header("myLog.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()
        .expect("Unable to build bindgen");
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("mylog_bindings.rs"))
        .expect("Couldn't write bindings!");

    //Compile and link a static library named `myLog`:
    cc::Build::new()
        .file("myLog.c")
        .compile("myLog");
}

不要忘记将cc机箱添加到您的build-dependencies中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64092805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档