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

由于(静态)库可以包含许多在大多数链接到它们的应用程序中未使用的代码,因此链接器对于它们将链接到应用程序的静态库的哪些部分往往非常保守。

在某些情况下,这会使我们作为开发人员的生活更加困难,因为您必须遵循不成文的规则才能让所有东西都能正常运行。其中一些不成文的规则是

  • 链接器按照在命令行中给出的顺序处理其输入
  • 链接器仅在第一次通过输入时考虑库 这两个组合的效果是库只能解析在链接器的早期输入中找到的未解析符号。

结果是,为了让链接器满意,应在最后指定库,如果库 A 依赖于库 B,则应在 B 之前指定 A。

于 2012-11-23T12:32:29.733 回答