c++ - g++ 静态库的顺序很重要吗?

标签 c++ makefile g++

为了这个问题我折腾了一整天。我在我的项目中使用了一些库,但我总是遇到一些编译错误,提示 undefined reference

相关文件如下:

encode.cc//the main file
url_codec.h//the header of the libraries, got some function definition in it
libimageenc.a
libmbpicenc.a
liburlaes.a
liburldecode.a

生成文件是这样的:

cflags = -Wall -O2 -fPIC

libpath=./libs/
libs+=$(libpath)liburlaes.a
libs+=$(libpath)liburldecode.a $(libpath)libimageenc.a $(libpath)libmbpicenc.a

cxx  = g++
bin  = encode

all: $(bin)

srcs = $(shell ls *.cc *.cpp)
objs = $(srcs:%.cc=%.o)

$(bin):${objs}
    $(cxx) $(cflags) $(inc) -o $@ ${objs} ${libs}

$(objs):%.o:%.cc
    $(cxx) $(cflags) $(inc) -c -o $@ $<

clean:
    rm -f *.o
    rm -f *.bak
    rm -f $(bin)

g++ 编译器提示:

g++ -Wall -O2 -fPIC  -o encode encode.o ./libs/liburlaes.a ./libs/liburldecode.a ./libs/libimageenc.a ./libs/libmbpicenc.a
./libs/liburldecode.a(url_codec.o): In function `url_codec::offpic_url_decode_func(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&)':
url_codec.cc:(.text+0x18da): undefined reference to `uuid_unparse'
./libs/liburldecode.a(crypto_aes.o): In function `encode_aes':
crypto_aes.cc:(.text+0x4e): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `decode_aes':
crypto_aes.cc:(.text+0xae): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_encrypt_key':
crypto_aes.cc:(.text+0xf3): undefined reference to `AES_set_encrypt_key'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_decrypt_key':
crypto_aes.cc:(.text+0x143): undefined reference to `AES_set_decrypt_key'
collect2: ld returned 1 exit status

但所有这些功能都在 liburlaes.a 中定义良好,如 nm -C

所示
    nm -C liburlaes.a | grep -i 'aes'
    decode_byaes.o:
         U AES_cbc_encrypt
         U AES_set_decrypt_key
         U AES_set_encrypt_key
00000060 T decode_byaes
00000000 T encode_byaes
00000110 T init_byaes_decrypt_key
000000c0 T init_byaes_encrypt_key
         U decode_byaes
         U encode_byaes
         U init_byaes_decrypt_key
         U init_byaes_encrypt_key

liburlaes.a 移动到 libs 的末尾,事情不会变得更好,输出与上面完全相同。向后移动 libimageenc 会使情况变得更糟,更多的符号声称未定义:

libs+=$(libpath)liburldecode.a $(libpath)libimageenc.a $(libpath)libmbpicenc.a
libs+=$(libpath)liburlaes.a

那么,我该如何解决这个问题呢?

更新

我试图将 liburlaes.a 放在两边,但它不起作用,我用 '**' 包裹了 libaray 以强调:

g++ -Wall -O2 -fPIC  -o encode encode.o **./libs/liburlaes.a** ./libs/liburldecode.a ./libs/libimageenc.a ./libs/libmbpicenc.a **./libs/liburlaes.a**
./libs/liburldecode.a(url_codec.o): In function `url_codec::offpic_url_decode_func(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&)':
url_codec.cc:(.text+0x18da): undefined reference to `uuid_unparse'
./libs/liburldecode.a(crypto_aes.o): In function `encode_aes':
crypto_aes.cc:(.text+0x4e): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `decode_aes':
crypto_aes.cc:(.text+0xae): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_encrypt_key':
crypto_aes.cc:(.text+0xf3): undefined reference to `AES_set_encrypt_key'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_decrypt_key':
crypto_aes.cc:(.text+0x143): undefined reference to `AES_set_decrypt_key'
collect2: ld returned 1 exit status
make: *** [encode] Error 1

最佳答案

是的,库的顺序绝对重要。你需要先放任何使用图书馆的东西,然后是图书馆。

我遇到过库 A 依赖于库 B 中的某些东西,而库 B 需要库 A 中的东西的情况,因此您需要将库 A 两次放入列表中。

链接器的工作方式是处理目标文件,然后读取库以解析目标文件中不存在的符号。如果库有对象"file"来解决依赖关系,那么这些部分都包括在内。然后它继续到下一个图书馆。它不会“记住”它在以前的库中看到的内容。

关于c++ - g++ 静态库的顺序很重要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17669941/

相关文章:

c++ - 可移植地编译整个目录

python - 如何在 Windows 中安装 pacparser?

ubuntu - make 命令无法识别 .o 文件格式

c++ - 我可以让虚拟抽象类抛出异常吗

c++ - Connect 4 板中的不均匀圆圈

c - Makefile - 用函数替换冗余

c++ - 最大警告数

c++ - cartTexture 成员实际上是否正确初始化?

c++ - 具有析构函数和新运算符的类。

c++ - 闯入 vector