【问题标题】:How can I force MSVC++ to ignore CRT dependencies of a static library?如何强制 MSVC++ 忽略静态库的 CRT 依赖项?
【发布时间】:2009-03-26 19:21:29
【问题描述】:

我不知道是否可以这样做,但我希望将 /NODEFAULTLIB 应用于静态库项目。

我有许多使用通用静态库 D.lib 的应用程序项目(A.exe、B.dll、C.dll)。 这个库有很多代码,也有其他 .lib 依赖项。其中之一是 openssl 库,它似乎是针对 CRT 的 Release 版本为 win32 构建的(我没有原始项目/源)。

到目前为止,为了避免混合 CRT 的发布/调试版本,我必须将 /NODEFAULTLIB:msvcrt.lib 链接器指令放在所有叶项目(A.exe、B.dll)中。这可行,但我认为这不是处理该问题的理想方式。 我试图把这个属性放在D.lib项目中,但是没有效果。

有没有办法强制 msvc++ 忽略来自 3rd 方库的 msvcrt.lib 依赖项?

【问题讨论】:

    标签: visual-c++ runtime static-libraries msvcrt


    【解决方案1】:

    .lib 没有任何链接器设置,因为您不链接它,而是链接 它。 .lib 只是 .obj 文件的存档,有点像未压缩的 .zip 文件 - 这就是为什么您必须将设置放在链接到它的所有项目上。

    如果您使用的是 VS2005+,您可以使用属性表,这样您只需将设置放在一个位置,然后在所有项目中使用该属性表。

    但是,OpenSSL 就是这样 - 开源,因此您应该能够获取您正在使用的版本的源代码并重新构建它(当然,并将其添加到您的版本控制系统中)。我认为 OpenSSL 可以构建为 DLL 或 LIB,这将解决您的问题,因为 DLL 不会干扰您的代码链接。

    如果做不到这一点,您始终可以选择将您的功能拆分到一个单独的 DLL 中,这样您就只会遇到一个项目的问题。

    【讨论】:

    • 我认为您第一段中的声明是不正确的——当然,如果我使用 CL.EXE(并且不使用 /Zl 开关)将 C 文件编译为 .OBJ,则“/DEFAULTLIB:xyz ”(其中 xyz 通常是 /MD 编译的“MSVCRT”,/MT 等的“LIBCMT”)被添加到 .OBJ 文件的 .drectve 部分,并保留在 .LIB 文件中。如果在链接 .LIB 文件时需要该 .OBJ,则该指令将被执行,导致链接器警告“LNK4098:defaultlib 'LIBCMT' 与其他库的使用冲突;如果其他 .OBJ 有,请使用 /NODEFAULTLIB:library”请求了不同的 CRT 库。
    • 好的,那句话是一个概括。您可以使用“#pragma comment”和 lib/linker 通过 .lib 中的 .obj 文件将附加指令传递给链接器。
    【解决方案2】:

    我的理解是,如果库 LIB 静态链接到 DLL 中,则 DLL 已经包含来自 LIB 的所有相关代码。因此,这种耦合不能被移除。这只是基于我对静态链接的理解,而不是实验。

    【讨论】:

      【解决方案3】:

      为防止您的分布式静态链接库依赖于特定的 MSVC 运行时库,您需要设置此编译器选项(在 Visual Studio 2010 中看起来像):

      配置属性 -> C/C++ -> 高级 -> 省略默认库名称 = Yes (/ZI)

      现在您的用户可以从他们的调试版本链接到您的发布构建的静态库,而不是尝试链接到导致问题的不正确运行时库以及链接器警告。

      请注意,如果您的库实际上依赖于特定的运行时库或其行为,并且未以其他方式提供兼容组件,则可能会导致链接错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        • 2014-05-09
        • 2018-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-06
        相关资源
        最近更新 更多