Files
GmSSL/INSTALL.md
2026-06-21 10:33:50 +08:00

350 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 编译与安装
[TOC]
## 概述
GmSSL当前版本采用CMake构建系统。由于CMake是一个跨平台的编译、安装工具因此GmSSL可以在大多数主流操作系统上编译、安装和运行。GmSSL项目官方测试了Windows (包括Visual Studio和Cygwin)、Linux、macOS、Android和iOS这几个主流操作系统上的编译并通过GitHub的CI工作流对提交的最新代码进行自动化的编译测试。
和其他基于CMake的开源项目类似GmSSL的构建过程主要包含配置、编译、测试、安装这几个步骤。默认配置会生成动态库如果需要静态库可以在配置阶段设置`-DBUILD_SHARED_LIBS=OFF`
### Linux/macOS源码安装
在Linux或macOS环境下下载并解压GmSSL源代码后进入源码目录执行如下命令
```bash
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
ctest --output-on-failure
sudo cmake --install .
```
就可以完成配置、编译、测试和安装。
在执行`cmake --build .`编译成功后,在`build/bin`目录下会生成项目的可执行文件和库文件。对于密码工具来说,在安装使用之前通过`ctest --output-on-failure`进行测试是重要的一步,如果测试失败,那么不应该使用这个软件。在发生某个测试错误后,可以执行`build/bin`下的具体某个测试命令行,如`sm4test`,这样可以看到具体的错误打印信息。
执行`sudo cmake --install .`,安装完成后,可以命令行中调用`gmssl`命令行工具。在Linux和macOS环境下头文件通常被安装在`/usr/local/include/gmssl`目录下,库文件被安装在`/usr/local/lib`目录下。Linux默认动态库名称为`libgmssl.so`macOS默认动态库名称为`libgmssl.dylib`
在Linux上安装动态库时安装程序不会自动修改`/etc/ld.so.conf.d`或执行`ldconfig`。如果安装后系统找不到`libgmssl.so`,可以临时设置动态库搜索路径:
```bash
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
```
也可以配置系统级动态库搜索路径:
```bash
echo /usr/local/lib | sudo tee /etc/ld.so.conf.d/gmssl.conf
sudo ldconfig
```
如果不希望安装到系统目录,可以指定安装前缀:
```bash
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/local/gmssl
cmake --build .
ctest --output-on-failure
cmake --install .
```
### Windows源码安装
在Windows上建议使用Visual Studio 2022或更新版本。在"Developer Command Prompt for VS 2022"中执行:
```bat
mkdir build
cd build
cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
nmake
ctest --output-on-failure
nmake install
```
默认安装目录通常为`C:\Program Files\GmSSL`,命令行工具、头文件和库文件分别安装到`bin``include``lib`目录。普通用户执行安装可能会因为权限不足失败,需要以管理员身份打开开发者命令提示符,或者通过`-DCMAKE_INSTALL_PREFIX=C:\path\to\gmssl`指定用户可写的目录。
## 项目源代码
GmSSL项目的源代码在GitHub中发布和维护。
项目在GitHub的主页为https://github.com/guanzhi/GmSSL
源代码包含主分支的最新代码和定期发布的Release版本建议优先采用主分支最新版。
### 通过CI判断当前代码状态
有时候最新提交的代码可能存在编译错误通常这些错误会在1-2天内被新的提交修复。如果当前最新代码还没有修复那么可以通过GitHub的CI状态来选择没有错误的代码。
通过GitHub的CI工作流状态可以判断某次提交是否存在编译错误目前GmSSL项目中配置了如下编译环境
* CMake ubuntu-latest
* CMake windows-latest
* CMake macos-latest
* CMake-Android
* CMake-iOS
* CMake-OpenHarmony
* MSVC CMake
通过查看这些CI的状态可以判断当前代码是否可以在对应操作系统上成功编译。如果当前最新代码无法在某个平台上编译那么可以选择之前某个通过测试的Commit版本。
## 配置编译选项
在执行`cmake`阶段可以对项目的默认编译配置进行修改修改是通过设置CMake变量来完成的可以查看项目源代码中的`CMakeLists.txt`中所有的`option`指令来查看可选的配置。例如:
```cmake
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
```
表明项目默认生成动态库。
### 设置生成动态库或静态库
GmSSL的CMake默认生成动态库可以通过设定CMake变量`BUILD_SHARED_LIBS``ON`或者`OFF`来指定生成动态库或静态库。
```
cmake .. -DBUILD_SHARED_LIBS=ON
cmake .. -DBUILD_SHARED_LIBS=OFF
```
### 设置优化的密码算法实现
GmSSL包含了针对特定硬件和处理指令集的密码算法优化实现如针对Intel AVX2、AES-NI、ARMv8/AArch64和OpenCL等平台的优化。这些优化实现在匹配的处理器上的实现速度或安全性会大大超过默认的C语言实现。
在配置阶段可以显式地指定采用优化实现可选的CMake配置变量包括
* `ENABLE_SM2_ARM64` SM2算法的ARMv8汇编实现。
* `ENABLE_SM2_AMD64` SM2算法的x86_64汇编实现。
* `ENABLE_SM3_ARM64` SM3算法的ARM NEON实现。
* `ENABLE_SM3_SSE` SM3算法的SSE实现。
* `ENABLE_SM4_ARM64` SM4算法的AArch64汇编实现。
* `ENABLE_SM4_CE` SM4算法的ARMv8 Cryptography Extensions实现。
* `ENABLE_SM4_AVX2` SM4算法的AVX2并行实现。
* `ENABLE_SM4_AESNI` SM4算法的AES-NI实现。
* `ENABLE_SM4_CTR_AESNI_AVX` SM4 CTR模式的AES-NI + AVX实现。
* `ENABLE_GMUL_ARM64` GF(2^128)乘法的AArch64实现。
* `ENABLE_INTEL_RDRAND` 基于Intel RDRAND指令的硬件随机数生成器。
* `ENABLE_INTEL_RDSEED` 基于Intel RDSEED指令的硬件随机数生成器。
* `ENABLE_SM4_CL` SM4算法的OpenCL实现。
### 裁剪可选算法和模块
GmSSL的部分算法、协议和硬件接口可以在配置阶段关闭以减少二进制体积或满足特定部署要求。例如
```bash
cmake .. -DENABLE_SHA1=OFF -DENABLE_AES=OFF -DENABLE_SKF=OFF -DENABLE_SDF=OFF
cmake --build .
```
可选开关以`CMakeLists.txt`中的`option(...)`定义为准。关闭底层算法可能会影响依赖它的协议、工具和测试用例。
## 在Visual Studio环境中编译
CMake支持通过指定不同的构建系统生成器Generator生成不同类型的Makefile。在Windows和Visual Studio环境下CMake即可以生成常规的Visual Studio解决方案(.sln)文件在Visual Studio图形界面中完成编译也可以生成类似于Linux环境下的Makefile文件在命令行环境下完成编译和测试。
### 生成Makefile编译
在安装完Visual Studio之后在启动菜单栏中会出现Visual Studio菜单目录其中包含x64 Native Tools Command Prompt for VS 2022等多个终端命令行环境菜单项。
```bash
C:\Program Files\Microsoft Visual Studio\2022\Community>cd /path/to/gmssl
mkdir build
cd build
cmake .. -G "NMake Makefiles"
nmake
ctest --output-on-failure
```
在编译完成后直接执行安装会报权限错误,这是因为安装过程需要向系统目录中写入文件,而当前打开命令行环境的用户不具备该权限。可以通过右键选择“更多-以管理员身份运行”打开x64 Native Tools Command Prompt for VS 2022终端执行
```
nmake install
```
那么`gmssl`命令行程序、头文件和库文件分别被写入`C:/Program Files/GmSSL/bin``C:/Program Files/GmSSL/include``C:/Program Files/GmSSL/lib`这几个系统目录中。为了能够直接在命令行环境任意目录下执行`gmssl`命令行程序,需要将其安装目录加入到系统路径中,可以执行:
```bash
set path=%path%;C:\Program Files\GmSSL\bin
```
设置完毕后可以在命令行中执行`path`,查看新的路径是否已经成功加入。
### 在Visual Studio图形界面中编译
在安装完Visual Studio之后在启动菜单栏中会出现Visual Studio菜单目录其中包含x64 Native Tools Command Prompt for VS 2022等多个终端命令行环境菜单项。
```bash
C:\Program Files\Microsoft Visual Studio\2022\Community>cd /path/to/gmssl
mkdir build
cd build
cmake ..
```
完成后可以看到CMake在`build`目录下生成了一个`GmSSL.sln`文件和大量的`.vcxproj`文件。
点击`GmSSL.sln`就打开Visual Studio点击Visual Studio工具栏上的"本地Windows调试器"按钮,可以启动编译。
在Visual Studio界面中可以选择Debug、Release、MinSizeRel等不同配置。
### 在Visual Studio中运行测试
在解决方案资源管理器中找到`RUN_TESTS`项目,右键菜单选择"调试-启动新实例"即可运行测试并且在”输出“窗口中看到测试结果。测试完成后会出现RUN_TESTS拒绝访问的对话框。
### 选择生成32位或64位程序
通过在Visual Studio不同的命令行环境中编译GmSSL可以生成32位的X86或者64位的X86_64程序在x64 Native Tools Command Prompt for VS 2022命令行环境下生成的是64位的程序在x86 Native Tools Command Prompt for VS 2022命令行环境下生成的是32位的程序。
可以通过Windows操作系统内置的资源管理器来检查编译生成的可执行程序是32位还是64位在资源管理器的CPU页面中通过“选择列”增加“平台”列这样就可以显示每个进程的是32位或64位。可以运行`gmssl tlcp_client`或者在某个测试文件中增加循环时间来保持命令行运行一段时间。
## 在Cygwin环境中编译
Cygwin是Windows上的Linux模拟运行环境。Cygwin提供了Linux Shell和大量Linux命令行工具也提供了应用程序开发必须的编译工具、头文件和库文件。面向Linux开发的应用通常依赖`unistd.h``sys/socket.h`等头文件及函数但是Visual Studio的C库并没有提供这些POSIX函数实现因此这些Linux应用没有办法直接在Windows环境下编译。Cygwin通过封装Windows操作系统原生功能提供了一个POSIX接口层以及封装这些功能的动态库(`cygwin1.dll`)并且提供了GCC、CMake等完整的Linux编译工具链这意味着标准Linux环境下的头文件都存在并且代码中依赖GCC编译器的特殊语法都可以被编译器识别Visual Studio的`cl`编译器不能完整支持C99语法因此标准的Linux应用都可以通过Cygwin移植到Windows环境编译为Windows本地应用。Cygwin提供的Linux Shell环境意味着Shell脚本也是可以使用的。
在Cygwin环境下编译生成的可执行程序是原生的Windows程序和Visual Studio编译的程序的主要区别在于Cygwin下编译的程序都必须依赖`cygwin1.dll`这个动态库因为应用所有的POSIX函数调用都需要通过这个动态库翻译为Windows本地的系统调用如WinSock2因此发布Cygwin的程序不太方便必须要包含一个较大的`cygwin1.dll`库文件。另外如果应用涉及大量的系统调用那么通过Cygwin中间层会引入一定的开销理论上会比Visual Studio编译的应用效率略低。
总的来说如果你想在Windows环境下快速尝试一下GmSSL的命令行功能并且可能需要利用Linux Shell环境下的一些常用工具做实验和测试或者不太熟悉Visual Studio开发环境那么采用Cygwin环境是一个非常方便的选择。
### 准备Cygwin环境
Cygwin的安装、配置都是通过一个单一的`setup-x86_64.exe`应用程序完成的。在Cygwin的官网 https://www.cygwin.com/ 可以下载这个应用程序。
注意,在首次安装的时候可能没有选择所有需要的程序,再次运行`setup-x86_64.exe`程序可以对环境进行配置和更新。有些工具例如CMake官方提供了独立的Windows安装包在Cygwin环境下没有必要独立安装这些工具也不建议安装所有依赖的Linux工具都应该通过Cygwin环境来配置管理。
在安装、配置完成之后,可以通过运行`Cygwin64 Terminal`应用,打开一个命令行环境。
### 在Cygwin环境中编译GmSSL
Cygwin环境相对标准的Linux环境有一些细微的差别。首先在Cygwin命令行环境中文件系统是一个类似Linux文件系统结构的独立目录如果源代码已经下载到Windows操作系统中比如下载到用户的Download目录那么需要首先将源代码拷贝到Cygwin文件系统的用户目录中例如当前用户默认目录`~`。在Cygwin文件系统中Windows文件系统被映射到`/cygdrive`目录中Windows当前用户Guan Zhi的下载目录中的`GmSSL-master.zip`文件就被映射到`/cygdrive/c/Users/Guan Zhi/Downloads/GmSSL-master.zip`中。
```bash
cp "/cygdrive/c/Users/Guan Zhi/Downloads/GmSSL-master.zip" ~/
```
然后可以按照Linux环境下相似的过程编译、安装
```bash
unzip GmSSL-master.zip
cd GmSSL-master
mkdir build
cd build
cmake ..
cmake --build .
ctest --output-on-failure
cmake --install .
```
注意由于在Cygwin环境中用户本身具有系统权限因此在执行`cmake --install .`时不需要`sudo`
在安装完成之后可以在Cygwin的命令行环境下执行`gmssl`命令行,或者运行源代码`demo`目录下的演示脚本。
注意,将`gmssl`等可执行程序直接从Cygwin目录拷贝到Windows文件系统下在执行时会提示找不到`cygwin1.dll`的错误,运行或者发布可执行程序时,应处理好对这个动态库的依赖问题。
### 存在的问题
Cygwin的动态库名称比较特殊是以`cyg`开头的。使用Cygwin生成的可执行程序和动态库通常依赖`cygwin1.dll`发布给非Cygwin环境使用时需要额外处理这个运行时依赖。
## 面向iOS/iPhoneOS的交叉编译
下载 https://github.com/leetal/ios-cmake ,将`ios.toolchain.cmake`文件复制到`build`目录。
```bash
mkdir build; cd build
cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../ios.toolchain.cmake -DPLATFORM=OS64
cmake --build . --config Release
```
如果出现“error: Signing for "gmssl" requires a development team.”错误可以用Xcode打开工程文件在Signing配置中设置Development Team。
## 面向Android的交叉编译
下载Android NDK执行
```bash
mkdir build; cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-23
cmake --build .
```
## 安装包构建
依赖cmake工具包中的cpack工具生成可发布的安装包。
生成的安装包在`build`目录下。
### 构建DEB安装包
```
mkdir build; cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
cpack -G DEB
```
### 构建RPM安装包
```
mkdir build; cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
cpack -G RPM
```
### 构建`.sh`安装脚本
```
mkdir build; cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
cpack -G STGZ
```
## 生成二进制包
为了保证兼容性,发布的二进制包不包含针对特定指令集的优化代码,并且不启用编译器的`-O3`优化。
在正式发布之前,需要在测试平台上编译、测试、安装。验证`gmssl`命令行可以正确使用,验证`sm3_demo.c`可以正确和`-lgmssl`编译,并且可以正确输出哈希值。
完成编译和测试后,在源码目录下执行如下操作。二进制包需要同时提供动态库和静态库,因此使用两个构建目录:先安装动态库,再安装静态库到同一个打包目录。第二次安装会覆盖`bin/gmssl`,使发布包中的命令行工具链接静态`libgmssl`,同时`lib`目录中保留动态库和静态库。
```bash
#!/bin/bash -x
VERSION=3.2.0
OS=macos
ARCH=arm64
PREFIX="$PWD/gmssl-$VERSION"
rm -rf "$PREFIX" build-shared build-static
cmake -S . -B build-shared -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_PREFIX="$PREFIX"
cmake --build build-shared
ctest --test-dir build-shared --output-on-failure
cmake --install build-shared
cmake -S . -B build-static -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_INSTALL_PREFIX="$PREFIX"
cmake --build build-static
ctest --test-dir build-static --output-on-failure
cmake --install build-static
tar czvf gmssl-$VERSION-$OS-$ARCH.tar.gz gmssl-$VERSION
```
发布包目录结构如下:
```bash
gmssl-$VERSION/
bin/
gmssl
include/
gmssl/
lib/
libgmssl.a
libgmssl.so # Linux动态库
libgmssl.dylib # macOS动态库
```
其中静态库和动态库的具体文件名会随操作系统变化。例如Linux通常生成`libgmssl.so`及其版本符号链接macOS通常生成`libgmssl.dylib`及其版本符号链接Windows通常生成`.dll`和导入库。打包前需要在目标平台上确认`bin/gmssl version`可以运行并确认一个外部C程序可以通过`-I<package>/include``-L<package>/lib -lgmssl`完成编译和链接。