☰
Linux源码编译Python 3.9.2:依赖、OpenSSL与多版本共存
2026/11/3 8:34:41 网站建设 项目流程

近段时间陆陆续续有人问我同一个问题:手上有个老项目,requirements.txt里一堆包锁死在特定版本,跑在系统自带的 Python 上各种报错,是不是得单独装一个 Python 3.9.2?问的人多了,我干脆把整套流程和踩过的坑整理一遍。这篇内容讲的就是在 Linux 上从源码编译安装 Python 3.9.2 这件事——从依赖准备、configure 参数取舍、编译报错的排查链路,到装完之后的软链接、venv、多版本共存与回滚。适合两类人看:一类是被版本兼容性折磨、需要精确控制解释器版本的后端和算法同学;另一类是刚接手一台新机器、对make install心存敬畏、想搞清楚每一步在干什么的运维新手。3.9.2 这个版本有点特殊,它是 2021 年初的产物,放到今天的新发行版上编译,会撞上 OpenSSL 3.x 这道墙,这也是很多人卡住的地方。

1. 系统的 Python 为什么不能直接用,以及三条路的取舍

先把话说明白:绝大多数情况下,你不应该去动系统自带的那个 Python。系统里的/usr/bin/python3是包管理器的依赖项,apt、dnf、cloud-init、各种系统脚本全都指着它活。你把它替换掉,轻则某个系统工具启动失败,重则包管理器直接罢工,修复起来比重装还麻烦。我在早期就干过一次这种蠢事,为了装一个新版本顺手把/usr/local/bin/python3指过去,结果apt报了ModuleNotFoundError: No module named 'apt_pkg',折腾了小半天才把链接改回来。

1.1 系统解释器的两个硬伤

系统 Python 的问题不在于新旧,而在于不可控。第一,版本被发行版冻结了。你用的发行版发布时打包的是 3.11,那基本就一直是 3.11 的补丁级别,不会给你跳到 3.9。第二,也是更要命的一点,系统 Python 的site-packages目录被系统包管理器占用着,你用pip install往里塞东西,会和发行版打包的包打架,出现同一个包两个版本、dist-info混乱的情况。

所以思路很清晰:系统 Python 原封不动,我们自己另起一套,装到独立目录,用独立的名字调用。这是所有方案的共同出发点,剩下的只是"用哪种方式另起一套"。

1.2 源码编译、版本管理工具、发行版第三方仓库的对比

这三条路我都走过,各有各的位置,先把结论摆出来:

方案上手成本版本控制粒度对老版本的友好度典型适用场景
源码编译中高,需要懂依赖完全可控,补丁级别都能指定好,任何历史版本都能编需要精确锁定 3.9.2、要定制编译选项
版本管理工具(如 pyenv)低,几条命令搞定好,版本列表任选好,但本质也是帮你编译一个人一台机器要切多个版本
发行版第三方仓库低一般,通常只提供大版本差,老版本容易被淘汰只想要个新版本、不挑补丁号

这里有个很多人不知道的事实:pyenv 装 Python 的时候,底层执行的也是源码编译。它只是把下载、解压、configure、make 这一套自动化了而已。所以你如果不会手动编译,用 pyenv 遇到依赖缺失一样会失败,而且因为过程被藏起来了,报错更难定位。我见过不少人pyenv install 3.9.2卡在那里,翻日志才发现是libffi-dev没装。

那么什么时候我仍然推荐源码编译?答案是当你需要精确控制编译选项的时候。比如你想把 OpenSSL 静态编进去、想关掉某些模块、想指定--prefix到一个特定的交付目录、想开启 PGO 优化,这些 pyenv 做起来就绕了。而且从交付角度讲,你手动编译出来的这套东西,目录结构、依赖关系清清楚楚,出了问题好排查。

还有一点值得提:3.9.2 这个具体版本号,很多老项目的runtime.txt或者 CI 配置里就写死了它。你要复现一个三年前的构建环境,最稳的办法就是真把它编出来,而不是拿 3.9.18 去凑——虽然大版本号一样,但 CPython 在补丁版本之间也会改 C API 细节,某些带 C 扩展的包(尤其是当年没维护的)表现可能不同。

2. 依赖清单:编译前该装的东西一个都不能少

