g ++静态库的顺序问题? [英] g++ the order of static library matters?

查看:233
本文介绍了g ++静态库的顺序问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在为这个问题奋斗一整天。我在我的项目中使用一些库,我总是有一些编译错误抱怨未定义的引用



如下:

  encode.cc //主文件
url_codec.h //库的标题,得到一些函数定义
libimageenc.a
libmbpicenc.a
liburlaes.a
liburldecode.a

makefile如下:

  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 = $ ls * .cc * .cpp)
objs = $(srcs:%。cc =%。o)

$(bin):$ {objs}
$ )$(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):在函数`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>>& amp;)':
url_codec.cc:(.text+0x18da):undefined reference to`uuid_unparse'
./libs/liburldecode.a(crypto_aes.o):在函数`encode_aes'中:
crypto_aes.cc:(.text+0x4e):未定义引用`AES_cbc_encrypt'
./ libs / liburldecode.a(crypto_aes.o):在函数`decode_aes'中:
crypto_aes.cc:(.text+0xae):未定义引用`AES_cbc_encrypt'
./libs/liburldecode.a crypto_aes.o):在函数`init_aes_encrypt_key'中:
crypto_aes.cc:(.text+0xf3):未定义的引用`AES_set_encrypt_key'
./libs/liburldecode.a(crypto_aes.o):In函数`init_aes_decrypt_key':
crypto_aes.cc:(.text+0x143):未定义的引用`AES_set_decrypt_key'
collect2:ld返回1退出状态
但是所有这些函数都是在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
/ pre>

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



UPDATES p>

我试图把 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):在函数`url_codec :: offpic_url_decode_func(std :: basic_string< char,std :: char_traits< char>,std :: allocator< char>> const& unsigned int& std :: basic_string& std :: char_traits< char>,std :: allocator< char>>& amp;)':
url_codec.cc:(.text+0x18da):未定义引用`uuid_unparse'
./libs/liburldecode.a(crypto_aes.o):在函数`encode_aes'中:
crypto_aes.cc:(.text+0x4e):未定义对`AES_cbc_encrypt'
./libs/liburldecode的引用。 a(crypto_aes.o):在函数`decode_aes'中:
crypto_aes.cc:(.text+0xae):未定义引用`AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o) :在函数`init_aes_encrypt_key'中:
crypto_aes.cc:(.text+0xf3):未定义引用`AES_set_encrypt_key'
./libs/liburldecode.a(crypto_aes.o):在函数`init_aes_decrypt_key' :
crypto_aes.cc:(.text+0x143):未定义的引用`AES_set_decrypt_key'
collect2:ld返回1退出状态
make:*** [encode]错误1


解决方案

是的,图书馆的顺序确实很重要。你需要把任何使用库首先,然后是库。



我有一些案例,其中库A依赖于库B中的某些东西,库B需要库A中的某些东西,因此您需要在库列表A中加入库A两次。



链接器工作的方式是它处理对象文件,然后读取库来解析对象文件中不存在的符号。如果库具有对象files来解决依赖性,则包括这些部分。然后进入下一个图书馆。它不记住在以前的图书馆看到了什么。


I have been struggling all day for this problem. I use some libraries in my project and I always got some compilation errors complaining that undefined reference.

The relevant files are as follows:

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

The makefile is like:

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)

The g++ compiler complains that:

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

But all these function are well defined in liburlaes.a as shown by 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

Things won't get better by moving the liburlaes.a to the end of libs, the output is exactly as above. And move libimageenc backward will make it worse, with more symbols claimed undefined:

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

So, how can I fix this?

UPDATES

I tried to put the liburlaes.a in both side, but it doesn't work, I wrap the libaray with '**' to emphasize :

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

解决方案

Yes, the order of libraries definitely matter. You need to put whatever uses the library first, then the library.

I have had cases where library A depends on something in library B, and library B needs something in library A, so you then need to put library A twice in the list.

The way the linker works is that it processes the object files, then reads the libraries to resolve the symbols not present in the object files. If the library has the object "files" to solve the dependency, then those parts are included. It then goes on to the next library. It doesn't "remember" what it has seen in the previous libraries.

这篇关于g ++静态库的顺序问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