1

私は Makefile を作成するのが初めてです。動的リンクを使用するとプログラムを正常にコンパイルできますが、静的にコンパイルしようとすると「未定義の参照」エラーが発生します。

CC=g++
CXXFLAGS= -g -Wall -Wextra
#LDFLAGS= -g -l boost_iostreams #this works for dynamic linking
LDFLAGS= -Wl,-Bstatic -lboost_iostreams -Wl,-Bdynamic 

default: zoneParserTester

zoneParser:
    $(CC) $(CXXFLAGS) $(LDFLAGS) $@.cpp

zoneParserTester: zoneParser.o
    $(CC) $(CXXFLAGS) $(LDFLAGS) zoneParser.o -o $@ $@.cpp 

gzExample:
    $(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $@.cpp

オンラインで検索したところ、使用する正しい引数は次のように見えました: "-Wl,-Bstatic -lboost_iostreams -Wl,-Bdynamic"。誰かが私が間違っていることを教えてもらえますか?

4

1 に答える 1

3

静的リンクと動的リンクの重要な違いがありません。アプリケーション A をライブラリ B に動的にリンクすると、明示的に指定しなくても、実行時にライブラリ B の すべての依存関係が取り込まれます。アプリケーションを静的にリンクする場合、リンク時にライブラリ B のすべての依存関係 (および依存関係の依存関係など) を依存関係チェーンと同じ順序で含める必要もあります(つまり、アプリケーション A がライブラリ B に依存している場合、ライブラリ B はライブラリ C に依存するため、ライブラリをその順序で指定する必要があります (これは .o ファイルにも当てはまります)。

特定のライブラリの依存チェーン全体 (およびその順序) を把握するのは、少し面倒な場合があります。リンク中のエラー メッセージからヒントが得られる場合があります。それでも解決しない場合は、他にいくつかの方法があります。

  1. 十分な情報に基づいて推測してください: libboost_iostreams が何に依存しているかを推測する 1 つの方法は、ライブラリの動的バージョンが何に依存しているかを調べることです。ldd ツールを使用してこれを行うことができます。

    $ ldd /usr/lib/libboost_iostreams.so.1.46.1 
    

    私のコンピューターでは、libz と libbz2 に依存しています。したがって、追加するだけでアプリケーションがリンクされると確信しています

    -lbz2 -lz
    

    アプリケーションをリンクする行に。-Wl,-Bstatic が必要かどうかはわかりません。私にとっては、-static を指定するだけで十分です。

     $ gcc -static -o test test.cpp -lboost_iostreams -lbz2 -lz
    
  2. pkg-config を使用します。ほとんどのパッケージ (残念ながらブーストではありません) は、特定のライブラリを使用するためにプログラムをリンクする方法を正確に追跡する pkg-config ファイルをインストールします。たとえば、libcairo に静的にリンクしたいとします。

    $ pkg-config --static --libs cairo
    -pthread -lcairo -lgobject-2.0 -lffi -lpixman-1 -lfontconfig -lexpat -lfreetype -lpng12 -lz -lm -lxcb-shm -lxcb-render -lXrender -lglib-2.0 -lrt -lpcre -lX11 -lpthread -lxcb -lXau -lXdmcp 
    
  3. .la ファイルと libtool を使用します。これはやや非推奨の方法であり、ますます使用されなくなっているため、.la ファイルの可用性はディストリビューションによって異なります。libtool は、この問題を回避するためのもう 1 つのツールです。リンクするときは、g++ を直接使用する代わりに、libtool というラッパーを使用します。

    $ libtool --mode=link gcc -static -o my_app -lboost_iostreams
    

    libtool は、必要なライブラリを追加して、自動的に gcc に渡そうとします。これは、ライブラリと同じ名前 (この場合は libboost_iostreams) で、接尾辞が .la (.a ではなく) のファイルを検索することによって行われます。.la ファイルをテキスト エディターで開くと、libboost_iostreams の依存関係がリストされていることがわかります。私は個人的に libtool が好きではありません。セットアップが少し難しく、ますます使用されなくなりました。おそらく.laファイルを見て、依存関係を手動で追加するだけです。

于 2013-08-22T11:07:35.077 に答える