最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

macos - How to link static library to PyO3 package generated by maturin? - Stack Overflow

programmeradmin7浏览0评论

I am trying to make Python bindings for a library written in C, using Rust + maturin as glue layer. However, the Python .so extension does not have my library (let's call it foo) linked and therefore it fails to load.

My target is MacOS, in case that matters.

I have a Cargo project with the following structure:

src/lib.rs  # contains PyO3 bindings for my foo library
build.rs    # build script for my wrapper crate

Contents of build.rs:

use cmake::Config;

const FOO_DIR: &str = "vendor/foo";

fn main() {
    let foolib = Config::new(FOO_DIR)
        .define("BUILD_SHARED_LIBS", "ON")
        .build();

    println!("cargo:rustc-link-search=native={}/build", foolib.display());
    println!("cargo:rustc-link-lib=dylib=foo");
}

My Cargo.toml contains nothing special:

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

[dependencies]
pyo3 = { version = "0.24.0", features = ["extension-module"] }

[build-dependencies]
cmake = "0.1.54"
cc = "1.2.17"

What I see is that when I run

maturin develop

I get a Python extension package named foo_python, but it fails to load with the following message:

    from foo_python import FooFunction
venv/lib/python3.12/site-packages/foo_python/__init__.py:1: in <module>
    from .foo_python import *
E   ImportError: dlopen(...venv/lib/python3.12/site-packages/foo_python/foo_python.cpython-312-darwin.so, 0x0002): symbol not found in flat namespace '_foo_SomeFunction'

This _foo_SomeFunction is defined in libfoo.dylib that is generated by CMake somewhere at target/debug/build/foo_python-.../out/lib/libfoo.dylib

When I run otool on this .so file, I don't see it mentioning my libfoo.dylib:

otool -L ./venv/lib/python3.12/site-packages/foo_python/foo_python.cpython-312-darwin.so
./venv/lib/python3.12/site-packages/foo_python/foo_python.cpython-312-darwin.so:
    @rpath/foo_python.cpython-312-darwin.so (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)

and running nm on this file shows that the symbol is indeed undefined:

nm ./venv/lib/python3.12/site-packages/foo_python/foo_python.cpython-312-darwin.so | grep SomeFunction
                U _foo_SomeFunction

What I observe is that cargo build or maturin develop fails if I omit the cargo:rustc-link-* directives in build.rs or change the library name, so it does something with these, but it fails to link the foo library into the Python extension.

The same behaviour is seen when I try to link the library statically using

println!("cargo:rustc-link-lib=static=foo");

in my build.rs.

发布评论

评论列表(0)

  1. 暂无评论