源码编译 Python 最容易翻车的地方不在编译本身,而在依赖没装全。麻烦的是,依赖缺失往往不会让编译直接失败,而是静默跳过某个模块,等你装完跑起来才发现import ssl报错、import sqlite3找不到。所以这一步宁可多装,不要少装。

2.1 两类发行版的包名对照

Python 标准库里有十来个模块是依赖外部 C 库的,缺一个就少一块功能。下面这张表是我整理的核心清单,左边是基于 apt 的发行版,右边是基于 dnf/yum 的发行版:

依赖库apt 系包名dnf/yum 系包名缺失后受影响的模块
编译工具链build-essentialgcc make整个编译过程
zlibzlib1g-devzlib-develzlib、zipimport、pip 解压 wheel
OpenSSLlibssl-devopenssl-develssl、hashlib、pip 走 HTTPS
libffilibffi-devlibffi-develctypes、cffi
bzip2libbz2-devbzip2-develbz2
xz / lzmaliblzma-devxz-devellzma
readlinelibreadline-devreadline-develreadline(交互式方向键、历史记录)
sqlite3libsqlite3-devsqlite-develsqlite3
ncurseslibncursesw5-devncurses-develcurses
gdbmlibgdbm-devgdbm-develdbm.gnu
uuiduuid-devlibuuid-develuuid
Tktk-devtk-develtkinter

一次性的安装命令长这样:

# 基于 apt 的发行版 sudo apt update sudo apt install -y build-essential zlib1g-dev libssl-dev libffi-dev \ libbz2-dev liblzma-dev libreadline-dev libsqlite3-dev libncursesw5-dev \ libgdbm-dev uuid-dev tk-dev wget curl
# 基于 dnf/yum 的发行版 sudo dnf groupinstall -y "Development Tools" sudo dnf install -y zlib-devel openssl-devel libffi-devel bzip2-devel \ xz-devel readline-devel sqlite-devel ncurses-devel gdbm-devel \ libuuid-devel tk-devel wget curl

2.2 三个最容易被漏掉的开发库

上面那张表里,有三个我觉得必须单独拎出来说,因为它们缺失后的表现特别有迷惑性。

第一个是 zlib。缺它的时候,编译能完整跑完、make altinstall也成功,但你在新环境里pip install任何包都会报zipimport.ZipImportError: can't decompress data; zlib not available。看到这个报错的人第一反应往往是"pip 坏了",然后开始重装 pip,越搞越乱。实际上根子是解释器编译时没链上 zlib。更隐蔽的一种情况是:ensurepip阶段就失败了,你会看到WARNING: The pip package is not available,但因为只是个 warning,很多人扫一眼就过去了。

第二个是 libffi。缺它的表现比 zlib 更晚暴露。解释器本身完全正常,pip install也能跑,直到某个包(比如cryptography、cffi、pycparser相关的一堆东西)import 时报ModuleNotFoundError: No module named '_ctypes'。_ctypes是 Python 调用 C 函数的桥梁,没有它,一大半需要编译扩展的包全都装不上或者跑不起来。

第三个是 OpenSSL 的开发包。注意,装运行时库openssl是不够的,必须装带头文件的-dev/-devel版本。只装运行时的话,configure 阶段找不到openssl/ssl.h,_ssl模块会被静默跳过,结果就是你的解释器import ssl直接失败。而 pip 从 HTTP 源装包时可能看不出问题,一换成 HTTPS 源立刻崩。

2.3 编译前的资源检查

Python 3.9.2 完整编译一遍,源代码目录大概占 300MB,安装目录 200MB 出头。如果开了--enable-optimizations,编译过程中还要跑 PGO 的训练测试,峰值内存会明显上去。我一般会先看一眼:

df -h /opt free -h nproc

如果内存只有 1GB 出头,make -j$(nproc)很容易被系统的内存回收机制干掉,报一个特别吓人的internal compiler error: Killed (program cc1)。这个报错跟代码质量毫无关系,纯粹是 OOM,把并行度降到-j2就好了。这个坑我在一些轻量云主机上踩过不止一次,第一次看到的时候还以为是编译器有 bug。

3. configure 那一行命令,每个参数都有代价

拿到源码包之后,解压、进目录,然后就到了最关键的./configure。这一步决定了装在哪、启用了什么、链接了哪个 OpenSSL。参数写错了,后面所有的编译时间都是白费。

3.1 源码获取与校验

