使用 GNU 链接器的正确方法
Posted
技术标签:
【中文标题】使用 GNU 链接器的正确方法【英文标题】:The correct way to use the GNU linker 【发布时间】:2020-08-26 23:35:03 【问题描述】:我正在尝试在 ubuntu 环境中使用几个库 libglfw3-dev 和 libglew-dev,但无法让链接器执行其预期目的。我通常会使用 makefile,但出于调试目的,我刚刚在 CLI 上使用了 g++。
g++ -I-Iinclude -I/usr/include/GL -I/usr/include/GLFW -L/usr/lib/x86_64-linux-gnu/
我知道我需要使用 -l 标志来指定库本身,但会收到表单错误
/usr/bin/ld: cannot find -llibglfw
这里是一些关于包裹位置的信息(省略不相关的)
root@Jake-Faptop:/usr/include/GLFW# dpkg -L libglfw3-dev
/usr/include/GLFW/glfw3.h
/usr/include/GLFW/glfw3native.h
/usr/lib/x86_64-linux-gnu/libglfw.so
root@Jake-Faptop:/usr/include/GLFW# dpkg -L libglew-dev
/usr/include/GL/glew.h
/usr/include/GL/glxew.h
/usr/include/GL/wglew.h
/usr/lib/x86_64-linux-gnu/libGLEW.so
共享库的名称让我非常困惑,因为它们被命名为 /usr/lib/x86_64-linux-gnu/libGLEW.so.2.1.0
和 /usr/lib/x86_64-linux-gnu/libglfw.so.3.3
---编辑---
根据给出的在库名称上省略前缀和后缀的建议,我仍然在以下输入中遇到链接器错误
g++ -Iinclude -I/usr/include/GL -I/usr/include/GLFW -L/usr/lib/x86_64-linux-gnu/ -lGLEW -lglfw src/main.cpp -o build/main
->
/usr/bin/ld: main.cpp:(.text+0x3b): undefined reference to glfwTerminate'
/usr/bin/ld: main.cpp:(.text+0x54): undefined reference to `glfwWindowHint'
/usr/bin/ld: main.cpp:(.text+0x63): undefined reference to `glfwWindowHint'
/usr/bin/ld: main.cpp:(.text+0x72): undefined reference to glfwWindowHint'
Confused.com...
【问题讨论】:
去掉名字开头的lib
是否也应该省略版本号和 .so 后缀?
是的,您只传递不带lib
且不带后缀(.so
、a
、...)且不带版本的库名称。
【参考方案1】:
删除名称开头的lib
。例如。图书馆的名字是
libGLEW.so.2.1.0
链接
-lGLEW
这将链接到libxGLEW.so
,这通常是一个符号链接到一个版本库,如libGLEW.so.2.1.0
。
-图书馆
-l 库
链接时搜索名为 library 的库。 (将库作为单独参数的第二种选择仅用于 POSIX 合规性,不推荐。)
-l 选项由 GCC 直接传递给链接器。有关详细信息,请参阅您的链接器文档。下面的一般描述适用于 GNU 链接器。
链接器搜索库的标准目录列表。搜索的目录包括几个标准系统目录以及您使用 -L 指定的任何目录。
静态库是目标文件的存档,文件名类似于 liblibrary.a。一些目标还支持共享库,通常具有类似 liblibrary.so 的名称。如果同时找到静态库和共享库,则链接器会优先选择与共享库进行链接,除非使用了 -static 选项。
在命令的哪个位置写这个选项会有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,“foo.o -lz bar.o”在文件 foo.o 之后但在 bar.o 之前搜索库“z”。如果 bar.o 引用了“z”中的函数,则这些函数可能不会被加载。
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
【讨论】:
@JakeO'Neill Tryg++ src/main.cpp -o build/main -Iinclude -I/usr/include/GL -I/usr/include/GLFW -L/usr/lib/x86_64-linux-gnu/ -lGLEW -lglfw
我的答案中的最后一段说:“在您编写此选项的命令中有所不同;链接器搜索并处理库和目标文件按照它们指定的顺序。因此,“foo.o -lz bar.o”在文件 foo.o 之后但在 bar.o 之前搜索库“z”。如果 bar.o 引用“z”中的函数,这些函数可能未加载。”以上是关于使用 GNU 链接器的正确方法的主要内容,如果未能解决你的问题,请参考以下文章