如何使用 Visual Studio 2017 在 Windows 上构建 OpenSSL?

Posted

技术标签:

【中文标题】如何使用 Visual Studio 2017 在 Windows 上构建 OpenSSL?【英文标题】:How to build OpenSSL on Windows with Visual Studio 2017? 【发布时间】:2018-01-11 16:10:21 【问题描述】:

我正在尝试使用 OpenSSL,但我被困在编译步骤上。 OpenSSL 项目的文档非常不友好(糟糕)。

对于如何使用 Visual Studio 2017 在 Windows 上构建最新的 OpenSSL 版本有任何实际帮助吗?

我在 OpenSSL 官方网站上没有找到任何有用的信息。是的,网上有很多关于OpenSSL编译的帖子,但是都已经过时了。

【问题讨论】:

你有没有考虑过使用pre-compiled OpenSSL binaries而不是自己编译? 您阅读安装文件了吗?这提供了有关如何构建 OpenSSL 的说明。 github.com/openssl/openssl/blob/OpenSSL_1_1_0-stable/INSTALL。您还应该阅读 NOTES.WIN 以了解 Windows 特定信息:github.com/openssl/openssl/blob/OpenSSL_1_1_0-stable/NOTES.WIN 您应该针对特定问题提出特定问题。由于 Stack Overflow 向您隐藏了关闭原因:“要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。" 关于"...网上有很多帖子...但都已过时" - 我对此表示怀疑。 【参考方案1】:

对于 OpenSSL 1.0.2,我编写了一个 Python 脚本来为我构建。我有制作这些脚本的习惯,因为我不喜欢每次需要构建一些东西时都重新发明***。

该脚本是为 OpenSSL 1.0.2 制作的。对于 OpenSSL 1.1.0 而言,更改可能很小。

这是脚本:

import os
from subprocess import call
import sys
import re

vs_version = "140"
compile_flags = "-no-asm -no-shared"


openssl_32_flag = "VC-WIN32"
openssl_64_flag = "VC-WIN64A"

src_32_suffix = "_" + "vs" + vs_version + "_32"
src_64_suffix = "_" + "vs" + vs_version + "_64"

vs_tools_env_var = "VS" + vs_version + "COMNTOOLS"

if len(sys.argv) < 2:
    print("First argument must be the tar.gz file of OpenSSL source")
    exit(1)

if len(sys.argv) < 3:
    print("Second argument must be 32 or 64")
    exit(1)

filename = sys.argv[1]
dirname  = filename.replace(".tar.gz","")
working_dir = os.getcwd()
arch = sys.argv[2]

if arch != "32" and arch != "64":
    print("Second argument must be 32 or 64")
    exit(1)


if not bool(re.match("(openssl-)1(\d)+(.)(\d)+(.)(\d)+(\w)+(.tar.gz)",filename)):
    print("The file given doesn't seem to be an openssl source file. It must be in the form: openssl-x.y.zw.tar.gz")
    exit(1)


call("7z x " + filename) #extract the .gz file

dirname_src_32 = dirname + src_32_suffix
dirname_src_64 = dirname + src_64_suffix
dirname_bin_32 = dirname + src_32_suffix + "_build"
dirname_bin_64 = dirname + src_64_suffix + "_build"

openssl_tar_file = filename[0:-3]

if arch == "32":
#extract tar file for 32
    call("7z x " + openssl_tar_file)
    os.rename(dirname, dirname_src_32)

#Compile 32
    os.chdir(dirname_src_32)

    call("perl Configure " + openssl_32_flag + " --prefix=" + os.path.join(working_dir,dirname_bin_32) + " " + compile_flags,shell=True)
    call(r"ms\do_ms.bat",shell=True)
    call(r"nmake -f ms\nt.mak",shell=True)
    call(r"nmake -f ms\nt.mak instalL",shell=True)

    print("32-bit compilation complete.")

#Go back to base dir
os.chdir(working_dir)
################

if arch == "64":
#extract for 64
    call("7z x " + openssl_tar_file)
    os.rename(dirname, dirname_src_64)

