Ubuntu 18.04源码编译安装GN与Ninja构建工具链指南 📅 2026/8/15 1:55:19 1. 项目概述为什么要在Ubuntu 18.04上折腾GN和Ninja如果你正在接触像Chromium、Fuchsia、或者一些大型的C项目那么你大概率会碰到两个名字GN和Ninja。这俩不是什么新潮的编程语言而是构建系统里的“黄金搭档”。GN负责生成构建指令Ninja负责以最快的速度执行这些指令。在Ubuntu 18.04这个至今仍被许多企业级开发、嵌入式环境和特定框架比如PX4无人机固件所依赖的“经典”LTS版本上正确安装和配置它们往往是开启后续复杂项目编译的第一步。我遇到过不少新手照着零散的教程安装结果编译时冒出各种ninja: error: unknown target或者gn: command not found的错误一下就卡住了。这通常不是因为工具本身复杂而是安装路径、环境变量或者版本依赖没处理好。这篇文章我就以Ubuntu 18.04为舞台带你走一遍从源码编译安装GN和Ninja的完整流程把每一步的原理、可能踩的坑以及如何验证都讲清楚。目标很简单让你装完就能用并且理解为什么这么装。2. 核心工具解析GN与Ninja的角色与关系在动手之前我们得先搞明白这两个工具到底是干嘛的以及它们为什么经常成对出现。这能帮你未来在遇到构建问题时更快地定位是哪个环节出了岔子。2.1 Ninja追求极速的构建执行器你可以把Ninja想象成一个极度专注、话不多的“施工队长”。它不关心你的项目设计图构建逻辑是怎么画的它只关心一份极其详细的、最优化的“施工任务清单”build.ninja文件。这份清单里写明了要生成目标A需要先执行命令X、Y、Z它们之间的依赖关系是什么哪些任务可以并行。Ninja的设计哲学就是“快”。它没有像Make那样的复杂规则推导和Shell调用开销启动速度极快并且能最大限度地利用多核CPU进行并行编译。当你运行ninja命令时它做的就是读取build.ninja检查文件时间戳然后以最高效的顺序执行必要的命令。我们常见的编译错误ninja: error: unknown target ‘gz_x500‘其实就是Ninja在说“你给我的这份任务清单里根本找不到名叫‘gz_x500’的施工项目啊”这问题通常出在生成清单的上一环——GN。2.2 GN生成Ninja清单的元构建系统GNGenerate Ninja的角色就是那位画出“施工任务清单”的“设计师”。它用一种比CMake的CMakeLists.txt更简洁、更易读的.gn和BUILD.gn文件来描述项目的构建规则、依赖关系、编译选项比如是编译给x86还是ARM开不开优化。GN的输入是你的项目源码结构和这些.gn文件输出就是给Ninja用的build.ninja文件。所以一个标准的构建流程往往是gn gen out/DefaultGN根据配置生成构建目录 -ninja -C out/DefaultNinja在该目录下执行编译。GN本身并不编译任何代码它只生成构建指令。因此gn命令找不到你就没法生成清单而生成的清单里如果目标名写错了Ninja自然就会报“unknown target”的错误。2.3 为何选择从源码编译安装在Ubuntu 18.04上你有几种安装方式通过包管理器apt、预编译二进制包、或者从源码编译。我强烈推荐从源码编译理由有三版本可控apt仓库里的版本可能非常老旧无法满足新项目的需求。从源码可以获取最新版本或特定版本。环境一致编译过程会适配你的系统环境避免二进制兼容性问题。理解更深走一遍编译过程能让你对工具的依赖和构建过程有更直观的认识后续排错能力更强。3. 系统准备与依赖安装在开始编译GN和Ninja之前我们需要确保系统环境是准备好的。Ubuntu 18.04的默认环境对于开发来说通常是不完整的。3.1 更新系统与安装基础编译工具首先更新软件包列表并升级已安装的包这是一个好习惯能避免一些因基础库版本过低导致的问题。sudo apt update sudo apt upgrade -y接下来安装编译所需的“工具链”。这包括编译器g、链接器、标准库、以及构建自动化工具本身CMake 有趣的是我们用它来构建Ninja。sudo apt install -y build-essential cmake python3 gitbuild-essential这是一个元包包含了gcc, g, make, libc-dev等编译C/C程序必不可少的基础工具。cmakeNinja项目本身使用CMake作为其构建系统所以我们需要CMake来构建Ninja。python3GN的构建脚本是用Python写的因此Python3是必须的。git用于从代码仓库克隆GN和Ninja的源代码。注意Ubuntu 18.04默认可能安装了Python 2和Python 3。确保python3命令可用。GN的构建脚本明确要求Python 3。3.2 处理可能的依赖缺失在某些最小化安装的系统或容器内可能会缺少一些底层库。如果你在后续编译过程中遇到关于libssl或libxml2的错误可以提前安装它们sudo apt install -y libssl-dev libxml2-dev这些库不是GN或Ninja直接的核心依赖但它们可能被构建脚本或测试套件所使用提前安装可以避免意外中断。4. 实战安装Ninja我们将采用从源码编译的方式安装Ninja。这是最可靠的方法能确保获得最新版本。4.1 获取Ninja源代码Ninja的源代码托管在GitHub上。我们使用git克隆其仓库。推荐克隆深度为1以节省时间和空间。git clone --depth 1 https://github.com/ninja-build/ninja.git cd ninja--depth 1选项意味着只克隆最近一次提交的历史这对于仅用于编译的场景足够了。4.2 使用CMake配置与编译进入ninja目录后我们使用CMake来配置生成构建系统并指定使用Makefile是的用Make来构建Ninja自己。cmake -B build-cmake-B build-cmake告诉CMake在build-cmake子目录中生成构建文件。这保持了源码目录的整洁是一种推荐的做法。接着进行编译cmake --build build-cmake这条命令会调用生成的构建系统默认是Unix Makefiles来编译Ninja。编译过程很快你会在build-cmake目录下看到生成的可执行文件ninja。4.3 安装与验证编译完成后我们可以将ninja可执行文件安装到系统路径如/usr/local/bin这样在任何地方都能调用。sudo cp build-cmake/ninja /usr/local/bin/现在验证安装是否成功ninja --version如果终端输出了Ninja的版本号例如1.11.1那么恭喜你Ninja安装成功了。你可以通过which ninja命令查看它的安装路径确认是/usr/local/bin/ninja。实操心得我不推荐直接运行源码目录下的./configure.py ./ninja这是Ninja提供的另一种构建方式。在Ubuntu 18.04上使用CMake的方式更标准兼容性更好尤其是对于后续可能存在的依赖管理。另外将二进制文件放入/usr/local/bin是符合Linux Filesystem Hierarchy Standard (FHS)的做法比放在个人目录下更方便全局使用。5. 实战安装GNGN的安装过程比Ninja稍微复杂一点因为它本身是用C写的且其构建过程依赖于一个特定的工具链甚至包括一个特定版本的Clang编译器。幸运的是GN项目提供了一个内置的引导脚本bootstrap.py来自动化这个过程。5.1 获取GN源代码同样地我们从GitHub克隆GN的仓库。cd ~ # 回到你的工作目录 git clone --depth 1 https://gn.googlesource.com/gn cd gn注意GN的官方仓库地址是googlesource.com。5.2 运行引导脚本进行编译GN源码目录下有一个bootstrap.py脚本。这个脚本的神奇之处在于它会先下载一个特定版本的Clang编译器如果本地没有合适的然后用这个编译器来编译GN自身。这确保了GN构建环境的纯净和一致性。python3 bootstrap.py这个过程可能需要几分钟因为它会下载构建工具链。你会看到大量的编译输出。如果一切顺利最终会在当前目录生成一个名为gn或gn.exe的可执行文件。5.3 安装与验证和Ninja一样我们将编译好的gn程序复制到系统路径。sudo cp out/gn /usr/local/bin/注意bootstrap.py编译生成的gn二进制文件默认放在out/目录下这是GN自己约定的输出目录。验证安装gn --version如果命令返回了GN的版本哈希值一长串字符说明安装成功。重要注意事项网络问题bootstrap.py脚本在运行时需要从Google的服务器下载工具链。如果你的网络环境无法访问这个过程会失败。这是从源码构建GN最大的一个“坑”。备选方案如果引导脚本因网络问题失败你可以尝试寻找他人预编译好的、适用于Linux的gn二进制文件但需要确保其与你的系统架构通常是x86_64兼容并且版本不要太旧。将其下载后赋予执行权限chmod x gn然后同样放入/usr/local/bin/即可。但这不如从源码编译可靠。内存要求编译GN特别是引导脚本下载和编译Clang时需要一定的磁盘空间约1-2GB和内存。在资源受限的虚拟机或容器中请留意。6. 环境集成与基础工作流测试工具安装好了我们还需要确保它们能在任何目录下被调用并且能协同工作。6.1 检查系统路径确保/usr/local/bin在你的PATH环境变量中。通常默认就在。可以这样检查echo $PATH | grep /usr/local/bin如果有输出说明路径已包含。如果没有你需要将下面这行添加到你的shell配置文件~/.bashrc或~/.zshrc中export PATH/usr/local/bin:$PATH然后执行source ~/.bashrc使配置生效。6.2 模拟一个简单的GNNinja工作流为了验证GN和Ninja是否真的能配合工作我们可以用一个最简单的例子测试。GN项目源码里就自带了一个examples/simple_build的例子。cd ~/gn/examples/simple_build gn gen out # 使用gn生成构建目录和ninja构建文件 ninja -C out # 告诉ninja在out目录下执行构建如果一切正常ninja命令会执行编译并在out目录下生成一个可执行文件例如hello。你可以尝试运行它./out/hello。这个简单的测试验证了从GN生成构建文件到Ninja执行构建的完整链条是通的。这比单独检查--version更有说服力。7. 常见问题排查与解决实录即便按照步骤操作你也可能会遇到一些问题。这里我记录了几个最常见的情况和解决方法。7.1 “Command ‘gn‘ not found” 或 “Command ‘ninja‘ not found”问题现象在终端输入gn或ninja命令提示找不到命令。原因与解决未安装最直接的原因回头检查第4步和第5步的安装和sudo cp复制操作是否成功执行。路径问题/usr/local/bin不在PATH中。按照6.1节的方法检查和添加。权限问题极少数情况下/usr/local/bin目录的权限可能导致问题。可以检查gn文件是否有执行权限ls -l /usr/local/bin/gn。应该有-rwxr-xr-x类似的权限。如果没有x执行权限运行sudo chmod x /usr/local/bin/gn。7.2 “ninja: error: unknown target ‘xxx‘”问题现象在项目目录下运行ninja时报告找不到某个特定的目标如前面热词中的gz_x500。原因与解决构建目录未生成或配置错误这是最可能的原因。Ninja完全依赖于gn gen生成的build.ninja文件。请确保你已经在正确的项目源码目录下。你已经为当前配置运行过gn gen output_dir例如gn gen out/Default。你运行ninja -C output_dir时指定的目录就是之前gn gen生成的那个目录。你指定的目标名例如ninja -C out/Default gz_x500在项目的BUILD.gn文件中正确定义了。目标名大小写敏感且必须完全匹配。对于PX4这类项目gz_x500可能是一个特定的SITL软件在环目标你需要确认项目的构建文档中这个目标的确切名称。GN配置错误可能在运行gn gen时传递了错误的参数导致某些目标没有被包含进构建文件。检查gn args output_dir列出的配置。7.3 GN的bootstrap.py脚本执行失败问题现象运行python3 bootstrap.py时卡住、报网络错误或编译错误。排查步骤网络连接脚本需要从https://chrome-infra-packages.appspot.com等地址下载工具链。确保你的网络可以访问这些资源。如果是网络问题考虑使用备选方案寻找预编译二进制包。Python版本确认使用的是python3。Ubuntu 18.04上python命令可能指向Python 2。依赖缺失虽然bootstrap脚本会处理大部分依赖但确保系统已安装build-essential和cmake。如果报关于libssl的错误尝试安装libssl-dev。查看详细日志脚本失败时会输出错误信息。仔细阅读最后几行错误信息通常会指明是下载失败、解压失败还是编译失败。磁盘空间检查磁盘剩余空间是否充足至少有几个GB可用。7.4 版本兼容性问题问题现象项目要求特定版本的GN或Ninja而你安装的版本太新或太旧。解决NinjaNinja的版本兼容性通常较好。如果需要特定版本在克隆Ninja源码后使用git checkout v1.10.2将1.10.2替换为你需要的版本号切换到对应标签然后再进行编译安装。GNGN的版本兼容性要求更严格一些。同样在GN源码目录使用git checkout commit-hash切换到项目要求的特定提交。然后重新运行python3 bootstrap.py。项目的构建说明如README.md或docs/里通常会写明所需的GN版本或提交哈希。8. 进阶配置与使用技巧基础安装搞定后这里有一些提升效率和使用体验的技巧。8.1 为Ninja启用更多并行编译Ninja默认会尝试使用所有可用的CPU核心进行并行编译。你可以通过-j参数手动指定并行任务数。例如如果你有一个8核CPU可以显式指定ninja -C out/Default -j 8甚至更激进一些使用-j不跟数字让Ninja自己决定通常等于CPU核心数ninja -C out/Default -j在内存充足的情况下这能显著缩短大型项目的编译时间。8.2 使用GN Args管理构建配置大型项目通常有不同的构建类型Debug/Release和配置选项。GN使用args.gn文件来管理这些配置。一个高效的工作流是cd your_project gn args out/Default这条命令会用默认编辑器如vim或nano打开out/Default/args.gn文件。你可以在这里设置变量例如is_debug true # 启用调试符号 is_component_build true # 编译为动态链接库加速增量编译 target_cpu x64 # 目标CPU架构保存退出后GN会自动根据新的参数重新生成build.ninja文件。你可以通过gn args out/Default --list查看所有可用的参数及其当前值。8.3 清理构建输出Ninja本身没有clean命令。要清理构建输出最干净的做法是直接删除整个构建输出目录rm -rf out/Default然后重新运行gn gen out/Default。如果你只想重新构建而不清理中间文件直接运行ninja即可Ninja的增量构建非常智能只会编译有变动的部分。8.4 在资源受限环境中的优化如果你在内存较小的虚拟机或Docker容器中工作编译大型项目时可能会遇到内存不足OOM的问题。除了增加交换空间swap外在运行Ninja时可以限制并行任务数以减少内存峰值使用ninja -C out/Default -j 2 # 只使用2个并行任务同时在GN的args.gn中可以关闭一些耗内存的优化例如将is_component_build设为false静态链接但这可能会增加增量编译的时间。安装GN和Ninja本身只是第一步但却是构建许多现代C项目的基石。掌握了从源码编译安装的方法你就能在任何类似Ubuntu 18.04的环境包括WSL、Docker容器中快速搭建起这套高效的构建工具链。下次再遇到unknown target的错误时你就能胸有成竹地知道该去检查GN的配置而不是怀疑Ninja出了问题。