2013-03-29 15 views
6

मैं बाहरी पुस्तकालय (wierd प्रक्रिया, mpicc + Cython + आदि), से जोड़ रहा हूं लेकिन मेरे पास एक लिंकिंग प्रक्रिया का अजीब व्यवहार है।अजीब लिंकिंग व्यवहार और अपरिभाषित प्रतीकों

दो ओ फ़ाइलें, libpetsc4py.o और PETSc.o वे एक .so फ़ाइल में जुड़े हुए हैं कर रहे हैं PETSc.so

एक अनिर्धारित प्रतीक __pyx_tp_new_8petsc4py_5PETSc_Object

[[email protected] src]$ nm libpetsc4py.o | grep __pyx_tp_new_8petsc4py_5PETSc_Object 
         U __pyx_tp_new_8petsc4py_5PETSc_Object 

यह परिभाषित किया गया है शामिल एक और ओ फ़ाइल में:

[[email protected] src]$ nm PETSc.o | grep __pyx_tp_new_8petsc4py_5PETSc_Object 
00000000001b92f0 t __pyx_tp_new_8petsc4py_5PETSc_Object 

फिर, तो जोड़ने से किया जाता है (संकलन लाइन, अजीब खेद है)

mpicc -pthread -fPIC -wd1572 -g -shared -fno-strict-aliasing -g -O2 -DNDEBUG -O2 -g 
build/temp.linux-x86_64-2.7/arch-linux2-c-debug/src/PETSc.o build/temp.linux-x86_64- 
2.7/arch- linux2-c-debug/src/libpetsc4py.o -L/home/users/zheltkov/tmp/petsc-3.3/arch 
-linux2-c-debug/lib -L/home/users/zheltkov/ivan/soft/epd7.2/lib 
-Wl,rpath,/home/users/zheltkov/tmp/petsc-3.3/arch-linux2-c-debug/lib 
-Wl,-rpath,/home/users/zheltkov/ivan/soft/epd7.2/lib -lpetsc -lpython2.7 -o 
build/lib.linux-x86_64-2.7/petsc4py/lib/a rch-linux2-c-debug/PETSc.so -lX11 -Wl, 
-rpath,/home/users/zheltkov/tmp/petsc-3.3/arch-linux2-c-debug/lib 
-L/home/users/zheltkov/tmp/petsc-3.3/arch-linux2-c-debug/lib -lfftw3_mpi -lfftw3 -lHYPRE 
-Wl,-rpath,/opt/intel/impi/4.1.0.030/intel64/lib 
-L/opt/intel/impi/4.1.0.030/intel64/lib -Wl, 
-rpath,/opt/intel/composer_xe_2013.2.146/mkl/lib/intel64 
-L/opt/intel/composer_xe_2013.2.146/mkl/lib/intel64 
-Wl,-rpath,/opt/intel/composer_xe_2013.2.146/compiler/lib/intel64 
-L/opt/intel/composer_xe_2013.2.146/compiler/lib/intel64 -Wl, 
-rpath,/usr/lib/gcc/x86_64-redhat-linux/4.4.6 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.6 
-Wl,- rpath,/mnt/data/users/dm4/vol9/zheltkov/tmp/petsc-3.3/-Xlinker -lmpigc4 
-Wl,-rpath,/opt/intel/mpi-rt/4.1 -lml -lpthread -Wl,-rpath, 
/opt/intel/composer_xe_2013/mkl/lib/intel64 
-L/opt/intel/composer_xe_2013/mkl/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread 
-lmkl_core -liomp5 -lifport -lifcore -lm -ldl -lmpigf -lmpi_dbg -lmpigi -lrt 
-limf -lsvml -lirng -lipgo -ldecimal -lcilkrts -lstdc++  -lgcc_s -lirc -lirc_s 

लेकिन अंत में, जिसके परिणामस्वरूप फ़ाइलें एक ही नाम, उनमें से एक अपरिभाषित है और सब कुछ काम नहीं करता है के साथ दो प्रतीक हैं:

[[email protected] arch-linux2-c-debug]$ nm PETSc.so | grep __pyx_tp_new_8petsc4py_5PETSc_Object 
0000000000200d20 t __pyx_tp_new_8petsc4py_5PETSc_Object 
       U __pyx_tp_new_8petsc4py_5PETSc_Object 

क्या मैं गलत कर रहा हूँ? एक ही नाम के साथ दो प्रतीकों क्यों हैं?

उत्तर

7

एक वस्तु फ़ाइल t में इंगित करता है समारोह, आंतरिक संबंध है (अर्थात static के रूप में घोषित किया जाता है), जबकि एक अन्य फ़ाइल में, U इंगित करता है समारोह संदर्भित है, लेकिन नहीं परिभाषित किया। एक बाहरी फ़ंक्शन T के साथ इंगित किया गया है।

जब आप साझा लाइब्रेरी बनाने के लिए लिंक करते हैं, तो लिंकर अनसुलझे संदर्भों के बारे में शिकायत नहीं करता है, इसलिए इसमें स्थैतिक फ़ंक्शन (केवल उस फ़ाइल में उपलब्ध है जो इसे परिभाषित किया गया है), और एक बाहरी प्रतीक अपरिभाषित के रूप में चिह्नित किया गया है।

यहां एक आसान उदाहरण है। दो फाइलें:

foo.c

#include <stdio.h> 

static void hello(void) 
{ 
    printf("Hello\n"); 
} 

bar.c

void sayhello(void) 
{ 
    hello(); 
} 

संकलित दो:

$ gcc -c -fPIC foo.c 
$ gcc -c -fPIC bar.c 
$ nm foo.o 
0000000000000000 t hello 
$ nm bar.o 
       U hello 
0000000000000000 T sayhello 

अब किसी साझा लाइब्रेरी बनाने

$ gcc -shared -o libhello.so foo.o bar.o 
$ nm libhello.so 
0000000000000700 t hello 
       U hello 

इसका नतीजा यह है कि यदि मैं एक फ़ंक्शन hello को परिभाषित करता हूं और निष्पादन योग्य बनाने के लिए इस लाइब्रेरी के विरुद्ध लिंक करता हूं, तो लाइब्रेरी मेरे फ़ंक्शन को sayhello में कॉल करेगी - स्थिर नहीं। अगर मैं इसे परिभाषित नहीं करता हूं, तो लिंकर एक अपरिभाषित प्रतीक त्रुटि देगा।

+0

यह ध्यान देने योग्य है कि बाहरी प्रतीक के रूप में 'टी' ('टी' के बजाय) होता है। – shakurov

+0

@shakurov - जोड़ा गया। – teppic

संबंधित मुद्दे