[Python] Cython can't link external library

Discussão em 'Python' iniciado por Stack, Março 11, 2025.

  1. Stack

    Stack Membro Participativo

    Part of a Python library I'm working on is written in Cython. I need to use the LinBox C++ library (which depends on the Givaro library). Just to test, I've written a small C++ function that eats Cython-accessible data, does something with Givaro, and returns Cython-accessible data. Everything compiles correctly, but when I run the test, I get the following error:

    ImportError: dlopen(<path/to/cython>/matrices.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace '__ZN6GivarolsERSoRKNS_7IntegerE'

    Running nm on matrices.cpython-311-darwin.so, it looks like the symbol is undefined, because I get U __ZN6GivarolsERSoRKNS_7IntegerE. Here's my MWE:

    // fastcomputation.cpp

    #include <vector>
    #include <givaro/gfq.h>

    using namespace std;

    int kernel(vector<int> A, int rank, int nullity, double field) {
    Givaro::GFqDom<int> F(field);
    return 1;
    }


    // fastcomputation.hpp

    #include <vector>

    int kernel(std::vector<int> A, int rank, int nullity, double field);


    # matrices.pyx

    # distutils: language = c++

    from libcpp.vector cimport vector

    cdef extern from "fastcomputation.hpp":
    int kernel(vector[int] A, int rank, int nullity, double field)

    cpdef pkernel(vector[int] A, int rank, int nullity, double field):
    print(kernel(A, rank, nullity, field))


    # setup.py


    from setuptools import setup, Extension
    from Cython.Build import cythonize
    import os
    import numpy

    os.environ["CC"] = "gcc-14"
    os.environ["CXX"] = "g++-14"

    extensions = [
    Extension(
    "*",
    ["<path/to/cython>/*.pyx", "<path/to/cython>/fastcomputation.cpp"],
    include_dirs=[
    numpy.get_include(),
    "<path/to/cython>",
    "/opt/homebrew/Cellar/linbox/include",
    "/opt/homebrew/Cellar/fflas-ffpack/2.5.0/include",
    "/opt/homebrew/Cellar/givaro/4.2.0_1/include",
    "/opt/homebrew/Cellar/gmp/6.3.0/include",
    "/opt/homebrew/Cellar/libomp/20.1.0/include"
    ],
    library_dirs=[
    "/opt/homebrew/Cellar/linbox/lib",
    "/opt/homebrew/Cellar/fflas-ffpack/2.5.0/lib",
    "/opt/homebrew/Cellar/givaro/4.2.0_1/lib",
    "/opt/homebrew/Cellar/gmp/6.3.0/lib",
    "/opt/homebrew/Cellar/libomp/20.1.0/lib"
    ],
    runtime_library_dirs=[
    "/opt/homebrew/Cellar/linbox/lib",
    "/opt/homebrew/Cellar/fflas-ffpack/2.5.0/lib",
    "/opt/homebrew/Cellar/givaro/4.2.0_1/lib",
    "/opt/homebrew/Cellar/gmp/6.3.0/lib",
    "/opt/homebrew/Cellar/libomp/20.1.0/lib"
    ],
    libraries=["linbox", "givaro"],
    language="c++"
    )
    ]

    setup(
    ext_modules=cythonize(extensions, annotate=True, language_level="3")
    )


    I am not an expert (or even that capable) of getting C++ to compile, so it's possible that I've misdiagnosed this and I'm leaving something out completely. The issue is that, without trying to use Givaro, everything compiles and runs, but I need to use Givaro.

    Continue reading...

Compartilhe esta Página