防止在cython中对c文件进行双重编译 [英] Prevent double compilation of c files in cython
问题描述
我正在用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
推荐答案
注意:此答案仅说明如何避免使用的
功能。但是,它没有说明如何避免由于违反ODR而导致的可能问题-有关此问题,请参见此SO-post 。库
参数对c / cpp文件进行多次编译设置
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屋!