【问题标题】:G++. Cannot link libraryG++。无法链接库
【发布时间】:2020-05-18 11:13:22
【问题描述】:

我正在尝试链接一个库以编译一些 OpenGL 代码。

我有我要编译的源代码mytest1.cpp,在同一个目录中,我有一个名为include 的文件夹,其中包含头文件,另一个文件夹名为lib,其中包含所有库。

这就是名为lib 的文件夹中的内容:

所以当我运行此命令时,为了将所有内容链接在一起:

g++ -I.\include\ mytest1.cpp -L.\lib\ -llibfreeglut -lopengl32 -lglew32

我得到这个错误:

c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot fin
d -llibfreeglut
collect2.exe: error: ld returned 1 exit status

操作系统:Windows x64

编辑:我遵循了 Mike Kinghan 的指示,但不幸的是,这就是我得到的

C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x75): undefined
 reference to `_imp____glewDeleteVertexArrays'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x90): undefined
 reference to `_imp____glewDeleteBuffers'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc0): undefined
 reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xd9): undefined
 reference to `_imp____glewBindBuffer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xfa): undefined
 reference to `_imp____glewBufferData'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x123): undefine
d reference to `_imp____glewEnableVertexAttribArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x136): undefine
d reference to `_imp____glewVertexAttribPointer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x171): undefine
d reference to `_imp____glewBindBuffer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x195): undefine
d reference to `_imp____glewBufferData'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x1be): undefine
d reference to `_imp____glewEnableVertexAttribArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x1d1): undefine
d reference to `_imp____glewVertexAttribPointer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x20c): undefine
d reference to `_imp____glewBindBuffer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x230): undefine
d reference to `_imp____glewBufferData'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x273): undefine
d reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x28f): undefine
d reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x2db): undefine
d reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x4d4): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x6e8): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x859): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xaf1): undefine
d reference to `_imp____glewGenVertexArrays'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xb0c): undefine
d reference to `_imp____glewGenBuffers'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbbe): undefine
d reference to `initshaders(unsigned int, char const*)'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbd7): undefine
d reference to `initshaders(unsigned int, char const*)'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbf3): undefine
d reference to `initprogram(unsigned int, unsigned int)'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbfd): undefine
d reference to `_imp____glewGetUniformLocation'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc1e): undefine
d reference to `_imp____glewGetUniformLocation'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc3f): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc8e): undefine
d reference to `_imp____glewUniformMatrix4fv'
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: C:\Users\U
ser1\AppData\Local\Temp\ccyjpOjl.o: bad reloc address 0xd in section `.text$_ZSt
4sqrtf[__ZSt4sqrtf]'
collect2.exe: error: ld returned 1 exit status

【问题讨论】:

  • 我看到了反对票,但没有解决方案。如果这很容易,那么您为什么不提供解决方案而不是投反对票呢?这些天你发布的所有内容似乎都会被否决。

标签: opengl compiler-errors compilation linker g++


【解决方案1】:

也许您已经成功实现了以下链接:

g++ ... -L.\lib\ ... -lglew32

.\lib\glew32.lib,现在你想知道为什么有人喜欢:

g++ ... -L.\lib\ ... -llibfreeglut

找不到.\lib\libfreeglut.a

在这里,您在使用 Windows 端口时遇到了一些问题 一个 Unix/Linux 工具链 (GCC & GNU binutils)。

在 *nix 系统上,一个为链接提供 name 库的文件通常是 被称为libname.a(静态库)或libname.so(动态库,也称为共享库)。

-lname 选项指示 GNU 链接器搜索指定的和 文件libname.alibname.so 的默认库目录 并将找到的第一个输入到链接中。如果它发现两者在同一个 搜索目录然后它选择libname.so

但此协议不适用于工具链的 Windows 端口 - 例如您的 mingw 端口 - 因为在 Windows 上,原生传统是调用静态库 name.lib 和一个动态库 name.dll,一个动态库总是有 扩展.dll

所以你的mingw GNU 链接器服从-lname 通过搜索 任何文件:

libname.a libname.dll name.lib name.dll

(如果它和我的一样,它更喜欢*.lib 而不是*.a,以及*.a 而不是*.dll 如果在同一搜索目录中找到多个候选人。)

因此您的链接:

g++ -I.\include\ mytest1.cpp -L.\lib\ -llibfreeglut -lopengl32 -lglew32

会成功服从-lglew32,因为glew32.lib 存在于.\lib 中。 但它会在-llibfreeglut 上失败,因为没有一个:

liblibfreeglut.a liblibfreeglut.dll libfreeglut.lib libfreeglut.dll

存在。由于libfreeglut.a 确实存在,使用:

g++ -I.\include\ mytest1.cpp -L.\lib\ -lfreeglut -lopengl32 -lglew32

解决这个特定的联动失败。你没有向我们展示你期望的地方 链接器找到满足-lopengl32的文件。

稍后...新的麻烦

已获得找到图书馆的链接.\lib\libfreeglut.a 您现在有许多参考的未定义参考链接错误 从您自己的代码mytest1.cpp 匹配_imp____glew*。显然没有 正在解析您的代码对 glew 库的预期引用。

使用 Windows .lib.dll 文件时需要了解的一件事是 name.lib 文件可能是一个独立的静态库(相同的 存档格式为 *nix name.a 静态库),或者它可能是专门的 实际用作DLL import library 的存档 在链接时代表 DLL 的代理,后者是纯粹的 Microsoft 主意。 DLL 导入库name.lib 定义了_imp_<symbol>1 形式的符号,其在程序中的链接允许 OS loader 为程序提供一个指向<symbol> 的DLL 定义的运行时地址的指针, 当name.dll 被加载到进程地址空间时。

我有信心猜测您的 glew32.lib 实际上并不是一个静态库 您或其他人使用 mingw GCC 4.8.1 或 ABI compatible compiler 从源代码构建 但是是来自您下载的二进制glew 包的DLL 导入库 它是使用 Microsoft 编译器构建的,可与 Microsoft 编译器一起使用。

一般来说,您不能在同一个链接中混合目标文件和/或库 由不同的非 ABI 兼容编译器构建,并且 MS C/C++ 不是 ABI 与 GCC C/C++ 兼容。

名称修改协议是 ABI 的一部分。名称修饰协议 MS C++ 和 GCC/Clang C++ 是完全不同的和尝试的联系 将两者混合总是会因未定义的参考错误而失败。名字改头换面 MS C 和 GCC/Clang C 的协议有点分歧,但他们确实分歧, 并且您的联系现在违反了他们的分歧之一,试图 匹配 mingw g++ 从 C 头文件 <GL/*.h> 生成的 C 符号 当它使用 MS C 生成的 C 符号编译 mytest1.cpp 时 它建立了你的glew32.lib。例如,您的编译器输出未定义的 参考

_imp____glewBindVertexArray

链接只能解析为glew32.lib中定义的符号,但是 如果你运行:

>objdump -t glew32.lib | findstr "glewBindVertexArray"

在您的mingw 控制台中,您最接近的是:

__imp___glewBindVertexArray

缺少一个_

您需要构建glew - 静态库或 DLL,或两者兼有 - 从源代码使用您的 mingw 工具链,然后编译您的 mytest1.cpp(和 任何后续 GLEW 程序)使用您构建的库的头文件和 将您的程序与您构建的库链接起来。

您会在互联网上找到大量有关“为 mingw 构建 glew”的指南, 特别是在 Stackoverflow 上对Building glew on windows with mingw的回答中@


[1] 由于 C 或 C++ 编译器,<symbol> 本身可能有一个或多个前导 _ name-mangling 可能还有源代码命名约定。

【讨论】:

  • 谢谢!我尝试了您的命令,但编译器出现了太多错误,无法放入评论中,因此我将编辑问题。
  • 因为整整两天我都在为这个编译不成功而苦苦挣扎,我想知道......是否是我必须从源代码重新编译 FreeGLUT 的情况?
  • @user1584421 为您的新问题扩展答案。
猜你喜欢
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
相关资源
最近更新 更多