Каков наилучший способ справиться с суффиксом "_d" для расширений C при использовании отладочной сборки?

Я пытаюсь отладить мое расширение C для Python 2.7. Я использую python2.7 debug build. Я строю свой проект с setuptools, а мой setup.py имеет такие строки:

ext_modules=[Extension("my.extension",
                       ["my/_extension.c"])]

Когда я вызываю python setup.py install, по какой-то причине расширение компилируется в файл с суффиксом _d, а после этого в Python я не могу сделать import my.extension, я могу сделать только import my.extension_d. И я получаю:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "build/bdist.linux-x86_64/egg/my/extension_d.py", line 7, in <module>
  File "build/bdist.linux-x86_64/egg/my/extension_d.py", line 6, in __bootstrap__
ImportError: dynamic module does not define init function (initextension_d)

Конечно, у моего расширения нет initextension_d, он имеет только функцию initextension.

Это очень маловероятно, потому что мне нужно изменить код и добавить этот суффикс _d к импорту и другим материалам.

Можно ли отключить добавление этого суффикса? Или как справиться с этой проблемой по-другому? Может быть, есть некоторые "официальные" способы?

ОБНОВЛЕНИЕ # 0

Я использую Ubuntu Linux.

Ответ 1

Чтобы решить эту проблему, вы можете определить в своей функции модуля C

void initextension_d()
{ initextension(); }

Ответ 2

Комментарий от исходного файла distutils build_ext.py:

# расширения в debug_mode называются 'module_d.pyd' под окнами

То же самое для C Extensions, поэтому проблем не должно быть. Но так как там один, также можно удалить суффикс _d:

import os.path
from setuptools.command.build_ext import build_ext as _build_ext

class build_ext(_build_ext):
    def get_ext_filename(self, ext_name):
        fn = _build_ext.get_ext_filename(self, ext_name)
        fn = os.path.splitext(fn)
        if fn[0].endswith('_d'):
            fn[0] = fn[0][:-2]
        return fn[0] + fn[1]

Или просто отключите отладку на некоторое время:

from setuptools.command.build_ext import build_ext as _build_ext

class build_ext(_build_ext):
    def get_ext_filename(self, ext_name):
        debug, self.debug = self.debug, False
        fn = _build_ext.get_ext_filename(self, ext_name)
        self.debug = debug
        return fn

Не забудьте установить cmdclass в пределах setup:

setup(
    ...
    cmdclass={'build_ext': build_ext},
    ...
)

Я не использую Windows самостоятельно, так что это просто дикая догадка, но, возможно, вы смешиваете debug и выпускаете части Python.

Ответ 3

Просто отключите режим отладки при сборке C Расширение. Или, если вам нравится сохранять отладочную информацию, временно отключите макрос _DEBUG:

#ifdef _DEBUG
# ifndef BOOST_DEBUG_PYTHON
#  ifdef _MSC_VER  
    // VC8.0 will complain if system headers are #included both with
    // and without _DEBUG defined, so we have to #include all the
    // system headers used by pyconfig.h right here.
#   include <stddef.h>
#   include <stdarg.h>
#   include <stdio.h>
#   include <stdlib.h>
#   include <assert.h>
#   include <errno.h>
#   include <ctype.h>
#   include <wchar.h>
#   include <basetsd.h>
#   include <io.h>
#   include <limits.h>
#   include <float.h>
#   include <string.h>
#   include <math.h>
#   include <time.h>
#  endif
#  undef _DEBUG // Don't let Python force the debug library just because we're debugging.
#  define DEBUG_WRAP_PYTHON_H
# endif
#endif

#include <Python.h>

#ifdef DEBUG_WRAP_PYTHON_H
# define _DEBUG
#endif

Для полного примера кода вы можете взглянуть на полную версию того, как boost.python включает python.h.