我正在编写一个 c 库的包装器,这个库包含几乎所有函数的文件,比如说 all_funcs.c
。该文件又需要编译许多其他 c 文件
我已经创建了 all_funcs.pyx
,其中包装了所有函数,但我还想创建一个子模块,它可以访问 all_funcs.c
中的函数。现在有效的方法是将所有 c 文件添加到 setup.py 中的两个扩展中,但是每个 c 文件都会编译两次:第一次用于 all_funcs.pyx
,第二次用于子模块扩展。
有没有办法为每个扩展提供通用源文件?
当前 setup.py 的示例:
ext_helpers = Extension(name=SRC_DIR + '.wrapper.utils.helpers',
sources=[SRC_DIR + '/wrapper/utils/helpers.pyx'] + source_files_paths,
include_dirs=[SRC_DIR + '/include/'])
ext_all_funcs = Extension(name=SRC_DIR + '.wrapper.all_funcs',
sources=[SRC_DIR + '/wrapper/all_funcs.pyx'] + source_files_paths,
include_dirs=[SRC_DIR + '/include/'])
EXTENSIONS = [
ext_helpers,
ext_all_funcs,
]
if __name__ == "__main__":
setup(
packages=PACKAGES,
zip_safe=False,
name='some_name',
ext_modules=cythonize(EXTENSIONS, language_level=3)
)
source_files_paths
- 常见 C 源文件列表
最佳答案
注意:此答案仅解释如何使用 setup
函数的 libraries
参数避免多次编译 c/cpp 文件。但是,它没有解释如何避免由于 ODR 违规而可能出现的问题 - 请参阅 this SO-post .
将libraries
参数添加到setup
将在构建ext_modules
之前触发build_clib
(当运行 >setup.py build
或 setup.py install
命令),当扩展链接时,生成的静态库也将自动传递给链接器。
对于您的setup.py
,这意味着:
from setuptools import setup, find_packages, Extension
...
#common c files compiled to a static library:
mylib = ('mylib', {'sources': source_files_paths}) # possible further settings
# no common c-files (taken care of in mylib):
ext_helpers = Extension(name=SRC_DIR + '.wrapper.utils.helpers',
sources=[SRC_DIR + '/wrapper/utils/helpers.pyx'],
include_dirs=[SRC_DIR + '/include/'])
# no common c-files (taken care of in mylib):
ext_all_funcs = Extension(name=SRC_DIR + '.wrapper.all_funcs',
sources=[SRC_DIR + '/wrapper/all_funcs.pyx'],
include_dirs=[SRC_DIR + '/include/'])
EXTENSIONS = [
ext_helpers,
ext_all_funcs,
]
if __name__ == "__main__":
setup(
packages=find_packages(where=SRC_DIR),
zip_safe=False,
name='some_name',
ext_modules=cythonize(EXTENSIONS, language_level=3),
# will be build as static libraries and automatically passed to linker:
libraries = [mylib]
)
要就地构建扩展,应该调用:
python setupy.py build_clib build_ext --inplace
仅作为 build_ext
是不够的:我们需要先构建静态库,然后才能在扩展中使用它们。
关于cython - 防止cython中c文件的双重编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57673283/