虽然符号出现在* .so文件中,但是g ++未定义引用

时间:2017-04-06 13:20:48

标签: c++ g++ undefined-reference name-mangling

我发现了一些类似的问题(例如thisthatthis),但这些问题都没有帮我解决问题。我有一个* .so文件(来自gnss-sdr的核心),如下所示:

DECLARE @Table1 table (Week_End_Date DATE)

INSERT INTO @Table1 
VALUES ('2016-04-03'), ('2016-04-10'), ('2016-04-17'), ('2016-04-24'),
       ('2016-05-01'), ('2016-05-08'), ('2016-05-15'), ('2016-05-22'),
       ('2016-05-29'), ('2016-06-05'), ('2016-06-12'), ('2016-06-19'),
       ('2016-06-26'), ('2016-07-03'), ('2016-07-10'), ('2016-07-17'),
       ('2016-07-24'), ('2016-07-31'), ('2016-08-07'), ('2016-08-14'),
       ('2016-08-21'), ('2016-08-28'), ('2016-09-04'), ('2016-09-11'),
       ('2016-09-18'), ('2016-09-25'), ('2016-10-02'), ('2016-10-09'),   
       ('2016-10-16'), ('2016-10-23'), ('2016-10-30'), ('2016-11-06'),
       ('2016-11-13'), ('2016-11-20'), ('2016-11-27'), ('2016-12-04'),
       ('2016-12-11'), ('2016-12-18'), ('2016-12-25'), ('2017-01-01'),
       ('2017-01-08'), ('2017-01-15'), ('2017-01-22'), ('2017-01-29'),   
       ('2017-02-05'), ('2017-02-12'), ('2017-02-19'), ('2017-02-26'),
       ('2017-03-05'), ('2017-03-12'), ('2017-03-19'), ('2017-03-26'),
       ('2017-04-02'), ('2017-04-09'), ('2017-04-16'), ('2017-04-23'),
       ('2017-04-30'), ('2017-05-07'), ('2017-05-14'), ('2017-05-21'),
       ('2017-05-28'), ('2017-06-04'), ('2017-06-11'), ('2017-06-18'),
       ('2017-06-25'), ('2017-07-02'), ('2017-07-09'), ('2017-07-16'),
       ('2017-07-23'), ('2017-07-30'), ('2017-08-06'), ('2017-08-13'),
       ('2017-08-20'), ('2017-08-27'), ('2017-09-03'), ('2017-09-10'),
       ('2017-09-17'), ('2017-09-24'), ('2017-10-01'), ('2017-10-08'),
       ('2017-10-15'), ('2017-10-22'), ('2017-10-29'), ('2017-11-05'),
       ('2017-11-12'), ('2017-11-19'), ('2017-11-26'), ('2017-12-03'),
       ('2017-12-10'), ('2017-12-17'), ('2017-12-24'), ('2017-12-31'),
       ('2018-01-07'), ('2018-01-14'), ('2018-01-21'), ('2018-01-28'),
       ('2018-02-04'), ('2018-02-11'), ('2018-02-18'), ('2018-02-25'),
       ('2018-03-04'), ('2018-03-11'), ('2018-03-18'), ('2018-03-25'),
       ('2018-04-01')

DECLARE @FirstWeek INT = (SELECT DATEPART(WEEK,MIN(Week_End_Date))-1 FROM @Table1)

SELECT
    Week_End_Date,
    ROW_NUMBER() OVER (ORDER BY Week_End_Date)+@FirstWeek AS WeekNumber
FROM 
    @Table1 

包含符号$nm libgnss_system_parameters_dyn.so | c++filt |grep Gps_Eph ,它应该是构造函数。

我写了一些最小的代码:

Gps_Ephemeris::Gps_Ephemeris()
我编译的

#include <iostream>
#include <core/system_parameters/gps_ephemeris.h>

int main(int argc,const char* argv[])
{
    Gps_Ephemeris ge;
    return 0; 
}

然后链接器抱怨:

g++  main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn`

我也尝试了 cmake ,但是它生成的行类似于它(它在链接之前只添加了/tmp/ccHCvldG.o: In function `main': main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()' collect2: error: ld returned 1 exit status ),它仍然生成完全相同的链接器错误。

请注意,库和我的最小代码都是使用相同的编译器(g ++ - 5)编译的,具有完全相同的标志和相同的c ++ 0x标准。

解决Maxim Egorushkin的答案:

-rdynamic

不输出任何内容。但是,符号在静态库中定义(即。 * .a库):

nm --demangle --defined-only --extern-only libgnss_system_parameters.so  |grep Gps_Eph

知道两者都是由 cmake 生成的,通过以下方式:

00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()

这些库中包含/定义的符号应该没有区别,对吗?我在add_library(lib_name SHARED ${sources_etc}) #for the *.so add_library(lib_name_2 ${sources_etc}) #for the *.a cmake 文档中没有注意到任何内容。我错过了一些明显的东西吗?

2 个答案:

答案 0 :(得分:21)

检查.so导出符号是nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>的迂腐正确的方法。

如果没有--defined-only,您的命令也会显示 undefined 符号。

如果没有--extern-only,它还会显示内部链接的符号,这些符号无法用于链接。

看起来您需要关联其他库,因为Gps_Ephemeris::Gps_Ephermeris()未通过链接libgnss_system_parameters_dyn.so来解决。一个好的开始方式是库的文档和示例。

答案 1 :(得分:2)

我在过去发现此类错误是由于包含文件中缺少正确的extern "C" { ... }包围而导致的。