一、openHarmony源码的编译构建系统

openHarmony编译3种方式

三种编译殊途同归
1、hb set
2、build.py
3、build.sh

build.py入口解析

3种形式的编译入口最终都汇总到hb build。即内部实际上是统一的。下面以build.py为例进行讲解

build.py文件

1.jpg

hb/main.py文件解析

2.jpg
3.jpg

OHOSBuildModule模块

4.jpg
5.jpg

BuildModuleInterface接口

6.jpg

OpenHarmony构建体系的核心

GN与Ninja典型传统linux下软件开发做法

(1)源码编辑。工具:vi、sourceinsight、vscode等
(2)编译工具链。gcc、clang等
(3)基本工程管理。工具:make和makefile。
(4)复杂工程管理。一般用脚本,如bash、python等。参考uboot和linux kernel工程
(5)makefile生成器。如cmake。

鸿蒙系统的构建工具

(1)源码编辑。用户自选,如sourceinsight,vscode都比较常用
(2)编译工具链。鸿蒙官方提供,目前均为交叉编译工具链,clang或gcc系
(3)基本工程管理。使用ninja,来自于google
(4)工程管理脚本。使用python3
(5)ninja生成器。使用gn python+gn+ninja

什么是Ninja?什么是GN?

构建样例

GN+Ninja完成代码的整个编译过程

lib文件夹

libtest1.h

extern void func1();

libtest1.c

#include "libtest1.h"
#include <stdio.h>

void func1() {
    printf("func1\n");
}

BUILD.gn文件

// 生成程序集合
sources("lib") {
    sources = [
        "libtest1.c",
        "libtest1.h"
    ]

    public =[
        "libtest1.h",
    ]
}

main文件夹

main.c

#include <stdio.h>
#include "lib/libtest1.h"

int main() {
    printf("Hello, World!\n");
    func1();
}

BUILD.gn文件

// 生成可执行文件
executable("main") {
    sources = [
        "main.c",
    ]

    deps =[
        // “//”表示根目录
        "//lib",
    ]
}

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-wholearchive {{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}}"
  }
}

BUILDCONFIG.gn文件

set_default_toolchain("//build/toolchains:gcc") 
cflags_cc = [ "-std=c++14" ] 
include_dirs = [ "//" ]

根目录

BUILD.gn文件

// 生成可执行文件
group("executable") {
    deps = ["//main"]
}

.gn文件

buildconfig = "//build/BUILDCONFIG.gn"

编译构建

gn gen out 
ninja -C out/ main
7.png
8.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容