#Compile 64
    os.chdir(dirname_src_64)

    call("perl Configure " + openssl_64_flag + " --prefix=" + os.path.join(working_dir,dirname_bin_64) + " " + compile_flags,shell=True)
    call(r"ms\do_ms.bat",shell=True)
    call(r"nmake -f ms\nt.mak",shell=True)
    call(r"nmake -f ms\nt.mak instalL",shell=True)

    print("64-bit compilation complete.")

#Go back to base dir
os.chdir(working_dir)
################

os.remove(openssl_tar_file)

选项1:将脚本保存到CompileOpenSSL.py,并下载预计名称格式为openssl-1.X.Y.tar.gz的OpenSSL源文件。现在假设 7zip 和 perl 可以在命令提示符的全局范围内访问,并且加载了正确的 MSVC 变量(例如vsvars32.bat,或启动正确的终端),运行以下命令:

python CompileOpenSSL.py openssl-1.X.Y.tar.gz 32

如果您使用的是 MSVC 32 位,或者

python CompileOpenSSL.py openssl-1.X.Y.tar.gz 64

适用于 MSVC 64 位。

选项 2:手动执行脚本执行的操作。该脚本只是提取存档、配置源并运行do_ms.bat,然后运行nmake。关注源代码,它会起作用的。

祝你好运!

【讨论】:

OpenSSL 1.0.2 和 OpenSSL 1.1.0 之间的构建过程发生了显着变化 我使用了最新的资源 - 没有以下文件:ms\do_ms.bat, ms\nt.mak @AeroSun 就像那家伙说的,OpenSSL 1.1.0 是不同的。我给出的说明适用于 OpenSSL 1.0.2。【参考方案2】:

我没有使用过 VS2017 而是以前的版本。我想它是一样的。请注意,以下说明适用于 OpenSSL 1.1.0 或更高版本。它们不适用于 OpenSSL 1.0.2。简而言之,步骤是:

    安装 Perl(ActiveState 或 Strawberry)

[编辑,请参阅下面的(kritzel_sw)评论:我强烈建议使用草莓)]

    安装 NASM

    确保 Perl 和 NASM 都在您的 %PATH% 上

    使用管理权限启动 Visual Studio 开发人员命令提示符(如果您正在构建 32 位 OpenSSL,请确保使用 32 位命令提示符,如果您正在构建 64 位 OpenSSL,请确保使用 64 位命令提示符)

    如果需要 32 位 OpenSSL,请从 OpenSSL 源目录的根目录输入 perl Configure VC-WIN32,如果需要 64 位 OpenSSL,请输入 perl Configure VC-WIN64A

    输入nmake

    输入nmake test

    输入nmake install

[编辑,除非您更改配置中的目标目录,否则nmake install 需要管理员权限。因此,VC 命令提示符必须以管理员身份启动才能完成这最后一步]

如果在任何阶段出现任何问题,请检查INSTALL 文件和NOTES.WIN 文件。

【讨论】:

有以下帖子 - developer.covenanteyes.com/building-openssl-for-visual-studio 不建议使用 nasm 的地方:“不要尝试像 Windows 安装说明中提到的那样使用 NASM。Visual Studio 构建没有必要。(它只无论如何都支持32位。)”。至少我发现 nams 现在有 2 个版本 - 用于 32 位和 64 位。所以我会尝试一下,也许它真的适用于 x64。 @AeroSun - 别再听那些垃圾博客了。从这些博客中长出的废话是网络上关于 OpenSSL 的错误和错误信息如此之多的原因之一。一旦某个白痴有了想法,它就会进入推文或博客。遵循 OpenSSL 开发人员提供的 Windows README 或 INSTALL。或者更好的是,听马特的。他是一名 OpenSSL 开发人员。 @MattCaswell 仅供参考,是的,这在 VS 2017 中运行良好。干得好。 是的,如果您使用普通命令提示符而不是开发人员命令提示符,vcvarsall.bat 也可以工作。 @MikeOnline,这包含在安装文件中。使用“--debug”选项进行调试构建。对静态构建使用“no-shared”选项。例如perl Configure --debug VC-WIN32 no-shared【参考方案3】:

    使用 Visual Studio cmd 进入 ssl 目录并将 perl 和 nasm 添加到系统路径,然后键入:

    perl Configure --openssldir=D:OpenSSLdirectory VC-WIN32

    ms\do_ms.bat

    nmake -f ms\ntdll.mak

    nmake -f ms\ntdll.mak install

    (享受。)

