如何修改Cython的setup.py以编译带依赖的多文件C++代码?
Alright, let's break this down for you. First off: you don't need a separate .pyx file for test_B.cpp—not unless you want to directly expose the test_B structure or its functions to your Python code. If test_B is only used internally by test_A, you just need to adjust your existing test_A.pyx and update setup.py to include all your C++ source files.
Step 1: Update your test_A.pyx to declare test_B
Since your test struct in test_A.cpp now uses test_B, you need to tell Cython about the test_B structure. Add an extern declaration for it in your test_A.pyx, pointing to its header file:
# First, declare the test_B struct from its header cdef extern from "test_B.h": cdef cppstruct test_B: float z # Match the member(s) defined in test_B.h # Then declare your original test struct from test_A.cpp cdef extern from "test_A.cpp": cdef cppstruct test: float x test_B y # Cython now recognizes test_B here
Step 2: Modify setup.py to compile all C++ files
The key change here is adding all your C++ source files (test_A.cpp and test_B.cpp) to the sources list of your Extension. This tells distutils to compile these files and link them together with the Cython-generated code. Here's the updated setup.py:
import numpy as np from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize extensions = [ Extension( "test_A", # Include the .pyx file + all your .cpp source files sources=["test_A.pyx", "test_A.cpp", "test_B.cpp"], include_dirs=[np.get_include()], extra_compile_args=["-std=c++11"], language="c++" # Critical for compiling C++ code ) ] setup(ext_modules=cythonize(extensions))
A few important notes:
- If
test_B.his in a subdirectory (not the same folder as your .pyx/cpp files), add that path toinclude_dirsso the compiler can find it. - If
test_B.cppcontains implementations fortest_B's member functions (not just a plain struct), you must include it in thesourceslist—otherwise you'll get linker errors about undefined references. - If later you want to create or manipulate
test_Bobjects directly in Python, you can split it into a separate .pyx file, but that's optional for your current use case.
内容的提问来源于stack exchange,提问作者somebody

