Python setuptools源码构建安装咨询及bpy模块跨平台实现问题
First off, great job getting the Windows build working—packaging compiled extensions like bpy cross-platform is no small feat! Let’s break down the key setuptools concepts and options you’ll need to nail the other platforms.
Core Setuptools Paradigms to Wrap Your Head Around
1. Build System vs. Distribution Framework
Setuptools wears two hats: it’s both the tool that compiles/assembles your code into installable artifacts (build system) and the framework that defines how your package is structured and distributed. For your bpy project, the build system side is critical because you’re dealing with pre-compiled binaries (bpy.pyd/bpy.so) rather than pure Python code.
2. pyproject.toml is Non-Negotiable Now
Gone are the days of relying solely on setup.py. Modern setuptools uses pyproject.toml to declare the tools needed to build your package before anything else runs. This ensures that whoever installs your package (including pip) has the right versions of setuptools and wheel upfront. Here’s a minimal working snippet:
[build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta"
3. Handling Compiled Extensions
Since bpy is a compiled C extension, you won’t be using setuptools.Extension to compile it (you’re pre-building the binaries), but you do need to tell setuptools where to find those binaries and how to install them.
Critical Setuptools Options for Your bpy Project
1. Packaging Pre-Built Binaries
You have two main ways to include your bpy binaries:
package_data: If you structure your project as a Python package (even a dummy one), this lets you include non-Python files in the package directory. Example insetup.py:from setuptools import setup, find_packages setup( name="blenderpy", version="4.0.0", packages=find_packages(), package_data={ "your_dummy_package": ["bpy.pyd", "bpy.so"], }, )data_files: This lets you place the binary directly into the site-packages directory (or another system path) without wrapping it in a package. Just be careful with cross-platform path handling:import site from setuptools import setup setup( # ... other metadata ... data_files=[(site.getsitepackages()[0], ["bpy.pyd"])] )
package_data is generally cleaner, but data_files might be simpler if you want import bpy to work directly without extra paths.
2. Platform-Specific Wheel Building
Since bpy binaries are tied to the OS and architecture, you need to build separate wheels for each platform. Use the --plat-name flag when building to tag the wheel correctly:
# Windows 64-bit python setup.py bdist_wheel --plat-name win_amd64 # Linux (use manylinux tag for portability) python setup.py bdist_wheel --plat-name manylinux_2_17_x86_64 # macOS Intel python setup.py bdist_wheel --plat-name macosx_10_15_x86_64 # macOS Apple Silicon python setup.py bdist_wheel --plat-name macosx_11_0_arm64
These tags ensure pip only installs the correct wheel for the user’s system.
3. Declaring Dependencies
If bpy relies on packages like numpy, use install_requires in setup.py to make pip install them automatically:
setup( # ... other metadata ... install_requires=[ "numpy>=1.21.0", ] )
Cross-Platform Pro Tips
- Embed System Dependencies: On Linux, use
auditwheelto bundle any shared libraries (likelibblender.so) into the wheel so users don’t have to install system packages. On macOS,delocatedoes the same thing. For Windows, make sure all DLLs thatbpy.pyddepends on are included in your package. - Test Across Platforms: Use
toxto automate testing on different Python versions and OSes (via CI tools like GitHub Actions). This catches issues like missing DLLs or path mismatches early. - Python Version Matching: Blender’s
bpyis built against specific Python versions—make sure your wheels are tagged with the correct Python versions (e.g.,cp310for Python 3.10) so pip doesn’t install it on incompatible versions.
Troubleshooting Common Hurdles
- ImportError: If
import bpyfails, check that the binary is in a directory listed insys.path. You can printsys.pathin a Python shell to verify. - Wheel Installation Rejected: Double-check the
plat-nametag—pip will block installation if the wheel’s platform doesn’t match the user’s system. - Missing Dependencies: Use tools like
ldd(Linux) orotool(macOS) to list the shared libraries yourbpy.so/bpy.pydneeds, then make sure those are included in the wheel.
Content of this question originates from stack exchange, asked by user6767685