【讨论】:

【参考方案4】:

The Quantum Physicist python 脚本的修改版

它可以编译 OpenSSL 1.0.x 或 OpenSSL 1.1.x

它可以编译包含多个版本的 Visual Studio 2017/2019。

1) 创建文件:CompileOpenSSL.py

import os
import os.path
from subprocess import call
import shutil
import sys
import re
import argparse

# args
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--filename", help="First argument must be the tar.gz file of OpenSSL source", required=True)
parser.add_argument("-a", "--arch", help="Second argument must be x86 or amd64", required=True)
parser.add_argument("-v", "--vs_version", help="Visual Studio version (eg:90, 140, 150)", required=True)
parser.set_defaults(writeVersionInfos=False)
args = parser.parse_args()

compile_flags = "-no-asm"
#compile_flags = "-no-asm -no-shared"

openssl_32_flag = "VC-WIN32"
openssl_64_flag = "VC-WIN64A"

working_dir = os.getcwd()

dirname  = args.filename.replace(".tar.gz","")

src_32_suffix = "_" + "vs" + args.vs_version + "_32"
src_64_suffix = "_" + "vs" + args.vs_version + "_64"

vs_tools_env_var = "VS" + args.vs_version + "COMNTOOLS"


if args.arch != "x86" and args.arch != "amd64":
    print("Second argument must be x86 or amd64")
    exit(1)


if not bool(re.match("(openssl-)1(\d)+(.)(\d)+(.)(\d)+(\w)+(.tar.gz)",args.filename)):
    print("The file given doesn't seem to be an openssl source file. It must be in the form: openssl-x.y.zw.tar.gz")
    exit(1)


call("7z x -y " + args.filename) #extract the .gz file

dirname_src_32 = dirname + src_32_suffix
dirname_src_64 = dirname + src_64_suffix
dirname_bin_32 = dirname + src_32_suffix + "_build"
dirname_bin_64 = dirname + src_64_suffix + "_build"

openssl_tar_file = args.filename[0:-3]

if args.arch == "x86":

#delete previous directories
    shutil.rmtree(os.getcwd()+'/'+dirname, ignore_errors=True)
    shutil.rmtree(os.getcwd()+'/'+dirname_src_32, ignore_errors=True)

#extract tar file for 32

    call("7z x -y " + openssl_tar_file)
    os.rename(dirname, dirname_src_32)

#Compile 32
    os.chdir(dirname_src_32)

    print("perl Configure " + openssl_32_flag + " --prefix=" + os.path.join(working_dir,dirname_bin_32) + " " + compile_flags)
    call("perl Configure " + openssl_32_flag + " --prefix=" + os.path.join(working_dir,dirname_bin_32) + " " + compile_flags,shell=True)

    if( os.path.exists("ms/do_ms.bat") ):
        call("ms\do_ms.bat",shell=True)
        print(os.getcwd())
        call("nmake -f ms/ntdll.mak",shell=True)
        call("nmake -f ms/ntdll.mak install",shell=True)
    else:
        call("nmake",shell=True)
        call("nmake test",shell=True)
        call("nmake install",shell=True)

    print("32-bit compilation complete.")

#Go back to base dir
os.chdir(working_dir)
################

if args.arch == "amd64":

#delete previous directories
    shutil.rmtree(os.getcwd()+'/'+dirname, ignore_errors=True)
    shutil.rmtree(os.getcwd()+'/'+dirname_src_64, ignore_errors=True)


#extract for 64
    call("7z x -y " + openssl_tar_file)
    os.rename(dirname, dirname_src_64)

#Compile 64
    os.chdir(dirname_src_64)

    call("perl Configure " + openssl_64_flag + " --prefix=" + os.path.join(working_dir,dirname_bin_64) + " " + compile_flags,shell=True)
    if( os.path.exists("ms\do_ms.bat") ):
        call("ms\do_win64a.bat",shell=True)
        call("nmake -f ms/ntdll.mak",shell=True)
        call("nmake -f ms/ntdll.mak install",shell=True)
    else:
        call("nmake",shell=True)
        call("nmake test",shell=True)
        call("nmake install",shell=True)

    print("64-bit compilation complete.")

