基於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後,對比之前的編譯結果可以看到,編譯的步驟變少了,即沒有對標準庫的文件進行編譯,但編譯出的內容是一致的。