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

使用conda build构建含子包的conda包遇模块找不到问题求示例

Conda Build 含C/Cython子包的最小可行示例

目录结构

conda-package-mwe/
├── package1/
│   ├── __init__.py
│   └── module.py
├── subpackages/
│   └── subpackage1/
│       ├── __init__.py
│       ├── subpackage1cython.pyx
│       ├── lib/
│       │   ├── Cfunctions.c
│       │   └── Cheaders.h
│       ├── Makefile
│       └── setup.py
├── build.sh
├── meta.yaml
└── setup.py

核心文件内容

1. meta.yaml(Conda 构建配置)

package:
  name: mycompositepackage
  version: "0.1.0"

source:
  path: .

build:
  number: 0
  script: bash build.sh
  script_env:
    - CC
    - CXX

requirements:
  build:
    - {{ compiler('c') }}
    - cython
    - make
    - python {{ python }}
    - pip
  run:
    - python {{ python }}

test:
  imports:
    - package1
    - subpackage1
  commands:
    - python -c "from package1 import module; module.test_import()"

2. build.sh(构建脚本)

#!/bin/bash
set -e  # 出错即终止

# 编译并安装子包subpackage1
cd subpackages/subpackage1
# 编译C核心库
cd lib
make
cd ..
# 安装子包(含Cython编译)
$PYTHON setup.py install

# 返回根目录,安装主包
cd ../..
$PYTHON setup.py install

3. 主包 setup.py

from setuptools import setup, find_packages

setup(
    name="mycompositepackage",
    version="0.1.0",
    packages=find_packages(),
    install_requires=[
        "subpackage1>=0.1.0"
    ],
)

4. 主包 module.py(测试导入子包)

import subpackage1 as subp

def test_import():
    print("子包导入成功,测试函数结果:", subp.add(2, 3))

5. 子包 C 核心文件

subpackages/subpackage1/lib/Cheaders.h

#ifndef CHEADERS_H
#define CHEADERS_H

int add(int a, int b);

#endif

subpackages/subpackage1/lib/Cfunctions.c

#include "Cheaders.h"

int add(int a, int b) {
    return a + b;
}

6. 子包 Makefile

CC ?= gcc
CFLAGS = -fPIC -Wall -O2

# 编译动态链接库
lib/libCfunctions.so: lib/Cfunctions.c lib/Cheaders.h
	$(CC) $(CFLAGS) -shared -o $@ $<

all: lib/libCfunctions.so

clean:
	rm -f lib/libCfunctions.so

7. 子包 Cython 文件

# subpackages/subpackage1/subpackage1cython.pyx
cdef extern from "lib/Cheaders.h":
    int add(int a, int b)

def add_numbers(int a, int b):
    return add(a, b)

8. 子包 setup.py(Cython 编译配置)

from setuptools import setup, Extension
from Cython.Build import cythonize
import os

# 定位C库路径
LIB_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "lib")

setup(
    name="subpackage1",
    version="0.1.0",
    packages=["subpackage1"],
    ext_modules=cythonize(
        Extension(
            "subpackage1.subpackage1cython",
            sources=["subpackage1cython.pyx"],
            include_dirs=[LIB_DIR],
            library_dirs=[LIB_DIR],
            libraries=["Cfunctions"],
            runtime_library_dirs=[LIB_DIR],
        ),
        compiler_directives={"language_level": "3"}
    ),
)

9. 子包 init.py

from .subpackage1cython import add_numbers as add

构建与测试步骤

  1. 安装conda-build:conda install conda-build -y
  2. 进入示例目录:cd conda-package-mwe
  3. 执行构建:conda build .
  4. 测试构建成果:执行conda-build输出的conda build --test <包文件路径>命令

原问题排查要点

  • 子包setup.py的name字段必须与导入名一致(本例为subpackage1)
  • 构建脚本需确保子包安装到conda构建环境的site-packages目录,使用$PYTHON变量避免环境冲突
  • meta.yaml需明确测试依赖,确保子包被纳入测试环境的可导入路径
  • 主包的install_requires需声明对子包的依赖,保证安装时子包被正确部署

内容的提问来源于stack exchange,提问作者Riccardo Buscicchio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 09:02:11