#Go back to base dir
os.chdir(working_dir)
################

os.remove(openssl_tar_file)

2) 创建文件:CompileOpenSSL_vs.cmd

ECHO  --------------------------------------
ECHO Require Python, 7Zip, PERL and NASM in PATH
ECHO  --------------------------------------

Rem ------------------------------------------------------
Rem TO CONFIGURE -----------------------------------------
Rem ------------------------------------------------------

Rem SET YOUR LOCAL PATHS-----------------------------------------
SET PATH=C:\Program Files (x86)\7-Zip;C:\Perl64\bin;M:\Backup\Coders\_tools\7-Zip\;%PATH% 

Rem SET YOUR OPENSSL ARCHIVE-----------------------------------------
REM SET FILENAME=openssl-1.0.2r.tar.gz 
SET FILENAME=openssl-1.1.1b.tar.gz

Rem SET THE VERSION OF YOUR VISUAL STUDIO-----------------------------------------
SET VSVERSION=%1


Rem ------------------------------------------------------
Rem COMPILATION LAUNCH -----------------------------------
Rem ------------------------------------------------------

Rem UTILS PATH-----
SET VSCOMNTOOLSNAME=VS%VSVERSION%COMNTOOLS

Rem Pick the good path for Visual Studio-----------------------------------------
IF %VSVERSION% GEQ 150 (
    Echo DO NOT FORGET TO ADD A SYSTEM VARIABLE %VSCOMNTOOLSNAME% - like: "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\"
    SET VCVARPATH="%%%VSCOMNTOOLSNAME%%%..\..\VC\Auxiliary\Build\vcvarsall.bat"
) ELSE (
    SET VCVARPATH="%%%VSCOMNTOOLSNAME%%%..\..\VC\vcvarsall.bat"
)

Rem Set env -----------------------------------------
@pushd "%~dp0"
call %VCVARPATH% %2
@popd

Rem ------------------------------------------------------
Rem TEST APP EXIST -----------------------------------
Rem ------------------------------------------------------

where /q 7z.exe
IF ERRORLEVEL 1 (
    ECHO The application "7z.exe" is missing. Ensure to add/install it to the PATH in beginning of this script, check SET PATH
    PAUSE
    EXIT /B
)

where /q perl.exe
IF ERRORLEVEL 1 (
    ECHO The application "perl.exe" is missing. Ensure to add/install it to the PATH in beginning of this script, check SET PATH
    PAUSE
    EXIT /B
)

where /q nmake.exe
IF ERRORLEVEL 1 (
    ECHO The application "nmake.exe" is missing. Ensure to add/install it to the PATH in beginning of this script, check SET PATH
    PAUSE
    EXIT /B
)

where /q py.exe
IF ERRORLEVEL 1 (
    ECHO The application "py.exe" [shortcut of python] is missing. Ensure to add/install it to the PATH in beginning of this script, check SET PATH
    PAUSE
    EXIT /B
)

Rem Launch compilation -----------------------------------------

py CompileOpenSSL.py -f %FILENAME% -a %2 -v %VSVERSION%


PAUSE

3) 从命令行启动编译(Visual Studio 外部) 例如:

CompileOpenSSL_vs.cmd 150 x86
CompileOpenSSL_vs.cmd 150 amd64

CompileOpenSSL_vs.cmd 90 x86

【讨论】:

以上是关于如何使用 Visual Studio 2017 在 Windows 上构建 OpenSSL?的主要内容,如果未能解决你的问题,请参考以下文章

visual studio2017社区版如何空格操作?

如何在 Visual Studio 2017 中使用 Qt 库?

如何使用 Visual Studio 2017 在 Windows 上构建 OpenSSL?

Intel parallel studio 2017 集成在visual studio 2013 中,现在如何集成到visual studio 2015

如何在 Visual Studio 2017 中使用 C# 8?

如何在 Visual Studio 2017 中使用 C# 8?