【问题标题】:Cython conditional compile based on external value基于外部值的 Cython 条件编译
【发布时间】:2010-09-29 22:50:17
【问题描述】:

我尝试从 Cython pxd 有条件地编译(或生成)c 代码。我读到我可以 DEF 定义 aa 值和 IF 以根据其值有条件地生成,但是我怎样才能从 pxd 文件外部获取此值?

特别是这两个案例现在对我来说很有趣:

  • 为 Cython 提供一些命令行定义,最好通过 Cython.Distutils setuptools 方式
  • extern-ed C 头文件定义了一些值,并根据该值使用 Cython 有条件地定义(现在可能不可能?)

谢谢

【问题讨论】:

  • 实际上第二点是不可行的,因为据我所知,Cython 实际上并没有解析外部头文件。
  • stackoverflow.com/questions/26225187/… 给出了类似问题的更好答案。 (当被问到这个问题时,我不知道这是否是一个可行的解决方案)
  • @DavidW 使用compile_time_env 的答案确实更容易(可能),但如果值发生变化,它不会自动重新编译。此处接受的答案中的方法将(但请参阅我的评论)。

标签: conditional cython conditional-compilation


【解决方案1】:

您可以生成一个 pxi 文件,并在执行 IF 之前包含它(与 ./configure 生成一个 config.h 相同。) 例如,这就是我们在 Kivy setup.py 中所做的:

c_options = { 
'use_opengl_es2': True,
'use_opengl_debug': False,
'use_glew': False,
'use_mesagl': False}

print 'Generate config.pxi'
with open(join(dirname(__file__), 'kivy', 'graphics', 'config.pxi'), 'w') as fd:
    for k, v in c_options.iteritems():
        fd.write('DEF %s = %d\n' % (k.upper(), int(v)))

然后,在您的 pxd 中:

include "config.pxi"
IF USE_OPENGL_DEBUG == 1:
  # do other import or whatever you want

【讨论】:

  • 您也可以通过复制和将'DEF %s = %d'更改为'#define %s %d'来完成同一代“config.h”
  • 我发现编辑该文件不会触发该文件的缓存破坏。即,如果您更改 config.pxi,旧的仍将被构建。有什么办法吗?
  • 啊有办法,需要在 setup.py 中将 config.pxi 包含到 source_files 中
  • 您可能还希望仅在选项更改时生成 config.pxi,例如将选项移动到单独的文件并检查它是否比 config.pxi 更新。否则每次都会重新编译 pxd。顺便说一句,即使没有在 sources_list 中包含 config.pxi,自动重新编译(即缓存破坏)也适用于我。
【解决方案2】:

实际上,第二种选择更简单。在一些 .h 文件中创建一个 FLAG,然后执行

cdef extern from "header.h":
    cdef int FLAG

那你想用的时候就写

if FLAG:
    ...

即使 Cython 会生成代码,C 编译器也会自动修剪掉它,因为它在编译时知道 FLAG 的值。

【讨论】:

  • 这适用于简单的事情,但它不会让你做有条件的外部,而接受的答案可以。
  • 它不会让你ctypedef 来决定,例如,在单精度和双精度浮点数之间。所以公认的答案肯定更强大
猜你喜欢
  • 2015-02-01
  • 1970-01-01
  • 2020-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-15
  • 1970-01-01
  • 2020-07-02
相关资源
最近更新 更多