mingw忽略'-L'标志

时间:2012-12-19 10:07:26

标签: qt gcc mingw qmake

我在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\libsSyren.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

但我仍然得到完全相同的错误消息!

3 个答案:

答案 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.

的内容

请参阅qmake variable reference.