2012-12-19 17 views
6

Mam trywialny program do testowania dostępność plików rozwoju Pythona:Niezdefiniowany odniesienia - mimo lib znajdowane przez łącznik

#include<Python.h> 
int main(){Py_Initialize(); Py_Finalize(); } 

skompilować go (z Pythona 2.7 zainstalowany) jako gcc -I/usr/include/python2.7 -lpython2.7 p.c. To działa dobrze na innych maszynach, poza tym, że w większości-czystą chroot Ubuntu 12.04 (precyzyjnego) ciśgle są zainstalowane

/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 

Główki, /usr/lib/libpython2.7.so istnieje, ale mimo to nie łącznik. Symbol jest wymieniony w pliku .so i gcc czyta prawo 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 

pomysłów?

Odpowiedz

17

Spróbuj:

gcc -I/usr/include/python2.7 p.c -lpython2.7 

łącznik nie wie jeszcze, że Py_Initialize jest wymagany symbol gdy ładuje libpython2.7.a, więc rzuca ją. A następnie dostaje p.o i rzuca pasuje na brakujący symbol. Zamówienie w ten sposób pozwoli linkerowi szukać brakującego symbolu w kolejnych wejściach.

Patrz: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

To robi różnicę, gdzie w komendzie piszesz tę opcję; linker przeszukuje i przetwarza biblioteki i pliki obiektów w kolejności, w jakiej zostały określone. Tak więc, foo.o -lz bar.o' searches library z 'po pliku foo.o, ale przed bar.o. Jeśli bar.o odnosi się do funkcji w `z ', funkcje te mogą nie być ładowane.

+0

Dzięki, to zadziałało! Nowe rzeczy się nauczyły. – eudoxos

+0

Czy masz jakiś pomysł, dlaczego działa on na inne maszyny? Czy to zachowanie zależne od wersji? – eudoxos

+0

To zależy od linkera, który jest używany, jak sądzę. Ale jeśli ją położysz, to zawsze będzie działać. – yiding

0

Napotkano ten sam problem z łączeniem i osobiście mój problem polegał na tym, że mój 32-bitowy kompilator mingw nie może załadować 64-bitowej biblioteki pythona. Uaktualniam moje mingw do wersji 64-bitowej i rozwiązuję mój problem. Zostawić notatkę tutaj na wypadek, gdyby ktoś wpadł na ten sam problem.

3

Napotkano na ten sam problem z łączeniem. Ale w moim przypadku nie wystarczyło podać -lpython. Potrzebny był także -L. To znaczy.

g++ -I/usr/include/python3.5 hw.cpp -L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu -lpython3.5 

I tak. Zamów sprawy.

Powiązane problemy