/usr/bin/ld:
.gnu.linkonce.t._ZSt18uninitialized_copyIN9__gnu_cxx17__normal_iteratorIPKN5boost7variantINS2_8weak_ptrIvEENS2_8s
.gnu.linkonce.r._ZSt18uninitialized_copyIN9__gnu_cxx17__normal_iteratorIP
ignals26detail21foreign_void_weak_ptrENS2_6detail7variant5void_ESB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_EESt6vectorI
SC_SaISC_EEEEPSC_ET0_T_SL_SK_' referenced in section
KN5boost7variantINS2_8weak_ptrIvEENS2_8signals26detail21foreign_void_weak_ptrENS2_6detail7variant5void_ESB_SB_SB_SB_SB_SB_SB_SB
SB_SB_SB_SB_SB_SB_SB_SB_SB_EESt6vectorISC_SaISC_EEEEPSC_ET0_T_SL_SK’ of ../fancirclese/libfancirclese.a(fancirclese_dump_thre
ad.o): defined in discarded section `.gnu.linkonce.t._ZSt18uninitialized_copyIN9__gnu_cxx17__normal_iteratorIPKN5boost7variantI
NS2_8weak_ptrIvEENS2_8signals26detail21foreign_void_weak_ptrENS2_6detail7variant5void_ESB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_SB_S
B_SB_SB_SB_EESt6vectorISC_SaISC_EEEEPSC_ET0_T_SL_SK_’ of ../fancirclese/libfancirclese.a(fancirclese_dump_thread.o)
以上是我遇到的编译warning
经网上搜索发现这是gcc编译器引入后COMDAT section(或者叫linkonce section)才会出现的。
COMDAT section简单地说就是编译器将可能存在多处定义的symbol(c++模板、inline函数等)作了一个特殊处理,放到了一个特殊的section,这样多个object文件的COMDAT section可能保存了同一个symbol的信息,在linker选择symbol进行读取的时候只会选择其中一个section,而丢弃其他secition。
如果由于链接顺序不对,导致引用了不对的section(即被丢弃的那个),就会报这个错。(不同的编译参数,如-g -pipe -W -Wall -fPIC -O2,可能导致这个问题)
为解决这个问题,需要统一编译参数,并检查链接顺序(按照链接参数从左向右链接)。
以上的warning经排查就是因为链接的某一个库的编译参数与其他模块不同,少了-O2
还有一种warning:
/usr/bin/ld:
.gnu.linkonce.t._ZN5boost8signals25slot0IvNS_8functionIFvvEEEED1Ev' referenced in section
.gnu.linkonce.r._ZN5boost8signals25slot0IvNS_8functionIFvvEEEED1Ev’ of ./libut_doraemon.a(ut_doraemon_city_id_data_handler.o): defined in discarded section `.gnu.linkonce.t._ZN5boost8signals25slot0IvNS_8functionIFvvEEEED1Ev’ of ./libut_doraemon.a(ut_doraemon_city_id_data_handler.o)
这个warning是因为一个模板类的T类型在定义的时候,显示定义了析构函数,导致引用了不同的基类。