运行时报错undefined symbol

问题:链接动态库so后,运行时报错undefined symbol

解决方法:我遇到的是因为在编译动态库so时,需要链接多个静态库,-la -lb -lc没有按照依赖顺序排列

gcc中链接顺序问题,总结出以下几点:

  • 动态库中可以包含另一个静态库,通过参数 -lxxx 把静态库libxxx.a加入so文件中,这样so文件中就包含了libxxx.a的所有实现。当然,如果不包含libxxx.a也没有问题,这样生成的so会小一点。
  • 如果不包含libxxx.a,最终使用这个so的可执行文件,在其生成时必须加入 -lxxx。2个so文件可以包含同一个静态库libxxx.a,最终生成exe文件时,不会产生冲突。更广泛的说,生成exe文件时候,可以链接多个so文件和a文件,如果其中的a文件有多份实现,最终只会有一份生效,其他都会被忽略。不用担心冲突。
  • 当生成exe时候,当a文件有多份实现时,最左边指定的a文件才生效。

具体例子来说:

  • libstatic.a : 一个静态库文件
  • libdynamic1.so:需要使用libstatic.a中的函数,但是没有包含libstatic.a
  • libdynamic2.so:需要使用libstatic.a中的函数,包含libstatic.a
  • libdynamic3.so:需要使用libstatic.a中的函数,也包含libstatic.a
  • test.exe:最终的生成的可执行文件(linux对后缀没有要求,为了说明文件,姑且用exe后缀来表示可执行文件)

gcc中库的链接顺序是从右往左进行,所以要把最基础实现的库放在最后,这样左边的lib就可以调用右边的lib中的代码。同时,当一个函数的实现代码在多个lib都存在时,最左边的lib代码最后link,所以也将最终保存下来。

打赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注