I have a trivial program to test for availability of python development files:
#include<Python.h>
int main(){Py_Initialize(); Py_Finalize(); }
I compile it (with python 2.7 installed) as gcc -I/usr/include/python2.7 -lpython2.7 p.c
. It works fine on other machines, except that at mostly-clean chroot of Ubuntu 12.04 (precise) I keep getting
/tmp/ccj8Mgjb.o: In function `main':
p.c:(.text+0x5): undefined reference to `Py_Initialize'
p.c:(.text+0xa): undefined reference to `Py_Finalize'
collect2: ld returned 1 exit status
Headers are installed, /usr/lib/libpython2.7.so
exists but the linker nevertheless fails. The symbol is listed in the .so
file, and gcc is reading the right libpython2.7.so
:
$ nm -D libpython2.7.so.1.0 | grep Py_Initialize
00000000000c9c20 T Py_Initialize
00000000000c9260 T Py_InitializeEx
$ strace -f gcc -I/usr/include/python2.7 -lpython2.7 /tmp/p.c 2>&1 |grep libpython2.7 |grep open
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/libpython2.7.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/libpython2.7.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libpython2.7.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libpython2.7.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10618] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libpython2.7.so", O_RDONLY) = 7
Any ideas?
Try:
gcc -I/usr/include/python2.7 p.c -lpython2.7
the linker doesn't yet know that Py_Initialize
is a required symbol when it loads libpython2.7.a
, so it tosses it away. And then it gets to p.o and throws a fit about the missing symbol. Ordering it this way will let the linker look for the missing symbol in subsequent inputs.
See: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus,
foo.o -lz bar.o' searches library
z' after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded.