如何在构建Cython模块时覆盖-DNDEBUG编译标志
我有一个Cython模块,它通过cdef extern
调用一个C++函数。这个C++函数里面有assert()
语句,我想检查这些断言。但是,当我通过运行python setup.py build_ext --inplace
来创建模块时,GCC总是带着-DNDEBUG
这个选项。每次运行代码时,断言都不会被检查。
我找不到办法在setup.py
中覆盖-DNDEBUG
这个选项。这可能吗?
目前我找到的唯一解决办法是手动调用Cython、GCC和g++
,并使用python setup.py
时用的选项,但把-DNDEBUG
去掉。不过肯定有更简单的方法。
2 个回答
12
你可以在你的 setup.py 文件中取消定义 NDEBUG。只需要在定义扩展时使用 undef_macros 这个选项就可以了:
extensions = [ Extension ( "myprog", [ mysrc.c ], undef_macros = [ "NDEBUG" ] ) ]
在构建输出中,你会看到 -DNDEBUG 后面跟着 -UNDEBUG,这样就会覆盖掉前面的设置。想了解更多关于扩展选项的信息,可以查看 distutils 文档。
不过要注意,如果在扩展模块中触发了 assert,那么 Python 或者 IPython 解释器会直接退出。
1
如果你在代码中定义了 NDEBUG
,可以手动取消这个定义,然后再包含 <cassert>
。你只需要在包含这些断言语句的 cpp 文件的最上面加上以下几行代码。记得这些代码要放在文件的第一行。
#ifdef NDEBUG
# define NDEBUG_DISABLED
# undef NDEBUG
#endif
#include <cassert>
#ifdef NDEBUG_DISABLED
# define NDEBUG // re-enable NDEBUG if it was originally enabled
#endif
// rest of the file
这样做可以确保在处理器包含 <cassert>
时,NDEBUG
是没有定义的,这样断言检查就会被编译进你的代码里。