如何通过setuptools将CMake编译的可执行文件安装至site-packages
解决CMake构建的可执行文件无法进入Python扩展目录的问题
问题描述
我通过setuptools.Extension将C++代码打包为Python扩展,自定义了BuildCMakeExtension类依赖CMake完成构建。目前Python扩展模块(cytosim.xxxxx.so)能正常部署到site-packages/cytosim目录,但通过CMake的add_executable(${SIM_TARGET} "${PROJECT_SOURCE_DIR}/../src/sim/sim.cc")生成的可执行文件始终无法进入该目录。
解决方案
方法1:在setup.py中添加可执行文件移动逻辑
原有的build_extension方法仅处理了Python扩展模块的移动,需补充可执行文件的拷贝/移动步骤:
- 在
build_extension方法的末尾(现有移动so文件的代码之后)添加以下代码:
# 移动可执行文件到目标目录 # 替换成你的SIM_TARGET实际名称(比如CMake中定义的"sim") executable_name = "sim" target_dir = ct_dir # 即site-packages/cytosim目录 for cfg in ('Release', 'Debug'): # 可执行文件位于CMake临时构建目录的对应配置子目录下 exec_src_path = os.path.join(self.build_temp, cfg, executable_name) # 适配Windows平台的.exe后缀 if os.name == 'nt' and not exec_src_path.endswith('.exe'): exec_src_path += '.exe' if os.path.exists(exec_src_path): shutil.copy(exec_src_path, target_dir) print(f"Moved executable {executable_name} to {target_dir}")
- 确保代码顶部已导入
shutil和os模块(未导入则补充)。
方法2:通过CMake直接输出到目标目录
将setup.py中的目标目录传递给CMake,让CMake直接把可执行文件生成到最终位置:
- 在setup.py的
cmake_args列表中添加目标目录参数:
cmake_args = [ # 保留原有参数... # 传递可执行文件输出目录给CMake f"-DEXECUTABLE_OUTPUT_DIR={ct_dir}", ]
- 在CMakeLists.txt中配置可执行文件的输出路径:
# 接收setup.py传递的变量,设置可执行文件输出目录 set_target_properties(${SIM_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_DIR}" # 适配多配置生成器(如Visual Studio) RUNTIME_OUTPUT_DIRECTORY_RELEASE "${EXECUTABLE_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY_DEBUG "${EXECUTABLE_OUTPUT_DIR}" )
注意事项
- 方法1无需修改CMake配置,适合快速调整;方法2更贴合CMake构建流程,减少文件移动步骤。
- 注意区分不同平台的可执行文件后缀:Windows为
.exe,Linux/macOS无后缀。 - 确认
self.build_temp是执行CMake命令的临时构建目录。
内容的提问来源于stack exchange,提问作者SergeD
相关产品推荐
相关产品推荐

