web-dev-qa-db-ja.com

シンボルが* .soファイルに存在するが、g ++未定義参照

同様の質問をいくつか見つけました(例: thisthat または this ))どれも私の問題の解決に役立ちませんでした。 * .soファイルがあります( gnss-sdr のコアから)。

_$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`
_

次に、リンカは文句を言います:

_/tmp/ccHCvldG.o: In function `main':
main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()'
collect2: error: ld returned 1 exit status
_

私もcmakeを試しましたが、生成された行はそれに似ていました(リンクする前に_-rdynamic_を追加しただけです)、それでもまだ生成されましたまったく同じリンカエラー。

ライブラリと最小限のコードの両方が、まったく同じフラグと同じc ++ 0x標準を使用して、同じコンパイラ(g ++-5)でコンパイルされていることに注意してください。


Maxim Egorushkinによる答えに対処するには、次の行を使用します。

_nm --demangle --defined-only --extern-only libgnss_system_parameters.so  |grep Gps_Eph
_

何も出力しません。ただし、シンボルは静的ライブラリで定義されています(つまり* .aライブラリ):

_00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
_

どちらもcmakeによって次のように生成されることがわかります。

_add_library(lib_name SHARED ${sources_etc}) #for the *.so
add_library(lib_name_2 ${sources_etc}) #for the *.a
_

これらのライブラリに含まれる/定義されるシンボルに違いはないはずですよね? cmakeの_add_library_に関するドキュメントには何も記載されていません。明らかなものがないのですか?

36
Ash

_.so_がシンボルをエクスポートすることを確認するための正確な方法は_nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>_です。

_--defined-only_がない場合、コマンドにはndefined記号も表示されます。

_--extern-only_がないと、リンクに使用できない内部リンケージのシンボルも表示されます。

Gps_Ephemeris::Gps_Ephermeris()は_libgnss_system_parameters_dyn.so_をリンクしても解決されないため、別のライブラリをリンクする必要があるようです。開始する良い方法は、そのライブラリのドキュメントと例です。

26

このタイプのエラーは適切なextern "C" { ... }インクルードファイル内のブラケット。

2
Nicole