對於gn來說,工具鏈被抽象爲一系列的工具描述,我們要做的就是寫對應的工具描述文件出來。
首先在工程根目錄建立一個文件.gn(注意文件的名字爲空,後綴爲.gn),文件中配置工具鏈描述文件所在的路徑
buildconfig = "//build/buildconfig.gn"
該變量定義了構建工具鏈描述文件所在的路徑,//表示工程根目錄。
在buildconfig.gn中定義工具鏈。
set_default_toolchain("//build/toolchain:armcc")
上面說到了,工具鏈就是一系列的描述,所以修改工具鏈也就是修改這一系列的描述,以下爲一個典型的armcc的描述文件
toolchain("armcc") {
tool("cc") {
depfile = "{{output}}.d"
command = "$MDK_DIR/ARM/ARMCC/bin/armcc.exe --c99 -g --apcs=interwork -DUSE_STDPERIPH_DRIVER --depend $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("asm") {
depfile = "{{output}}.d"
command = "$MDK_DIR/ARM/ARMCC/bin/armasm.exe -g --apcs=interwork --xref --depend $depfile {{include_dirs}} {{asmflags}} {{source}} -o {{output}}"
depsformat = "gcc"
description = "ASM {{output}}"
outputs = [
"{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
]
}
tool("alink") {
rspfile = "{{output}}.rsp"
command = "$MDK_DIR/ARM/ARMCC/bin/armar.exe -r {{output}} --via $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("link") {
outfile = "bin/{{target_output_name}}{{output_extension}}"
rspfile = "$outfile.rsp"
command = "$MDK_DIR/ARM/ARMCC/bin/armlink.exe {{ldflags}} --info veneers --info unused --info totals --info sizes --symbols --callgraph --xref --strict --summary_stderr --info summarysizes --map --list bin/{{target_output_name}}.map -o $outfile --via $rspfile {{libs}}"
description = "LINK $outfile"
default_output_dir = "{{root_out_dir}}"
rspfile_content = "{{inputs}}"
default_output_extension = ".axf"
outputs = [
outfile,
]
}
tool("stamp") {
command = "cmd.exe /c echo > {{output}}"
description = "STAMP {{output}}"
}
tool("copy") {
command = "cp /y {{source}} {{output}}"
description = "COPY {{source}} {{output}}"
}
}
其可選的所有定義在該博客中進行介紹:
各個工具分開看,首先是編譯器
tool("cc") {
depfile = "{{output}}.d"
command = "$MDK_DIR/ARM/ARMCC/bin/armcc.exe --c99 -g --apcs=interwork -DUSE_STDPERIPH_DRIVER --depend $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("cc")表徵爲編譯器,其依賴文件生成爲.d文件command即爲執行編譯時需要運行的指令,編譯器的固定參數的話可以直接寫在toolchain的定義中,其他參數則由具體的編譯實體定義,其中使用雙大括號包起來的參數將在運行gn時進行展開以生成對應的inja文件。armcc的編譯參數在此不進行解釋,詳細的作用自行查閱armcc的官方說明手冊。
彙編器,彙編器與編譯器類似,也沒什麼需要多說的。
tool("asm") {
depfile = "{{output}}.d"
command = "$MDK_DIR/ARM/ARMCC/bin/armasm.exe -g --apcs=interwork --xref --depend $depfile {{include_dirs}} {{asmflags}} {{source}} -o {{output}}"
depsformat = "gcc"
description = "ASM {{output}}"
outputs = [
"{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
]
}
靜態庫鏈接器
tool("alink") {
rspfile = "{{output}}.rsp"
command = "$MDK_DIR/ARM/ARMCC/bin/armar.exe -r {{output}} --via $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"
}
靜態庫鏈接器在arm工具鏈中爲armar,其主要作用就是把.o文件打包成.a文件(即靜態庫文件),需要注意這個地方配置了rsp文件,原因是在靜態庫打包時,可能會存在命令行長度過長的問題(windows限制命令行最大程度爲8192個字符),超出該長度的話會導致鏈接失效,因此將鏈接參數寫入rsp文件,armar讀取rsp文件來做鏈接,這樣就不會有字符長度限制了。
鏈接器
tool("link") {
outfile = "bin/{{target_output_name}}{{output_extension}}"
rspfile = "$outfile.rsp"
command = "$MDK_DIR/ARM/ARMCC/bin/armlink.exe {{ldflags}} --info veneers --info unused --info totals --info sizes --symbols --callgraph --xref --strict --summary_stderr --info summarysizes --map --list bin/{{target_output_name}}.map -o $outfile --via $rspfile {{libs}}"
description = "LINK $outfile"
default_output_dir = "{{root_out_dir}}"
rspfile_content = "{{inputs}}"
default_output_extension = ".axf"
outputs = [
outfile,
]
}
鏈接器在arm工具鏈中爲armlink,起作用是完成完整鏈接,鏈接處最終生成文件axf,只要有了axf就可以進行下載和調試了!
其他工具
tool("stamp") {
command = "cmd.exe /c echo > {{output}}"
description = "STAMP {{output}}"
}
tool("copy") {
command = "cp /y {{source}} {{output}}"
description = "COPY {{source}} {{output}}"
}
其他工具主要包含了兩個,stamp用於創建一個保存構建時間戳的文件,copy則用來進行必要的複製操作。
對於其中使用到的相關的工具鏈命令行參數均需要自行查閱對應的官方說明手冊進行學習,這篇文章主要介紹構建系統,對於編譯工具鏈的使用在此不進行贅述。
這樣我們就配置好了最基本的armcc編譯工具鏈,之後可以開始工程的架構了