使用 -fPIC 一致编译 C 代码以获得 rust ffi crate

Hen*_*rik 5 c python gcc ffi rust

我的 rust 项目使用 C lib SuperLU 的 FFI,称为superlu-sys。我的 Rust 代码生成与 PyO3 的 Python 绑定。一旦 python 绑定有一个调用 SuperLU 的函数,我就会在构建时收到以下链接器错误:

relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为 -fPIC 是由 superlu-sys 的 build.rs 强制执行的:

run!(cmd!("make")
    .current_dir(&source.join("SRC"))
    .arg("NOOPTS=-O0 -fPIC -w")
    .arg("CFLAGS=-O3 -DNDEBUG -DPRNTlevel=0 -fPIC -w")
    .arg("DZAUX=")
    .arg("SCAUX=")
    .arg(&format!("SuperLUroot={}", source.display()))
    .arg(&format!(
        "SUPERLULIB={}",
        lib.join("libsuperlu.a").display()
    )));
Run Code Online (Sandbox Code Playgroud)

这是完整的build.rs

在生成一个最小示例时,我发现只要 PyO3 绑定位于构建 SuperLu 的同一个板条箱中,它就可以工作。我的印象是,只有当它是板条箱树的根时,才会遵守 build.rs 中的标志。

如何修改 build.rs 以获得 -fPIC 的一致执行?

这是导致问题的最小示例:lib.rs:

use pyo3::prelude::*;
use std::os::raw::c_int;
use superlu_sys;

#[pyclass]
pub struct Object {}

#[pymethods]
impl Object {
    pub fn test(&self) -> i32 {
        unsafe {
            *superlu_sys::intMalloc(1 as c_int)
        }
    }
}

#[allow(unused)]
#[pymodule]
fn bind_superlu(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_class::<Object>()?;
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

货物.toml:

[package]
name = "bind_superlu"
version = "0.1.0"
edition = "2021"

[lib]
name = "ress"
crate-type = ["cdylib"]

[dependencies]
superlu-sys = "0.3.4"
pyo3 = {version = "0.18.1", features = ["auto-initialize"]}
Run Code Online (Sandbox Code Playgroud)

Hen*_*rik 0

我将 buid.rs 脚本切换为使用 cmake rust crate,而不是调用 make 作为子进程。