Can't load Boost.Python module - undefined symbols
<p>I have a library that I wrote in C and need to access from Python, so I wrapped it using Boost.Python. I can compile my library into a Boost .so file with no problems, but when I try to load it into Python (with <code>import tropmodboost</code>), I get the following error:</p>

<pre><code>ImportError: ./tropmodboost.so: undefined symbol: _Z12simplex_freeP7simplex
</code></pre>

<p>I <a href="http://stackoverflow.com/questions/17671912/cannot-import-module-using-boost-python">found</a> out that this is a <a href="http://stackoverflow.com/questions/1780003/import-error-on-boost-python-hello-program">common</a> error, and that it can often be fixed be reordering the <code>-l</code> directives in my g++ linker call, but as fa as I can tell mine are already okay.</p>

<p>Here's the text of my Makefile, which is running on Ubuntu:</p>

<pre><code># location of the Python header files
PYTHON_VERSION = 2.7
PY_VER2        = 27

# various include directories, used separately in different compiler tasks
PYN_INC = /usr/include/python$(PYTHON_VERSION)
IGH_INC = /usr/local/include/igraph
BST_INC = /usr/include

# library locations for linking
LS = -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -L/usr/lib/python$(PYTHON_VERSION)/config
lS = -lboost_python-py$(PY_VER2) -lpython$(PYTHON_VERSION) 

# source files for different compiler tasks
CORE_SRC = permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c build_complex.c
TEST_SRC = main.c tests/tests.c -ligraph -lm

# objects for linking the core to the boost module
CORE_OBJS = permutation_src.o permutation_parity.o split.o simplex.o simplex_src.o build_complex.o

.PHONY: clean tests

main: tropmod.boost.o
    g++ -shared -Wl,--export-dynamic tropmod.boost.o $(LS) $(lS) $(CORE_OBJS) -o tropmodboost.so

tropmod.boost.o: tropmod.boost.cpp tmstuff
    g++ -I$(PYN_INC) -I$(BST_INC) -I$(IGH_INC) -fPIC -c tropmod.boost.cpp

tmstuff: main.c permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c tests/tests.c
    gcc -I. -I=$(IGH_INC) -fPIC -c $(CORE_SRC)

debug: main.c permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c tests/tests.c
    gcc -I. -I=$(IGH_INC) -g -fPIC -c $(CORE_SRC)

tests:
    gcc -I. -I=$(IGH_INC) -g -o tmtest $(CORE_SRC) $(TEST_SRC) -L/usr/local/lib -ligraph -lm

clean:
    rm *.o *.so
</code></pre>

<p>Calling <code>ldd tropmodboost.so</code> outputs:</p>

<pre><code>linux-vdso.so.1 =&gt;  (0x00007ffff79a3000)
libpython2.7.so.1.0 =&gt; /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007f34ea732000)
libboost_python-py27.so.1.58.0 =&gt; /usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0 (0x00007f34ea4e6000)
libstdc++.so.6 =&gt; /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f34ea163000)
libgcc_s.so.1 =&gt; /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f34e9f4d000)
libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007f34e9b84000)
libpthread.so.0 =&gt; /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f34e9966000)
libz.so.1 =&gt; /lib/x86_64-linux-gnu/libz.so.1 (0x00007f34e974c000)
libdl.so.2 =&gt; /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f34e9548000)
libutil.so.1 =&gt; /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f34e9344000)
libm.so.6 =&gt; /lib/x86_64-linux-gnu/libm.so.6 (0x00007f34e903b000)
/lib64/ld-linux-x86-64.so.2 (0x0000561fcfee3000)
</code></pre>

<p>Here's an except from an .hpp file shows the Boost wrapper code itself:</p>

<pre><code>#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/list.hpp&gt;
#include &lt;boost/python/object.hpp&gt;

[...]

BOOST_PYTHON_MODULE(tropmodboost) {

    using namespace boost::python;

    class_&lt;ConfigSpace&gt;("ConfigSpace", init&lt;int, int&gt;())
        .def("destroy", &amp;ConfigSpace::destroy)
        .def("getTraceOfPerm", &amp;ConfigSpace::getTraceOfPerm)
        ;


}
</code></pre>

<p>After running <code>nm</code> on a few of my object files, I found that in the undefined symbol <code>_Z12simplex_freeP7simplex</code> was defined in simplex.o as just <code>simplex_free</code>, presumably because it was compiled from simplex.c using gcc. In other words, I think gcc and g++ were naming things differently from one another, so I switched everything to g++ and compiled my C code as C++, and that resolved the issue.</p>

python c++ python-2.7 linker boost-python