0

I'm following the tutorial for SWIG and Python, but I'm getting an error when I try to import the compiled extension in Python.

Python 3.5.2 (default, Oct 11 2016, 15:01:25)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin

>>> import _example
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/pat/to/_example.cpython-35m-darwin.so, 2): Symbol not found: _fact
  Referenced from: /path/to/_example.cpython-35m-darwin.so
  Expected in: flat namespace
 in /path/to/_example.cpython-35m-darwin.so

Note that the error says it can't find the symbol _fact. I'm not sure where the leading underscore is coming from, and I can't find any information about how to resolve this problem.

Here is example.i (matches what's in the tutorial):

%module example

%{
#define SWIG_FILE_WITH_INIT
#include "example.h"
%}

int fact(int n);

example.h and example.c also match what's in the tutorial; I can post here if necessary.

Here's setup.py:

# coding=utf-8
from setuptools import Extension, setup

setup(
  name = 'SWIG Test',
  ext_modules = [Extension('_example', ['example.i'])],
  py_modules = ['example'],
)

This is the relevant output of pip install -e . -v:

running build_ext
building '_example' extension
swigging example.i to example_wrap.c
swig -python -o example_wrap.c example.i
creating build
creating build/temp.macosx-10.12-x86_64-3.5
/usr/bin/clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -pipe -Os -I/opt/local/Library/Frameworks/Python.framework/Versions/3.5/include/python3.5m -c example_wrap.c -o build/temp.macosx-10.12-x86_64-3.5/example_wrap.o
creating build/lib.macosx-10.12-x86_64-3.5
/usr/bin/clang -bundle -undefined dynamic_lookup -L/opt/local/lib -Wl,-headerpad_max_install_names build/temp.macosx-10.12-x86_64-3.5/example_wrap.o -o build/lib.macosx-10.12-x86_64-3.5/_example.cpython-35m-darwin.so
copying build/lib.macosx-10.12-x86_64-3.5/_example.cpython-35m-darwin.so ->

Some things that I've tried that didn't work:

  • Declaring fact as int fact(int n) asm("fact") (after building, I get Symbol not found: fact when importing).
  • Adding swig_opts=['-py3'] to the extension in setup.py.
todofixthis
  • 1,072
  • 1
  • 12
  • 25

1 Answers1

1

The leading underscore was a red herring. Turns out, I simply forgot to include example.c in my extension sources.

Here's what setup.py is supposed to look like:

# coding=utf-8
from setuptools import Extension, setup

setup(
  name = 'SWIG Test',
  ext_modules = [Extension('_example', ['example.i', 'example.c'])],
  py_modules = ['example'],
)

Note that the extension has both example.i and example.c in its sources.

Now everything works as expected (:

Python 3.5.2 (default, Oct 11 2016, 15:01:25)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin

>>> import example
>>> example.fact(42)
0
>>> example.fact(0)
1
Community
  • 1
  • 1
todofixthis
  • 1,072
  • 1
  • 12
  • 25