Linker 使用CMake从静态库链接Windows DLL文件,而无需手工制作未解析的符号名 形势

Linker 使用CMake从静态库链接Windows DLL文件,而无需手工制作未解析的符号名 形势,linker,cmake,static-libraries,visual-studio-2008-sp1,Linker,Cmake,Static Libraries,Visual Studio 2008 Sp1,我正在使用VisualStudio2008 SP1(专业版,适用于32位和64位) 构建)。我正在寻找一个解决办法,我认为这是一个非常重要的问题 Visual Studio中的“”没有帮助 我觉得很有趣 令人惊讶的是,VisualStudio链接器和编译器在DLL文件中没有这样做 创建时间,自动扫描所有指定的静态库 以和中给出的相同方式用于所有导出符号。我确认仅仅申请是不够的 \uu declspec(dllexport)和\uu declspec(dllimport)属性 类、函数和数据声明,

我正在使用VisualStudio2008 SP1(专业版,适用于32位和64位) 构建)。我正在寻找一个解决办法,我认为这是一个非常重要的问题 Visual Studio中的“”没有帮助

我觉得很有趣 令人惊讶的是,VisualStudio链接器和编译器在DLL文件中没有这样做 创建时间,自动扫描所有指定的静态库 以和中给出的相同方式用于所有导出符号。我确认仅仅申请是不够的
\uu declspec(dllexport)
\uu declspec(dllimport)
属性 类、函数和数据声明,这些声明位于构成 静态库

链接器不会扫描所有静态库 对于导出的符号,因此不会将它们拉入DLL文件(符号 必须由DLL链接命令行上的
.obj
文件或 通过其他方式(见下文)。没有明确提到每一个 导出符号时,仍可创建DLL文件,但其关联 未创建导入库文件

据我所知,微软建议使用 创建文件,但不幸的是,页面 应用约束:

请注意,如果在初步步骤中创建导入库, 在创建
.dll
之前,必须传递同一组对象文件 在构建
.dll
时,正如您在构建导入时传递的那样 图书馆

这是一个不幸的限制,因为我也在使用中 我的新构建环境。CMake隐藏了实际情况的细节 传递给链接器(我认为这在99%的用户中是件好事) 时间),但在这种情况下,我需要在 CMake执行时间,而不是之后使用手工制作的脚本或 其他易碎品

问题是: 如何强制DLL链接器 解析所有静态库中包含的所有导出符号 DLL文件,这不会导致脆弱性和额外的构建 逻辑维护杂务?从全自动化的角度考虑,以及 请记住,我需要多次执行此操作 不同的DLL

我的问题是:

  • 如何获取所使用的对象文件集和静态库 在最后一个DLL链接命令行上单独使用CMake语法

  • 第行列出的文件的顺序(使用的文件)是否正确 要生成文件),必须完全匹配上使用的顺序 DLL链接行

  • 我在使用过程中是否会遇到其他困难 生成文件的方法是什么

  • 有没有更好的方法来实现这一点,而不需要 在调用 最后一环?我担心的是,除了 链接LIB.EXE以重新扫描所有静态库 尽管它只是在单独的执行中写下了它们

  • 非官方答复: 下面是我现在不能考虑的解决方案:

  • 手动指定除以下位置以外的任何位置的未引用符号 在原始的
    .h
    .cpp
    文件中,这样做将 每次开发人员忘记更新列出的文件时中断 符号名称(很可能名称已损坏)。它会碎的 关于未解析符号的非用户友好链接器错误 这将是开发人员调试的代价。这不是答案 包括以下方法:

  • 显式地将
    .obj
    文件添加到DLL链接命令行, (这方面的变体包括添加具有 对以其他方式未引用但已导出的 符号(请注意,这是我的旧构建环境 是今天,而且很臭),而且

  • 手工制作文件以包含未引用但 导出的符号,以及

  • 链接器命令行选项,该选项专门引用 未引用但已导出的符号

  • 完全停止使用静态库。我现在不能那样做 短期的,因为这是一个从旧的结构变化太多 构建我要离开的环境。我很可能会的 将来走这条路,一旦旧建筑的所有残余物 环境是在“垃圾桶”,但这不是我在这里的重点

  • 参考资料:

    我的回答只是想说明您不使用静态库的感觉是正确的

    DLRdave在评论中已经提到,您的构建系统正被LIB文件滥用。一个LIB文件很像一个真正的库,你只带着你想要的东西出去,而不是库中的所有东西

    如果VisualStudio2008工具集中存在漏洞,那就是它不支持部分链接。部分链接的输入是一组OBJ文件,输出是单个OBJ文件,其中包含输入OBJ文件中的所有代码和数据

    归档/库和部分链接之间的区别在对以下问题的回答中针对g++进行了描述:,其中GNU链接器()支持部分链接


    至于可能的短期缓解措施——就我个人而言,我会尝试使用脚本在构建时动态构建DEF文件,方法是使用
    LIB/List
    DUMPBIN/ARCHIVEMEMBERS
    获取obj文件,并使用
    LIB/DEF
    从该列表生成DEF文件。或者,正如我假设使用的是
    \u declspec(dllexport
    ),您也可以使用
    DUMPBIN/DIRECTIVES
    ,查找
    /EXPORT
    ,然后自己构建DEF文件。

    Mozilla构建系统使用非answer 1.1,并且每隔一段时间就需要有人记住更新
    dlldeps.cpp
    文件,以便正确的操作