I create a c file named test.c with two functions defined as follows:
#include<stdio.h>
void hello_1(void){
printf("hello 1\n");
}
void hello_2(void){
printf("hello 2\n");
}
After that, I create test.pyx as follows:
import cython
cdef extern void hello_1()
The setup file is as follows:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(cmdclass={'buld_ext':build_ext},
ext_modules=[Extension("test",["test.pyx", "test.c"],
include_dirs=[np.get_include()],
extra_compile_args=['-g', '-fopenmp'],
extra_link_args=['-g', '-fopenmp', '-pthread'])
])
When I run setup file, it always reports hello_1 and hello_2 have multiple definitions. Can anybody tell me the problem?
What is multiple definition error in C? If you put a definition of a global variable in a header file, then this definition will go to every . c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.20-Jul-2013.
Multiple definition of main means you have written main function more than once in your program which is not correct according to C language specifications.
There are a number of things wrong with your files as posted, and I have no idea which one is causing the problem in your real code—especially since the code you showed us doesn't, and can't possibly, generate those errors.
But if I fix all of the obvious problems, everything works. So, let's go through all of them:
Your setup.py
is missing the imports at the top, so it's going to fail with a NameError
immediately.
Next, there are multiple typos—Extenson
for Extension
, buld_ext
for build_ext
, and I think one more that I fixed but don't remember.
I stripped out the numpy and openmp stuff because it's not relevant to your problem, and it was easier to just get it out of the way.
When you fix all of that and actually run the setup, the next problem becomes immediately obvious:
$ python setup.py build_ext -i
running build_ext
cythoning test.pyx to test.c
You're either overwriting your test.c
file with the file that gets built from test.pyx
, or, if you get lucky, ignoring the generated test.c
file and using the existing test.c
as if it were the cython-compiled output of test.pyx
. Either way, you're compiling the same file twice and trying to link the results together, hence your multiple definitions.
You can either configure Cython to use a non-default name for that file or, more simply, follow the usual naming conventions and don't have a test.pyx
that tries to use a test.c
in the first place.
So:
ctest.c:
#include <stdio.h>
void hello_1(void){
printf("hello 1\n");
}
void hello_2(void){
printf("hello 2\n");
}
test.pyx:
import cython
cdef extern void hello_1()
setup.py:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(cmdclass={'build_ext':build_ext},
ext_modules=[Extension("test",["test.pyx", "ctest.c"],
extra_compile_args=['-g'],
extra_link_args=['-g', '-pthread'])
])
And running it:
$ python setup.py build_ext -i
running build_ext
cythoning test.pyx to test.c
# ...
clang: warning: argument unused during compilation: '-pthread'
$ python
>>> import test
>>>
Tada.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With