静态库中的未定义引用,尽管该函数存在

时间:2016-11-28 18:21:10

标签: c++ static-libraries icc

我尝试在Intel Xeon超级计算机上使用Intel 17编译器和Intel MPI编译QDP++ C ++库。依赖QMP C库已经使用该编译器(mpiicc)编译,没有编译错误。

尝试配置QDP ++时,我从英特尔编译器收到此错误:

~/local-jureca/lib/libqmp.a(QMP_init.o): In function `QMP_comm_get_allocated':
QMP_init.c:(.text+0x55): undefined reference to `QMP_abort_mpi(int)'

这来自GCC 5.4:

~/local-jureca/lib/libqmp.a(QMP_init.o):QMP_init.c:function QMP_comm_get_allocated: error: undefined reference to 'QMP_abort_mpi(int)'

所以这是一个实际问题,而不仅仅是带有MPI编译器的英特尔C ++无法做到的事情。

nm ~/local-jureca/lib/libqmp.a的输出包含此QMP_comm_get_allocated所在的节。

QMP_init.o:
                 U atol
                 U __ctype_b_loc
                 U exit
                 U __gcc_personality_v0
                 U __gxx_personality_v0
                 U malloc
00000000000015f0 T QMP_abort
00000000000015c0 T QMP_abort_string
0000000000000010 D QMP_allocated_comm
0000000000000018 d QMP_allocated_comm_s
0000000000000000 D QMP_args
0000000000000000 b QMP_args_s
                 U QMP_barrier
                 U QMP_comm_declare_logical_topology_map
0000000000000000 T QMP_comm_get_allocated
0000000000001760 T QMP_comm_get_default
00000000000000e0 T QMP_comm_get_job
                 U QMP_comm_get_logical_coordinates
                 U QMP_comm_logical_topology_is_declared
0000000000000070 T QMP_comm_set_allocated
00000000000016f0 T QMP_comm_set_default
0000000000000150 T QMP_comm_set_job
                 U QMP_comm_split
0000000000000048 D QMP_default_comm
                 U QMP_error
00000000000001c0 T QMP_finalize_msg_passing
                 U QMP_get_allocated_dimensions
                 U QMP_get_allocated_number_of_dimensions
                 U QMP_get_msg_passing_type
0000000000001620 T QMP_init_msg_passing
0000000000000040 D QMP_job_comm
0000000000000008 D QMP_machine
0000000000000048 b QMP_machine_s
0000000000000080 B QMP_stack_level
                 U __svml_idiv4
0000000000000000 r __$U0
0000000000000017 r __$U1
000000000000002e r __$U2
000000000000003f r __$U3
0000000000000091 r __$U4
000000000000007c r __$U5
0000000000000050 r __$U6
000000000000005a r __$U7
0000000000000067 r __$U8
                 U _Unwind_Resume
0000000000000500 t _Z12process_argsPiPPPc
000000000000002c r _Z12process_argsPiPPPc$$LSDA
                 U _Z13QMP_abort_mpii
                 U _Z20QMP_init_machine_mpiPiPPPc16QMP_thread_levelPS3_
                 U _Z28QMP_finalize_msg_passing_mpiv
00000000000001e0 t _Z9get_colorv
0000000000000000 r _Z9get_colorv$$LSDA

另一节包含假定无法找到的函数QMP_abort_mpi

QMP_init_mpi.o:
                 U malloc
                 U MPI_Abort
                 U MPI_Comm_dup
                 U MPI_Comm_rank
                 U MPI_Comm_size
                 U MPI_Finalize
                 U MPI_Get_processor_name
                 U MPI_Init_thread
0000000000000010 T QMP_abort_mpi
                 U QMP_abort_string
                 U QMP_allocated_comm
0000000000000000 T QMP_finalize_msg_passing_mpi
0000000000000020 T QMP_init_machine_mpi
                 U QMP_machine