cd /tmp wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz.asc tar -xzf Python-3.9.2.tgz cd Python-3.9.2

严格来说还应该验一下签名,尤其是要往生产环境交付的时候。我一般会顺手把Python-3.9.2.tgz的哈希记下来,写进内部的部署文档,后面别的机器复现时先比对一遍,避免中间某个环节文件被换掉。

3.2--prefix决定了所有后果

--prefix是这里面最重要的参数,没有之一。它决定了装完之后文件落在哪里,也决定了你以后删的时候会不会误伤别的东西。

我的习惯是装到/opt/python3.9,理由很简单:/opt就是给这种独立软件准备的,和系统文件天然隔离,卸载时一个rm -rf干净利落,不影响任何系统组件。

./configure --prefix=/opt/python3.9

如果你图省事用--prefix=/usr/local,那要特别小心后面执行make install。因为/usr/local/bin通常在PATH里排在/usr/bin前面,make install创建的python3软链接会直接抢走python3这个命令的归属权,系统的包管理器下次调用python3时用的就是你的新解释器——很多"装完 Python 系统就坏了"的事故都是这么来的。

提示:--prefix一旦定了就别中途改。改了之后重新 configure 是可以,但旧的安装目录会残留一堆文件,尤其是.so和头文件,后面排查起来很烦。

3.3--enable-optimizations值不值得开

这个选项干的事情是启用 PGO(Profile Guided Optimization):先编一个临时版本,用它跑一遍 Python 自带的测试套件,收集热点代码的执行路径,再根据这份数据重新编译。理论上能带来 10% 到 20% 的运行性能提升。

代价也很实在:编译时间从三四分钟涨到二十分钟以上,机器性能差的话半小时也正常。而且这个过程对内存要求更高,因为要同时跑测试。我的判断标准是这样的:

  • 如果是长期运行的服务或频繁跑批的环境,值得开,一次编译的代价换来长期的性能收益。
  • 如果是临时验证、CI 镜像里跑一次就扔,别开,纯粹浪费时间。
  • 如果机器只有 1GB 内存,别开,大概率 OOM。
./configure --prefix=/opt/python3.9 --enable-optimizations

3.4 OpenSSL 3.x:3.9.2 绕不过去的一道坎

这是本文最想强调的部分。Python 3.9 这一支官方不支持 OpenSSL 3.0,正式支持要等到 3.10。原因很具体:OpenSSL 3.0 移除了一批旧宏,而 CPython 3.9 的_ssl.c里还在用ERR_GET_FUNC这类已经被删掉的宏,编译时就会直接报 undeclared 或者 undefined reference。

如果你用的发行版比较新,系统里装的已经是 OpenSSL 3.x,那默认编译出来的 Python 3.9.2 的_ssl模块会编不出来。表现出来就是装完之后:

>>> import ssl ModuleNotFoundError: No module named '_ssl'

解决办法是给这个 Python 单独准备一份 OpenSSL 1.1.1,编到一个独立目录,configure 时指过去:

cd /tmp wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz tar -xzf openssl-1.1.1w.tar.gz cd openssl-1.1.1w ./config --prefix=/opt/openssl11 --openssldir=/opt/openssl11/ssl shared zlib make -j$(nproc) sudo make install

装好之后,configure 要加上路径,同时用 rpath 把这个库路径烧进二进制,避免运行时还要手动设LD_LIBRARY_PATH:

cd /tmp/Python-3.9.2 ./configure \ --prefix=/opt/python3.9 \ --with-openssl=/opt/openssl11 \ --enable-optimizations \ --with-ensurepip=install \ --enable-loadable-sqlite-extensions \ LDFLAGS="-Wl,-rpath,/opt/openssl11/lib"

这里的-Wl,-rpath是我强烈建议加上的。不加的话,编出来的_ssl.so在运行时按名字去找libssl.so.1.1,如果系统里只有 3.x,就会在import ssl时抛ImportError: libssl.so.1.1: cannot open shared object file。这个错误发生在运行时而不是编译时,特别容易让人误以为编译成功了。

3.5--enable-shared的陷阱

网上不少教程会让你加--enable-shared,说是方便其他程序嵌入 Python。这个选项本身没问题,但它会带来一个副作用:生成的libpython3.9.so不在系统的动态库搜索路径里,你装完直接跑/opt/python3.9/bin/python3.9会报:

