builder.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. // Copyright 2015 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package cc
  15. // This file generates the final rules for compiling all C/C++. All properties related to
  16. // compiling should have been translated into builderFlags or another argument to the Transform*
  17. // functions.
  18. import (
  19. "path/filepath"
  20. "runtime"
  21. "strconv"
  22. "strings"
  23. "github.com/google/blueprint"
  24. "github.com/google/blueprint/pathtools"
  25. "android/soong/android"
  26. "android/soong/cc/config"
  27. "android/soong/remoteexec"
  28. )
  29. const (
  30. objectExtension = ".o"
  31. staticLibraryExtension = ".a"
  32. )
  33. var (
  34. pctx = android.NewPackageContext("android/soong/cc")
  35. // Rule to invoke gcc with given command, flags, and dependencies. Outputs a .d depfile.
  36. cc = pctx.AndroidRemoteStaticRule("cc", android.RemoteRuleSupports{Goma: true, RBE: true},
  37. blueprint.RuleParams{
  38. Depfile: "${out}.d",
  39. Deps: blueprint.DepsGCC,
  40. Command: "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -MD -MF ${out}.d -o $out $in",
  41. CommandDeps: []string{"$ccCmd"},
  42. },
  43. "ccCmd", "cFlags")
  44. // Rule to invoke gcc with given command and flags, but no dependencies.
  45. ccNoDeps = pctx.AndroidStaticRule("ccNoDeps",
  46. blueprint.RuleParams{
  47. Command: "$relPwd $ccCmd -c $cFlags -o $out $in",
  48. CommandDeps: []string{"$ccCmd"},
  49. },
  50. "ccCmd", "cFlags")
  51. // Rules to invoke ld to link binaries. Uses a .rsp file to list dependencies, as there may
  52. // be many.
  53. ld, ldRE = pctx.RemoteStaticRules("ld",
  54. blueprint.RuleParams{
  55. Command: "$reTemplate$ldCmd ${crtBegin} @${out}.rsp " +
  56. "${crtEnd} -o ${out} ${ldFlags} ${extraLibFlags}",
  57. CommandDeps: []string{"$ldCmd"},
  58. Rspfile: "${out}.rsp",
  59. RspfileContent: "${in} ${libFlags}",
  60. // clang -Wl,--out-implib doesn't update its output file if it hasn't changed.
  61. Restat: true,
  62. },
  63. &remoteexec.REParams{
  64. Labels: map[string]string{"type": "link", "tool": "clang"},
  65. ExecStrategy: "${config.RECXXLinksExecStrategy}",
  66. Inputs: []string{"${out}.rsp", "$implicitInputs"},
  67. RSPFiles: []string{"${out}.rsp"},
  68. OutputFiles: []string{"${out}", "$implicitOutputs"},
  69. ToolchainInputs: []string{"$ldCmd"},
  70. Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXLinksPool}"},
  71. }, []string{"ldCmd", "crtBegin", "libFlags", "crtEnd", "ldFlags", "extraLibFlags"}, []string{"implicitInputs", "implicitOutputs"})
  72. // Rules for .o files to combine to other .o files, using ld partial linking.
  73. partialLd, partialLdRE = pctx.RemoteStaticRules("partialLd",
  74. blueprint.RuleParams{
  75. // Without -no-pie, clang 7.0 adds -pie to link Android files,
  76. // but -r and -pie cannot be used together.
  77. Command: "$reTemplate$ldCmd -fuse-ld=lld -nostdlib -no-pie -Wl,-r ${in} -o ${out} ${ldFlags}",
  78. CommandDeps: []string{"$ldCmd"},
  79. }, &remoteexec.REParams{
  80. Labels: map[string]string{"type": "link", "tool": "clang"},
  81. ExecStrategy: "${config.RECXXLinksExecStrategy}",
  82. Inputs: []string{"$inCommaList", "$implicitInputs"},
  83. OutputFiles: []string{"${out}", "$implicitOutputs"},
  84. ToolchainInputs: []string{"$ldCmd"},
  85. Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXLinksPool}"},
  86. }, []string{"ldCmd", "ldFlags"}, []string{"implicitInputs", "inCommaList", "implicitOutputs"})
  87. // Rule to invoke `ar` with given cmd and flags, but no static library depenencies.
  88. ar = pctx.AndroidStaticRule("ar",
  89. blueprint.RuleParams{
  90. Command: "rm -f ${out} && $arCmd $arFlags $out @${out}.rsp",
  91. CommandDeps: []string{"$arCmd"},
  92. Rspfile: "${out}.rsp",
  93. RspfileContent: "${in}",
  94. },
  95. "arCmd", "arFlags")
  96. // Rule to invoke `ar` with given cmd, flags, and library dependencies. Generates a .a
  97. // (archive) file from .o files.
  98. arWithLibs = pctx.AndroidStaticRule("arWithLibs",
  99. blueprint.RuleParams{
  100. Command: "rm -f ${out} && $arCmd $arObjFlags $out @${out}.rsp && $arCmd $arLibFlags $out $arLibs",
  101. CommandDeps: []string{"$arCmd"},
  102. Rspfile: "${out}.rsp",
  103. RspfileContent: "${arObjs}",
  104. },
  105. "arCmd", "arObjFlags", "arObjs", "arLibFlags", "arLibs")
  106. // Rule to run objcopy --prefix-symbols (to prefix all symbols in a file with a given string).
  107. prefixSymbols = pctx.AndroidStaticRule("prefixSymbols",
  108. blueprint.RuleParams{
  109. Command: "$objcopyCmd --prefix-symbols=${prefix} ${in} ${out}",
  110. CommandDeps: []string{"$objcopyCmd"},
  111. },
  112. "objcopyCmd", "prefix")
  113. // Rule to run objcopy --remove-section=.llvm_addrsig on a partially linked object
  114. noAddrSig = pctx.AndroidStaticRule("noAddrSig",
  115. blueprint.RuleParams{
  116. Command: "rm -f ${out} && $objcopyCmd --remove-section=.llvm_addrsig ${in} ${out}",
  117. CommandDeps: []string{"$objcopyCmd"},
  118. },
  119. "objcopyCmd")
  120. _ = pctx.SourcePathVariable("stripPath", "build/soong/scripts/strip.sh")
  121. _ = pctx.SourcePathVariable("xzCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/xz")
  122. _ = pctx.SourcePathVariable("createMiniDebugInfo", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/create_minidebuginfo")
  123. // Rule to invoke `strip` (to discard symbols and data from object files).
  124. strip = pctx.AndroidStaticRule("strip",
  125. blueprint.RuleParams{
  126. Depfile: "${out}.d",
  127. Deps: blueprint.DepsGCC,
  128. Command: "XZ=$xzCmd CREATE_MINIDEBUGINFO=$createMiniDebugInfo CLANG_BIN=${config.ClangBin} $stripPath ${args} -i ${in} -o ${out} -d ${out}.d",
  129. CommandDeps: func() []string {
  130. if runtime.GOOS != "darwin" {
  131. return []string{"$stripPath", "$xzCmd", "$createMiniDebugInfo"}
  132. } else {
  133. return []string{"$stripPath", "$xzCmd"}
  134. }
  135. }(),
  136. Pool: darwinStripPool,
  137. },
  138. "args")
  139. // Rule to invoke `strip` (to discard symbols and data from object files) on darwin architecture.
  140. darwinStrip = pctx.AndroidStaticRule("darwinStrip",
  141. blueprint.RuleParams{
  142. Command: "${config.MacStripPath} -u -r -o $out $in",
  143. CommandDeps: []string{"${config.MacStripPath}"},
  144. })
  145. // b/132822437: objcopy uses a file descriptor per .o file when called on .a files, which runs the system out of
  146. // file descriptors on darwin. Limit concurrent calls to 5 on darwin.
  147. darwinStripPool = func() blueprint.Pool {
  148. if runtime.GOOS == "darwin" {
  149. return pctx.StaticPool("darwinStripPool", blueprint.PoolParams{
  150. Depth: 5,
  151. })
  152. } else {
  153. return nil
  154. }
  155. }()
  156. darwinLipo = pctx.AndroidStaticRule("darwinLipo",
  157. blueprint.RuleParams{
  158. Command: "${config.MacLipoPath} -create -output $out $in",
  159. CommandDeps: []string{"${config.MacLipoPath}"},
  160. })
  161. _ = pctx.SourcePathVariable("archiveRepackPath", "build/soong/scripts/archive_repack.sh")
  162. // Rule to repack an archive (.a) file with a subset of object files.
  163. archiveRepack = pctx.AndroidStaticRule("archiveRepack",
  164. blueprint.RuleParams{
  165. Depfile: "${out}.d",
  166. Deps: blueprint.DepsGCC,
  167. Command: "CLANG_BIN=${config.ClangBin} $archiveRepackPath -i ${in} -o ${out} -d ${out}.d ${objects}",
  168. CommandDeps: []string{"$archiveRepackPath"},
  169. },
  170. "objects")
  171. // Rule to create an empty file at a given path.
  172. emptyFile = pctx.AndroidStaticRule("emptyFile",
  173. blueprint.RuleParams{
  174. Command: "rm -f $out && touch $out",
  175. })
  176. _ = pctx.SourcePathVariable("tocPath", "build/soong/scripts/toc.sh")
  177. // A rule for extracting a table of contents from a shared library (.so).
  178. toc = pctx.AndroidStaticRule("toc",
  179. blueprint.RuleParams{
  180. Depfile: "${out}.d",
  181. Deps: blueprint.DepsGCC,
  182. Command: "CLANG_BIN=$clangBin $tocPath $format -i ${in} -o ${out} -d ${out}.d",
  183. CommandDeps: []string{"$tocPath"},
  184. Restat: true,
  185. },
  186. "clangBin", "format")
  187. // Rules for invoking clang-tidy (a clang-based linter).
  188. clangTidy, clangTidyRE = pctx.RemoteStaticRules("clangTidy",
  189. blueprint.RuleParams{
  190. Depfile: "${out}.d",
  191. Deps: blueprint.DepsGCC,
  192. Command: "CLANG_CMD=$clangCmd TIDY_FILE=$out " +
  193. "$tidyVars$reTemplate${config.ClangBin}/clang-tidy.sh $in $tidyFlags -- $cFlags",
  194. CommandDeps: []string{"${config.ClangBin}/clang-tidy.sh", "$ccCmd", "$tidyCmd"},
  195. },
  196. &remoteexec.REParams{
  197. Labels: map[string]string{"type": "lint", "tool": "clang-tidy", "lang": "cpp"},
  198. ExecStrategy: "${config.REClangTidyExecStrategy}",
  199. Inputs: []string{"$in"},
  200. OutputFiles: []string{"${out}", "${out}.d"},
  201. ToolchainInputs: []string{"$ccCmd", "$tidyCmd"},
  202. EnvironmentVariables: []string{"CLANG_CMD", "TIDY_FILE", "TIDY_TIMEOUT"},
  203. // Although clang-tidy has an option to "fix" source files, that feature is hardly useable
  204. // under parallel compilation and RBE. So we assume no OutputFiles here.
  205. // The clang-tidy fix option is best run locally in single thread.
  206. // Copying source file back to local caused two problems:
  207. // (1) New timestamps trigger clang and clang-tidy compilations again.
  208. // (2) Changing source files caused concurrent clang or clang-tidy jobs to crash.
  209. Platform: map[string]string{remoteexec.PoolKey: "${config.REClangTidyPool}"},
  210. }, []string{"cFlags", "ccCmd", "clangCmd", "tidyCmd", "tidyFlags", "tidyVars"}, []string{})
  211. _ = pctx.SourcePathVariable("yasmCmd", "prebuilts/misc/${config.HostPrebuiltTag}/yasm/yasm")
  212. // Rule for invoking yasm to compile .asm assembly files.
  213. yasm = pctx.AndroidStaticRule("yasm",
  214. blueprint.RuleParams{
  215. Command: "$yasmCmd $asFlags -o $out $in && $yasmCmd $asFlags -M $in >$out.d",
  216. CommandDeps: []string{"$yasmCmd"},
  217. Depfile: "$out.d",
  218. Deps: blueprint.DepsGCC,
  219. },
  220. "asFlags")
  221. _ = pctx.SourcePathVariable("sAbiDumper", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-dumper")
  222. // -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information.
  223. sAbiDump, sAbiDumpRE = pctx.RemoteStaticRules("sAbiDump",
  224. blueprint.RuleParams{
  225. Command: "rm -f $out && $reTemplate$sAbiDumper --root-dir . --root-dir $$OUT_DIR:out -o ${out} $in $exportDirs -- $cFlags -w -isystem prebuilts/clang-tools/${config.HostPrebuiltTag}/clang-headers",
  226. CommandDeps: []string{"$sAbiDumper"},
  227. }, &remoteexec.REParams{
  228. Labels: map[string]string{"type": "abi-dump", "tool": "header-abi-dumper"},
  229. ExecStrategy: "${config.REAbiDumperExecStrategy}",
  230. Inputs: []string{"$sAbiLinkerLibs"},
  231. Platform: map[string]string{
  232. remoteexec.PoolKey: "${config.RECXXPool}",
  233. },
  234. }, []string{"cFlags", "exportDirs"}, nil)
  235. _ = pctx.SourcePathVariable("sAbiLinker", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-linker")
  236. _ = pctx.SourcePathVariable("sAbiLinkerLibs", "prebuilts/clang-tools/${config.HostPrebuiltTag}/lib64")
  237. // Rule to combine .dump sAbi dump files from multiple source files into a single .ldump
  238. // sAbi dump file.
  239. sAbiLink, sAbiLinkRE = pctx.RemoteStaticRules("sAbiLink",
  240. blueprint.RuleParams{
  241. Command: "$reTemplate$sAbiLinker --root-dir . --root-dir $$OUT_DIR:out -o ${out} $symbolFilter -arch $arch $exportedHeaderFlags @${out}.rsp",
  242. CommandDeps: []string{"$sAbiLinker"},
  243. Rspfile: "${out}.rsp",
  244. RspfileContent: "${in}",
  245. }, &remoteexec.REParams{
  246. Labels: map[string]string{"type": "tool", "name": "abi-linker"},
  247. ExecStrategy: "${config.REAbiLinkerExecStrategy}",
  248. Inputs: []string{"$sAbiLinkerLibs", "${out}.rsp", "$implicitInputs"},
  249. RSPFiles: []string{"${out}.rsp"},
  250. OutputFiles: []string{"$out"},
  251. ToolchainInputs: []string{"$sAbiLinker"},
  252. Platform: map[string]string{remoteexec.PoolKey: "${config.RECXXPool}"},
  253. }, []string{"symbolFilter", "arch", "exportedHeaderFlags"}, []string{"implicitInputs"})
  254. _ = pctx.SourcePathVariable("sAbiDiffer", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-diff")
  255. // Rule to compare linked sAbi dump files (.ldump).
  256. sAbiDiff = pctx.RuleFunc("sAbiDiff",
  257. func(ctx android.PackageRuleContext) blueprint.RuleParams {
  258. commandStr := "($sAbiDiffer ${extraFlags} -lib ${libName} -arch ${arch} -o ${out} -new ${in} -old ${referenceDump})"
  259. commandStr += "|| (echo '${errorMessage}'"
  260. commandStr += " && (mkdir -p $$DIST_DIR/abidiffs && cp ${out} $$DIST_DIR/abidiffs/)"
  261. commandStr += " && exit 1)"
  262. return blueprint.RuleParams{
  263. Command: commandStr,
  264. CommandDeps: []string{"$sAbiDiffer"},
  265. }
  266. },
  267. "extraFlags", "referenceDump", "libName", "arch", "errorMessage")
  268. // Rule to zip files.
  269. zip = pctx.AndroidStaticRule("zip",
  270. blueprint.RuleParams{
  271. Command: "${SoongZipCmd} -o ${out} -C $$OUT_DIR -r ${out}.rsp",
  272. CommandDeps: []string{"${SoongZipCmd}"},
  273. Rspfile: "${out}.rsp",
  274. RspfileContent: "$in",
  275. })
  276. _ = pctx.SourcePathVariable("cxxExtractor",
  277. "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/cxx_extractor")
  278. _ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
  279. _ = pctx.VariableFunc("kytheCorpus",
  280. func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
  281. _ = pctx.VariableFunc("kytheCuEncoding",
  282. func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
  283. // Rule to use kythe extractors to generate .kzip files, used to build code cross references.
  284. kytheExtract = pctx.StaticRule("kythe",
  285. blueprint.RuleParams{
  286. Command: `rm -f $out && ` +
  287. `KYTHE_CORPUS=${kytheCorpus} ` +
  288. `KYTHE_OUTPUT_FILE=$out ` +
  289. `KYTHE_VNAMES=$kytheVnames ` +
  290. `KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
  291. `KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` +
  292. `$cxxExtractor $cFlags $in `,
  293. CommandDeps: []string{"$cxxExtractor", "$kytheVnames"},
  294. },
  295. "cFlags")
  296. )
  297. func PwdPrefix() string {
  298. // Darwin doesn't have /proc
  299. if runtime.GOOS != "darwin" {
  300. return "PWD=/proc/self/cwd"
  301. }
  302. return ""
  303. }
  304. func init() {
  305. // We run gcc/clang with PWD=/proc/self/cwd to remove $TOP from the
  306. // debug output. That way two builds in two different directories will
  307. // create the same output.
  308. pctx.StaticVariable("relPwd", PwdPrefix())
  309. pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
  310. }
  311. // builderFlags contains various types of command line flags (and settings) for use in building
  312. // build statements related to C++.
  313. type builderFlags struct {
  314. // Global flags (which build system or toolchain is responsible for). These are separate from
  315. // local flags because they should appear first (so that they may be overridden by local flags).
  316. globalCommonFlags string
  317. globalAsFlags string
  318. globalYasmFlags string
  319. globalCFlags string
  320. globalToolingCFlags string // A separate set of cFlags for clang LibTooling tools
  321. globalToolingCppFlags string // A separate set of cppFlags for clang LibTooling tools
  322. globalConlyFlags string
  323. globalCppFlags string
  324. globalLdFlags string
  325. // Local flags (which individual modules are responsible for). These may override global flags.
  326. localCommonFlags string
  327. localAsFlags string
  328. localYasmFlags string
  329. localCFlags string
  330. localToolingCFlags string // A separate set of cFlags for clang LibTooling tools
  331. localToolingCppFlags string // A separate set of cppFlags for clang LibTooling tools
  332. localConlyFlags string
  333. localCppFlags string
  334. localLdFlags string
  335. libFlags string // Flags to add to the linker directly after specifying libraries to link.
  336. extraLibFlags string // Flags to add to the linker last.
  337. tidyFlags string // Flags that apply to clang-tidy
  338. sAbiFlags string // Flags that apply to header-abi-dumps
  339. aidlFlags string // Flags that apply to aidl source files
  340. rsFlags string // Flags that apply to renderscript source files
  341. toolchain config.Toolchain
  342. // True if these extra features are enabled.
  343. tidy bool
  344. needTidyFiles bool
  345. gcovCoverage bool
  346. sAbiDump bool
  347. emitXrefs bool
  348. assemblerWithCpp bool // True if .s files should be processed with the c preprocessor.
  349. systemIncludeFlags string
  350. proto android.ProtoFlags
  351. protoC bool // If true, compile protos as `.c` files. Otherwise, output as `.cc`.
  352. protoOptionsFile bool // If true, output a proto options file.
  353. yacc *YaccProperties
  354. lex *LexProperties
  355. }
  356. // StripFlags represents flags related to stripping. This is separate from builderFlags, as these
  357. // flags are useful outside of this package (such as for Rust).
  358. type StripFlags struct {
  359. Toolchain config.Toolchain
  360. StripKeepSymbols bool
  361. StripKeepSymbolsList string
  362. StripKeepSymbolsAndDebugFrame bool
  363. StripKeepMiniDebugInfo bool
  364. StripAddGnuDebuglink bool
  365. StripUseGnuStrip bool
  366. }
  367. // Objects is a collection of file paths corresponding to outputs for C++ related build statements.
  368. type Objects struct {
  369. objFiles android.Paths
  370. tidyFiles android.Paths
  371. tidyDepFiles android.Paths // link dependent .tidy files
  372. coverageFiles android.Paths
  373. sAbiDumpFiles android.Paths
  374. kytheFiles android.Paths
  375. }
  376. func (a Objects) Copy() Objects {
  377. return Objects{
  378. objFiles: append(android.Paths{}, a.objFiles...),
  379. tidyFiles: append(android.Paths{}, a.tidyFiles...),
  380. tidyDepFiles: append(android.Paths{}, a.tidyDepFiles...),
  381. coverageFiles: append(android.Paths{}, a.coverageFiles...),
  382. sAbiDumpFiles: append(android.Paths{}, a.sAbiDumpFiles...),
  383. kytheFiles: append(android.Paths{}, a.kytheFiles...),
  384. }
  385. }
  386. func (a Objects) Append(b Objects) Objects {
  387. return Objects{
  388. objFiles: append(a.objFiles, b.objFiles...),
  389. tidyFiles: append(a.tidyFiles, b.tidyFiles...),
  390. tidyDepFiles: append(a.tidyDepFiles, b.tidyDepFiles...),
  391. coverageFiles: append(a.coverageFiles, b.coverageFiles...),
  392. sAbiDumpFiles: append(a.sAbiDumpFiles, b.sAbiDumpFiles...),
  393. kytheFiles: append(a.kytheFiles, b.kytheFiles...),
  394. }
  395. }
  396. // Generate rules for compiling multiple .c, .cpp, or .S files to individual .o files
  397. func transformSourceToObj(ctx ModuleContext, subdir string, srcFiles, noTidySrcs, timeoutTidySrcs android.Paths,
  398. flags builderFlags, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
  399. // Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
  400. objFiles := make(android.Paths, len(srcFiles))
  401. var tidyFiles android.Paths
  402. noTidySrcsMap := make(map[string]bool)
  403. var tidyVars string
  404. if flags.tidy {
  405. tidyFiles = make(android.Paths, 0, len(srcFiles))
  406. for _, path := range noTidySrcs {
  407. noTidySrcsMap[path.String()] = true
  408. }
  409. tidyTimeout := ctx.Config().Getenv("TIDY_TIMEOUT")
  410. if len(tidyTimeout) > 0 {
  411. tidyVars += "TIDY_TIMEOUT=" + tidyTimeout + " "
  412. // add timeoutTidySrcs into noTidySrcsMap if TIDY_TIMEOUT is set
  413. for _, path := range timeoutTidySrcs {
  414. noTidySrcsMap[path.String()] = true
  415. }
  416. }
  417. }
  418. var coverageFiles android.Paths
  419. if flags.gcovCoverage {
  420. coverageFiles = make(android.Paths, 0, len(srcFiles))
  421. }
  422. var kytheFiles android.Paths
  423. if flags.emitXrefs {
  424. kytheFiles = make(android.Paths, 0, len(srcFiles))
  425. }
  426. // Produce fully expanded flags for use by C tools, C compiles, C++ tools, C++ compiles, and asm compiles
  427. // respectively.
  428. toolingCflags := flags.globalCommonFlags + " " +
  429. flags.globalToolingCFlags + " " +
  430. flags.globalConlyFlags + " " +
  431. flags.localCommonFlags + " " +
  432. flags.localToolingCFlags + " " +
  433. flags.localConlyFlags + " " +
  434. flags.systemIncludeFlags
  435. cflags := flags.globalCommonFlags + " " +
  436. flags.globalCFlags + " " +
  437. flags.globalConlyFlags + " " +
  438. flags.localCommonFlags + " " +
  439. flags.localCFlags + " " +
  440. flags.localConlyFlags + " " +
  441. flags.systemIncludeFlags
  442. toolingCppflags := flags.globalCommonFlags + " " +
  443. flags.globalToolingCFlags + " " +
  444. flags.globalToolingCppFlags + " " +
  445. flags.localCommonFlags + " " +
  446. flags.localToolingCFlags + " " +
  447. flags.localToolingCppFlags + " " +
  448. flags.systemIncludeFlags
  449. cppflags := flags.globalCommonFlags + " " +
  450. flags.globalCFlags + " " +
  451. flags.globalCppFlags + " " +
  452. flags.localCommonFlags + " " +
  453. flags.localCFlags + " " +
  454. flags.localCppFlags + " " +
  455. flags.systemIncludeFlags
  456. asflags := flags.globalCommonFlags + " " +
  457. flags.globalAsFlags + " " +
  458. flags.localCommonFlags + " " +
  459. flags.localAsFlags + " " +
  460. flags.systemIncludeFlags
  461. var sAbiDumpFiles android.Paths
  462. if flags.sAbiDump {
  463. sAbiDumpFiles = make(android.Paths, 0, len(srcFiles))
  464. }
  465. cflags += " ${config.NoOverrideGlobalCflags}"
  466. toolingCflags += " ${config.NoOverrideGlobalCflags}"
  467. cppflags += " ${config.NoOverrideGlobalCflags}"
  468. toolingCppflags += " ${config.NoOverrideGlobalCflags}"
  469. if flags.toolchain.Is64Bit() {
  470. cflags += " ${config.NoOverride64GlobalCflags}"
  471. toolingCflags += " ${config.NoOverride64GlobalCflags}"
  472. cppflags += " ${config.NoOverride64GlobalCflags}"
  473. toolingCppflags += " ${config.NoOverride64GlobalCflags}"
  474. }
  475. modulePath := android.PathForModuleSrc(ctx).String()
  476. if android.IsThirdPartyPath(modulePath) {
  477. cflags += " ${config.NoOverrideExternalGlobalCflags}"
  478. toolingCflags += " ${config.NoOverrideExternalGlobalCflags}"
  479. cppflags += " ${config.NoOverrideExternalGlobalCflags}"
  480. toolingCppflags += " ${config.NoOverrideExternalGlobalCflags}"
  481. }
  482. // Multiple source files have build rules usually share the same cFlags or tidyFlags.
  483. // Define only one version in this module and share it in multiple build rules.
  484. // To simplify the code, the shared variables are all named as $flags<nnn>.
  485. shared := ctx.getSharedFlags()
  486. // Share flags only when there are multiple files or tidy rules.
  487. var hasMultipleRules = len(srcFiles) > 1 || flags.tidy
  488. var shareFlags = func(kind string, flags string) string {
  489. if !hasMultipleRules || len(flags) < 60 {
  490. // Modules have long names and so do the module variables.
  491. // It does not save space by replacing a short name with a long one.
  492. return flags
  493. }
  494. mapKey := kind + flags
  495. n, ok := shared.flagsMap[mapKey]
  496. if !ok {
  497. shared.numSharedFlags += 1
  498. n = strconv.Itoa(shared.numSharedFlags)
  499. shared.flagsMap[mapKey] = n
  500. ctx.Variable(pctx, kind+n, flags)
  501. }
  502. return "$" + kind + n
  503. }
  504. for i, srcFile := range srcFiles {
  505. objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
  506. objFiles[i] = objFile
  507. // Register compilation build statements. The actual rule used depends on the source file type.
  508. switch srcFile.Ext() {
  509. case ".asm":
  510. ctx.Build(pctx, android.BuildParams{
  511. Rule: yasm,
  512. Description: "yasm " + srcFile.Rel(),
  513. Output: objFile,
  514. Input: srcFile,
  515. Implicits: cFlagsDeps,
  516. OrderOnly: pathDeps,
  517. Args: map[string]string{
  518. "asFlags": shareFlags("asFlags", flags.globalYasmFlags+" "+flags.localYasmFlags),
  519. },
  520. })
  521. continue
  522. case ".o":
  523. objFiles[i] = srcFile
  524. continue
  525. }
  526. var moduleFlags string
  527. var moduleToolingFlags string
  528. var ccCmd string
  529. tidy := flags.tidy
  530. coverage := flags.gcovCoverage
  531. dump := flags.sAbiDump
  532. rule := cc
  533. emitXref := flags.emitXrefs
  534. switch srcFile.Ext() {
  535. case ".s":
  536. if !flags.assemblerWithCpp {
  537. rule = ccNoDeps
  538. }
  539. fallthrough
  540. case ".S":
  541. ccCmd = "clang"
  542. moduleFlags = asflags
  543. tidy = false
  544. coverage = false
  545. dump = false
  546. emitXref = false
  547. case ".c":
  548. ccCmd = "clang"
  549. moduleFlags = cflags
  550. moduleToolingFlags = toolingCflags
  551. case ".cpp", ".cc", ".cxx", ".mm":
  552. ccCmd = "clang++"
  553. moduleFlags = cppflags
  554. moduleToolingFlags = toolingCppflags
  555. case ".h", ".hpp":
  556. ctx.PropertyErrorf("srcs", "Header file %s is not supported, instead use export_include_dirs or local_include_dirs.", srcFile)
  557. continue
  558. default:
  559. ctx.PropertyErrorf("srcs", "File %s has unknown extension. Supported extensions: .s, .S, .c, .cpp, .cc, .cxx, .mm", srcFile)
  560. continue
  561. }
  562. // ccCmd is "clang" or "clang++"
  563. ccDesc := ccCmd
  564. ccCmd = "${config.ClangBin}/" + ccCmd
  565. var implicitOutputs android.WritablePaths
  566. if coverage {
  567. gcnoFile := android.ObjPathWithExt(ctx, subdir, srcFile, "gcno")
  568. implicitOutputs = append(implicitOutputs, gcnoFile)
  569. coverageFiles = append(coverageFiles, gcnoFile)
  570. }
  571. ctx.Build(pctx, android.BuildParams{
  572. Rule: rule,
  573. Description: ccDesc + " " + srcFile.Rel(),
  574. Output: objFile,
  575. ImplicitOutputs: implicitOutputs,
  576. Input: srcFile,
  577. Implicits: cFlagsDeps,
  578. OrderOnly: pathDeps,
  579. Args: map[string]string{
  580. "cFlags": shareFlags("cFlags", moduleFlags),
  581. "ccCmd": ccCmd, // short and not shared
  582. },
  583. })
  584. // Register post-process build statements (such as for tidy or kythe).
  585. if emitXref {
  586. kytheFile := android.ObjPathWithExt(ctx, subdir, srcFile, "kzip")
  587. ctx.Build(pctx, android.BuildParams{
  588. Rule: kytheExtract,
  589. Description: "Xref C++ extractor " + srcFile.Rel(),
  590. Output: kytheFile,
  591. Input: srcFile,
  592. Implicits: cFlagsDeps,
  593. OrderOnly: pathDeps,
  594. Args: map[string]string{
  595. "cFlags": shareFlags("cFlags", moduleFlags),
  596. },
  597. })
  598. kytheFiles = append(kytheFiles, kytheFile)
  599. }
  600. // Even with tidy, some src file could be skipped by noTidySrcsMap.
  601. if tidy && !noTidySrcsMap[srcFile.String()] {
  602. tidyFile := android.ObjPathWithExt(ctx, subdir, srcFile, "tidy")
  603. tidyFiles = append(tidyFiles, tidyFile)
  604. tidyCmd := "${config.ClangBin}/clang-tidy"
  605. rule := clangTidy
  606. reducedCFlags := moduleFlags
  607. if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CLANG_TIDY") {
  608. rule = clangTidyRE
  609. // b/248371171, work around RBE input processor problem
  610. // some cflags rejected by input processor, but usually
  611. // do not affect included files or clang-tidy
  612. reducedCFlags = config.TidyReduceCFlags(reducedCFlags)
  613. }
  614. sharedCFlags := shareFlags("cFlags", reducedCFlags)
  615. srcRelPath := srcFile.Rel()
  616. // Add the .tidy rule
  617. ctx.Build(pctx, android.BuildParams{
  618. Rule: rule,
  619. Description: "clang-tidy " + srcRelPath,
  620. Output: tidyFile,
  621. Input: srcFile,
  622. Implicits: cFlagsDeps,
  623. OrderOnly: pathDeps,
  624. Args: map[string]string{
  625. "cFlags": sharedCFlags,
  626. "ccCmd": ccCmd,
  627. "clangCmd": ccDesc,
  628. "tidyCmd": tidyCmd,
  629. "tidyFlags": shareFlags("tidyFlags", config.TidyFlagsForSrcFile(srcFile, flags.tidyFlags)),
  630. "tidyVars": tidyVars, // short and not shared
  631. },
  632. })
  633. }
  634. if dump {
  635. sAbiDumpFile := android.ObjPathWithExt(ctx, subdir, srcFile, "sdump")
  636. sAbiDumpFiles = append(sAbiDumpFiles, sAbiDumpFile)
  637. dumpRule := sAbiDump
  638. if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ABI_DUMPER") {
  639. dumpRule = sAbiDumpRE
  640. }
  641. ctx.Build(pctx, android.BuildParams{
  642. Rule: dumpRule,
  643. Description: "header-abi-dumper " + srcFile.Rel(),
  644. Output: sAbiDumpFile,
  645. Input: srcFile,
  646. Implicit: objFile,
  647. Implicits: cFlagsDeps,
  648. OrderOnly: pathDeps,
  649. Args: map[string]string{
  650. "cFlags": shareFlags("cFlags", moduleToolingFlags),
  651. "exportDirs": shareFlags("exportDirs", flags.sAbiFlags),
  652. },
  653. })
  654. }
  655. }
  656. var tidyDepFiles android.Paths
  657. if flags.needTidyFiles {
  658. tidyDepFiles = tidyFiles
  659. }
  660. return Objects{
  661. objFiles: objFiles,
  662. tidyFiles: tidyFiles,
  663. tidyDepFiles: tidyDepFiles,
  664. coverageFiles: coverageFiles,
  665. sAbiDumpFiles: sAbiDumpFiles,
  666. kytheFiles: kytheFiles,
  667. }
  668. }
  669. // Generate a rule for compiling multiple .o files to a static library (.a)
  670. func transformObjToStaticLib(ctx android.ModuleContext,
  671. objFiles android.Paths, wholeStaticLibs android.Paths,
  672. flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths, validations android.Paths) {
  673. arCmd := "${config.ClangBin}/llvm-ar"
  674. arFlags := ""
  675. if !ctx.Darwin() {
  676. arFlags += " --format=gnu"
  677. }
  678. if len(wholeStaticLibs) == 0 {
  679. ctx.Build(pctx, android.BuildParams{
  680. Rule: ar,
  681. Description: "static link " + outputFile.Base(),
  682. Output: outputFile,
  683. Inputs: objFiles,
  684. Implicits: deps,
  685. Validations: validations,
  686. Args: map[string]string{
  687. "arFlags": "crsPD" + arFlags,
  688. "arCmd": arCmd,
  689. },
  690. })
  691. } else {
  692. ctx.Build(pctx, android.BuildParams{
  693. Rule: arWithLibs,
  694. Description: "static link " + outputFile.Base(),
  695. Output: outputFile,
  696. Inputs: append(objFiles, wholeStaticLibs...),
  697. Implicits: deps,
  698. Args: map[string]string{
  699. "arCmd": arCmd,
  700. "arObjFlags": "crsPD" + arFlags,
  701. "arObjs": strings.Join(objFiles.Strings(), " "),
  702. "arLibFlags": "cqsL" + arFlags,
  703. "arLibs": strings.Join(wholeStaticLibs.Strings(), " "),
  704. },
  705. })
  706. }
  707. }
  708. // Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
  709. // and shared libraries, to a shared library (.so) or dynamic executable
  710. func transformObjToDynamicBinary(ctx android.ModuleContext,
  711. objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps, crtBegin, crtEnd android.Paths,
  712. groupLate bool, flags builderFlags, outputFile android.WritablePath,
  713. implicitOutputs android.WritablePaths, validations android.Paths) {
  714. ldCmd := "${config.ClangBin}/clang++"
  715. var libFlagsList []string
  716. if len(flags.libFlags) > 0 {
  717. libFlagsList = append(libFlagsList, flags.libFlags)
  718. }
  719. if len(wholeStaticLibs) > 0 {
  720. if ctx.Host() && ctx.Darwin() {
  721. libFlagsList = append(libFlagsList, android.JoinWithPrefix(wholeStaticLibs.Strings(), "-force_load "))
  722. } else {
  723. libFlagsList = append(libFlagsList, "-Wl,--whole-archive ")
  724. libFlagsList = append(libFlagsList, wholeStaticLibs.Strings()...)
  725. libFlagsList = append(libFlagsList, "-Wl,--no-whole-archive ")
  726. }
  727. }
  728. libFlagsList = append(libFlagsList, staticLibs.Strings()...)
  729. if groupLate && !ctx.Darwin() && len(lateStaticLibs) > 0 {
  730. libFlagsList = append(libFlagsList, "-Wl,--start-group")
  731. }
  732. libFlagsList = append(libFlagsList, lateStaticLibs.Strings()...)
  733. if groupLate && !ctx.Darwin() && len(lateStaticLibs) > 0 {
  734. libFlagsList = append(libFlagsList, "-Wl,--end-group")
  735. }
  736. for _, lib := range sharedLibs {
  737. libFile := lib.String()
  738. if ctx.Windows() {
  739. libFile = pathtools.ReplaceExtension(libFile, "lib")
  740. }
  741. libFlagsList = append(libFlagsList, libFile)
  742. }
  743. deps = append(deps, staticLibs...)
  744. deps = append(deps, lateStaticLibs...)
  745. deps = append(deps, wholeStaticLibs...)
  746. deps = append(deps, crtBegin...)
  747. deps = append(deps, crtEnd...)
  748. rule := ld
  749. args := map[string]string{
  750. "ldCmd": ldCmd,
  751. "crtBegin": strings.Join(crtBegin.Strings(), " "),
  752. "libFlags": strings.Join(libFlagsList, " "),
  753. "extraLibFlags": flags.extraLibFlags,
  754. "ldFlags": flags.globalLdFlags + " " + flags.localLdFlags,
  755. "crtEnd": strings.Join(crtEnd.Strings(), " "),
  756. }
  757. if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
  758. rule = ldRE
  759. args["implicitOutputs"] = strings.Join(implicitOutputs.Strings(), ",")
  760. args["implicitInputs"] = strings.Join(deps.Strings(), ",")
  761. }
  762. ctx.Build(pctx, android.BuildParams{
  763. Rule: rule,
  764. Description: "link " + outputFile.Base(),
  765. Output: outputFile,
  766. ImplicitOutputs: implicitOutputs,
  767. Inputs: objFiles,
  768. Implicits: deps,
  769. OrderOnly: sharedLibs,
  770. Validations: validations,
  771. Args: args,
  772. })
  773. }
  774. // Generate a rule to combine .dump sAbi dump files from multiple source files
  775. // into a single .ldump sAbi dump file
  776. func transformDumpToLinkedDump(ctx android.ModuleContext, sAbiDumps android.Paths, soFile android.Path,
  777. baseName, exportedHeaderFlags string, symbolFile android.OptionalPath,
  778. excludedSymbolVersions, excludedSymbolTags []string) android.OptionalPath {
  779. outputFile := android.PathForModuleOut(ctx, baseName+".lsdump")
  780. implicits := android.Paths{soFile}
  781. symbolFilterStr := "-so " + soFile.String()
  782. if symbolFile.Valid() {
  783. implicits = append(implicits, symbolFile.Path())
  784. symbolFilterStr += " -v " + symbolFile.String()
  785. }
  786. for _, ver := range excludedSymbolVersions {
  787. symbolFilterStr += " --exclude-symbol-version " + ver
  788. }
  789. for _, tag := range excludedSymbolTags {
  790. symbolFilterStr += " --exclude-symbol-tag " + tag
  791. }
  792. rule := sAbiLink
  793. args := map[string]string{
  794. "symbolFilter": symbolFilterStr,
  795. "arch": ctx.Arch().ArchType.Name,
  796. "exportedHeaderFlags": exportedHeaderFlags,
  797. }
  798. if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ABI_LINKER") {
  799. rule = sAbiLinkRE
  800. rbeImplicits := implicits.Strings()
  801. for _, p := range strings.Split(exportedHeaderFlags, " ") {
  802. if len(p) > 2 {
  803. // Exclude the -I prefix.
  804. rbeImplicits = append(rbeImplicits, p[2:])
  805. }
  806. }
  807. args["implicitInputs"] = strings.Join(rbeImplicits, ",")
  808. }
  809. ctx.Build(pctx, android.BuildParams{
  810. Rule: rule,
  811. Description: "header-abi-linker " + outputFile.Base(),
  812. Output: outputFile,
  813. Inputs: sAbiDumps,
  814. Implicits: implicits,
  815. Args: args,
  816. })
  817. return android.OptionalPathForPath(outputFile)
  818. }
  819. func transformAbiDumpToAbiDiff(ctx android.ModuleContext, inputDump, referenceDump android.Path,
  820. baseName, nameExt string, extraFlags []string, errorMessage string) android.Path {
  821. var outputFile android.ModuleOutPath
  822. if nameExt != "" {
  823. outputFile = android.PathForModuleOut(ctx, baseName+"."+nameExt+".abidiff")
  824. } else {
  825. outputFile = android.PathForModuleOut(ctx, baseName+".abidiff")
  826. }
  827. libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
  828. ctx.Build(pctx, android.BuildParams{
  829. Rule: sAbiDiff,
  830. Description: "header-abi-diff " + outputFile.Base(),
  831. Output: outputFile,
  832. Input: inputDump,
  833. Implicit: referenceDump,
  834. Args: map[string]string{
  835. "referenceDump": referenceDump.String(),
  836. "libName": libName,
  837. "arch": ctx.Arch().ArchType.Name,
  838. "extraFlags": strings.Join(extraFlags, " "),
  839. "errorMessage": errorMessage,
  840. },
  841. })
  842. return outputFile
  843. }
  844. // Generate a rule for extracting a table of contents from a shared library (.so)
  845. func TransformSharedObjectToToc(ctx android.ModuleContext, inputFile android.Path, outputFile android.WritablePath) {
  846. var format string
  847. if ctx.Darwin() {
  848. format = "--macho"
  849. } else if ctx.Windows() {
  850. format = "--pe"
  851. } else {
  852. format = "--elf"
  853. }
  854. ctx.Build(pctx, android.BuildParams{
  855. Rule: toc,
  856. Description: "generate toc " + inputFile.Base(),
  857. Output: outputFile,
  858. Input: inputFile,
  859. Args: map[string]string{
  860. "clangBin": "${config.ClangBin}",
  861. "format": format,
  862. },
  863. })
  864. }
  865. // Generate a rule for compiling multiple .o files to a .o using ld partial linking
  866. func transformObjsToObj(ctx android.ModuleContext, objFiles android.Paths,
  867. flags builderFlags, outputFile android.WritablePath, deps android.Paths) {
  868. ldCmd := "${config.ClangBin}/clang++"
  869. rule := partialLd
  870. args := map[string]string{
  871. "ldCmd": ldCmd,
  872. "ldFlags": flags.globalLdFlags + " " + flags.localLdFlags,
  873. }
  874. if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
  875. rule = partialLdRE
  876. args["inCommaList"] = strings.Join(objFiles.Strings(), ",")
  877. args["implicitInputs"] = strings.Join(deps.Strings(), ",")
  878. }
  879. ctx.Build(pctx, android.BuildParams{
  880. Rule: rule,
  881. Description: "link " + outputFile.Base(),
  882. Output: outputFile,
  883. Inputs: objFiles,
  884. Implicits: deps,
  885. Args: args,
  886. })
  887. }
  888. // Generate a rule for running objcopy --prefix-symbols on a binary
  889. func transformBinaryPrefixSymbols(ctx android.ModuleContext, prefix string, inputFile android.Path,
  890. flags builderFlags, outputFile android.WritablePath) {
  891. objcopyCmd := "${config.ClangBin}/llvm-objcopy"
  892. ctx.Build(pctx, android.BuildParams{
  893. Rule: prefixSymbols,
  894. Description: "prefix symbols " + outputFile.Base(),
  895. Output: outputFile,
  896. Input: inputFile,
  897. Args: map[string]string{
  898. "objcopyCmd": objcopyCmd,
  899. "prefix": prefix,
  900. },
  901. })
  902. }
  903. // Generate a rule for running objcopy --remove-section=.llvm_addrsig on a partially linked object
  904. func transformObjectNoAddrSig(ctx android.ModuleContext, inputFile android.Path, outputFile android.WritablePath) {
  905. objcopyCmd := "${config.ClangBin}/llvm-objcopy"
  906. ctx.Build(pctx, android.BuildParams{
  907. Rule: noAddrSig,
  908. Description: "remove addrsig " + outputFile.Base(),
  909. Output: outputFile,
  910. Input: inputFile,
  911. Args: map[string]string{
  912. "objcopyCmd": objcopyCmd,
  913. },
  914. })
  915. }
  916. // Registers a build statement to invoke `strip` (to discard symbols and data from object files).
  917. func transformStrip(ctx android.ModuleContext, inputFile android.Path,
  918. outputFile android.WritablePath, flags StripFlags) {
  919. args := ""
  920. if flags.StripAddGnuDebuglink {
  921. args += " --add-gnu-debuglink"
  922. }
  923. if flags.StripKeepMiniDebugInfo {
  924. args += " --keep-mini-debug-info"
  925. }
  926. if flags.StripKeepSymbols {
  927. args += " --keep-symbols"
  928. }
  929. if flags.StripKeepSymbolsList != "" {
  930. args += " -k" + flags.StripKeepSymbolsList
  931. }
  932. if flags.StripKeepSymbolsAndDebugFrame {
  933. args += " --keep-symbols-and-debug-frame"
  934. }
  935. ctx.Build(pctx, android.BuildParams{
  936. Rule: strip,
  937. Description: "strip " + outputFile.Base(),
  938. Output: outputFile,
  939. Input: inputFile,
  940. Args: map[string]string{
  941. "args": args,
  942. },
  943. })
  944. }
  945. // Registers build statement to invoke `strip` on darwin architecture.
  946. func transformDarwinStrip(ctx android.ModuleContext, inputFile android.Path,
  947. outputFile android.WritablePath) {
  948. ctx.Build(pctx, android.BuildParams{
  949. Rule: darwinStrip,
  950. Description: "strip " + outputFile.Base(),
  951. Output: outputFile,
  952. Input: inputFile,
  953. })
  954. }
  955. func transformDarwinUniversalBinary(ctx android.ModuleContext, outputFile android.WritablePath, inputFiles ...android.Path) {
  956. ctx.Build(pctx, android.BuildParams{
  957. Rule: darwinLipo,
  958. Description: "lipo " + outputFile.Base(),
  959. Output: outputFile,
  960. Inputs: inputFiles,
  961. })
  962. }
  963. // Registers build statement to zip one or more coverage files.
  964. func transformCoverageFilesToZip(ctx android.ModuleContext,
  965. inputs Objects, baseName string) android.OptionalPath {
  966. if len(inputs.coverageFiles) > 0 {
  967. outputFile := android.PathForModuleOut(ctx, baseName+".zip")
  968. ctx.Build(pctx, android.BuildParams{
  969. Rule: zip,
  970. Description: "zip " + outputFile.Base(),
  971. Inputs: inputs.coverageFiles,
  972. Output: outputFile,
  973. })
  974. return android.OptionalPathForPath(outputFile)
  975. }
  976. return android.OptionalPath{}
  977. }
  978. // Rule to repack an archive (.a) file with a subset of object files.
  979. func transformArchiveRepack(ctx android.ModuleContext, inputFile android.Path,
  980. outputFile android.WritablePath, objects []string) {
  981. ctx.Build(pctx, android.BuildParams{
  982. Rule: archiveRepack,
  983. Description: "Repack archive " + outputFile.Base(),
  984. Output: outputFile,
  985. Input: inputFile,
  986. Args: map[string]string{
  987. "objects": strings.Join(objects, " "),
  988. },
  989. })
  990. }