1

g++ でプログラムをビルドしようとしていますが、「未定義の参照」が発生します。

フォルダ構造:

Makefile
libs/
  libcrypotpp.a
  libz.a
sources/
  here are the sources and headers
out/
objfiles/

Makefile は次のようになります。

#makefile for program
#needs libz.a and libcryptopp.a

CC = g++
SOURCES = sources/*.cpp
LIBS = -lcryptopp -lz -pthread
LIBPATH = libs/
OBJPATH = objfiles/
OUTPUT = out/
OBJS = *.o
HEADERPATHS = -Isources -Isources/cryptopp

all:
    echo "Program"
    echo "------------------"
ifneq ("$(wildcard libs/libz.a)", "")
    echo "ZLIB found!"
ifneq ("$(wildcard libs/libcryptopp.a)", "")
    echo "Cryptopp found!"  #all librarys found
    $(CC) $(HEADERPATHS) -L$(LIBPATH) $(LIBS) $(SOURCES)
    mv *.o $(OBJPATH)
else
    echo "error: Cryptopp(libs/libcryptopp.a) was not found!"
endif
else ifneq ("$(wildcard libs/libcryptopp.a)", "")
    echo "Cryptopp found!"
    echo "error: ZLIB(libs/libz.a) was not found!"
else
    echo "error: ZLIB(libs/libz.a) was not found!"
    echo "error: Cryptopp(libs/libcryptopp.a) was not found!"
endif

.SILENT: all

g++ はコンパイルしますが、未定義の参照を出力します。

未定義の参照

なぜ失敗するのですか?

4

1 に答える 1

2

(静的) ライブラリには、それらにリンクするほとんどのアプリケーションで使用されないままのコードが多数含まれている可能性があるため、リンカーは、静的ライブラリのどの部分をアプリケーションにリンクするかについて非常に慎重になる傾向があります。

場合によっては、すべてがうまく機能するようにするために不文律に従う必要があるため、開発者としての生活がより困難になります。それらの不文律のいくつかは、

  • コマンドラインで指定された順序でリンカーが入力を処理すること
  • リンカーは、入力に対する最初のパスでライブラリのみを考慮します。これら 2 つを組み合わせると、ライブラリはリンカーへの以前の入力で見つかった未解決のシンボルのみを解決できるという効果があります。

その結果、リンカーを満足させるには、ライブラリを最後に指定する必要があり、ライブラリ A がライブラリ B に依存している場合は、A を B の前に指定する必要があります。

于 2012-11-23T12:32:29.733 に答える