3. 开发环境搭建(Linux):安装GCC/Clang、CMake、Ninja、依赖管理工具(pkg-config)
做跨平台SDK编译,Linux几乎是绕不开的战场。我个人的主力开发机一直是Ubuntu LTS,但说实话,CentOS、Debian甚至Arch我也都踩过坑。环境搭好了,后面省心一大半;搭不好,你能被“找不到头文件”“链接器报错”这种问题折腾一整天。
这章我就把Linux下必备的几样工具——GCC/Clang、CMake、Ninja、pkg-config——怎么装、怎么验证、有哪些坑,一次性说清楚。
3.1 为什么选Linux做SDK编译
你可能会想:“macOS和Windows不也能编译吗?”能,但Linux的天然优势摆在那:
- 包管理器统一,一行命令装完整个工具链
- 系统库路径规范,/usr/include、/usr/lib 几乎不用手动配
- CI/CD环境基本全是Linux,本地和线上一致
- 性能开销低,同样硬件下编译速度普遍比Windows快10%~20%
3.2 安装GCC与Clang
3.2.1 GCC(GNU编译器套件)
GCC是Linux C/C++编译的默认标准。Ubuntu上装它很简单:
sudo apt update
sudo apt install build-essential
build-essential 是一个元包,会拉取gcc、g++、make、dpkg-dev等一整套。装完验证:
gcc --version
g++ --version
我遇到过一个问题:某些老项目依赖gcc-7,而Ubuntu 22.04默认装的是gcc-11。这时候需要手动指定版本:
sudo apt install gcc-7 g++-7
# 然后通过 update-alternatives 设置优先级
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 70
嗯,这里要注意:不同版本的GCC对std::filesystem、std::variant等特性支持不同,编译前最好读一下项目文档的“编译器要求”。
3.2.2 Clang/LLVM
Clang的优势是编译速度快、报错信息友好。我更喜欢用Clang做日常开发,用GCC做最终发布。安装:
sudo apt install clang lldb lld
验证:
clang --version
clang++ --version
如果你需要最新版,可以去LLVM官网下载预编译包,或者用llvm.sh脚本一键安装。我在Android NDK开发和WebAssembly编译中常用Clang的交叉编译能力——这点后面讲到跨平台编译时会细说。
| 编译器 | 安装命令 | 验证 | 适用场景 |
|---|---|---|---|
| GCC | apt install build-essential |
gcc --version |
Linux发布、兼容性要求高 |
| Clang | apt install clang |
clang --version |
开发调试、交叉编译、静态分析 |
std::string、异常处理等细节可能不匹配,我曾经因此花了半天定位一个随机崩溃。
3.3 安装CMake
CMake是跨平台构建的事实标准。我个人建议用Kitware官方提供的apt仓库,而不是Ubuntu自带的旧版。
# 添加Kitware签名密钥
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -
# 添加源(以Ubuntu 22.04为例)
sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ jammy main'
sudo apt update
sudo apt install cmake cmake-curses-gui
装完验证:
cmake --version
# 输出类似 3.27.6
如果系统自带的是3.16.x,建议升级到3.22以上,否则有些现代CMake特性(如PRIVATE_HEADER、BUILD_INTERFACE)用不了。我曾经就因为CMake版本太低,导致一个用target_sources的工程死活生成不了正确Makefile。
3.4 安装Ninja
Ninja是Make的替代品,特点是极快。配合CMake使用,编译大型项目(比如Qt、LLVM)能节省30%~50%的时间。安装:
sudo apt install ninja-build
ninja --version
# 输出 1.11.1 或更高
使用方式很简单,在cmake -B build时指定生成器:
cmake -B build -G Ninja
cmake --build build
3.5 依赖管理工具:pkg-config
pkg-config是Linux下管理库头文件和链接标志的瑞士军刀。你装了一个库(比如libcurl),怎么知道去哪里找头文件?怎么知道链接什么库?pkg-config 给你一把解决。
安装:
sudo apt install pkg-config
pkg-config --version
# 输出 0.29.2
使用示例:
pkg-config --cflags --libs libcurl
# 输出: -I/usr/include/x86_64-linux-gnu -lcurl
在CMake里可以这样集成:
find_package(PkgConfig REQUIRED)
pkg_check_modules(CURL REQUIRED libcurl)
target_link_libraries(my_app PRIVATE ${CURL_LIBRARIES})
target_include_directories(my_app PRIVATE ${CURL_INCLUDE_DIRS})
注意,有些库没有提供.pc文件,比如OpenCV的旧版本。这时候需要手动设置PKG_CONFIG_PATH环境变量,指向自定义pkg路径。我处理过一个客户项目,他们的私有库放在/opt/mylib,没有.pc文件,我只好自己写了一个——其实核心就是几个变量定义,不难。
pkg-config --list-all查看系统里所有可用的pc文件。如果找不到某个库的pc,先确认是否安装了-dev包,比如libcurl4-openssl-dev。
3.6 环境验证与常见问题
所有工具装完后,我习惯写一个验证脚本,确保编译器、构建系统和依赖管理能协同工作。下面是一个完整的测试流程:
- 新建一个测试目录,写一个最简单的
main.cpp:#include <iostream> int main(){ std::cout << "hello" << std::endl; return 0; } - 用
g++ main.cpp -o test_gcc编译一次 - 用
clang++ main.cpp -o test_clang再编译一次 - 用CMake+Ninja构建(
CMakeLists.txt里写project(Hello) add_executable(hello main.cpp)) - 运行
./hello,输出"hello"
如果这一步卡住了,大概率是环境变量PATH问题,或者包的安装路径没在标准位置。我曾在Docker里遇到过pkg-config找不到glib-2.0的情况,最终发现是因为libglib2.0-dev装在/usr/lib/x86_64-linux-gnu/pkgconfig/,而默认PKG_CONFIG_PATH没包含这个路径。解决:
export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH
3.7 知识体系总览
PATH生效。我见过太多“明明装了却说找不到命令”的案例,其实就是缓存没刷新。