第 4 章 开发环境搭建:操作系统、编译器、依赖库
搞国密改造,第一步不是写代码,而是先把环境搭结实。我见过太多团队在项目中期发现 GCC 版本不对、OpenSSL 缺模块,来回折腾好几天。所以这一章咱们就把地基打牢——操作系统、编译器、依赖库,一个一个说清楚。
4.1 操作系统选型
政务场景嘛,首选 Linux,Windows 基本不考虑。我建议直接从这两个方向入手:
- CentOS 7 / 8(或 Rocky Linux / AlmaLinux)—— 服务器端用得最多
- Ubuntu 20.04 / 22.04 LTS —— 开发机或快速验证环境
- 统信 UOS / 麒麟 —— 信创环境强制要求时用
我个人习惯:开发机用 Ubuntu 20.04,部署机用 CentOS 7.9。内核版本尽量 3.10 以上,因为国密 SKF 接口需要内核支持随机数设备和 /dev/crypto 节点。
下面这张表是我自己整理的选型参考:
| 操作系统 | 内核版本要求 | OpenSSL 默认支持 | 推荐场景 |
|---|---|---|---|
| CentOS 7.9 | 3.10.0+ | 1.0.2k(需升级) | 传统政务内网服务器 |
| Ubuntu 20.04 | 5.4+ | 1.1.1f(自带) | 开发机、CI/CD 环境 |
| 统信 UOS 20 | 4.19+ | 1.1.1d(自带) | 信创适配验收 |
| 麒麟 V10 | 4.19+ | 1.1.1k(自带) | 党政机关部署 |
4.2 编译工具链
编译器版本是关键。国密 SDK 很多用 C++11 / C++14 特性,GCC 4.8.5 是底线,但我推荐直接上 7.3 以上,省得后面折腾。
先看一眼当前版本:
gcc --version
g++ --version
如果版本太低,升级方法很简单:
- CentOS:用
yum install centos-release-scl安装 devtoolset-7 或 devtoolset-9 - Ubuntu:
apt install gcc-7 g++-7,再用update-alternatives切换默认版本
除了 gcc/g++,还有几个工具必须提前装好:
- CMake ≥ 3.12(国密 SDK 很多用 CMake 构建)
- Make 4.x
- pkg-config — 用来查找库的头文件和链接路径
- autoconf / automake / libtool — GmSSL 和老版本 OpenSSL 编译时可能需要
避坑指南:我曾经在 CentOS 7 上用 yum 直接装的 cmake 是 2.8 版本,结果项目里的
add_compile_definitions 指令不认。后来老老实实从 cmake.org 下载源码编译安装了 3.20。记住,yum 源里的 cmake 版本通常很老,建议手动装。
4.3 国密 SDK 依赖库
核心依赖就两个:OpenSSL 和 GmSSL(或 gmssl- tengine)。
- OpenSSL 1.1.1+(推荐 1.1.1l 以上)— 原生支持 SM2/SM3/SM4,但默认不开启,编绎时需要加
enable-ec_nistp_64_gcc_128和-DOPENSSL_SM2等选项 - GmSSL 3.x — 国密标准库,如果项目要求纯国密就选它
- libcurl + nghttp2 — 很多国密 SDK 的 HTTP 调用需要 HTTPS,这两个最好也装全
装 OpenSSL 时建议用源码编译,配置参数我一般这样写:
./configure \
--prefix=/usr/local/openssl-1.1.1l \
--openssldir=/usr/local/openssl-1.1.1l/ssl \
shared enable-ec_nistp_64_gcc_128
make -j$(nproc) && make install
装好之后记得更新动态库缓存:
echo "/usr/local/openssl-1.1.1l/lib" > /etc/ld.so.conf.d/openssl-1.1.1l.conf
ldconfig
关键检查点:运行
openssl version 确认版本,再执行 openssl ecparam -list_curves | grep SM2 看看 SM2 曲线是否存在。如果输出空信息,那说明 OpenSSL 编译时没加上 SM2 支持,得重新编。
4.4 环境验证脚本
每次换机器我都先跑一遍这个脚本,省得踩坑:
#!/bin/bash
echo "=== 检查 GCC 版本 ==="
gcc --version | head -1
echo "=== 检查 CMake 版本 ==="
cmake --version | head -1
echo "=== 检查 OpenSSL 版本 ==="
openssl version
echo "=== 检查 SM2 支持 ==="
openssl ecparam -list_curves 2>/dev/null | grep SM2 || echo "❌ 未找到 SM2 曲线"
echo "=== 检查 GmSSL 是否可用 ==="
which gmssl 2>/dev/null && echo "✅ GmSSL 已安装" || echo "⚠️ GmSSL 未安装"
把脚本保存成 check-env.sh,然后 chmod +x check-env.sh && ./check-env.sh 跑一遍。任何一步出错都先解决再往下。
4.5 常见问题与避坑
- 问题:链接时找不到 libcrypto.so
原因:用了系统自带的旧 OpenSSL,但编译时链接了手动安装的新版本。
解决:编译时加-I/usr/local/openssl-1.1.1l/include -L/usr/local/openssl-1.1.1l/lib -Wl,-rpath,/usr/local/openssl-1.1.1l/lib - 问题:编译 GmSSL 报错 undefined reference to 'pthread_atfork'
原因:某些老版本 GmSSL 的 configure 没正确处理线程库。
解决:加上CFLAGS="-pthread" LDFLAGS="-lpthread" ./configure - 问题:openssl version 显示新版,但 SM2 曲线不存在
原因:编译参数里没加enable-ec_nistp_64_gcc_128或者没打开 SM2 特性。
解决:重新编译,用上面 4.3 节的参数。
我曾经在信创适配现场折腾了一下午,就是由于开发机上用的 Ubuntu 自带 OpenSSL 1.1.1,但编译时没加
-DOPENSSL_API_COMPAT=0x10101000L,导致 SM3 相关的符号找不到。后来给 Makefile 里补了这行编译宏才搞定。所以环境验证脚本真的不是摆设,建议你也养成习惯——换机器就跑。