6

(奇妙なプロセス、mpicc + Cython + などを介して) 外部ライブラリをリンクしていますが、リンク手順の動作がおかしいです。

libpetsc4py.o と PETSc.o の 2 つの .o ファイルがあり、.so ファイル PETSc.so にリンクされています。

1 つに未定義のシンボルが含まれています__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

別の .o ファイルで定義されています。

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

しかし最後に、結果のファイルには同じ名前の 2 つのシンボルがあり、そのうちの 1 つは未定義で、すべてが機能しません。

[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

私は何を間違っていますか?同じ名前のシンボルが 2 つあるのはなぜですか?

4

1 に答える 1

7

オブジェクト ファイルtでは、 は関数に内部リンケージがある (つまり、 として宣言されているstatic) ことを示し、別のファイルでUは は関数が参照されているが定義されていないことを示します。外部関数は で示されTます。

リンクして共有ライブラリを作成すると、リンカーは未解決の参照について文句を言わないため、静的関数 (それを定義したファイルでのみ使用可能) と未定義としてマークされた外部シンボルが含まれます。

より簡単な例を次に示します。2 つのファイル:

foo.c

#include <stdio.h>

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

bar.c

void sayhello(void)
{
    hello();
}

2 つをコンパイルします。

$ 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静的関数ではなく関数を呼び出します。定義しないと、リンカは未定義のシンボル エラーを返します。

于 2013-03-29T15:22:56.567 に答える