GN 构建系统简介

259 阅读3分钟

GN 构建系统简介

GN (Generate Ninja) 是一个元构建系统,用于生成适用于 Ninja 的构建文件。GN 最初由 Google 开发,广泛应用于管理大规模项目的构建流程,特别是在 Chromium 和 Fuchsia 等项目中。GN 旨在提供一种高效、简洁、适合大团队和多平台项目的构建方式,帮助开发人员快速生成构建文件并确保构建的正确性。

GN 的特点与优势
  1. 为大型项目和团队设计
    GN 针对大型项目进行了优化,能够扩展到数千个构建文件和数万个源文件,保持良好的性能和构建效率。这使得 GN 非常适合像 Chromium 这样庞大的项目。

  2. 简洁易读的语法
    GN 语法简洁、直观,开发人员可以轻松上手。一旦构建系统搭建完成,即使不熟悉 GN 的开发人员也能轻松进行基本的编辑和维护。

  3. 支持多平台项目
    GN 可以很好地处理跨平台项目,能够在一次构建调用中生成多个平台的目标文件。它清晰地表达不同平台和配置之间的构建差异,是构建跨平台应用程序的理想选择。

  4. 并行输出目录支持
    GN 支持多个并行输出目录,每个目录都有独立的配置。这让开发人员能够并行维护不同版本的构建,如调试版、发布版,或针对不同平台的构建,而无需频繁重新构建。

  5. 注重构建的正确性
    GN 提供多种工具来确保构建的正确性,如 gn checktestonlyassert_no_deps。这些工具帮助开发人员确保依赖关系正确、构建输入输出合理,并及时发现潜在问题。

GN 示例

下面是一个简单的 GN 构建示例,用于构建一个基本的 C++ 项目。

假设我们有以下目录结构:

project/
├── BUILD.gn
├── src/
│   ├── main.cc
│   └── util.cc
│   └── util.h
└── out/
1. BUILD.gn 文件

BUILD.gn 是 GN 的主要配置文件,用于定义如何编译项目。以下是一个简单的 BUILD.gn 文件示例:

# 定义项目的输出目录和目标类型
executable("my_app") {
  sources = [
    "src/main.cc",
    "src/util.cc",
  ]
  
  # 指定编译器标志
  configs += [ ":default_config" ]
}

# 配置编译选项
config("default_config") {
  cflags = [ "-std=c++17" ]
  ldflags = []
}

这个文件定义了一个可执行文件 my_app,并指定了源文件列表和编译器标志。

2. main.cc 文件

src/main.cc 中,我们编写一个简单的主程序:

#include <iostream>
#include "util.h"

int main() {
    std::cout << "Hello from GN project!" << std::endl;
    print_message();
    return 0;
}
3. util.h 文件

src/util.h 文件定义了一个简单的函数声明:

#pragma once

void print_message();
4. util.cc 文件

src/util.cc 中实现 print_message 函数:

#include <iostream>

void print_message() {
    std::cout << "Utility function says hello!" << std::endl;
}
5. 生成 Ninja 构建文件

首先,创建一个 out 目录来存放生成的构建文件。然后使用 GN 生成 Ninja 构建文件:

gn gen out/

这条命令会在 out/ 目录下生成 Ninja 构建文件。

6. 使用 Ninja 构建项目

GN 生成的 Ninja 文件可以通过 Ninja 工具进行编译:

ninja -C out/

这会在 out/ 目录下构建可执行文件 my_app。运行该可执行文件:

./out/my_app

输出结果将会是:

Hello from GN project!
Utility function says hello!
总结

GN 是一个强大且高效的构建系统,适合大型项目和多平台开发。它的简洁语法、扩展能力和跨平台支持使其成为许多大规模项目的首选工具。通过 GN 与 Ninja 的结合,开发人员可以轻松管理复杂的构建流程,并确保项目的构建准确无误。