第 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

如果版本太低,升级方法很简单:

  1. CentOS:用 yum install centos-release-scl 安装 devtoolset-7 或 devtoolset-9
  2. 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 里补了这行编译宏才搞定。所以环境验证脚本真的不是摆设,建议你也养成习惯——换机器就跑。
开发环境搭建依赖关系 开发环境搭建依赖关系图 操作系统选型 编译器 (GCC 7.3+) 构建工具 (CMake) 依赖库 (OpenSSL/GmSSL) 环境验证脚本 国密 SDK 改造开发 箭头方向:依赖 / 前置条件