基于GN+ninja的构建系统已经在构建系统层面将速度提升到了极致,但对于编译来说远远没有!
我们可以通过对于不常改动的文件编译为lib的方式来避免每次清理后的重复构建,这样直接把编译的过程都省掉了,构建就可以变得更快。
静态链接库
编译一个静态链接库对于gn来说简直是小菜一碟
static_library("stm32f103c8t6") {
sources = [
"core/core_cm3.c",
"core/startup_stm32f10x_md.s",
"core/stm32f10x_it.c",
"core/system_stm32f10x.c",
"std_lib/src/misc.c",
"std_lib/src/stm32f10x_adc.c",
"std_lib/src/stm32f10x_bkp.c",
"std_lib/src/stm32f10x_can.c",
"std_lib/src/stm32f10x_cec.c",
"std_lib/src/stm32f10x_crc.c",
"std_lib/src/stm32f10x_dac.c",
"std_lib/src/stm32f10x_dbgmcu.c",
"std_lib/src/stm32f10x_dma.c",
"std_lib/src/stm32f10x_exti.c",
"std_lib/src/stm32f10x_flash.c",
"std_lib/src/stm32f10x_fsmc.c",
"std_lib/src/stm32f10x_gpio.c",
"std_lib/src/stm32f10x_i2c.c",
"std_lib/src/stm32f10x_iwdg.c",
"std_lib/src/stm32f10x_pwr.c",
"std_lib/src/stm32f10x_rcc.c",
"std_lib/src/stm32f10x_rtc.c",
"std_lib/src/stm32f10x_sdio.c",
"std_lib/src/stm32f10x_spi.c",
"std_lib/src/stm32f10x_tim.c",
"std_lib/src/stm32f10x_usart.c",
"std_lib/src/stm32f10x_wwdg.c",
]
configs = [ "//build/mcuconfig:stm32f103c8t6" ]
#配置默认包含config,即所有依赖于该lib的目标均会继承该config
all_dependent_configs = [ ":stm32f103_config" ]
}
以上就是把stm32f103x的标准库编译为lib的代码,可以看到非常简单,只需要把目标类型声明为静态库即可。这样执行一次构建之后,将生成的.a文件复制到一个文件夹中,在之后的构建中直接使用该lib即可,如:
libs = [ "//stm32f103x/libstm32f103c8t6.a" ]
构建参数
以上手动修改的方式在偶尔需要真正编译文件的时候并不是很爽,尤其是当这种lib比较多的时候可能要修改好多地方,这时候引入构建参数,根据构建参数来控制构建行为,在gni文件中指定一个默认构建参数
declare_args() {
uselib = false
}
这样根据该变量可以控制编译时使用lib还是真实的去构建。
source_set("stm32f103x") {
if (uselib) {
libs = [ "//stm32f103x/libstm32f103c8t6.a" ]
} else {
deps = [
":stm32f103c8t6",
]
}
all_dependent_configs = [ ":stm32f103_config" ]
}
测试结果
使用以下指令配置编译参数
gn args out/demo
执行该指令后会弹出一个编辑器页面,在编辑器中输入表示使用lib,如果未指定这个参数的话,默认将使用false
uselib = true
在编译之前先清除原有的构建,该动作对于正常的增量编译来说不是必须的步骤,在此清除的主要目的是看编译的差异,另外该clean不会清除args的配置
gn clean out/demo
配置编译使用lib后,对比之前的编译结果可以看到,编译的步骤变少了,即没有对标准库的文件进行编译,但编译出的内容是一致的。