【问题标题】:How do I build OpenSSL statically linked against Windows runtime?如何构建与 Windows 运行时静态链接的 OpenSSL?
【发布时间】:2013-08-31 10:17:27
【问题描述】:

我正在为使用 OpenSSL 1.0.1e 库的 Windows 开发 C++ 应用程序。我在 Visual Studio 2008 上。

出于可移植性原因,我的应用程序与运行时库静态链接(/MT/MTd 选项)。而且我的应用程序不提供运行时库。

根据OpenSSL FAQ,该库默认链接到多线程 DLL 运行时 (/MDd),这显然与我的方案不兼容。因此,为了使我的程序正常运行,我将applink.c 添加到我的项目中。在我的开发机器和大多数测试计算机上,该程序运行良好。

但不幸的是,我找到了应用程序无法启动的计算机。 Windows 显示错误:

The application failed to initialize properly (0xc0150002). Click on OK to
terminate the application. 

我在 Dependency Walker 中打开了 libeay32.dll,我发现找不到 MSVCR90.dll。所以applink.c 的技巧对我来说真的不起作用。

如何使用/MT/MTd 选项构建OpenSSL?

【问题讨论】:

  • “但不幸的是,我找到了应用程序无法启动的计算机...我发现没有找到 MSVCR90.dll” - 请确保计算机有问题MSVC 运行时的正确版本。您可以从 Microsoft 站点下载它们。它们应该包含在您的软件包安装程序中。
  • 我有同样的问题,openssl 1.1.1c 在 windows 10 中编译,使用它的 libssl-1_1-x64.dll 和 libcrypto-1_1-x64.dll,得到运行时错误 msvcrt90.dll not found .在 cpp 文件旁边复制 msvcrt90.dll 后,出现 R6034 错误。 :(

标签: c windows openssl static-libraries static-linking


【解决方案1】:

使用nt.mak 生成文件而不是ntdll.mak 生成文件。

顺便说一句,我已经围绕标准 OpenSSL 构建脚本编写了一些脚本,这使得在 Windows 上使用 x86 和 x64 混合的 OpenSSL 变得“更容易”(至少对我而言),您可以从 @ 获取它们987654321@.

【讨论】:

  • 是的,找到了。非常感谢。
  • 求助,如何为 /MTd 编译?
  • 在 OpenSSL 发行版的“Install.w32”中有这样的注释:“您可以对 Win32 编译环境进行各种更改。默认情况下,该库不使用调试符号编译。如果添加'debug' 到 do_* 批处理文件中的 mk1mf.pl 行,然后将编译调试符号。注意 mk1mf.pl 期望平台是命令行上的最后一个参数,所以 'debug' 必须出现在它之前,与所有其他选项一样。”... 或使用 nt-dbg.mak
  • 不使用nt.mak 代替ntdll.mak 创建静态OpenSSL 库而不是具有静态链接运行时的动态库?
【解决方案2】:

如果您想使用 MT 预编译 OpenSSL 库,请查看此处:http://www.npcglib.org/~stathis/blog/precompiled-openssl/ 您将找到 OpenSSL 源代码的补丁程序,该补丁程序可以生成带有后缀 MT/MD 和“d”的库以进行调试,以便更轻松地识别库。

此外,您还可以找到实际的构建脚本,以便为许多不同版本的 Visual Studio 一次构建所有这些脚本。我自己构建和使用它们来精确生成不需要 DLL 用于我的项目的二进制文件,您可能会发现它们很有用。

【讨论】:

  • 注意:“所有静态构建的库都链接到静态运行时(/MT 而不是 /MD)。”因此,如果您希望构建使用 /MD[d] 编译的静态库,请继续寻找,尽管我发现查看补丁如何修改构建文件很有用。
  • 这与 OpenSSL 无关,但如果您混合链接静态 (/MT) 和动态 (/MD) C 运行时,您将面临一些非常难以调试的严重崩溃。也许您可以向我们展示您如何将两者混合在一起以及结果如何。同时:“因此,如果您希望构建使用 /MD[d] 编译的静态库”......请不要这样做。只要保持一致,就可以省去麻烦;尤其是旧的 MSVC。
  • 我需要将 openssl 作为使用 /MD[d] 编译的静态库,因为我正在构建一个静态链接的 DLL 出于各种原因,这些原因与客户有很大关系,与使研发更有趣无关.相信我,如果有其他选择,我会接受的。感谢您从未需要这样做。
  • @tekHedd 你的博文救了我的命tekhedd.com/?p=2305 顺便说一句,它对我来说与 asm 一起工作,我正在通过 powershell 破解 nt.mak,总的来说我的批处理文件看起来像这样:调用 cd src\openssl-1.0.2k call "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" call set path=C:\Perl64\bin;C:\Users\m\AppData\Local \NASM;%path% call perl Configure VC-WIN32 --prefix="../../build/1.0.2k-x86_rel_MD" call ms\do_nasm.bat powershell -Command "(Get-Content ms\nt.mak ).replace('/MT', '/MD') | Set-Content ms\nt.mak" call nmake -f ms\nt.mak call nmake -f ms\nt.mak install
  • @Daboul 很高兴它有帮助!我可以将您的代码添加到博客文章中吗?有一天它可能会帮助别人。甚至我。
【解决方案3】:

我为 Windows 找到的最优雅的选项是使用 http://p-nand-q.com/programming/windows/building_openssl_with_visual_studio_2013.html 提供的脚本

他们为每个脚本版本提供 VS2010/VS2013/VS2015 的脚本,它构建了 x86/x86-64 与运行时 MDd/MD/MTd/MT 的所有组合。

引用说明:

先决条件:

脚本假定您在 Windows 上。

脚本假定您已安装 Visual Studio 2010、2013 或 2015 在所有常见的地方。重要提示:如果您有不同的 安装文件夹,您的里程可能会有所不同

该脚本假定您已下载 OpenSSL 压缩包,如下所示 一个。

该脚本假定您已安装 Python(2.7 或 3.x)并在您的 路径

脚本假定您已安装 7-zip(不需要打开 你的路径)选择你想使用的脚本并编辑它。例如, 我们来看看rebuild_openssl_vs2015.cmd的顶部:

T:

设置 OPENSSL_VERSION=1.0.1p

设置 SEVENZIP="C:\Program Files\7-Zip\7z.exe"

设置 VS2015="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"

设置 VS2015_AMD64="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"

所以很容易看到:你必须输入 OpenSSL 版本 手动,其余的应该有合理的默认值...

注意:该脚本使用 SUBST T:\ 驱动器来构建 OpenSSL。

我测试过,不到 10 分钟就可以了!为脚本作者点赞!!

更新:要生成 x64 版本,您需要安装 nasm 汇编器并将其放在 PATH 中。

【讨论】:

    【解决方案4】:

    要使用 Visual Studio 2015 构建静态链接的 64 位 OpenSSL(这会生成一个没有任何 DLL 的单个 .exe 文件),您需要满足以下先决条件:

    您需要在系统范围内安装所有这些工具并将它们添加到您的 %PATH% 环境变量中。

    在您得到我们需要的一切后,只需按照以下简单步骤操作:

    1. 从“开始”菜单打开 VS2015 x64 Native Tools 命令提示符。您将看到命令提示符。
    2. 创建C:\build目录并在命令提示符下发出以下命令:

      • cd c:\build
    3. 使用以下命令将最新的 zlib 和 OpenSSL 源代码下载到您的 build 目录:

      • git clone https://github.com/madler/zlib
      • git clone https://github.com/openssl/openssl
    4. 首先我们必须构建静态zlib。为此,我们首先需要编辑一些配置文件:

      • 导航到zlib 源文件夹:cd C:\build\zlib
      • 编辑win32\Makefile.msc 文件:

        1. 查找以CFLAGS 开头的行
        2. -MD 替换为-GL -MT -Zc:wchar_t-
        3. 查找以LDFLAGS 开头的行
        4. -debug 替换为-opt:icf -dynamicbase -nxcompat -ltcg /nodefaultlib:msvcrt
    5. 使用以下命令构建zlib(应该不到一分钟):

      • nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -DNDEBUG -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"
    6. 将生成的文件复制到您的OpenSSL 目录:

      • xcopy zlib.h C:\build\openssl\
      • xcopy zconf.h C:\build\openssl\
      • xcopy zlib.lib C:\build\openssl\
      • xcopy zlib.pdb C:\build\openssl\
    7. 导航到 OpenSSL 源:cd C:\build\openssl\ 并将其配置为使用静态 zlib 并从 C:\Windows\ 目录读取配置文件 (openssl.cnf)。

      • perl Configure VC-WIN64A no-shared zlib no-zlib-dynamic threads --prefix=C:\Windows\
    8. 现在对C:\build\openssl\makefile进行以下编辑:

      • 查找以:CFLAG 开头的行
      • 附加:/Zc:wchar_t- /GL /Zi
      • 查找以:LDFLAGS 开头的行
      • /debug 替换为/incremental:no /opt:icf /dynamicbase /nxcompat /ltcg /nodefaultlib:msvcrt
      • 查找以:EX_LIBS 开头的行
      • ZLIB1 替换为zlib.lib
      • 保存更改
    9. 通过发出nmake 命令构建OpenSSL(大约需要15 分钟)。

    生成的 ~3MB openssl.exe 文件将位于 C:\build\openssl\apps\ 目录。它是完全可移植的,因为所有 DLL 都包含在内。如果您需要使用自定义配置文件,请将C:\build\openssl\apps\openssl.cnf 复制到您的C:\Windows\ 目录并根据自己的喜好对其进行编辑。

    【讨论】:

    • 问题说链接针对静态windows运行时不静态编译代码有区别
    • @simon-p-r 你能澄清一下(eli5)的区别吗?
    【解决方案5】:

    OpenSSL 现在似乎与-MT -Zl 链接(至少在使用 msvc 时),这意味着它会丢弃默认命名库,然后在您的最终二进制文件中决定这些库。默认情况下,应用程序似乎使用静态运行时。

    换句话说,无需采取任何措施就可以将它与您的二进制文件一起使用,只需提供您想要的任何标志,OpenSSL 库就会使用它。不幸的是,没有很多关于构建如此重要的库的具体文档。

    【讨论】:

      猜你喜欢
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      相关资源
      最近更新 更多