Python and OpenMP C Extensions
Just to make it clearer, here is what your setup.py should look like:
ext = Extension( 'milk.unsupervised._som', sources = ['milk/unsupervised/_som.cpp'], extra_compile_args=['-fopenmp'], extra_link_args=['-lgomp'])...setup(..., ext_modules = [ext])
I know this is a dated post, but I'll share my experience as I too ran into this exact same issue, but when using f2py at the command line. I was originally compiling my OpenMP enabled Fortran 90 subroutine using
f2py --fcompiler=gfortran --f90flags='-fopenmp -lgomp' -m sub -c sub.90
which succesfully created the shared object sub.so. However, trying to import this from a Python shell produced the similar undefined symbol ImportError. However, as the original author stated it's because I was trying to pass both -fopenmp and -lgomp to the compiler, whereas only -fopenmp should be passed to it, and -lgomp should be passed to the linker.
Therefore, I should have been doing the following
f2py --fcompiler=gfortran --f90flags='-fopenmp' -lgomp -m sub -c sub.f90
And that's it, problem solved, I can now import my subroutine.
It was a simple linking issue. OpenMP wasn't being properly linked during the compilation of the module. So it IS possible to load a C Python extension that uses OpenMP. -fopenmp has to be passed to the compiler and -lgomp to the linker -- if you're using distutils, make sure your setup.py is configured properly. Rebuilding Python also worked, I'm guessing, because I had properly linked OpenMP with Python, so when Python loaded the module the library was already properly linked to.