BUILD.gn 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. declare_args() {
  2. host_ar = ar
  3. host_cc = cc
  4. host_cxx = cxx
  5. if (is_android) {
  6. _prefix = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin"
  7. if (host_os == "win") {
  8. target_ar = "$_prefix/llvm-ar.exe"
  9. target_cc = "$_prefix/clang.exe --target=$ndk_target$ndk_api -fno-addrsig"
  10. target_cxx =
  11. "$_prefix/clang++.exe --target=$ndk_target$ndk_api -fno-addrsig"
  12. } else {
  13. target_ar = "$_prefix/llvm-ar"
  14. target_cc = "$_prefix/$ndk_target$ndk_api-clang"
  15. target_cxx = "$_prefix/$ndk_target$ndk_api-clang++"
  16. }
  17. } else {
  18. target_ar = ar
  19. target_cc = cc
  20. target_cxx = cxx
  21. }
  22. cc_wrapper = ""
  23. }
  24. if (host_os == "win") {
  25. stamp = "cmd.exe /c echo >"
  26. } else {
  27. stamp = "touch"
  28. }
  29. toolchain("msvc") {
  30. lib_dir_switch = "/LIBPATH:"
  31. bin = "$win_vc/Tools/MSVC/$win_toolchain_version/bin/HostX64/$target_cpu"
  32. env_setup = ""
  33. if (target_cpu == "x86") {
  34. # Toolchain asset includes a script that configures for x86 building.
  35. # We don't support x86 builds with local MSVC installations.
  36. env_setup = "cmd /c $win_sdk/bin/SetEnv.cmd /x86 && "
  37. } else if (target_cpu == "arm64") {
  38. # ARM64 compiler is incomplete - it relies on DLLs located in the host toolchain directory.
  39. env_setup = "cmd /C set \"PATH=%PATH%;$win_vc\\Tools\\MSVC\\$win_toolchain_version\\bin\\HostX64\\x64\" && "
  40. }
  41. cl_m32_flag = ""
  42. if (clang_win != "") {
  43. if (target_cpu == "x86") {
  44. # cl.exe knows implicitly by the choice of executable that it's targeting
  45. # x86, but clang-cl.exe needs to be told when targeting non-host
  46. # platforms. (All our builders are x86-64, so x86 is always non-host.)
  47. cl_m32_flag = "-m32"
  48. }
  49. if (host_os == "win") {
  50. cl = "\"$clang_win/bin/clang-cl.exe\""
  51. lib = "\"$clang_win/bin/lld-link.exe\" /lib"
  52. link = "\"$clang_win/bin/lld-link.exe\""
  53. } else {
  54. cl = "\"$clang_win/bin/clang-cl\""
  55. lib = "\"$clang_win/bin/lld-link\" /lib"
  56. link = "\"$clang_win/bin/lld-link\""
  57. }
  58. } else {
  59. cl = "\"$bin/cl.exe\""
  60. lib = "\"$bin/lib.exe\""
  61. link = "\"$bin/link.exe\""
  62. }
  63. tool("asm") {
  64. _ml = "ml"
  65. if (target_cpu == "x64") {
  66. _ml += "64"
  67. }
  68. command = "$env_setup \"$bin/$_ml.exe\" {{asmflags}} /nologo /c /Fo {{output}} {{source}}"
  69. outputs = [
  70. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
  71. ]
  72. description = "assemble {{source}}"
  73. }
  74. tool("cc") {
  75. precompiled_header_type = "msvc"
  76. pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
  77. # Label names may have spaces so pdbname must be quoted.
  78. command = "$env_setup $cc_wrapper $cl /nologo /showIncludes /FC {{defines}} {{include_dirs}} {{cflags}} $cl_m32_flag {{cflags_c}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
  79. depsformat = "msvc"
  80. outputs = [
  81. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
  82. ]
  83. description = "compile {{source}}"
  84. }
  85. tool("cxx") {
  86. precompiled_header_type = "msvc"
  87. pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
  88. # Label names may have spaces so pdbname must be quoted.
  89. command = "$env_setup $cc_wrapper $cl /nologo /showIncludes /FC {{defines}} {{include_dirs}} {{cflags}} $cl_m32_flag {{cflags_cc}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
  90. depsformat = "msvc"
  91. outputs = [
  92. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
  93. ]
  94. description = "compile {{source}}"
  95. }
  96. tool("alink") {
  97. rspfile = "{{output}}.rsp"
  98. command = "$env_setup $lib /nologo /ignore:4221 {{arflags}} /OUT:{{output}} @$rspfile"
  99. outputs = [
  100. # Ignore {{output_extension}} and always use .lib, there's no reason to
  101. # allow targets to override this extension on Windows.
  102. "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
  103. ]
  104. default_output_extension = ".lib"
  105. default_output_dir = "{{target_out_dir}}"
  106. # inputs_newline works around a fixed per-line buffer size in the linker.
  107. rspfile_content = "{{inputs_newline}}"
  108. description = "link {{output}}"
  109. }
  110. tool("solink") {
  111. dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
  112. libname = "${dllname}.lib"
  113. pdbname = "${dllname}.pdb"
  114. rspfile = "${dllname}.rsp"
  115. command = "$env_setup $link /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile"
  116. outputs = [
  117. dllname,
  118. libname,
  119. pdbname,
  120. ]
  121. default_output_extension = ".dll"
  122. default_output_dir = "{{root_out_dir}}"
  123. link_output = libname
  124. depend_output = libname
  125. runtime_outputs = [
  126. dllname,
  127. pdbname,
  128. ]
  129. # I don't quite understand this. Aping Chrome's toolchain/win/BUILD.gn.
  130. restat = true
  131. # inputs_newline works around a fixed per-line buffer size in the linker.
  132. rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
  133. description = "link {{output}}"
  134. }
  135. tool("link") {
  136. exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
  137. pdbname = "$exename.pdb"
  138. rspfile = "$exename.rsp"
  139. command = "$env_setup $link /nologo /OUT:$exename /PDB:$pdbname @$rspfile"
  140. default_output_extension = ".exe"
  141. default_output_dir = "{{root_out_dir}}"
  142. outputs = [
  143. exename,
  144. ]
  145. # inputs_newline works around a fixed per-line buffer size in the linker.
  146. rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
  147. description = "link {{output}}"
  148. }
  149. tool("stamp") {
  150. command = "$stamp {{output}}"
  151. description = "stamp {{output}}"
  152. }
  153. tool("copy") {
  154. cp_py = rebase_path("../cp.py")
  155. command = "python $cp_py {{source}} {{output}}"
  156. description = "copy {{source}} {{output}}"
  157. }
  158. }
  159. template("gcc_like_toolchain") {
  160. toolchain(target_name) {
  161. ar = invoker.ar
  162. cc = invoker.cc
  163. cxx = invoker.cxx
  164. lib_switch = "-l"
  165. lib_dir_switch = "-L"
  166. tool("cc") {
  167. depfile = "{{output}}.d"
  168. command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
  169. depsformat = "gcc"
  170. outputs = [
  171. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
  172. ]
  173. description = "compile {{source}}"
  174. }
  175. tool("cxx") {
  176. depfile = "{{output}}.d"
  177. command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
  178. depsformat = "gcc"
  179. outputs = [
  180. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
  181. ]
  182. description = "compile {{source}}"
  183. }
  184. tool("objc") {
  185. depfile = "{{output}}.d"
  186. command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}"
  187. depsformat = "gcc"
  188. outputs = [
  189. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
  190. ]
  191. description = "compile {{source}}"
  192. }
  193. tool("objcxx") {
  194. depfile = "{{output}}.d"
  195. command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}"
  196. depsformat = "gcc"
  197. outputs = [
  198. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
  199. ]
  200. description = "compile {{source}}"
  201. }
  202. tool("asm") {
  203. depfile = "{{output}}.d"
  204. command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
  205. depsformat = "gcc"
  206. outputs = [
  207. "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
  208. ]
  209. description = "assemble {{source}}"
  210. }
  211. tool("alink") {
  212. rspfile = "{{output}}.rsp"
  213. rspfile_content = "{{inputs}}"
  214. ar_py = rebase_path("../ar.py")
  215. command = "python $ar_py $ar {{output}} $rspfile"
  216. outputs = [
  217. "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
  218. ]
  219. default_output_extension = ".a"
  220. output_prefix = "lib"
  221. description = "link {{output}}"
  222. }
  223. tool("solink") {
  224. soname = "{{target_output_name}}{{output_extension}}"
  225. rpath = "-Wl,-soname,$soname"
  226. if (is_mac) {
  227. rpath = "-Wl,-install_name,@rpath/$soname"
  228. }
  229. rspfile = "{{output}}.rsp"
  230. rspfile_content = "{{inputs}}"
  231. # --start-group/--end-group let us link multiple .a {{inputs}}
  232. # without worrying about their relative order on the link line.
  233. #
  234. # This is mostly important for traditional linkers like GNU ld and Gold.
  235. # The Mac/iOS linker neither needs nor accepts these flags.
  236. # LLD doesn't need these flags, but accepts and ignores them.
  237. _start_group = "-Wl,--start-group"
  238. _end_group = "-Wl,--end-group"
  239. if (is_mac || is_ios) {
  240. _start_group = ""
  241. _end_group = ""
  242. }
  243. command = "$cc_wrapper $cxx -shared {{ldflags}} $_start_group @$rspfile {{solibs}} $_end_group {{libs}} $rpath -o {{output}}"
  244. outputs = [
  245. "{{root_out_dir}}/$soname",
  246. ]
  247. output_prefix = "lib"
  248. default_output_extension = ".so"
  249. description = "link {{output}}"
  250. }
  251. tool("link") {
  252. exe_name = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
  253. rspfile = "$exe_name.rsp"
  254. rspfile_content = "{{inputs}}"
  255. # --start-group/--end-group let us link multiple .a {{inputs}}
  256. # without worrying about their relative order on the link line.
  257. #
  258. # This is mostly important for traditional linkers like GNU ld and Gold.
  259. # The Mac/iOS linker neither needs nor accepts these flags.
  260. # LLD doesn't need these flags, but accepts and ignores them.
  261. _start_group = "-Wl,--start-group"
  262. _end_group = "-Wl,--end-group"
  263. if (is_mac || is_ios) {
  264. _start_group = ""
  265. _end_group = ""
  266. }
  267. if (is_ios) {
  268. command = "$cc_wrapper $cxx {{ldflags}} $_start_group @$rspfile {{solibs}} $_end_group {{libs}} -o $exe_name && dsymutil $exe_name"
  269. } else {
  270. command = "$cc_wrapper $cxx {{ldflags}} $_start_group @$rspfile {{solibs}} $_end_group {{libs}} -o $exe_name"
  271. }
  272. outputs = [
  273. "$exe_name",
  274. ]
  275. if (is_ios) {
  276. outputs += [ "{{root_out_dir}}/{{target_output_name}}.dSYM" ]
  277. }
  278. description = "link {{output}}"
  279. }
  280. tool("stamp") {
  281. command = "$stamp {{output}}"
  282. description = "stamp {{output}}"
  283. }
  284. tool("copy") {
  285. cp_py = rebase_path("../cp.py")
  286. command = "python $cp_py {{source}} {{output}}"
  287. description = "copy {{source}} {{output}}"
  288. }
  289. tool("copy_bundle_data") {
  290. cp_py = rebase_path("../cp.py")
  291. command = "python $cp_py {{source}} {{output}}"
  292. description = "copy_bundle_data {{source}} {{output}}"
  293. }
  294. # We don't currently have any xcasset files so make this a NOP
  295. tool("compile_xcassets") {
  296. command = "true"
  297. description = "compile_xcassets {{output}}"
  298. }
  299. toolchain_args = {
  300. current_cpu = invoker.cpu
  301. current_os = invoker.os
  302. }
  303. }
  304. }
  305. gcc_like_toolchain("gcc_like") {
  306. cpu = current_cpu
  307. os = current_os
  308. ar = target_ar
  309. cc = target_cc
  310. cxx = target_cxx
  311. }
  312. gcc_like_toolchain("gcc_like_host") {
  313. cpu = host_cpu
  314. os = host_os
  315. ar = host_ar
  316. cc = host_cc
  317. cxx = host_cxx
  318. }