如何通过Setuptools/Conan将C++库纳入Python Wheel包?
Conan+C++库+Setuptools封装打包Wheel方案
一、通过Setuptools拉取Conan库并打包进Wheel
1. 集成Conan依赖拉取逻辑
在Python项目的setup.py中添加Conan调用代码,自动拉取并配置C++库依赖:
import subprocess from setuptools import setup, Extension import os # 调用Conan安装C++依赖 subprocess.run([ "conan", "install", ".", "--output-folder=conan_build", "--build=missing", "-s:b compiler.cppstd=17" # 替换为你的项目C++标准 ], check=True) # 获取Conan生成的编译/链接参数 conan_env = subprocess.check_output([ "conan", "run", ".", "--output-folder=conan_build", "--command=echo $CFLAGS $LDFLAGS" ], text=True, shell=True).strip().split() # 定义Python扩展模块,链接Conan拉取的库 ext_module = Extension( "your_python_module", sources=["src/py_wrapper.cpp"], # 你的Python封装源代码 extra_compile_args=conan_env, extra_link_args=conan_env )
2. 配置库文件打包逻辑
添加自定义安装钩子,将Conan下载的C++库文件复制到Wheel的对应目录:
from setuptools.command.install import install import shutil class CustomInstall(install): def run(self): install.run(self) # 复制库文件到安装目录 lib_src = os.path.join("conan_build", "lib") lib_dst = os.path.join(self.install_lib, "your_python_package", "libs") os.makedirs(lib_dst, exist_ok=True) for fname in os.listdir(lib_src): if fname.endswith((".so", ".dll", ".dylib")): shutil.copy(os.path.join(lib_src, fname), lib_dst) # 完善setup配置 setup( name="your_python_package", version="0.1.0", ext_modules=[ext_module], packages=["your_python_package"], cmdclass={"install": CustomInstall}, # 其他Setuptools配置(如author、description等) )
3. 构建Wheel
执行标准Setuptools命令生成Wheel:
python setup.py bdist_wheel # 或用pip构建(更推荐) pip wheel . --no-deps
二、通过Conan直接生成Wheel文件
Conan本身不直接支持生成Wheel,但可通过自定义Recipe实现:
1. 编写Conan Recipe扩展逻辑
在C++库的conanfile.py中添加Python封装的打包步骤:
from conans import ConanFile, tools import os class YourCxxLibConan(ConanFile): name = "your_cxx_lib" version = "1.0.0" settings = "os", "compiler", "build_type", "arch" # 其他Conan配置(如requires、build_requirements等) def package(self): # 打包C++库头文件和二进制 self.copy("*.h", dst="include", src="include") self.copy("*.so", dst="lib", src="build/lib") # 复制Python封装代码到Conan包目录 self.copy("py_wrapper/*", dst="python", src="py_wrapper") self.copy("setup.py", dst="python", src=".") def build(self): # 先构建C++库 self.run("cmake . -B build -DCMAKE_BUILD_TYPE=Release") self.run("cmake --build build") # 构建Wheel with tools.chdir(os.path.join(self.build_folder, "python")): self.run("pip install setuptools wheel") self.run("python setup.py bdist_wheel") # 复制Wheel到Conan输出目录 self.copy("*.whl", dst="../dist", src="dist")
2. 生成Wheel
执行Conan命令构建并生成Wheel:
conan create . user/channel # 生成的Wheel位于Conan包缓存或指定的输出目录
内容的提问来源于stack exchange,提问作者Sergey Gologuzov
相关产品推荐
相关产品推荐

