Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

linking with shared library, undefined reference to Py_BuildValue

542 views
Skip to first unread message

JW

unread,
Mar 4, 2003, 7:21:10 PM3/4/03
to
Hi all,

I'm fairly new to unix and python, so have patience with my questioning....

I have 2 files:
1) spam.c
int gcd(int x, int y)
{
int g;
g = y;
while(x > 0)
{
g = x;
x = y % x;
y = g;
}

return g;
}

2) spamwrapper.c
#include "Python.h"

extern int gcd(int, int);
extern void print_data(char *, char *, char *);

PyObject* spam_gcd(PyObject *self, PyObject *args)
{
int x, y, g;

if(!PyArg_ParseTuple(args, "ii", &x, &y))
{
return NULL;
}

g = gcd(x, y);
return Py_BuildValue("i", g);
}


---
Then, i make a shared libary file:

PYTHON = python2.2
INCLUDE = -I/usr/include/$(PYTHON)
gcc -c -fpic $(INCLUDE) spam.c spamwrapper.c
gcc -shared spam.o spamwrapper.c -o spammodule.so


After this, i have no problem from within a python script :
import spam
a=input("1st number:")
b=input("2nd:")
x=spam.gcd(a,b)

--
My problem occurs when I try to link the spammodule.so
to another .c file so that i could use the gcd() function

Example:
//file main.c
int main()
{
int x,a,b;
a=5;
b=10;
x=gcd(a,b);
return 0;
}


When i try compiling and linking main.c with spammodule.so and libpython2.2.a,
i get the following error messages:
-->./spammodule.so - undefined reference 'Py_BuildValue'
--> ./spammodule.so - undefined reference 'Py_InitModule4'

Any suggestions?
Thanks

Martin v. Löwis

unread,
Mar 5, 2003, 2:06:25 AM3/5/03
to
jkpan...@yahoo.com (JW) writes:

> When i try compiling and linking main.c with spammodule.so and libpython2.2.a,
> i get the following error messages:
> -->./spammodule.so - undefined reference 'Py_BuildValue'
> --> ./spammodule.so - undefined reference 'Py_InitModule4'

On Unix, if a static library (such as libpython2.2.a) is incorporated
into an executable (such as main), symbols from the shared library
might not be exported to other shared libraries you are also linking
with. Whether this happens and how to solve it depends on the flavour
of Unix, but most likely, you need to add -Wl,--export-dynamic to your
linker command line.

HTH,
Martin


JW

unread,
Mar 5, 2003, 8:54:54 PM3/5/03
to
mar...@v.loewis.de (Martin v. Löwis) wrote in message news:<m3d6l67...@mira.informatik.hu-berlin.de>...


I'm running RedHat 7.2 linux, on x86 platform.
I tried adding the " -Wl,--export-dynamic" to the gcc line,
and I still get same 'undefined reference' errors.

Any other suggestions. Also, does any one have suggestions for good
resource that explains linking/compiling on unix and linux? I'm coming
from Windows programming background.
Thanks!

Erwin S. Andreasen

unread,
Mar 6, 2003, 11:49:09 AM3/6/03
to
jkpan...@yahoo.com (JW) writes:

> I have 2 files:
> 1) spam.c
> int gcd(int x, int y)

> 2) spamwrapper.c


> #include "Python.h"
>
> extern int gcd(int, int);
> extern void print_data(char *, char *, char *);
>
> PyObject* spam_gcd(PyObject *self, PyObject *args)

> When i try compiling and linking main.c with spammodule.so and libpython2.2.a,


> i get the following error messages:
> -->./spammodule.so - undefined reference 'Py_BuildValue'
> --> ./spammodule.so - undefined reference 'Py_InitModule4'

Why do you want to link the Python part of your module if you are
going to call only the plain C method directly? I'd suggest compiling
spam.c to spam.so separately if that's all you want to do.

Your undefined reference however is caused by the linker discarding
all of libpython2.2.a. When you link with a *static* library (which is
really a collection of .o files with an index) the linker will decide
on a .o file basis whether that .o file is really needed -- and it
does that based what unsatisfied undefind references are pending so
far. If nothing needs that .o file inside the .a, it is not linked in.

Since nothing in your program needs anything in libpython2.2.a, no
part of it actually gets included into your main program.

With a real appliation that embeds Python, you woud call various
Python interpreter initiliazation functions, as described in
http://www.python.org/doc/current/ext/embedding.html -- this would
pull in the necessary Python functions from the library.

If you absolutely want to force inclusion of the .a file in its
entirety (which would be a waste if you aren't actually going to embed
Python), you can use the GNU ld --whole-archive option:

$ gcc -rdynamic test.c -o test -Wl,--whole-archive /usr/lib/python2.2/config/libpython2.2.a -Wl,--no-whole-archive -lutil -lm -ldl -lpthread

$ ls -la test
-rwxr-xr-x 1 erwin users 899268 Mar 6 17:45 test


. or use a shared libpython2.2, if available. Don't forget the
-rdynamic option, as Martin mentioned.


--
===============================================================
<er...@andreasen.org> Herlev, Denmark
<URL:http://www.andreasen.org/> <*>
===============================================================

0 new messages