鸿蒙源码构建工具Gn 与 Ninja 的介绍及使用入门

简介: 鸿蒙源码构建工具Gn 与 Ninja 的介绍及使用入门

之前搞嵌入式一直只听说和使用过makefile和make编译命令。


最近鸿蒙HarmonyOS系统的火爆,对其源码的编译构建产生了兴趣,了解到鸿蒙系统的编译构建是基于 Gn 和 Ninja 完成的。


那么什么是Gn 与 Ninja?比makefile强到哪了?


了解尝试了一番,被这速度惊到了!


为什么要使用它,总结两点就是:1.比写makefile省事,2.比make编译速度速度快不止一点点。


简单来说Gn有点儿类似于cmake或automake之类的辅助生成makefile脚本的东东,相当于构建脚本的命令。Ninja相当于构建指令,功能类似于make命令。解释的可能不太准确但是这样可能容易理解些。


专业的介绍:



什么是Ninja?


Ninja 是借由 Google Chrome 项目而诞生的一个构建工具,它的诞生目标是为了速度。换句话说,在 Google Chrome 项目的开发过程中,开发者们认为同类型的其它构建工具不给力,所以才会考虑重新开发更高效的工具。


官方介绍:https://ninja-build.org/


类似同类型的构建界的老大哥老古董make ,make 即 GNU Make,一个用于决定如何使用命令完成最终目标构建的程序。 make 有3 个特性:


make 只是一个通用程序,它不知道如何具体的完成目标的构建工作。


make 需要 makefile 中的描述来决定目标构建的具体方案。


make 需要借助其它工具(如:gcc)才能执行方案,最终完成工作。


Ninja 可以看作是一个更好更快的 make 。


什么是GN?


GN是一个生成Ninja构建文件的元构建系统,以便你可以用Ninja构建你的项目。


gn、ninja的安装,使用环境Ubuntu18.04,参见:https://blog.csdn.net/qiuguolu1108/article/details/103842556


嫌编译安装麻烦的,可以直接拷贝使用二进制文件gin和ninja到系统的/usr/bin文件夹中使用。


gin和ninja的二进制可执行文件,上述链接中有说明。


简单的使用入门:


以helloworld为例,建一个gn-test文件夹:


几个文件必不可少,这个需要手工去提前按照格式创建好。否则直接执行gn gen ./out会报错的。


前提是必须存在几个文件和文件夹。


必要的几个文件:


.gn文件


根目录下的BUIlD.gn文件


gnconfig文件夹中的BUILDCONFIG.gn文件


可以输入指令:


gn help dotfile


查看默认的.gin文件模板。


我的这个例子的.gin文件如下:


buildconfig="//gnconfig/BUILDCONFIG.gn"


然后在项目的根目录下创建gnconfig文件夹和内部的BUILDCONFIG.gn文件。


我的BUILDCONFIG.gn文件内容如下:


set_default_toolchain("//gnconfig/toolchain:gcc")
cflags_cc = [ "-std=c++11" ]


可以看到,这里面有指定了一些东西,那么还得在gnconfig文件夹下再放一些东西。


在gnconfig文件夹下创建toolchain文件夹,里面再放个BUILD.gn文件,内容挺复杂,先原样拷贝即可:


# 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 = "{{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".
    sofile = "{{output_dir}}/$soname"
    rspfile = soname + ".rsp"
    command = "g++ -shared {{ldflags}} -o $sofile -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"
    # Use this for {{output_dir}} expansions unless a target manually overrides
    # it (in which case {{output_dir}} will be what the target specifies).
    default_output_dir = "{{root_out_dir}}"
    outputs = [
      sofile,
    ]
    link_output = sofile
    depend_output = sofile
    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"
    default_output_dir = "{{root_out_dir}}"
    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文件和gnconfig中的buildconfig这两项创建好后,基本保持不动,剩下的就是跟编译具体项目相关了。


