web-dev-qa-db-ja.com

静的ライブラリに対してリンクする場合の「未定義の参照」

g ++(Ubuntu/Linaro 4.4.4-14ubuntu5)4.4.5

SdpAPI.aという次の静的ライブラリがあります。テストアプリケーションにリンクしようとすると問題が発生します。私は何か間違ったことをしているのではないかと思っています。静的ライブラリはg ++で構築されています。

私のディレクトリは次のとおりです。

/projects/unit_test/main.c
/projects/unit_test/sdp/inc/sdpAPH.h
/projects/unit_test/sdp/lib/sdpAPI.a

私のソースコードはこれです:

#include <stdio.h>

#include "sdpAPI.h"

int main(void)
{
    printf("----- TEST SDP ------\n");

    try {
        sdpSessionDescription sdp;
        sdp.clear();
    }
    catch(...) {
        printf("----- TEST FAILED --------\n");
        return 0;
    }

    printf("------ TEST SUCCESSFULL ------\n");

    return 0;
}

そして、私のMakefileはこれです:

OBJECT_FILES = main.o
CC = g++
CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0
TARGET = sdp_demo

INC_PATH = -I sdp/inc
LIB_PATH = -L sdp/lib/sdpAPI.a

$(TARGET): $(OBJECT_FILES)
 $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)

main.o: main.c
 $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) -c main.c

clean:
 rm -f $(TARGET) $(OBJECT_FILES) *~

これらは私が得ているリンカーエラーです:

undefined reference to `sdpSessionDescription::sdpSessionDescription()'
undefined reference to `sdpSessionDescription::clear()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'

提案に感謝します、

25
ant2009

_-L_は、特定のライブラリではなく、ライブラリpathを指定します。おそらく_-L sdp/lib -l sdpAPI_にパスおよびライブラリ名の両方を指定する必要があります。

ライブラリ名にlibと_.a_または_.sl_(または同様の)の接頭辞と接尾辞を付けようとします。

そのため、gccのマンページに従って、ライブラリの名前を_libsdpAPI.a_に変更する必要がある場合もあります。

_-l xyz_
リンカーは、ライブラリのディレクトリの標準リストを検索します。ライブラリは、実際には_libxyz.a_という名前のファイルです。


また、コマンドラインでの順序が重要であることにも留意してください。 $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)(オブジェクトの前のライブラリ)を実行すると、ライブラリをリストするポイントに未解決のシンボルがないため、そのライブラリからは何も取り込まれません。

その後、最終的にオブジェクト(未解決のシンボルを含む)を取り込むと、その後にリストされるライブラリがないため、オブジェクトはstay unresolvedになります。

通常、オブジェクトの後にライブラリを実行する必要があります。

_$(CC) $(CFLAGS) $(INC_PATH) $(OBJECT_FILES) $(LIB_PATH) -o $(TARGET)
_

ライブラリをチェックする前に、すべての未解決のシンボルが既知であることを確認します。

これはすべての問題(他の手段を使用して修正できる相互依存ライブラリなど)をキャッチしませんが、ライブラリを見る前にobjectファイル内のすべての未解決シンボルが認識されていることを確認します。

上記で引用したマニュアルページの同じセクションから:

コマンドでこのオプションを記述する場所に違いがあります。リンカーは、指定された順序でライブラリとオブジェクトファイルを検索して処理します。したがって、_foo.o -lz bar.o_は、ファイル_foo.o_の後、_bar.o_の前にライブラリzを検索します。 _bar.o_がz内の関数を参照している場合、それらの関数はロードされません。

44
paxdiablo
  • -Lは、ライブラリpathを指定するために使用されます。

    -Ldir-lを検索するディレクトリのリストにディレクトリdirを追加します

  • -lは、どのlibraryに対してリンクするかを指定する必要があるものです。

    -llibraryリンク時にlibraryという名前のライブラリを検索します。

おそらく-L sdp/lib/ -l sdpAPI

10
icecrime

さまざまなオプション、特に-lと-staticがどれほど正確に機能するかが、長い間私を混乱させていました。最後に、オンラインで見つけることができなかった詳細を取得するために、男性gccを行いました。これが他の誰かにも役立つことを願っています

-llibrary -l libraryリンク時にlibraryという名前のライブラリーを検索します。 (ライブラリを別の引数として使用する2番目の選択肢は、POSIX準拠のためだけであり、推奨されません。)

       It makes a difference where in the command you write this option;
       the linker searches and processes libraries and object files in the
       order they are specified.  Thus, foo.o -lz bar.o searches library z
       after file foo.o but before bar.o.  If bar.o refers to functions in
       z, those functions may not be loaded.

       The linker searches a standard list of directories for the library,
       which is actually a file named liblibrary.a.  The linker then uses
       this file as if it had been specified precisely by name.

       The directories searched include several standard system
       directories plus any that you specify with -L.

       Normally the files found this way are library files---archive files
       whose members are object files.  The linker handles an archive file
       by scanning through it for members which define symbols that have
       so far been referenced but not defined.  But if the file that is
       found is an ordinary object file, it is linked in the usual
       fashion.  The only difference between using an -l option and
       specifying a file name is that -l surrounds library with lib and .a
       and searches several directories.

-static動的リンクをサポートするシステムでは、共有ライブラリとのリンクを防ぎます。他のシステムでは、このオプションは効果がありません。

       This option will not work on Mac OS X unless all libraries
       (including libgcc.a) have also been compiled with -static.  Since
       neither a static version of libSystem.dylib nor crt0.o are
       provided, this option is not useful to most people.

-Ldir -lを検索するディレクトリのリストにディレクトリdirを追加します。

2
mna

知っておくべき3つのフラグ:

-Ldir -lLIB -static

静的ライブラリとリンクするため、3番目のフラグが必要です。そうしないと、動的ライブラリとリンクすることになります。