You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自定义Python包的常规与开发模式安装?解决develop命令未执行问题

问题描述

我正在构建example_package,需要自定义常规模式与开发(editable)模式下的安装流程。项目结构如下:

.
├── cpp
│   ├── CMakeLists.txt
│   └── helloworld.cpp
├── pyproject.toml
├── setup.py
└── src
    └── example_package
        └── __init__.py

各文件内容:

  • pyproject.toml:
[build-system]
requires = ["setuptools>=62.0.0", "wheel", "cmake>=3.20"]
build-backend = "setuptools.build_meta"

[project]
name = "example_package"
version = "0.0.1"
requires-python = ">=3.8"

[tool.setuptools.packages.find]
where = ["src"]
  • setup.py:
from setuptools import setup
from setuptools.command import develop, build_py, install
import subprocess

class CustomDevelop(develop.develop):
    def run(self):
        super(CustomDevelop, self).run()
        print("Execute CustomDevelop ......")

class CustomBuildPy(build_py.build_py):
    def run(self):
        super(CustomBuildPy, self).run()
        print("Execute CustomBuildPy ......")

class CustomInstall(install.install):
    def run(self):
        super(CustomInstall, self).run()
        print("Execute CustomInstall ......")
        
setup(
    cmdclass={
        'develop': CustomDevelop,
        'build_py': CustomBuildPy,
        'install': CustomInstall
    }
)

安装测试情况:

  1. 常规模式:执行python3 -m pip install -vv .后,CustomBuildPy和CustomInstall均正常执行,符合预期。
  2. 开发模式:执行python3 -m pip install -vv -e .后,仅CustomBuildPy执行,自定义的CustomDevelop未被调用,不符合预期。

实际需求:将cpp目录下的helloworld.cpp通过CMake编译为可执行文件helloworld,并放入sys.path中。修改CustomBuildPy后,常规模式安装正常,但开发模式下出现复制错误,因为源码目录中未生成build文件夹。


解决方案

1. 修复CustomDevelop未触发问题+统一编译逻辑

新版setuptools中,旧的develop命令已被editable_install替代,直接重载develop.develop不会生效。需要改用EditableInstall命令,同时封装CMake编译逻辑避免重复代码:

修改后的setup.py:

from setuptools import setup
from setuptools.command.build_py import build_py
from setuptools.command.install import install
from setuptools.command.editable_install import EditableInstall
import subprocess
import os
import shutil

def build_cpp():
    # 创建编译目录
    build_dir = os.path.join(os.path.dirname(__file__), "cpp", "build")
    os.makedirs(build_dir, exist_ok=True)
    
    # 执行CMake编译流程
    subprocess.run(["cmake", ".."], cwd=build_dir, check=True)
    subprocess.run(["make"], cwd=build_dir, check=True)
    
    # 返回编译后的可执行文件路径
    return os.path.join(build_dir, "helloworld")

class CustomBuildPy(build_py):
    def run(self):
        super().run()
        # 编译CPP并复制到安装后的包目录
        exe_path = build_cpp()
        package_dir = os.path.join(self.build_lib, "example_package")
        shutil.copy(exe_path, package_dir)
        print("CustomBuildPy: CPP编译完成并复制到安装包目录")

class CustomInstall(install):
    def run(self):
        super().run()
        print("CustomInstall: 常规安装流程执行完成")

class CustomEditableInstall(EditableInstall):
    def run(self):
        super().run()
        # 编译CPP并复制到源码包目录(开发模式下sys.path指向src)
        exe_path = build_cpp()
        package_dir = os.path.join(os.path.dirname(__file__), "src", "example_package")
        shutil.copy(exe_path, package_dir)
        print("CustomEditableInstall: 开发模式CPP编译完成并复制到源码目录")

setup(
    cmdclass={
        'build_py': CustomBuildPy,
        'install': CustomInstall,
        'editable_install': CustomEditableInstall
    }
)

2. 确保CMake配置正确

cpp/CMakeLists.txt需正确生成可执行文件,示例:

cmake_minimum_required(VERSION 3.20)
project(helloworld)

add_executable(helloworld helloworld.cpp)

3. 验证测试

  • 常规模式:执行python3 -m pip install -vv .,CustomBuildPy会编译CPP并复制到安装后的包目录,CustomInstall正常触发。
  • 开发模式:执行python3 -m pip install -vv -e .,CustomEditableInstall会编译CPP并复制到src/example_package,此时sys.path指向源码目录,可执行文件能被正确识别。

关键注意点

  • 用build_cpp函数封装编译逻辑,避免重复代码。
  • 开发模式下,editable安装指向src目录,需将可执行文件复制到src/example_package而非build目录。
  • 适配新版setuptools,用EditableInstall替代旧的develop命令。

内容的提问来源于stack exchange,提问作者Der Fänger im Roggen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:35:25