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

26

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

有没有实际帮助如何在Windows上使用Visual Studio 2017构建最新版本的OpenSSL的方法?

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


2
你是否考虑过使用预编译的OpenSSL二进制文件而不是自己编译它? - Remy Lebeau
2
你有读过INSTALL文件吗?这个文件提供了构建OpenSSL的指令。https://github.com/openssl/openssl/blob/OpenSSL_1_1_0-stable/INSTALL。你也应该阅读NOTES.WIN以获取Windows特定信息:https://github.com/openssl/openssl/blob/OpenSSL_1_1_0-stable/NOTES.WIN - Matt Caswell
你应该针对特定问题提出具体的问题。由于 Stack Overflow 隐藏了关闭原因:“要求我们推荐或查找书籍、工具、软件库、教程或其他离线资源的问题不适用于 Stack Overflow,因为它们往往会吸引带有个人观点的答案和垃圾邮件。相反,请描述问题以及已经采取的解决方案。”关于“......互联网上有很多帖子......但它们都已过时” - 我表示怀疑。 - jww
4个回答

64

我以前使用过VS的旧版本,但没有用过2017版。 我想它应该差不多。请注意,以下说明适用于OpenSSL 1.1.0或更高版本。 它们不适用于OpenSSL 1.0.2。 简而言之,步骤如下:

  1. 安装Perl(ActiveState或Strawberry都可以)

[编辑,请参见我的(kritzel_sw)下面的评论:我强烈推荐使用Strawberry)

  1. 安装NASM

  2. 确保Perl和NASM都在%PATH%中

  3. 用管理员权限启动Visual Studio开发人员命令提示符(如果要构建32位OpenSSL,则确保使用32位命令提示符;如果要构建64位OpenSSL,则使用64位命令提示符)

  4. 从OpenSSL源代码目录的根目录进入perl Configure VC-WIN32,如果您想要32位的OpenSSL,或者perl Configure VC-WIN64A,如果您想要64位的OpenSSL

  5. 输入nmake

  6. 输入nmake test

  7. 输入nmake install

[编辑,除非您在配置中更改了目标目录,否则nmake install需要管理员特权。 因此,必须以管理员身份启动VC命令提示符进行此最后一步操作]

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


8
@AeroSun - 别再听那些垃圾博客了。这些博客中的废话是导致网络上关于OpenSSL存在如此多错误和不正确信息的原因之一。只要某个白痴有一个想法,它就会被写成推文或博客。请遵循由OpenSSL开发人员提供的Windows README或INSTALL。或者更好的方法是听取Matt的建议,他是一个OpenSSL开发人员。 - jww
4
@MattCaswell 仅供参考,这在VS 2017中可以正常工作。干得好,伙计们。 - Paul Sanders
1
是的,即使您使用普通命令提示符而不是开发人员命令提示符,vcvarsall.bat也可以工作。 - Matt Caswell
3
@MikeOnline,这在INSTALL文件中有详细说明。对于调试版本,请使用“--debug”选项。对于静态构建,请使用“no-shared”选项。例如,perl Configure --debug VC-WIN32 no-shared - Matt Caswell
1
我可以确认这适用于Visual Studio 2022,但有一个重大问题:如果您打算构建64位应用程序,则必须使用正确的命令行x64 Native Tools Command Prompt for VS 2022。还有一个名为Developer Command Prompt for VS 2022的不同命令行,它将无法正常工作,因为它会导致期望的目标机器类型之间的不同步(它将尝试为x86和x64构建不同的部分),并在nmake阶段失败。 - Xirema
显示剩余17条评论

3

修改后的量子物理学家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

1
  1. 使用Visual Studio命令提示符进入SSL目录,并将Perl和NASM添加到系统路径中,然后输入:

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

  3. ms\do_ms.bat

  4. nmake -f ms\ntdll.mak

  5. nmake -f ms\ntdll.mak install

  6. (享受吧。)


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。按照源代码进行操作,它会起作用。

祝你好运!


3
在 OpenSSL 1.0.2 和 OpenSSL 1.1.0 之间,构建过程发生了重大变化。 - Matt Caswell
1
我使用了最新的源代码 - 没有以下文件:ms\do_ms.bat,ms\nt.mak。 - AeroSun
@AeroSun 像那个人说的一样,OpenSSL 1.1.0 是不同的。我给出的指示是针对 OpenSSL 1.0.2 的。 - The Quantum Physicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接