error while loading shared libraries: libpython3.9.so.1.0: cannot open shared object file

如果确实需要这个选项,就得补一步:

echo "/opt/python3.9/lib" | sudo tee /etc/ld.so.conf.d/python39.conf sudo ldconfig

我的建议是:除非你有明确的嵌入需求,否则别开这个选项。纯命令行使用、跑服务、建 venv,都不需要它。

3.6make与make altinstall

make -j$(nproc) sudo make altinstall

altinstall和install的区别就一句话:altinstall不创建python3这个软链接,只创建python3.9。就这一点差别,决定了你的系统会不会被搞坏。养成习惯,源码编译一律用altinstall。

编译过程中如果看到Failed to build these modules:这样的段落,一定要停下来看是哪些模块。常见的几个:

报错模块缺失的依赖补救方式
_sslOpenSSL 头文件或版本不匹配装-dev包或指定--with-openssl
_ctypeslibffi 开发包装libffi-dev/libffi-devel
zlibzlib 开发包装zlib1g-dev/zlib-devel
_sqlite3sqlite 开发包装libsqlite3-dev/sqlite-devel
readlinereadline 开发包装libreadline-dev/readline-devel
_lzmaxz 开发包装liblzma-dev/xz-devel

补完依赖之后,不用从头再来,直接make clean && ./configure ... && make -j$(nproc)就行。

4. 四类典型报错的完整排查链路

这一节我按"现象—判断—验证—修复—回归"的顺序写,因为实际排查就是这么走的,直接甩个结论意义不大。

4.1 现象:pip 装包报 zlib 解压失败

现象:pip install requests报zipimport.ZipImportError: can't decompress data; zlib not available。

判断:这个报错几乎可以确定为解释器本身没编进 zlib 模块,不是 pip 的问题。

验证:先确认模块到底在不在:

/opt/python3.9/bin/python3.9 -c "import zlib; print(zlib.ZLIB_VERSION)"

如果抛ModuleNotFoundError,实锤。

修复:回头检查系统里有没有装 zlib 的开发包:

dpkg -l | grep zlib1g-dev # apt 系 rpm -qa | grep zlib-devel # dnf 系

装好之后重新走一遍 configure 和 make。

回归:重编之后再用上面那条命令验证,能打印出版本号就对了。然后python3.9 -m pip install --upgrade pip应该能正常跑完。

这里有个容易忽略的细节:系统里装了 zlib 运行时库不等于装了开发包。很多人ls /usr/lib/x86_64-linux-gnu/libz.so.1看到文件存在,就认为依赖齐了,实际上-dev包提供的是libz.so这个符号链接和头文件,configure 需要的是后者。

4.2 现象:import ctypes 报 _ctypes 缺失

现象:解释器能跑,pip 能用,但装某些包或者 import 时抛ModuleNotFoundError: No module named '_ctypes'。

判断:libffi 开发包缺失。这个报错通常在装cffi、cryptography这类需要调用 C 代码的包时才暴露。

验证:

/opt/python3.9/bin/python3.9 -c "import ctypes; print(ctypes.__file__)"

同时回头翻一下当初编译的日志,搜索_ctypes:

grep -i "_ctypes" /tmp/build.log

如果看到Failed to build these modules: _ctypes,那就对上了。

修复:装libffi-dev(apt)或libffi-devel(dnf),重新 configure + make + altinstall。

一个额外提醒:libffi 有一部分是架构相关的,--enable-optimizations的 PGO 阶段如果因为 libffi 缺失导致测试套件大面积失败,编译过程本身可能也会中止。所以依赖要在 configure 之前一次装齐,别指望后面补。

4.3 现象:装完 import ssl 失败,且系统是 OpenSSL 3.x

现象:import ssl抛ModuleNotFoundError: No module named '_ssl',或者抛ImportError: libssl.so.1.1: cannot open shared object file。

判断:分两种情况。第一种是编译时_ssl模块压根没编出来,报的是No module named '_ssl';第二种是编出来了但运行时找不到对应的动态库,报的是libssl.so.1.1找不到。这两种的根因是同一个,但处理细节不同。

验证:

# 看系统 OpenSSL 版本 openssl version # 看编译日志里 _ssl 的情况 grep -i "ssl" /tmp/build.log | head -30 # 如果已经装好了,看它链的是哪个库 ldd /opt/python3.9/lib/python3.9/lib-dynload/_ssl*.so | grep ssl

