防止在cython中对c文件进行双重编译 [英] Prevent double compilation of c files in cython

查看:129
本文介绍了防止在cython中对c文件进行双重编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用c库编写包装程序,该库具有几乎所有功能的文件,比如 all_funcs.c 。反过来,此文件需要编译大量其他c文件

I am writing a wrapper over c libriary and this lib has file with almost all functions, let say, all_funcs.c. This file in turn requires compilation of lots of another c files

我创建了 all_funcs.pyx 所有功能,但我也想创建一个子模块,该子模块可以访问 all_funcs.c 中的函数。现在可行的是将所有c文件添加到setup.py中的两个扩展中,但是每个c文件都编译两次:第一个用于 all_funcs.pyx ,第二个用于子模块扩展。

I have created all_funcs.pyx, where I wraped all functions, but I also want to create a submodule, that has access to functions from all_funcs.c. What works for now is adding all c-files to both Extensions in setup.py, however each c-file compiles twice: first for all_funcs.pyx and second for submodule extension.

有没有办法为每个扩展名提供通用的源文件?

Are there any ways to provide common sourse files to each Extension?

当前setup.py的示例:

Example of current 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源文件的列表

source_files_paths - the list with common c source files

推荐答案

注意:此答案仅说明如何避免使用参数对c / cpp文件进行多次编译设置功能。但是,它没有说明如何避免由于违反ODR而导致的可能问题-有关此问题,请参见此SO-post

Note: this answer only explains how to avoid multiple compilation of c/cpp-files using libraries-argument of setup-function. It doesn't however explain how to avoid possible problems due to ODR-violation - for that see this SO-post.

设置中添加参数将触发在构建 ext_modules 之前构建build_clib (运行 setup.py build 或<$ c时) $ c> setup.py install 命令),则在扩展名被链接时,生成的 static 库也将自动传递给链接器。

Adding libraries-argument to setup will trigger build_clib prior to building of ext_modules (when running setup.py build or setup.py install commands), the resulting static library will also be automatically passed to the linker, when extensions are linked.

对于您的 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] 
        )

要就地构建扩展,应该调用:

To build the extensions inplace one should invoke:

python setupy.py build_clib build_ext --inplace

仅凭 build_ext 是不够的:我们需要先构建静态库,然后才能将其用于扩展程序。

as build_ext alone is not enough: we need the static libraries to build before they can be used in extensions.

这篇关于防止在cython中对c文件进行双重编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