bgo*_*odr 26 linker cmake static-libraries visual-studio-2008-sp1
我正在使用Visual Studio 2008 SP1(专业版,适用于32位和64位版本).我正在寻找一种解决方法,我认为这是Visual Studio中一个非常无益的" 限制 ".
我觉得很奇怪,在Visual Studio连接器和编译器不以DLL文件的创建时间这一权利,自动扫描所有导出的符号所有指定的静态库中所示的相同的方式构建一个导入库和导出文件,并在一StackOverflow评论.我确认仅仅在组成静态库的文件中应用__declspec(dllexport)和__declspec(dllimport)属性类,函数和数据声明是不够的
.
链接器不扫描导出符号的所有静态库,因此不会将它们拉入DLL文件(符号必须由.objDLL链接命令行上的文件或我在下面显示的其他方式引用).如果没有对每个导出符号的显式引用,仍可能会创建DLL文件,但不会创建其关联的导入库文件.
根据我的收集,Microsoft建议使用LIB.EXE 来创建DEF文件,但不幸的是,LIB.EXE页面应用了一个约束:
请注意,如果您在创建导入库之前创建导入库,则在构建导入库时,必须在构建导入库时
.dll传递相同的目标文件集.dll.
鉴于我在新的构建环境中也使用了CMake,这是一个不幸的约束.CMake隐藏了实际传递给链接器的细节(我认为这在99%的时间里都是好事),但在这种情况下我需要在CMake执行时访问一些信息,而不是然后使用手工制作的脚本或其他脆弱的skulduggery.
如何强制DLL链接器解析构成DLL文件的所有静态库中的所有导出符号,这不会导致脆弱性和额外的构建逻辑维护工作?在这里考虑全自动化,并记住我需要多次为多个不同的DLL执行此操作.
我的问题是:
如何仅使用CMake语法获取最终DLL链接命令行上使用的目标文件和静态库集?
有没有更好的方法来解决这个问题,在调用最终链接之前不需要调用单独的实用程序,例如LIB.EXE ?我担心LIB.EXE链接本身之外的额外构建开销会再次重新扫描所有静态库 ,即使它只是在单独的执行中写出来.
以下是我现在无法考虑的解决方案:
在原始文件.h或.cpp文件之外的任何地方手动指定未引用的符号,因为每次开发人员忘记更新列出(很可能是名称错位的)符号名称的文件时,这样做会中断.并且它将打破关于未解析符号的非用户友好链接器错误,这对于开发人员来说将是昂贵的调试.这个非答案包括以下方法:
明确地将.obj文件添加到DLL链接命令行中(其中的变体包括添加"假" .obj文件,这些文件具有对未引用但导出的符号的虚拟引用(并注意这是我的旧构建环境今天所做的,并且它很臭) ),和,
手工制作DEF文件以包含未引用但导出的符号,以及
链接器命令行选项,专门引用未引用但已导出的符号符号.
完全停止使用静态库.我不能在短期内做到这一点,因为它与我正在离开的旧构建环境的结构变化太大了.一旦旧构建环境的所有残余物都在"垃圾桶"中,我很可能在将来采用这条路线,但这不是我的重点.
我的回答只是为了表明您不使用静态库的感觉是正确的。
DLRdave 已经在评论中说过,您的构建系统正在被 LIB 文件滥用。LIB 文件很像一个真正的图书馆,你只带出你想要的东西,而不是图书馆中的所有东西。
如果说 Visual Studio 2008 工具集中有一个缺陷,那就是它不支持部分链接。部分链接的输入是一组 OBJ 文件,输出是单个 OBJ 文件,其中包含输入 OBJ 文件中的所有代码和数据。
存档/库和部分链接之间的区别在以下问题的答案中描述了 g++:g++ 部分链接而不是存档?,其中 GNU 链接器 ( ld ) 确实支持部分链接。
至于可能的短期缓解措施 - 就我个人而言,我会尝试使用脚本在构建时动态构建 DEF 文件,方法是使用LIB /List或DUMPBIN /ARCHIVEMEMBERS获取 obj 文件并LIB /DEF从该列表生成 DEF 文件。或者,正如我假设_declspec(dllexport的那样,您也可以使用 ) DUMPBIN /DIRECTIVES,自己查找/EXPORT并构建 DEF 文件。
| 归档时间: |
|
| 查看次数: |
6111 次 |
| 最近记录: |