Strange linking behaviour and undefined symbols
c, icc, linux, nm
Solution
In an object file `t` indicates that the function has internal linkage (i.e. is declared as `static`), while in another file, `U` indicates the function is referenced, but not defined. An external function is indicated with `T`.
When you link to create a shared library, the linker doesn't complain about unresolved references, so it includes the static function (available only in the file that defined it), and an external symbol marked as undefined.
Here's a simpler example. Two files:
foo.c
#include <stdio.h>
static void hello(void)
{
printf("Hello\n");
}
bar.c
void sayhello(void)
{
hello();
}
Compile the 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 function `hello` and link against this library to create an executable, the library will call my function in `sayhello` - not the static one. If I don't define it, the linker will give an undefined symbol error.
Problem
I am linking an external library (via wierd process, mpicc + Cython + etc), but I have a weird behaviour of a linking procedure. There are two .o files, libpetsc4py.o and PETSc.o they are linked into a .so file PETSc.so One contains an undefined symbol `__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, then linking is done (the compile line is weird, 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 has two symbols with the same name, one of them 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 there are two symbols with the same name?