我在MinGW
下遇到链接器失败,但我看不出原因。这是链接命令:
g ++ -shared -mthreads -Wl, - out-implib,C:\ Users \ camm \ Syren \ libs \ libSy_polyMesh.a -o C:\ Users \ camm \ Syren \ libs \ Sy_polyMesh.dll debug / Sy_polyMesh.o debug / moc_Sy_polyMesh.o debug / qrc_Sy_polyMesh.o -L“c:\ Qt \ 4.8.4 \ lib” -lglu32 -lopengl32 -lgdi32 -luser32 -LC:\ Users \ camm \ Syren / libs -lSyren -lglew32 -lboost_system -lQtSvgd4 -lQtSqld4 -lQtOpenGLd4 -lQtGuid4 -lQtCored4
undefined reference
错误来自Syren
dll(我应该说明命令是由qmake
自动生成的)。由于前向和反斜杠的混合,-LC:\Users\camm\Syren/libs
对我来说看起来很不正常,但是如果我手动将它们设置为所有方向 - 它不会改变编译器输出。
我之前遇到过我需要的第三方库的问题(特别是GLEW和Boost),但因为它们相对“常量”,所以将它们放在我的C:\MinGW\lib
目录中没有问题。但这对我的插件来说真的不是一个选择。
我发现MinGW docs状态位于以下几个位置:
...因为可以始终使用-L指定合适的搜索路径 选项。
...但是GCC本身通过提供有效的默认值 适当的-L选项。
但是,C:\Users\camm\Syren\libs
是Syren.dll
所在的位置!
编辑:以下是.pro
文件中的LIBS声明:
LIBS += -L$(SYREN_PATH)/libs \
-lSyren
win32 {
LIBS += -lglew32 \
-lboost_system
}
$(SYREN_PATH)
扩展为C:\Users\camm\Syren
。另外,我可以看到Syren.dll
中的“缺失”符号,例如:
C:\用户\ CAMM \文件\警报器\ Sy_polyMesh_debug /../ Sy_polyMesh / SRC / Sy_polyMesh.cpp:341: 未定义的引用`Sy_GLBuffer :: unbind()'
可以看作列为:
6c500bd6 T _ZN11Sy_GLBuffer6unbindEv
EDIT2
在链接器阶段添加详细标志后,我注意到链接器正在遍历每个搜索路径,然后遍历每个库命名约定,并使用它可以打开的第一个。
attempt to open C:\Users\camm\Syren/libs/libSyren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/libSyren.a succeeded
假设libSyren.a
可能被破坏,我重命名它以强制链接器使用.dll
:
attempt to open C:\Users\camm\Syren/libs/libSyren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/libSyren.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.lib failed
attempt to open C:\Users\camm\Syren/libs/libSyren.dll failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll succeeded
但我仍然得到完全相同的错误消息!
答案 0 :(得分:2)
如果您链接正确的DLL并且链接器没有抱怨丢失文件,则dll可能会丢失导出以允许链接。
如果MinGW链接器正确导出符号,它可以直接链接到DLL,尽管仍然建议链接到导入库(应该在qmake构建中创建),该库名为lib*.a
或{ {1}}。我相信链接器会查找带有和不带lib*.dll.a
前缀的变体,但我不确定并且应该自己测试。
您可以使用lib
和/或objdump
来检查DLL导出的符号。
答案 1 :(得分:1)
如果链接器没有抱怨无法加载Syren dll
,则表示文件已正确加载... Syren dll
中的符号丢失(未导出?) ...为什么没有更多信息就很难说出来
当您构建Syren lib时,您是否有关于缺少原型的警告? Syren lib使用什么,没有什么不可移植或需要Windows DLL? 你能给出缺失符号列表吗?
修改:如何编译Syren.dll
?你用过Mingw吗?您传递给编译器/链接器的选项是什么?
我建议阅读这两个链接:
如果要导出C ++函数,则必须在程序和DLL之间使用相同的编译器。或者您可以使用C风格的包装函数来封装C ++ ABI。
关于此主题的非常好的文章:http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
答案 2 :(得分:0)
将$(SYREN_PATH)
替换为$${SYREN_PATH}
时会发生什么?
因为前一种表示法$()
表示environment variable at the time Makefile is executed.