诊断多重定义错误

Diagnose a multiple definition error

本文关键字:错误 定义 诊断      更新时间:2023-10-16

我有一个库,我想用大型应用程序Chroma编译。这两个图书馆都有其他依赖性,这是一件纠结的事情,大约一百万行。Qphix已清洁编译,我将其安装到~/local-jureca中。

在色度汇编期间,英特尔C 版本17编译器给我类似这样的错误:

../../lib/libchroma.a(syssolver_mdagm_aggregate.o): In function `QPhiX::CommsUtils::sumDouble(double*)': 
syssolver_mdagm_aggregate.cc:(.text+0x180): multiple definition of `QPhiX::CommsUtils::sumDouble(double*)' 
../../lib/libchroma.a(syssolver_linop_aggregate.o):syssolver_linop_aggregate.cc:(.text+0x1d0): first defined here

编译器呼叫是这样,我手工分解了长线。复制了一些标志,因为configure拾取了用过的库的标志并将其插入CXXFLAGS

/usr/local/software/jureca/Stages/2016b/software/impi/2017.0.098-iccifort-2017.0.098-GCC-5.4.0/bin64/mpiicpc 
    -I/homec/hbn28/hbn28e/Sources/chroma/mainprogs/main 
    -I/homec/hbn28/hbn28e/Sources/chroma/lib 
    -I../../lib 
    -O2 
    -Wall 
    -fopenmp 
    --std=c++11 
    -I/homec/hbn28/hbn28e/local-jureca/include 
    -I/homec/hbn28/hbn28e/local-jureca/include/libxml2 
    -I/usr/local/software/jureca/Stages/2016b/software/GMP/6.1.1-iccifort-2017.0.098-GCC-5.4.0/include 
    -O2 
    -Wall 
    -fopenmp 
    -I/homec/hbn28/hbn28e/local-jureca/include 
    -O2 
    -Wall 
    -fopenmp 
    -L../../lib 
    -L/homec/hbn28/hbn28e/local-jureca/lib 
    -L/usr/local/software/jureca/Stages/2016b/software/GMP/6.1.1-iccifort-2017.0.098-GCC-5.4.0/lib 
    -L/homec/hbn28/hbn28e/local-jureca/lib 
    -L../../other_libs/qdp-lapack/lib
    -o cfgtransf 
    cfgtransf.o 
    -lchroma 
    -lqdp 
    -lXPathReader 
    -lxmlWriter 
    -lqio 
    -llime 
    -L/homec/hbn28/hbn28e/local-jureca/lib 
    -lxml2 
    -lm 
    -lqmp 
    -lqmp 
    -lintrin 
    -lfiledb 
    -lfilehash 
    -lgmp 
    -lqphix_solver 
    -lqdp-lapack

我已经查看了 QPhiX::CommsUtils::sumDouble(double*)的函数定义的位置。在Chroma中,该功能没有单一的使用。因此,错误在qphix内,但没有注意到,因为没有文件包含标头文件qphix/include/qphix/comm.h。剥离,此文件在这里:

namespace QPhiX {
#ifndef QPHIX_DO_COMMS
    namespace CommsUtils {
        void sumDouble(double *d) {}
    }
#else
// I see a multiple definition error of `sumDouble` when compiling Chroma. I
// suspect that somehow both flags are passed. Therefore check that only one of
// the mutually exclusive flags is given. Perhaps it would be even better to
// use a `#else` here.
#if defined(QPHIX_FAKE_COMMS) && defined(QPHIX_QMP_COMMS)
#error                                                                         
    "You must specify QPHIX_FAKE_COMMS xor QPHIX_QMP_COMMS when specifying QPHIX_DO_COMMS."
#endif
#ifdef QPHIX_FAKE_COMMS
    namespace CommsUtils {
        void sumDouble(double *d) {}
    };
#endif // QPHIX_FAKE_COMMS
#ifdef QPHIX_QMP_COMMS
    namespace CommsUtils {
        void sumDouble(double *d) { QMP_sum_double(d); };
    };
#endif // QPHIX_QMP_COMMS
#endif // ifndef QPHIX_DO_COMMS
}; // Namespace

预处理器分支看起来只能在此文件中激活一个定义。如果QPHIX_FAKE_COMMSQPHIX_QMP_COMMS都是由构建系统给出的,则#error应该已激活。

这两个错误消息都是在libchroma.a中引起的,这必须是编译色度的中间建筑步骤。这两个定义在不同的对象文件(syssolver_mdagm_aggregate.osyssolver_linop_aggregate.o)中,但是C 源文件都不包含功能定义,它们都包括QPHIX标头文件。该功能sumDouble定义了。

这里会发生什么?sumDouble的两个定义即使在这两种情况下是三个变体中的两个定义也是一个问题?还是这意味着两个Chroma源文件包含带有不同预处理器标志的qphix/include/qphix/comm.h

我该如何解决?只是在qphix中显式 inline中的所有有问题的功能?无论如何,他们似乎只将QDP 库委派给了

也许我很不幸,Qphix和Chroma的devel分支不起作用,但是master也无法使用。因此,我再次想知道我做错了什么,假设人们开发此软件可以很好地编译。

如果您在标题文件中定义函数,则需要在其之前放置。


否则,如果多个文件包含它,当链接器尝试链接时,它将发现多个定义并报告多个定义错误(如果有内联错误,链接器将选择其中一个)。