2. 开发环境搭建:操作系统选择、编译器安装、依赖库编译
做国密SDK的持续集成验证,第一步就是搭环境。环境搭不好,后面全是坑。我个人习惯把操作系统、编译器、依赖库这三件事先理清楚,再动手。
说白了,环境搭建就像盖房子的地基。你想想看,地基歪了,上面墙再直也没用。我早年碰到过一个项目,开发人员在Windows上用MSVC编译本地通过,放到Linux CI服务器上用GCC就报链接错误,最后查了三天——原来是不同编译器对结构体对齐的默认规则不一样。
2.1 操作系统选哪个?
国密SDK的验证场景主要分为两类:服务器端和客户端。服务器端基本是Linux,客户端可能是Windows或macOS。我建议按以下维度选:
| 操作系统 | 适用场景 | 推荐版本 | 注意点 |
|---|---|---|---|
| Linux (Ubuntu/Debian) | 服务器CI、交叉编译、生产验证 | Ubuntu 20.04/22.04 LTS Debian 11/12 |
apt包管理方便,GCC默认支持 |
| Windows | 桌面客户端SDK集成、MSVC测试 | Windows 10/11 + Visual Studio 2022 | 需额外安装Git、CMake、Perl |
| macOS | 开发者本机调试、Clang测试 | macOS Ventura / Sonoma | Homebrew管理依赖,注意Clang版本 |
嗯,这里还有一个我没明说的点:如果你需要交叉编译到国产平台(如飞腾、鲲鹏、龙芯),Ubuntu的交叉工具链最方便。我上次为一个信创项目搭环境,apt install一下就搞定ARM64交叉编译器,比在Windows上折腾MinGW省心多了。
2.2 编译器:GCC、Clang、MSVC怎么装?
编译器是SDK编译的核心工具。GmSSL和OpenSSL都用C语言写的,对编译器要求不高——但细节会坑人。我这里把三种常见的编译器安装方法列出来。
2.2.1 GCC (Linux首选)
GCC是Linux上的默认编译器。用apt安装最简单:
# Ubuntu/Debian
sudo apt update
sudo apt install build-essential gcc g++ gdb cmake
验证版本:
gcc --version
# 输出类似:gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
2.2.2 Clang (跨平台/ macOS常用)
Clang的编译错误信息比GCC友好,尤其适合开发阶段。在Linux上装:
sudo apt install clang-14 lld-14
macOS上Xcode自带Clang,但版本可能偏老。我习惯用Homebrew更新:
brew install llvm
export PATH="/usr/local/opt/llvm/bin:$PATH"
2.2.3 MSVC (Windows)
Windows下的编译器是MSVC,集成在Visual Studio里。我推荐用 Visual Studio 2022 Community(免费)。安装时勾选“使用C++的桌面开发”工作负载,然后打开“开发者命令提示符”即可使用 cl.exe。
为了在CI脚本中调用,你还需要设置环境变量:
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
inline 在MSVC中默认是C89标准,需要定义 __STDC__ 或加 /std:c11 开关。我写GmSSL的CMakeLists.txt时,专门加了一段判断:if(MSVC) target_compile_options(my_target PRIVATE /std:c11 /utf-8) endif()
2.3 依赖库编译:OpenSSL 和 GmSSL
好了,操作系统和编译器就绪后,该编译依赖库了。为什么强调“编译”,而不是直接用包管理器装?因为持续集成环境往往需要静态链接、定制编译选项(比如禁用某些算法、启用国密支持),打包好的二进制不一定满足你的需求。
我习惯把这个流程画成一张图,你一看就明白:
2.3.1 编译OpenSSL(带国密支持)
OpenSSL 1.1.1开始原生支持SM2/SM3/SM4曲线,但需要编译时显式开启。我一般这么干:
wget https://www.openssl.org/source/openssl-3.0.12.tar.gz
tar xzf openssl-3.0.12.tar.gz
cd openssl-3.0.12
./Configure linux-x86_64 \
--prefix=/opt/openssl-gm \
--openssldir=/opt/openssl-gm \
enable-ec enable-sm2 enable-sm3 enable-sm4 \
no-afalgeng \
-fPIC
make -j$(nproc)
make install
find_package(OpenSSL 3.0 REQUIRED PATHS /opt/openssl-gm),或者临时设置 LD_LIBRARY_PATH。
2.3.2 编译GmSSL(国密原生库)
GmSSL 3.x 的作者已经帮你把国密算法内置好了,不需要额外开关。它支持CMake和Configure两种方式。我个人习惯用CMake,因为方便在CI中控制安装路径:
git clone https://github.com/guanzhi/GmSSL.git
cd GmSSL
mkdir build && cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=/opt/gmssl \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_TESTING=ON
cmake --build . -j$(nproc)
cmake --install .
编译完成后,验证一下:
/opt/gmssl/bin/gmssl version
# 输出:GmSSL 3.2.0 - OpenSSL 3.0.12 兼容接口
2.3.3 集成到CI脚本
在持续集成中,我通常把编译脚本写成独立文件,比如 build_deps.sh,内容如下:
#!/bin/bash
set -euo pipefail
DEPS_DIR="$PWD/deps"
mkdir -p "$DEPS_DIR"
# 编译OpenSSL
cd "$DEPS_DIR"
if [ ! -d "openssl-3.0.12" ]; then
tar xzf ../openssl-3.0.12.tar.gz
cd openssl-3.0.12
./Configure linux-x86_64 --prefix="$DEPS_DIR/openssl" --openssldir="$DEPS_DIR/openssl" \
enable-ec enable-sm2 enable-sm3 enable-sm4 -fPIC
make -j$(nproc) && make install
fi
# 编译GmSSL
cd "$DEPS_DIR"
if [ ! -d "GmSSL" ]; then
git clone --depth 1 https://github.com/guanzhi/GmSSL.git
cd GmSSL && mkdir -p build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX="$DEPS_DIR/gmssl" -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc) && cmake --install .
fi
# 设置环境变量
export PATH="$DEPS_DIR/openssl/bin:$DEPS_DIR/gmssl/bin:$PATH"
export LD_LIBRARY_PATH="$DEPS_DIR/openssl/lib:$DEPS_DIR/gmssl/lib"
echo "Depencencies built at $DEPS_DIR"
set -euo pipefail,任何一步失败立刻停止,避免“半残”的依赖库被后续步骤使用。我之前吃过亏,make失败但make install继续执行,结果装了个残缺的libcrypto.so,API调用直接段错误。
2.4 本章小结
开发环境搭建看似枯燥,但你只要把操作系统、编译器、依赖编译这三步走顺,后面所有验证工作就有了统一的基础。
我再说一句实在的:环境平台尽早统一,宁可在Ubuntu 22.04上花一下午把脚本打磨好,也别到项目后期再回头补环境。那滋味,谁试谁知道。