最后这条ldd特别有用,能直接看出_ssl.so依赖的是libssl.so.3还是libssl.so.1.1。

修复:按 3.4 节的办法,编一份独立的 OpenSSL 1.1.1,configure 时用--with-openssl指定,并用LDFLAGS把 rpath 写进去。千万别图省事去系统里把 OpenSSL 3.x 卸载降级——那会把整个系统的软件生态拖下水,curl、ssh、包管理器全都依赖它。

回归验证:

/opt/python3.9/bin/python3.9 -c "import ssl; print(ssl.OPENSSL_VERSION)"

应该输出OpenSSL 1.1.1w x Sep 2023之类的内容。

4.4 现象:能 import ssl,但 pip 走 HTTPS 全失败

现象:import ssl正常,openssl.OPENSSL_VERSION也正常,但pip install任何包都报SSL: CERTIFICATE_VERIFY_FAILED或者HTTPSConnectionPool连接失败。

判断:这是证书路径的问题,不是编译问题。Python 3.9 在编译时如果没有显式指定证书包路径,会去 OpenSSL 的默认目录找cert.pem。你装的是自定义 prefix 的 OpenSSL,那个目录下通常是空的。

验证:

/opt/python3.9/bin/python3.9 -c "import ssl; print(ssl.get_default_verify_paths())"

看cafile和openssl_cafile指向哪里,再去ls一下那个路径,多半不存在或者是个空文件。

修复:把系统的证书包复制或者软链过去:

sudo mkdir -p /opt/openssl11/ssl sudo cp /etc/ssl/certs/ca-certificates.crt /opt/openssl11/ssl/cert.pem

或者在装 pip 之后显式指定:

/opt/python3.9/bin/python3.9 -m pip config set global.cert /etc/ssl/certs/ca-certificates.crt

这一步是我踩过的最隐蔽的坑之一。当时编译、install 一路绿灯,import ssl也 OK,结果 CI 上所有pip install全挂了,日志里只有一句干巴巴的证书校验失败,查了大半天才定位到证书路径。

5. 装完之后的三件事:命令入口、venv 与多版本共存

make altinstall跑完,产物在/opt/python3.9/bin/下:python3.9、pip3.9、idle3.9、2to3-3.9等等。没有python3,这是对的,别急着去创建。

5.1 命令入口怎么安排

最省事的做法是在/usr/local/bin下建软链接,让普通用户不用敲全路径:

sudo ln -sf /opt/python3.9/bin/python3.9 /usr/local/bin/python3.9 sudo ln -sf /opt/python3.9/bin/pip3.9 /usr/local/bin/pip3.9

注意这里链接的名字是python3.9,不是python3,也不是python。这个原则要守住:任何可能和系统默认解释器重名的入口,一律不碰。

如果你希望用alternatives机制来做更规范的管理,可以这样:

sudo update-alternatives --install /usr/local/bin/python3.9 python3.9 /opt/python3.9/bin/python3.9 100 sudo update-alternatives --config python3.9

不过说实话,对一个只装一个额外版本的环境,软链接已经够用了,alternatives 是版本多了之后才值得引入的工具。

5.2 别急着升 pip,先看看自带的是哪个

Python 3.9.2 的ensurepip自带的 pip 是 20.2.3 这个年代的版本。这个版本对现在很多包的 PEP 517 构建支持不完整,装带pyproject.toml的包时可能报Could not build wheels for xxx。

/opt/python3.9/bin/python3.9 -m pip --version

如果版本低于 21,先升一下:

/opt/python3.9/bin/python3.9 -m pip install --upgrade pip setuptools wheel

有个细节值得注意:升级 pip 时要确认走的是新解释器自己的 pip,命令用python3.9 -m pip而不是直接敲pip。直接敲pip有可能命中系统的那个,把你系统 Python 的 pip 给升级了,那又是一堆麻烦。

5.3 venv 创建与项目隔离

装好之后,我的习惯是在项目目录下建 venv,而不是全局装包:

/opt/python3.9/bin/python3.9 -m venv .venv source .venv/bin/activate python --version # 应该是 3.9.2 pip install -r requirements.txt

venv 创建后里面的python软链接指向的就是/opt/python3.9/bin/python3.9,所以系统解释器升级不受影响。

