源码编译安装:什么时候该自己编译

包管理器里没有的版本、需要特定编译选项、或者想用最新特性——这时候就得自己编译。流程固定,但有几个约定要知道。

一、什么时候该编译

情况建议
仓库里有合适版本用包管理器
需要特定模块(如 Nginx 加第三方模块)编译
需要更新的版本优先找官方源/第三方源,再考虑编译
需要打补丁编译

自己编译意味着你要负责后续的安全更新。能用包管理器就用,这是第一条原则。

二、三步走

bash
./configure          # 检查环境、生成 Makefile
make                 # 编译
sudo make install    # 安装

configure 常用选项

bash
./configure --help                  # 看所有选项,很有用

--prefix=/usr/local/nginx           # 安装位置,约定第三方软件放 /usr/local
--with-http_ssl_module              # 启用某功能
--without-http_rewrite_module       # 禁用某功能
--enable-shared / --disable-static  # 库类型

目录约定(FHS)

目录用途
/usr包管理器装的
/usr/local自己编译装的
/opt大型独立软件

所以自编译默认装到 /usr/localbin/usr/local/bin,不和系统包冲突。

三、装编译工具

bash
# Debian/Ubuntu
sudo apt install -y build-essential
# 包含 gcc g++ make libc-dev

# 常用依赖
sudo apt install -y pkg-config autoconf automake libtool cmake

四、实例:编译 Nginx

bash
# 1. 依赖
sudo apt install -y build-essential libpcre3-dev zlib1g-dev libssl-dev

# 2. 下载源码
cd /usr/local/src
sudo curl -O https://nginx.org/download/nginx-1.26.2.tar.gz
sudo tar xzf nginx-1.26.2.tar.gz && cd nginx-1.26.2

# 3. 配置(先看 ./configure --help)
./configure \
  --prefix=/usr/local/nginx \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_gzip_static_module

# 4. 编译(-j 用多核,快很多)
make -j$(nproc)

# 5. 安装
sudo make install

# 6. 验证
/usr/local/nginx/sbin/nginx -v
/usr/local/nginx/sbin/nginx -t

make -j$(nproc) 能大幅缩短时间。小内存机器别开太大并发,可能 OOM。

五、加到 PATH 与 systemd

bash
# 建软链到 /usr/local/bin
sudo ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
nginx -v
nginx
# /etc/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP server (source build)
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target
bash
sudo systemctl daemon-reload
sudo systemctl enable --now nginx

六、依赖缺失怎么查

configure 报错时看最后几行:

bash
./configure 2>&1 | tail -20

# 看详细日志
cat config.log | grep -i error

常见模式:

报错缺什么
C compiler cannot create executablesbuild-essential
the HTTP rewrite module requires PCRElibpcre3-dev
SSL modules require OpenSSLlibssl-dev
zlib library not foundzlib1g-dev

找某个头文件属于哪个包:

bash
apt-file search ssl.h           # 需安装 apt-file
apt-file update

七、卸载与版本管理

make install 的麻烦是不好卸载。几个办法:

  1. 保留源码目录make uninstall(很多项目支持):
bash
sudo make uninstall
  1. 用 checkinstall 打成 deb,之后就能 apt remove
bash
sudo apt install -y checkinstall
sudo checkinstall --pkgname=myapp --pkgversion=1.2.3
# 会生成一个 .deb 并安装,之后可用 dpkg -r myapp 卸载
  1. 装到独立目录--prefix=/opt/myapp-1.2.3),卸载就是删目录,切换版本就是改软链:
bash
/opt/node-v20.11.1/
/opt/node-v22.2.0/
/opt/node -> /opt/node-v22.2.0     # 软链切版本

八、升级编译安装的软件

以 Nginx 为例,平滑升级可以不中断服务:

bash
# 1. 编译新版本(同样的 configure 参数!)
make -j$(nproc)

# 2. 只替换二进制,不 make install
cp objs/nginx /usr/local/nginx/sbin/nginx.new

# 3. 备份旧的
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
mv /usr/local/nginx/sbin/nginx.new /usr/local/nginx/sbin/nginx

# 4. 让旧进程用新二进制启动新进程(USR2 + WINCH)
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)
kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)

# 5. 确认无误后退出旧进程
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)

关键:configure 参数必须和原来一致。用 nginx -V 能看到当时的编译参数,先存下来。

九、安全提醒

bash
# 校验源码包的签名/哈希,不要跑来路不明的脚本
sha256sum nginx-1.26.2.tar.gz
gpg --verify nginx-1.26.2.tar.gz.asc

# 源码放在固定位置方便管理
ls /usr/local/src
  • 从官方渠道下载并校验
  • 记录 configure 参数(存进 README 或脚本)
  • 用独立 prefix 或 checkinstall,保证可卸载
  • 关注上游安全公告,自己负责更新

编译不难,难的是后续的维护责任。能不编译就不编译。