pjsip 编译避坑指南:从零开始搭建开发环境的实战经验
最近在为一个嵌入式 VoIP 项目调研通信库时,我又一次和pjsip打上了交道。这个开源 SIP 框架功能强大、性能出色,几乎是做自主可控语音系统的首选方案。但说实话——第一次编译它的时候,我差点放弃。
不是因为代码难懂,而是构建过程太“真实”了:缺头文件、找不到编译器、Python 脚本报错……各种问题接踵而至,文档里却轻描淡写一句“运行./configure即可”。对于新手来说,这就像告诉你“把火箭点火就行”,却不提燃料加满没。
今天我就以一名踩过所有坑的开发者身份,带你一步步打通 pjsip 的编译之路。不讲虚的,只说你真正会遇到的问题和解决办法。
为什么 pjsip 难编译?
先搞清楚敌人是谁。
pjsip 并不是一个简单的 C 库。它是一个集成了 SIP 协议栈、媒体处理、音视频编解码、NAT 穿透(STUN/TURN)、TLS 加密等功能于一体的完整通信框架。这意味着:
- 它依赖很多系统级组件(ALSA、PulseAudio、OpenSSL、FFmpeg)
- 构建系统是自研的 Makefile + autoconf 组合,不像现代项目用 CMake 那样直观
- 功能通过宏定义开关控制,配置不当就会导致某些模块被静默禁用
- 跨平台支持广泛,但也带来了平台差异带来的兼容性问题
所以当你执行./configure && make失败时,往往不是某个单一错误,而是多个环境因素叠加的结果。
常见编译问题及解决方案(亲测有效)
❌ 问题一:configure: error: cannot run C compiled programs
这是最基础也最容易忽略的问题。
报错长这样:
configure: error: cannot run C compiled programs. If you meant to cross compile, use `--host'.根本原因:
你的系统压根没有安装能跑起来的 C 工具链。常见于:
- Docker 容器或最小化 Linux 系统(比如 Alpine)
- 新装系统还没装开发包
- 使用 WSL 但未初始化开发环境
解决方法:
Ubuntu / Debian:
sudo apt update sudo apt install -y build-essentialCentOS / RHEL:
sudo yum groupinstall "Development Tools" -y # 或者新版本用 dnf sudo dnf groupinstall "C Development Tools and Libraries" -ymacOS:
xcode-select --install✅ 小技巧:运行
gcc -v看是否输出版本信息。如果没有命令,说明工具链没装好。
如果你是在做交叉编译(比如给 ARM 板子编译),那就要加上--host=arm-linux-gnueabihf参数,否则 configure 会尝试运行生成的程序,自然失败。
❌ 问题二:音频支持缺失,提示snd_card_next in -lasound... no
你明明想做个通话应用,结果编译完发现不能录音也不能播放。
典型报错:
checking for snd_card_next in -lasound... no configure: WARNING: Audio capture/playback not available原因分析:
Linux 下音频默认使用 ALSA 接口,但你只装了运行时库,没装开发头文件!libasound2是有的,但libasound2-dev没装。
解决方案:
安装 ALSA 开发包:
sudo apt install -y libasound2-dev如果你想用 PulseAudio(桌面更常用):
sudo apt install -y libpulse-dev然后重新配置并启用 PulseAudio 支持:
./configure --enable-pulse-audio💡 提示:如果只是测试编译流程,不想折腾声音,可以直接关闭:
bash ./configure --disable-sound
这样可以跳过所有音频相关检查,加快构建速度。
❌ 问题三:TLS 不可用,SIPS 和 SRTP 无法启用
安全通信是现代 VoIP 的基本要求,但如果你看不到 TLS 支持,说明 OpenSSL 没配对。
报错内容:
checking for SSL_library_init in -lssl... no configure: WARNING: TLS disabled due to missing library原因:
缺少 OpenSSL 开发库。注意,光有openssl命令行工具不够,必须要有头文件和静态库。
解决方法:
Debian 系:
sudo apt install -y libssl-devRedHat 系:
sudo yum install -y openssl-devel # 或者 sudo dnf install -y openssl-devel重新配置并显式指定 SSL 路径(可选):
./configure --with-ssl成功后你会看到:
checking for SSL_library_init in -lssl... yes configure: enabling SSL support (OpenSSL)🔐 强烈建议生产环境开启 TLS。信令走明文等于把用户名密码暴露在网络上。
❌ 问题四:视频功能被禁用,提示 FFmpeg 相关函数找不到
你想加摄像头支持?先搞定视频依赖。
报错示例:
checking for av_register_all in -lavcodec... no configure: WARNING: Video disabled原因:
pjsip 视频模块依赖 FFmpeg 提供编解码能力,同时需要 V4L2 访问摄像头(Linux)。但大多数系统默认不带 FFmpeg 开发包。
解决方案:
安装必要的 FFmpeg 开发库:
sudo apt install -y \ libavcodec-dev \ libavdevice-dev \ libavformat-dev \ libswscale-dev然后启用视频支持:
./configure --enable-video如果 FFmpeg 装在非标准路径(比如/usr/local),可以指定位置:
./configure --enable-video --with-ffmpeg=/usr/local⚠️ 注意版本兼容性:推荐使用 FFmpeg 4.4 或 5.0 等稳定版。别用 git master 分支,API 变动频繁容易出错。
❌ 问题五:Python 脚本找不到,symbols.py报错
你以为只需要 C 编译器?错了,pjsip 构建过程中还有 Python 脚本参与。
错误日志片段:
python-gen/symbols.py: command not found Can't open perl script "build.mak": No such file or directory原因:
部分构建脚本是用 Python 写的,用于生成符号表或配置文件。如果系统没有python命令,或者版本不对(要求 2.7+ 或 3.x),就会中断。
解决方法:
确认 Python 可用:
python --version || python3 --version如果只有python3,创建软链接:
sudo ln -sf /usr/bin/python3 /usr/bin/python🐍 特别提醒:Alpine Linux 用户还需额外安装:
bash apk add python3 py3-pip
虽然现在都推 Python 3,但 pjsip 的脚本基本都能兼容,无需担心。
❌ 问题六:Android NDK 编译失败,找不到 clang
要在 Android 上跑 pjsip?那你得熟悉 NDK 的玩法。
报错典型表现:
arm-linux-androideabi-gcc: command not found原因:
NDK 工具链路径没设置正确,或者用了旧版 GCC(已被弃用)。
正确做法:
- 下载 Android NDK(建议 r25b 或更新)
- 设置环境变量:
export ANDROID_NDK_ROOT=/path/to/android-ndk-r25b export PATH=$PATH:$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin- 使用专用脚本配置:
./configure-android --use-ndk-cflags --target=armv7a-linux-androideabi- 编译:
make dep && make clean && make📱 注意事项:
- 必须使用 LLVM 工具链(clang),不再支持 GCC
- 不同 CPU 架构(armeabi-v7a、aarch64)要分别编译
- 推荐用 Docker 封装环境,避免主机污染
❌ 问题七:macOS 上strerror_r报错,C99 兼容性问题
苹果系统总是有点不一样。
报错信息:
error: implicit declaration of function 'strerror_r' is invalid in C99原因:
Linux 和 macOS 对strerror_r的实现不同。Linux 提供 GNU 和 POSIX 两个版本,而 macOS 只支持 POSIX 版本。pjsip 默认假设是 GNU 版,于是炸了。
解决方法:
修改pjlib/include/pj/config_site.h,添加以下定义:
#define PJ_HAS_POSIX_STRERROR_R 1 #undef PJ_HAS_GNU_STRERROR_R或者在 configure 时传参:
CFLAGS="-DPJ_HAS_POSIX_STRERROR_R=1" ./configure🍏 补充建议:确保 Xcode Command Line Tools 最新,并检查 SDK 路径:
bash xcrun --show-sdk-path
实战案例:Ubuntu 20.04 完整构建流程
下面是我在一个干净的 Ubuntu 20.04 虚拟机中成功编译 pjsip 的全过程,适用于大多数 Linux 桌面环境。
1. 安装全部依赖
sudo apt update sudo apt install -y \ build-essential \ libssl-dev \ libasound2-dev \ libpulse-dev \ libavcodec-dev \ libavdevice-dev \ libavformat-dev \ libswscale-dev \ python32. 下载源码(以 v2.13 为例)
wget https://github.com/pjsip/pjproject/archive/refs/tags/2.13.tar.gz tar -xzf 2.13.tar.gz cd pjproject-2.133. 配置功能选项
./configure \ --enable-shared=no \ # 静态库优先,减少依赖 --prefix=/usr/local \ # 安装路径 --enable-video \ # 启用视频 --with-ssl \ # 启用 TLS --enable-pulse-audio \ # 使用 PulseAudio --enable-log # 开启日志(调试用)4. 编译与安装
make dep # 生成依赖 make # 编译 sudo make install sudo ldconfig # 刷新动态库缓存完成后,你就可以在自己的项目中链接这些库了:
gcc myapp.c -lpjsua2 -lpjsip-ua -lpjmedia -lpjmedia-codec -lpjnath -lpjlib-util -lpj -lm -lstdc++如何判断编译是否成功?
除了看有没有报错,还可以验证几个关键点:
| 检查项 | 验证方式 |
|---|---|
| TLS 是否启用 | 查看config.log中是否有enabling SSL support |
| 视频是否启用 | 检查build/os-auto.mak中HAS_VIDEO := 1 |
| 音频后端 | 查看 configure 输出中使用的 audio device API |
| 日志级别 | 在代码中设置pjsua_logging_config.log_level = 5;看是否有详细输出 |
也可以运行自带的pjsua示例程序试试基本功能:
./pjsip-apps/bin/pjsua-x86_64-unknown-linux-gnu结语:入门之后才是开始
编译成功只是第一步。接下来你可能会面临:
- 如何裁剪体积(嵌入式设备资源有限)
- 如何移植到 RTOS 或裸机环境
- 如何集成 WebRTC 或与其他协议互通
- 如何优化 NAT 穿透成功率
但至少现在,你已经跨过了那道最高的门槛。
pjsip 虽然学习曲线陡峭,但它提供的灵活性和控制粒度,远超大多数商业 SDK。只要你能把它跑起来,后续的定制和优化空间非常大。
如果你在实现过程中遇到了其他挑战,欢迎在评论区分享讨论。我们一起把这条路走得更顺一点。