这里有个经验:venv 里的 pip 是创建那一刻的副本,不是软链接。所以你在外面升级了 pip,已有的 venv 不会跟着变。要在 venv 里再升一次:

python -m pip install --upgrade pip

我见过有人纳闷为什么新建的 venv 里 pip 版本跟全局不一样,原因就在这。

5.4 多版本共存的实际布局

一台机器上跑多个 Python 版本是很常见的。我的目录布局一般是这样:

/opt/python3.9/ # 3.9.2 /opt/python3.11/ # 3.11.x /opt/openssl11/ # 给 3.9 用的 OpenSSL 1.1.1

每个版本独立--prefix,独立软链接,互不干扰。需要切版本的时候,进不同项目目录source .venv/bin/activate就行,不需要全局切换。

如果确实需要全局切换,用 alternatives 把python3这个泛名字管起来是可以的,但要注意:很多系统工具用的是#!/usr/bin/env python3,一旦切换了,这些工具的行为就变了。所以我个人坚持不切,宁可命令行里多敲个版本号。

6. 验证清单与出问题时的回滚

装完之后我一定会跑一遍下面这组命令,确认每个关键模块都在。这比"能跑起来就行"要靠谱得多,因为很多模块缺失是延迟暴露的。

6.1 六个必查项

P=/opt/python3.9/bin/python3.9 $P -c "import sys; print(sys.version)" # 版本号 $P -c "import ssl; print(ssl.OPENSSL_VERSION)" # SSL 编译进去了 $P -c "import zlib; print(zlib.ZLIB_VERSION)" # zlib 可用 $P -c "import sqlite3; print(sqlite3.sqlite_version)" # sqlite 可用 $P -c "import ctypes; print('ctypes ok')" # libffi 可用 $P -c "import readline; print('readline ok')" # 交互式补全可用 $P -c "import lzma, bz2, uuid; print('compress ok')" # 压缩与 uuid $P -m pip --version # pip 可用

对照一下期望输出:

检查项期望结果不达标说明
sys.version显示3.9.2装错版本了
ssl.OPENSSL_VERSION显示OpenSSL 1.1.1x_ssl没编进去或链错库
zlib.ZLIB_VERSION显示具体版本号zlib 开发包缺失
sqlite3.sqlite_version显示具体版本号sqlite 开发包缺失
import ctypesctypes oklibffi 开发包缺失
import readlinereadline ok方向键、历史记录会失效
pip --version显示路径为/opt/python3.9/...命中了别的 pip

最后一项要特别看路径。如果pip --version输出的路径是/usr/lib/python3/dist-packages/pip,说明你调用的不是新装的 pip,需要检查软链接和 PATH。

6.2 回滚:删掉就完事,但要删对地方

源码编译安装的好处就是回滚特别干净。核心就三步:

# 1. 删除软链接 sudo rm -f /usr/local/bin/python3.9 /usr/local/bin/pip3.9 # 2. 删除安装目录 sudo rm -rf /opt/python3.9 # 3. 如果当初开了 --enable-shared,还要清理 ldconfig 配置 sudo rm -f /etc/ld.so.conf.d/python39.conf sudo ldconfig

再加上源码目录和 OpenSSL:

rm -rf /tmp/Python-3.9.2 /tmp/openssl-1.1.1w sudo rm -rf /opt/openssl11 # 确认没有别的程序在用再删

删除之前有个必须确认的动作:看有没有别的服务在依赖这个解释器。查一下 systemd 单元里的ExecStart、crontab 里的路径、nginx 或者 gunicorn 的配置。直接rm -rf一个正在被生产服务使用的解释器,后果不用我说。

grep -rl "/opt/python3.9" /etc/systemd/system/ 2>/dev/null crontab -l | grep python3.9

这两条命令花不了三十秒,能省下一堆麻烦。

我个人在实际操作中的体会是,源码编译 Python 这件事,九成的时间花在依赖和 OpenSSL 上,真正敲make的时间反而是最省心的部分。所以我现在的习惯是先花十分钟把依赖清单核对一遍,把 OpenSSL 的问题提前解决掉,再开始 configure。比起编到一半发现_ssl没编进去然后重来一遍,这个前置投入太划算了。另外,把这套命令整理成一个可复用的脚本,把版本号抽成变量,下次要装 3.9.18 或者 3.11.x 的时候改两个数字就能跑,长期来看省下的时间相当可观。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询