链接库C++链接器的顺序

The order of the linked libraries C++ linker

本文关键字:链接 顺序 C++      更新时间:2023-10-16

我正在调试一个依赖于一组库的项目,包括libfreenect,OpenGL和OpenCL。问题是输出是黑屏。

作为调试选项,我已经完全删除了 OpenCL 代码和链接库,以确保 OpenGL 工作正常,幸运的是它确实如此。

我注意到但不明白的是,我的项目使用这种库顺序运行良好

 -lfreenect -lGL -lglut -lGLU -lOpenCL 

另一方面,使用此顺序时会给出黑屏

-lfreenect -lOpenCL -lGL -lglut -lGLU

我的问题是:为什么链接库的顺序会影响程序的输出?

系统上安装的 OpenCL 接口库可能会拉入与程序最终加载的libGL.so不同的libGL.so。例如,如果您已经安装了 Mesa OpenCL 实现,但使用的是 NVidia 驱动程序,那么链接到 Mesa 的 OpenCL 可能会拉入 Mesa 的 libGL,与 OpenGL 在您的系统上工作所需的 libGL 冲突;当然,这只是猜测。

尝试在任一链接顺序配置中对生成的程序二进制文件使用 ldd,并查看它实际拉入了哪些共享对象(在哪些路径中)。

可以

这样想:

您已编译目标文件。这些文件需要额外的方法,而这些方法不存在,在链接步骤中,您需要提供"覆盖"这些所需方法的库,以便它可以创建一个整洁的可执行文件。

对于您提供的每个库,链接器都会获取它,对其进行处理,如果找到所需的方法,则使用它们。然后,它重建缺少方法的表,并继续包含下一个库。

如果第一个库包含 OpenCL,

但项目不直接调用 OpenCL 方法,则链接器将丢弃该库。稍后,当您包含需要 OpenCL 的库时,它将划出"未定义的 XXXXX 方法",因为该库已被处理。或者,在您的情况下,它可能使用另一个与您真正打算使用的内部库不同的内部库。

一个好的规则是最后包含"基本"库,以便它们在所有其他库中使用。在这种情况下,OpenCL 不依赖于任何 GL 库,因此您应该最后添加它。