Weird binding behavior and undefined characters

I am linking an external library (via wierd process, mpicc + Cython + etc.), but I have weird linking procedure behavior.

There are two .o files, libpetsc4py.o and PETSc.o they are linked in the .so file PETSc.so

One contains the undefined character __pyx_tp_new_8petsc4py_5PETSc_Object

 [ zheltkov@compiler-2 src]$ nm libpetsc4py.o | grep __pyx_tp_new_8petsc4py_5PETSc_Object U __pyx_tp_new_8petsc4py_5PETSc_Object 

It is defined in another .o file:

 [ zheltkov@compiler-2 src]$ nm PETSc.o | grep __pyx_tp_new_8petsc4py_5PETSc_Object 00000000001b92f0 t __pyx_tp_new_8petsc4py_5PETSc_Object 

Then the link is executed (the compilation line is strange, sorry)

 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 

But finally, the resulting files have two characters with the same name, one of which is undefined, and everything does not work:

 [ zheltkov@compiler-2 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 

What am I doing wrong? Why are there two characters with the same name?

+6
source share
1 answer

The object file t indicates that the function has an internal binding (i.e., is declared as static ), and in another file U indicates that the function is referenced, but not defined. The external function is indicated by t .

When you link to create a shared library, the linker does not complain about unresolved links, so it includes a static function (available only in the file that defined it), and an external symbol marked undefined.

Here is a simpler example. Two files:

foo.c

 #include <stdio.h> static void hello(void) { printf("Hello\n"); } 

bar.c

 void sayhello(void) { hello(); } 

Compile two:

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

Now create a shared library

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

The result of this is that if I define a hello function and contact this library to create an executable, the library will call my function in sayhello , not the static one. If I do not define it, the linker will give an undefined character error.

+7
source

All Articles