`configure的相关输出是:

configure:  Parscalar build! Checking for QMP 
checking for qmp-config... ~/local-jureca/bin/qmp-config
configure: Found QMP configuration program ~/local-jureca/bin/qmp-config
configure: QMP compile flags: -I~/local-jureca/include
configure: QMP linking flags: -L~/local-jureca/lib
configure: QMP libraries flags: -lqmp
checking if we can compile/link of a simple QMP C++ program... no
configure: error: Cannot compile/link a basic QMP C++ program!
        Check QMP_CFLAGS, QMP_LDFLAGS, QMP_LIBS.

所以它似乎很好地找到了库。

config.log中有一个更大的块:

configure:4227: /usr/local/software/jureca/Stages/2016b/software/impi/2017.0.098-iccifort-2017.0.098-GCC-5.4.0/bin64/mpiicpc -o conftest -O2 -Wall -fopenmp --std=c++11 -I~/local-jureca/include   -L~/local-jureca/lib conftest.cpp  -lqmp >&5
~/local-jureca/lib/libqmp.a(QMP_init.o): In function `QMP_comm_get_allocated':
QMP_init.c:(.text+0x55): undefined reference to `QMP_abort_mpi(int)'
~/local-jureca/lib/libqmp.a(QMP_init.o): In function `QMP_comm_set_allocated':
QMP_init.c:(.text+0xc7): undefined reference to `QMP_abort_mpi(int)'
~/local-jureca/lib/libqmp.a(QMP_init.o): In function `QMP_comm_get_job':
QMP_init.c:(.text+0x135): undefined reference to `QMP_abort_mpi(int)'
~/local-jureca/lib/libqmp.a(QMP_init.o): In function `QMP_comm_set_job':
QMP_init.c:(.text+0x1a7): undefined reference to `QMP_abort_mpi(int)'
~/local-jureca/lib/libqmp.a(QMP_init.o): In function `QMP_finalize_msg_passing':
QMP_init.c:(.text+0x1cf): undefined reference to `QMP_finalize_msg_passing_mpi()'
~/local-jureca/lib/libqmp.a(QMP_init.o): In function `get_color()':
QMP_init.c:(.text+0x29b): undefined reference to `QMP_abort_mpi(int)'
QMP_init.c:(.text+0x45c): undefined reference to `QMP_abort_mpi(int)'
QMP_init.c:(.text+0x4be): undefined reference to `QMP_abort_mpi(int)'
configure:4227: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "qdp++"
| #define PACKAGE_TARNAME "qdp--"
| #define PACKAGE_VERSION "1.44.0"
| #define PACKAGE_STRING "qdp++ 1.44.0"
| #define PACKAGE_BUGREPORT "edwards@jlab.org"
| #define PACKAGE_URL ""
| #define PACKAGE "qdp--"
| #define VERSION "1.44.0"
| #define QDP_ND 4
| #define QDP_NC 3
| #define QDP_NS 4
| #define QDP_AC_ALIGNMENT_SIZE 16
| #define QDP_USE_GENERIC_OPTS 1
| #define QDP_USE_BLUEGENEL 1
| #define BASE_PRECISION 64
| #define QDP_USE_CB2_LAYOUT 1
| #define ARCH_PARSCALAR 1
| /* end confdefs.h.  */
| #include "qmp.h"
| int
| main ()
| {
| 
|         int argc ; char **argv ;
|         QMP_thread_level_t prv;
|          ;
|         QMP_init_msg_passing(&argc, &argv, QMP_THREAD_SINGLE, &prv) ;
|          ;
|         QMP_finalize_msg_passing() ;
| 
|   ;
|   return 0;
| }
configure:4253: checking if we can compile/link of a simple QMP C++ program
configure:4261: result: no
configure:4263: error: Cannot compile/link a basic QMP C++ program!
        Check QMP_CFLAGS, QMP_LDFLAGS, QMP_LIBS.

我用~替换了我的主目录的绝对路径,因为实际路径不是很有趣。

这里发生了什么?我该怎么办呢?

更新1

这是QMP的make输出的一部分。它似乎是用mpiicc编译的,它是一个C(而不是C ++)编译器:

depbase=`echo mpi/QMP_topology_mpi.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
/usr/local/software/jureca/Stages/2016b/software/impi/2017.0.098-iccifort-2017.0.098-GCC-5.4.0/bin64/mpiicc -DHAVE_CONFIG_H -I. -I../include    -I../include  -O2 -Wall -fopenmp -MT mpi/QMP_topology_mpi.o -MD -MP -MF $depbase.Tpo -c -o mpi/QMP_topology_mpi.o mpi/QMP_topology_mpi.c &&\
mv -f $depbase.Tpo $depbase.Po

然后静态库从各个单元链接在一起:

rm -f libqmp.a
ar cru libqmp.a QMP_comm.o QMP_error.o QMP_grid.o QMP_init.o QMP_machine.o QMP_mem.o QMP_split.o QMP_topology.o QMP_util.o mpi/QMP_comm_mpi.o mpi/QMP_error_mpi.o mpi/QMP_init_mpi.o mpi/QMP_mem_mpi.o mpi/QMP_split_mpi.o mpi/QMP_topology_mpi.o  

0 个答案:

没有答案