如我的这个入门hellowold例子,跟目录下创建BUILD.gn文件,内容如下:


group("default"){
    deps = [
       "//src:hello",
    ]
}


在src目录里,创建BUILD.gn文件,内容如下:


executable("hello") {
    sources = [
        "test.c",
    ]
}


至此,总算是构建脚本整完了,感觉挺繁琐的。但是如果熟悉了,大概就是这套路吧。最后当你看到它惊人的构建速度时,就会觉得这一切都是值得的。


接下来就是敲命令啦:


项目根目录下执行 gn gen ./out



打开查看产生了如下内容:



最后生成可执行文件吧:



速度快的不到1秒就构建结束了。


查看下执行结果:



// test.c
#include <stdio.h>
#include "test.h"
int main()
{
    printf("Hello Ninja!\n");
    printf("CONST = %d\n", CONST);
    return 0;
}


相关文章
|
2月前
|
数据可视化 小程序 API
非鸿蒙官方低代码源码生成器
非鸿蒙官方低代码源码生成器
43 1
|
4月前
|
缓存 开发框架 JavaScript
人人都能看懂的鸿蒙 “JS 小程序” 数据绑定原理 | 解读鸿蒙源码
人人都能看懂的鸿蒙 “JS 小程序” 数据绑定原理 | 解读鸿蒙源码
|
7月前
|
存储 JavaScript 前端开发
【HarmonyOS 4.0 应用开发实战】TypeScript入门之元组详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之元组详讲
114 0
|
7月前
|
JavaScript 前端开发
【HarmonyOS 4.0 应用开发实战】TypeScript入门之模块化详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之模块化详讲
78 0
|
7月前
|
JavaScript 前端开发 索引
【HarmonyOS 4.0 应用开发实战】TypeScript入门之接口详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之接口详讲
97 0
|
7月前
|
JavaScript
【HarmonyOS 4.0 应用开发实战】TypeScript入门之声明、数据类型、函数、类的详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之声明、数据类型、函数、类的详讲
92 0
|
7月前
|
存储 Java 数据管理
HarmonyOS实战—HarmonyOS入门第一课
HarmonyOS实战—HarmonyOS入门第一课
117 0
HarmonyOS实战—HarmonyOS入门第一课
|
移动开发 前端开发 JavaScript
鸿蒙-webview的使用和JS交互(附源码)
日常我们在开发项目时,为了项目快速的开发和迭代,难免会用到H5页面。使用鸿蒙进行项目开发时,也一样免不了要加载H5页面,在移动开发中打开H5页面需要使用WebView组件。同时,为了和H5页面进行数据交换,有时候还需要借助JSBridge来实现客户端与H5之间的通讯。 那么鸿蒙之中用到的技术是什么呢?WebView 在此之前,先看一个报错 ​ App Launch: The Huawei Lite Simulator supports only Lite projects.
530 0
鸿蒙-webview的使用和JS交互(附源码)
|
移动开发 Ubuntu 网络协议
嵌入式linux/鸿蒙开发板(IMX6ULL)开发 (二)Ubuntu操作入门与Linux常用命令(中)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发 (二)Ubuntu操作入门与Linux常用命令
173 1
嵌入式linux/鸿蒙开发板(IMX6ULL)开发 (二)Ubuntu操作入门与Linux常用命令(中)
|
XML Web App开发 开发框架
鸿蒙开发入门 | 开发第一个鸿蒙应用+页面跳转
准备好鸿蒙开发环境后,接下来就需要创建鸿蒙项目,掌握项目的创建过程以及配置。项目创建好后,需要把项目运行在模拟器上,鸿蒙的模拟和安卓模拟器有些不同,鸿蒙提供远程模拟器和本地模拟器,通过登录华为账号登录在线模拟器,使用DevEco Studio可将项目部署到远程模拟器中。
1275 1
鸿蒙开发入门 | 开发第一个鸿蒙应用+页面跳转