之前介绍过GYP,它是Google早期用来维护chromium项目的meta-build system,GN则是用来替代GYP的工具,目前chromium及相关的开源项目都迁移到基于GN来管理。并且GN是基于C++编写,效率上比基于python的GYP快了近20倍。
环境准备
配置depot_tools (ninja)
参考:http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
配置gn
虽然depot_tools已经带了gn,但它其实只是一个shell脚本,直接使用会报错,找不到真正的gn二进制文件。
如果编译过webrtc或chromium,gn相关的工具链已经下载,可以在src/buildtools/mac/gn
找到。
自己编译可以基于gn的git仓库编译,可以参考:
#!/bin/bash set -e set -v # Get the sources mkdir gn-standalone cd gn-standalone mkdir tools cd tools git clone https://chromium.googlesource.com/chromium/src/tools/gn cd .. mkdir -p third_party/libevent cd third_party/libevent wget --no-check-certificate https://chromium.googlesource.com/chromium/chromium/+archive/master/third_party/libevent.tar.gz tar -xvzf libevent.tar.gz cd ../.. git clone https://chromium.googlesource.com/chromium/src/base git clone https://chromium.googlesource.com/chromium/src/build git clone https://chromium.googlesource.com/chromium/src/build/config mkdir testing cd testing git clone https://chromium.googlesource.com/chromium/testing/gtest cd .. # Build cd tools/gn ./bootstrap/bootstrap.py -s # At this point, the resulting binary is at: # gn-standalone/out/Release/gn
使用gn的例子
gn的例子可以参考gn的git仓库中带的example来开始。比如,以下测试的代码根目录是src
src
根目录下增加.gn
文件
.gn
文件内容
buildconfig = "//build/BUILDCONFIG.gn"
.gn
文件所在的目录是GN工具认定的工程的source root,.gn
的内容基本就是指定buildconfig,//
是指source root所在的路径。
建立build/BUILDCONFIG.gn
gn的build目录的配置可以参考gn仓库中example的build配置,但是需要适当修改在才能正常使用
BUILDCONFIG.gn
内容如下:
set_default_toolchain("//build/toolchains:gcc") cflags_cc = [ "-std=c++11" ]
第一行指定要使用的 toolchain,//build/toolchains:gcc
指的是 build/toolchains/BUILD.gn
里面定义的 gcc toolchain
建立 build/toolchains/BUILD.gn
因为gn没有内建的toolchain规则,都需要自己定义
# Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. toolchain("gcc") { tool("cc") { depfile = ".d" command = "gcc -MMD -MF $depfile -c -o " depsformat = "gcc" description = "CC " outputs = [ "/..o", ] } tool("cxx") { depfile = ".d" command = "g++ -MMD -MF $depfile -c -o " depsformat = "gcc" description = "CXX " outputs = [ "/..o", ] } tool("alink") { rspfile = ".rsp" command = "rm -f && ar rcs @$rspfile" description = "AR " rspfile_content = "" outputs = [ "/", ] default_output_extension = ".a" output_prefix = "lib" } tool("solink") { soname = "" # e.g. "libfoo.so". sofile = "/$soname" rspfile = soname + ".rsp" command = "g++ -shared -o $sofile -Wl,-soname=$soname @$rspfile" rspfile_content = "-Wl,--whole-archive -Wl,--no-whole-archive " description = "SOLINK $soname" # Use this for expansions unless a target manually # overrides it (in which case will be what the target # specifies). default_output_extension = ".so" # Use this for expansions unless a target manually overrides # it (in which case will be what the target specifies). default_output_dir = "" outputs = [ sofile, ] link_output = sofile depend_output = sofile output_prefix = "lib" } tool("link") { outfile = "" rspfile = "$outfile.rsp" command = "g++ -o $outfile @$rspfile " description = "LINK $outfile" default_output_dir = "" rspfile_content = "" outputs = [ outfile, ] } tool("stamp") { command = "touch " description = "STAMP " } tool("copy") { command = "cp -af " description = "COPY " } }
还可以参考下 chromium配置toolchain的做法
src
根目录下建立 BUILD.gn
group("default") { deps = [ "//test:hello_world", ] }
src/test
目录下增加build.gn
配置与源文件
- 增加
BUILD.gn
executable("hello_world") { sources = [ "test.cpp", ] }
- 增加
test.cpp
#include <iostream> int main() { std::cout << "hello world" << std::endl; return 0; }
编译
$ gn gen out/def --ide=xcode Generating Xcode projects took 0ms Done. Made 2 targets from 5 files in 6ms $ $ ninja -C out/def ninja: Entering directory `out/def' [3/3] STAMP obj/default.stamp $ $ ./out/def/hello_world hello world
参考
- https://blog.simplypatrick.com/posts/2016/01-23-gn/
- GN Quick Start guide
- GN Language and Operation