为什么在链接时调用dlopen / dlclose / dlerror的库之前需要列出-ldl

问题描述

我正在使用gcc 6.2在RHEL上构建可执行文件(我们称之为foo.exe)。它链接到一些第三方库libzzdesign.so,libyydesign.so。 Yydesign使用dlopen / dlclose / dlerror。我希望此命令行能够正常工作:
g++ -Wall -fcheck-new -fno-strict-aliasing -msse2 -fno-omit-frame-pointer -pthread -O3 -Wl,--export-dynamic -o foo.exe foo.o -L/path/to/zzdesign -Wl,-rpath=/path/to/zzdesign -lzzdesign -L/path/to/yydesign -Wl,-rpath=/path/to/yydesign -lyydesign -ldl
(我列出了所有可能使用的选项)

它会产生错误
/path/to/yydesign/libyydesign.so: undefined reference to 'dlclose'
/path/to/yydesign/libyydesign.so: undefined reference to 'dlerror'

如果我更改命令行以将-ldl放在之前 -lyydesign
g++ -Wall -fcheck-new -fno-strict-aliasing -msse2 -fno-omit-frame-pointer -pthread -O3 -Wl,-rpath=/path/to/yydesign -ldl -lyydesign
...它没有错误

这与我以为我在链接时了解命令行中的库顺序的一切相反。

  1. 为什么-ldl必须先于-lyydesign
  2. 除了碰巧遇到这个解决方案的运气不好之外,我该如何解决原始错误,以了解发生了什么情况?
  3. 由于将构建系统更改为在所有需要的位置先移动-ldl有点痛苦,因此有什么方法可以避免不得不将-ldl放在首位?

解决方法

LD的库顺序确实很重要。库yydesign使用dlclosedlerror,这就是为什么需要在dl之前传递库yydesign的原因。