GN介绍

GN INTRODUCTION

  • What’s GN

    1、GN

Generate Ninja,是Google为Ninja专门开发的上层编译框架,可以生成Ninja可以识别的输入文件。GN由c++编译,相比于基于python的gyp,速度快接近20倍。

    2、GN Language

由于GN和GYP都可以生成Ninja,所以我们可以稍稍将GN和GYP进行对比。风格方面,GYP有Json格式的文件组成,可以将所有的GYP文件和GYPI文件看成一个大的Json格式文件。而GN是函数式风格,最后的依赖关系可以由栈式函数调用来组成。

  • 变量

和大多数脚本语言一样,GN的变量种类不多,包含字符串(string),整形(int64),布尔(Boolean),列表(List),字典(dictionary)。使用方式也和脚本语言一样,不需要声明变量类型,直接对变量赋值即可,例如 a=”hello world”。

  • 函数

和GYP是基于JSON格式的组织方式不同,GN使用函数来组织依赖。

例如:

    a:简单函数调用:

print("hello, world")

    b:复试函数调用

static_library("mylibrary") {

  sources = [ "a.cc" ]

}

这种调用乍一看以为是函数定义,其实是一种函数调用,可以将函数体的返回值理解为函数的一个参数,上述例子的含义就是使用源文件a.cc编译出静态库mylibrary

  • 目标

和Makefile中的目标类似,GN中的目标通常也就是一种可执行文件或者依赖库。一个目标可以依赖另一个目标,从而形成依赖树。

action: Run a script to generate a file.

action_foreach: Run a script once for each source file.

bundle_data: Declare data to go into a Mac/iOS bundle.

create_bundle: Creates a Mac/iOS bundle.

executable: Generates an executable file.

group: A virtual dependency node that refers to one or more other targets.

shared_library: A .dll or .so.

loadable_module: A .dll or .so loadable only at runtime.

source_set: A lightweight virtual static library (usually preferrable over a real static library since it will build faster).

static_library: A .lib or .a file (normally you'll want a source_set instead).
  • Example

要编译成最终可以执行文件,需要三个部分构件系统,1、GN,2、Ninja,3、GCC。GN作为编译逻辑部分,和GYP起到相同的作用,通常和实际工程的配置息息相关。Ninja作为构建中间部分,他用最简单最快速的方式将编译文件编译参数传递给编译系统。GCC作为编译部分,通常随编译系统而变化。

1,gn_test/mian/main.cc:


#include<stdio.h>

#include"lib2/libtest1.h"



int main(void)

{

  printf("hello world\n");

  func1();

}

2,gn_test/main/BUILD.gn

executable("main"){

  sources = [

    "main.c",

  ]

  deps = [

    "//lib2",

  ] 

}


 

3, gn_test/lib2/ libtest1.c


#include"libtest1.h"

#include<stdio.h>



void func1()

{

         printf("func1\n");

}

4, gn_test/lib2/ libtest1.h

 

extern void func1();

 

5, gn_test/lib2/ BUILD.gn

source_set("lib2"){

  sources = [

    "libtest1.c",

    "libtest1.h",

  ]

  public = [

    "libtest1.h",

  ]

}

 

6,gn_test/.gn

 

buildconfig = "//build/BUILDCONFIG.gn"

7, gn_test/ BUILD.gn

group("executable"){

  deps = [ "//main" ]

}

8, gn_test/build/BUILDCONFIG.gn

set_default_toolchain("//build/toolchains:gcc")



cflags_cc = [ "-std=c++14" ]

include_dirs = [ "//" ]

9, gn_test/build/ toolchains/BUILD.gn

//参考官网

toolchain("gcc") {

  tool("cc") {

    depfile = "{{output}}.d"

    command = "gcc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"

    depsformat = "gcc"

    description = "CC {{output}}"

    outputs = [

      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",

    ]

  }

  tool("cxx") {

    depfile = "{{output}}.d"

    command = "g++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"

    depsformat = "gcc"

    description = "CXX {{output}}"

    outputs = [

      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",

    ]

  }

  tool("alink") {

    rspfile = "{{output}}.rsp"

    command = "rm -f {{output}} && ar rcs {{output}} @$rspfile"

    description = "AR {{target_output_name}}{{output_extension}}"

    rspfile_content = "{{inputs}}"

    outputs = [

      "{{target_out_dir}}/{{target_output_name}}{{output_extension}}",

    ]

    default_output_extension = ".a"

    output_prefix = "lib"

  }

  tool("solink") {

    soname = "{{target_output_name}}{{output_extension}}"  # e.g. "libfoo.so".

    rspfile = soname + ".rsp"

    command = "g++ -shared {{ldflags}} -o $soname -Wl,-soname=$soname @$rspfile"

    rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"

    description = "SOLINK $soname"

    # Use this for {{output_extension}} expansions unless a target manually

    # overrides it (in which case {{output_extension}} will be what the target

    # specifies).

    default_output_extension = ".so"

    outputs = [

      soname,

    ]

    link_output = soname

    depend_output = soname

    output_prefix = "lib"

  }

  tool("link") {

    outfile = "{{target_output_name}}{{output_extension}}"

    rspfile = "$outfile.rsp"

    command = "g++ {{ldflags}} -o $outfile @$rspfile {{solibs}} {{libs}}"

    description = "LINK $outfile"

    rspfile_content = "{{inputs}}"

    outputs = [

      outfile,

    ]

  }

  tool("stamp") {

    command = "touch {{output}}"

    description = "STAMP {{output}}"

  }

  tool("copy") {

    command = "cp -af {{source}} {{output}}"

    description = "COPY {{source}} {{output}}"

  }

}

编译:

注意,gn生成的是ninja的输入文件,所以gn需要和ninja的版本适配。可以都从git上下载各自最新代码进行编译。

下载编译ninja

git clone https://github.com/ninja-build/ninja.git

cd ninja

./configure.py –bootstrap

 

下载编译gn

git clone https://gn.googlesource.com/gn

cd gn

python build/gen.py

ninja -C out

 

代码组织结构为

gn_test

ninja

gn

编译测试代码

cd gn_test

../gn/out/gn gen out

##可以看到out目录下有build.ninja文件生成

../ninja/ninja –C out/ main

##可以看到main文件生成了

out/main

#打印如下结果
hello world

func1
  • Reference

1)、https://blog.simplypatrick.com/posts/2016/01-23-gn/

2)、https://github.com/p47t/GN-demo

3)、https://gn.googlesource.com/gn

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值