androidmk.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  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. // This file offers AndroidMkEntriesProvider, which individual modules implement to output
  15. // Android.mk entries that contain information about the modules built through Soong. Kati reads
  16. // and combines them with the legacy Make-based module definitions to produce the complete view of
  17. // the source tree, which makes this a critical point of Make-Soong interoperability.
  18. //
  19. // Naturally, Soong-only builds do not rely on this mechanism.
  20. package android
  21. import (
  22. "bytes"
  23. "fmt"
  24. "io"
  25. "os"
  26. "path/filepath"
  27. "reflect"
  28. "runtime"
  29. "sort"
  30. "strings"
  31. "github.com/google/blueprint"
  32. "github.com/google/blueprint/bootstrap"
  33. "github.com/google/blueprint/pathtools"
  34. )
  35. func init() {
  36. RegisterAndroidMkBuildComponents(InitRegistrationContext)
  37. }
  38. func RegisterAndroidMkBuildComponents(ctx RegistrationContext) {
  39. ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
  40. }
  41. // Enable androidmk support.
  42. // * Register the singleton
  43. // * Configure that we are inside make
  44. var PrepareForTestWithAndroidMk = GroupFixturePreparers(
  45. FixtureRegisterWithContext(RegisterAndroidMkBuildComponents),
  46. FixtureModifyConfig(SetKatiEnabledForTests),
  47. )
  48. // Deprecated: Use AndroidMkEntriesProvider instead, especially if you're not going to use the
  49. // Custom function. It's easier to use and test.
  50. type AndroidMkDataProvider interface {
  51. AndroidMk() AndroidMkData
  52. BaseModuleName() string
  53. }
  54. type AndroidMkData struct {
  55. Class string
  56. SubName string
  57. DistFiles TaggedDistFiles
  58. OutputFile OptionalPath
  59. Disabled bool
  60. Include string
  61. Required []string
  62. Host_required []string
  63. Target_required []string
  64. Custom func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData)
  65. Extra []AndroidMkExtraFunc
  66. Entries AndroidMkEntries
  67. }
  68. type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
  69. // Interface for modules to declare their Android.mk outputs. Note that every module needs to
  70. // implement this in order to be included in the final Android-<product_name>.mk output, even if
  71. // they only need to output the common set of entries without any customizations.
  72. type AndroidMkEntriesProvider interface {
  73. // Returns AndroidMkEntries objects that contain all basic info plus extra customization data
  74. // if needed. This is the core func to implement.
  75. // Note that one can return multiple objects. For example, java_library may return an additional
  76. // AndroidMkEntries object for its hostdex sub-module.
  77. AndroidMkEntries() []AndroidMkEntries
  78. // Modules don't need to implement this as it's already implemented by ModuleBase.
  79. // AndroidMkEntries uses BaseModuleName() instead of ModuleName() because certain modules
  80. // e.g. Prebuilts, override the Name() func and return modified names.
  81. // If a different name is preferred, use SubName or OverrideName in AndroidMkEntries.
  82. BaseModuleName() string
  83. }
  84. // The core data struct that modules use to provide their Android.mk data.
  85. type AndroidMkEntries struct {
  86. // Android.mk class string, e.g EXECUTABLES, JAVA_LIBRARIES, ETC
  87. Class string
  88. // Optional suffix to append to the module name. Useful when a module wants to return multiple
  89. // AndroidMkEntries objects. For example, when a java_library returns an additional entry for
  90. // its hostdex sub-module, this SubName field is set to "-hostdex" so that it can have a
  91. // different name than the parent's.
  92. SubName string
  93. // If set, this value overrides the base module name. SubName is still appended.
  94. OverrideName string
  95. // Dist files to output
  96. DistFiles TaggedDistFiles
  97. // The output file for Kati to process and/or install. If absent, the module is skipped.
  98. OutputFile OptionalPath
  99. // If true, the module is skipped and does not appear on the final Android-<product name>.mk
  100. // file. Useful when a module needs to be skipped conditionally.
  101. Disabled bool
  102. // The postprocessing mk file to include, e.g. $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk
  103. // If not set, $(BUILD_SYSTEM)/prebuilt.mk is used.
  104. Include string
  105. // Required modules that need to be built and included in the final build output when building
  106. // this module.
  107. Required []string
  108. // Required host modules that need to be built and included in the final build output when
  109. // building this module.
  110. Host_required []string
  111. // Required device modules that need to be built and included in the final build output when
  112. // building this module.
  113. Target_required []string
  114. header bytes.Buffer
  115. footer bytes.Buffer
  116. // Funcs to append additional Android.mk entries or modify the common ones. Multiple funcs are
  117. // accepted so that common logic can be factored out as a shared func.
  118. ExtraEntries []AndroidMkExtraEntriesFunc
  119. // Funcs to add extra lines to the module's Android.mk output. Unlike AndroidMkExtraEntriesFunc,
  120. // which simply sets Make variable values, this can be used for anything since it can write any
  121. // Make statements directly to the final Android-*.mk file.
  122. // Primarily used to call macros or declare/update Make targets.
  123. ExtraFooters []AndroidMkExtraFootersFunc
  124. // A map that holds the up-to-date Make variable values. Can be accessed from tests.
  125. EntryMap map[string][]string
  126. // A list of EntryMap keys in insertion order. This serves a few purposes:
  127. // 1. Prevents churns. Golang map doesn't provide consistent iteration order, so without this,
  128. // the outputted Android-*.mk file may change even though there have been no content changes.
  129. // 2. Allows modules to refer to other variables, like LOCAL_BAR_VAR := $(LOCAL_FOO_VAR),
  130. // without worrying about the variables being mixed up in the actual mk file.
  131. // 3. Makes troubleshooting and spotting errors easier.
  132. entryOrder []string
  133. }
  134. type AndroidMkExtraEntriesContext interface {
  135. Provider(provider blueprint.ProviderKey) interface{}
  136. }
  137. type androidMkExtraEntriesContext struct {
  138. ctx fillInEntriesContext
  139. mod blueprint.Module
  140. }
  141. func (a *androidMkExtraEntriesContext) Provider(provider blueprint.ProviderKey) interface{} {
  142. return a.ctx.ModuleProvider(a.mod, provider)
  143. }
  144. type AndroidMkExtraEntriesFunc func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries)
  145. type AndroidMkExtraFootersFunc func(w io.Writer, name, prefix, moduleDir string)
  146. // Utility funcs to manipulate Android.mk variable entries.
  147. // SetString sets a Make variable with the given name to the given value.
  148. func (a *AndroidMkEntries) SetString(name, value string) {
  149. if _, ok := a.EntryMap[name]; !ok {
  150. a.entryOrder = append(a.entryOrder, name)
  151. }
  152. a.EntryMap[name] = []string{value}
  153. }
  154. // SetPath sets a Make variable with the given name to the given path string.
  155. func (a *AndroidMkEntries) SetPath(name string, path Path) {
  156. if _, ok := a.EntryMap[name]; !ok {
  157. a.entryOrder = append(a.entryOrder, name)
  158. }
  159. a.EntryMap[name] = []string{path.String()}
  160. }
  161. // SetOptionalPath sets a Make variable with the given name to the given path string if it is valid.
  162. // It is a no-op if the given path is invalid.
  163. func (a *AndroidMkEntries) SetOptionalPath(name string, path OptionalPath) {
  164. if path.Valid() {
  165. a.SetPath(name, path.Path())
  166. }
  167. }
  168. // AddPath appends the given path string to a Make variable with the given name.
  169. func (a *AndroidMkEntries) AddPath(name string, path Path) {
  170. if _, ok := a.EntryMap[name]; !ok {
  171. a.entryOrder = append(a.entryOrder, name)
  172. }
  173. a.EntryMap[name] = append(a.EntryMap[name], path.String())
  174. }
  175. // AddOptionalPath appends the given path string to a Make variable with the given name if it is
  176. // valid. It is a no-op if the given path is invalid.
  177. func (a *AndroidMkEntries) AddOptionalPath(name string, path OptionalPath) {
  178. if path.Valid() {
  179. a.AddPath(name, path.Path())
  180. }
  181. }
  182. // SetPaths sets a Make variable with the given name to a slice of the given path strings.
  183. func (a *AndroidMkEntries) SetPaths(name string, paths Paths) {
  184. if _, ok := a.EntryMap[name]; !ok {
  185. a.entryOrder = append(a.entryOrder, name)
  186. }
  187. a.EntryMap[name] = paths.Strings()
  188. }
  189. // SetOptionalPaths sets a Make variable with the given name to a slice of the given path strings
  190. // only if there are a non-zero amount of paths.
  191. func (a *AndroidMkEntries) SetOptionalPaths(name string, paths Paths) {
  192. if len(paths) > 0 {
  193. a.SetPaths(name, paths)
  194. }
  195. }
  196. // AddPaths appends the given path strings to a Make variable with the given name.
  197. func (a *AndroidMkEntries) AddPaths(name string, paths Paths) {
  198. if _, ok := a.EntryMap[name]; !ok {
  199. a.entryOrder = append(a.entryOrder, name)
  200. }
  201. a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
  202. }
  203. // SetBoolIfTrue sets a Make variable with the given name to true if the given flag is true.
  204. // It is a no-op if the given flag is false.
  205. func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
  206. if flag {
  207. if _, ok := a.EntryMap[name]; !ok {
  208. a.entryOrder = append(a.entryOrder, name)
  209. }
  210. a.EntryMap[name] = []string{"true"}
  211. }
  212. }
  213. // SetBool sets a Make variable with the given name to if the given bool flag value.
  214. func (a *AndroidMkEntries) SetBool(name string, flag bool) {
  215. if _, ok := a.EntryMap[name]; !ok {
  216. a.entryOrder = append(a.entryOrder, name)
  217. }
  218. if flag {
  219. a.EntryMap[name] = []string{"true"}
  220. } else {
  221. a.EntryMap[name] = []string{"false"}
  222. }
  223. }
  224. // AddStrings appends the given strings to a Make variable with the given name.
  225. func (a *AndroidMkEntries) AddStrings(name string, value ...string) {
  226. if len(value) == 0 {
  227. return
  228. }
  229. if _, ok := a.EntryMap[name]; !ok {
  230. a.entryOrder = append(a.entryOrder, name)
  231. }
  232. a.EntryMap[name] = append(a.EntryMap[name], value...)
  233. }
  234. // AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling
  235. // for partial MTS test suites.
  236. func (a *AndroidMkEntries) AddCompatibilityTestSuites(suites ...string) {
  237. // MTS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
  238. // To reduce repetition, if we find a partial MTS test suite without an full MTS test suite,
  239. // we add the full test suite to our list.
  240. if PrefixInList(suites, "mts-") && !InList("mts", suites) {
  241. suites = append(suites, "mts")
  242. }
  243. a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
  244. }
  245. // The contributions to the dist.
  246. type distContributions struct {
  247. // List of goals and the dist copy instructions.
  248. copiesForGoals []*copiesForGoals
  249. }
  250. // getCopiesForGoals returns a copiesForGoals into which copy instructions that
  251. // must be processed when building one or more of those goals can be added.
  252. func (d *distContributions) getCopiesForGoals(goals string) *copiesForGoals {
  253. copiesForGoals := &copiesForGoals{goals: goals}
  254. d.copiesForGoals = append(d.copiesForGoals, copiesForGoals)
  255. return copiesForGoals
  256. }
  257. // Associates a list of dist copy instructions with a set of goals for which they
  258. // should be run.
  259. type copiesForGoals struct {
  260. // goals are a space separated list of build targets that will trigger the
  261. // copy instructions.
  262. goals string
  263. // A list of instructions to copy a module's output files to somewhere in the
  264. // dist directory.
  265. copies []distCopy
  266. }
  267. // Adds a copy instruction.
  268. func (d *copiesForGoals) addCopyInstruction(from Path, dest string) {
  269. d.copies = append(d.copies, distCopy{from, dest})
  270. }
  271. // Instruction on a path that must be copied into the dist.
  272. type distCopy struct {
  273. // The path to copy from.
  274. from Path
  275. // The destination within the dist directory to copy to.
  276. dest string
  277. }
  278. // Compute the contributions that the module makes to the dist.
  279. func (a *AndroidMkEntries) getDistContributions(mod blueprint.Module) *distContributions {
  280. amod := mod.(Module).base()
  281. name := amod.BaseModuleName()
  282. // Collate the set of associated tag/paths available for copying to the dist.
  283. // Start with an empty (nil) set.
  284. var availableTaggedDists TaggedDistFiles
  285. // Then merge in any that are provided explicitly by the module.
  286. if a.DistFiles != nil {
  287. // Merge the DistFiles into the set.
  288. availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
  289. }
  290. // If no paths have been provided for the DefaultDistTag and the output file is
  291. // valid then add that as the default dist path.
  292. if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
  293. availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
  294. }
  295. // If the distFiles created by GenerateTaggedDistFiles contains paths for the
  296. // DefaultDistTag then that takes priority so delete any existing paths.
  297. if _, ok := amod.distFiles[DefaultDistTag]; ok {
  298. delete(availableTaggedDists, DefaultDistTag)
  299. }
  300. // Finally, merge the distFiles created by GenerateTaggedDistFiles.
  301. availableTaggedDists = availableTaggedDists.merge(amod.distFiles)
  302. if len(availableTaggedDists) == 0 {
  303. // Nothing dist-able for this module.
  304. return nil
  305. }
  306. // Collate the contributions this module makes to the dist.
  307. distContributions := &distContributions{}
  308. // Iterate over this module's dist structs, merged from the dist and dists properties.
  309. for _, dist := range amod.Dists() {
  310. // Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
  311. goals := strings.Join(dist.Targets, " ")
  312. // Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
  313. var tag string
  314. if dist.Tag == nil {
  315. // If the dist struct does not specify a tag, use the default output files tag.
  316. tag = DefaultDistTag
  317. } else {
  318. tag = *dist.Tag
  319. }
  320. // Get the paths of the output files to be dist'd, represented by the tag.
  321. // Can be an empty list.
  322. tagPaths := availableTaggedDists[tag]
  323. if len(tagPaths) == 0 {
  324. // Nothing to dist for this tag, continue to the next dist.
  325. continue
  326. }
  327. if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
  328. errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
  329. "file for %q goals tag %q in module %s. The list of dist files, " +
  330. "which should have a single element, is:\n%s"
  331. panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
  332. }
  333. copiesForGoals := distContributions.getCopiesForGoals(goals)
  334. // Iterate over each path adding a copy instruction to copiesForGoals
  335. for _, path := range tagPaths {
  336. // It's possible that the Path is nil from errant modules. Be defensive here.
  337. if path == nil {
  338. tagName := "default" // for error message readability
  339. if dist.Tag != nil {
  340. tagName = *dist.Tag
  341. }
  342. panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
  343. }
  344. dest := filepath.Base(path.String())
  345. if dist.Dest != nil {
  346. var err error
  347. if dest, err = validateSafePath(*dist.Dest); err != nil {
  348. // This was checked in ModuleBase.GenerateBuildActions
  349. panic(err)
  350. }
  351. }
  352. if dist.Suffix != nil {
  353. ext := filepath.Ext(dest)
  354. suffix := *dist.Suffix
  355. dest = strings.TrimSuffix(dest, ext) + suffix + ext
  356. }
  357. if dist.Dir != nil {
  358. var err error
  359. if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
  360. // This was checked in ModuleBase.GenerateBuildActions
  361. panic(err)
  362. }
  363. }
  364. copiesForGoals.addCopyInstruction(path, dest)
  365. }
  366. }
  367. return distContributions
  368. }
  369. // generateDistContributionsForMake generates make rules that will generate the
  370. // dist according to the instructions in the supplied distContribution.
  371. func generateDistContributionsForMake(distContributions *distContributions) []string {
  372. var ret []string
  373. for _, d := range distContributions.copiesForGoals {
  374. ret = append(ret, fmt.Sprintf(".PHONY: %s\n", d.goals))
  375. // Create dist-for-goals calls for each of the copy instructions.
  376. for _, c := range d.copies {
  377. ret = append(
  378. ret,
  379. fmt.Sprintf("$(call dist-for-goals,%s,%s:%s)\n", d.goals, c.from.String(), c.dest))
  380. }
  381. }
  382. return ret
  383. }
  384. // Compute the list of Make strings to declare phony goals and dist-for-goals
  385. // calls from the module's dist and dists properties.
  386. func (a *AndroidMkEntries) GetDistForGoals(mod blueprint.Module) []string {
  387. distContributions := a.getDistContributions(mod)
  388. if distContributions == nil {
  389. return nil
  390. }
  391. return generateDistContributionsForMake(distContributions)
  392. }
  393. // Write the license variables to Make for AndroidMkData.Custom(..) methods that do not call WriteAndroidMkData(..)
  394. // It's required to propagate the license metadata even for module types that have non-standard interfaces to Make.
  395. func (a *AndroidMkEntries) WriteLicenseVariables(w io.Writer) {
  396. fmt.Fprintln(w, "LOCAL_LICENSE_KINDS :=", strings.Join(a.EntryMap["LOCAL_LICENSE_KINDS"], " "))
  397. fmt.Fprintln(w, "LOCAL_LICENSE_CONDITIONS :=", strings.Join(a.EntryMap["LOCAL_LICENSE_CONDITIONS"], " "))
  398. fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", strings.Join(a.EntryMap["LOCAL_NOTICE_FILE"], " "))
  399. if pn, ok := a.EntryMap["LOCAL_LICENSE_PACKAGE_NAME"]; ok {
  400. fmt.Fprintln(w, "LOCAL_LICENSE_PACKAGE_NAME :=", strings.Join(pn, " "))
  401. }
  402. }
  403. // fillInEntries goes through the common variable processing and calls the extra data funcs to
  404. // generate and fill in AndroidMkEntries's in-struct data, ready to be flushed to a file.
  405. type fillInEntriesContext interface {
  406. ModuleDir(module blueprint.Module) string
  407. Config() Config
  408. ModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{}
  409. ModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool
  410. }
  411. func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
  412. a.EntryMap = make(map[string][]string)
  413. amod := mod.(Module)
  414. base := amod.base()
  415. name := base.BaseModuleName()
  416. if a.OverrideName != "" {
  417. name = a.OverrideName
  418. }
  419. if a.Include == "" {
  420. a.Include = "$(BUILD_PREBUILT)"
  421. }
  422. a.Required = append(a.Required, amod.RequiredModuleNames()...)
  423. a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
  424. a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
  425. for _, distString := range a.GetDistForGoals(mod) {
  426. fmt.Fprintf(&a.header, distString)
  427. }
  428. fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS)")
  429. // Collect make variable assignment entries.
  430. a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
  431. a.SetString("LOCAL_MODULE", name+a.SubName)
  432. a.AddStrings("LOCAL_LICENSE_KINDS", base.commonProperties.Effective_license_kinds...)
  433. a.AddStrings("LOCAL_LICENSE_CONDITIONS", base.commonProperties.Effective_license_conditions...)
  434. a.AddStrings("LOCAL_NOTICE_FILE", base.commonProperties.Effective_license_text.Strings()...)
  435. // TODO(b/151177513): Does this code need to set LOCAL_MODULE_IS_CONTAINER ?
  436. if base.commonProperties.Effective_package_name != nil {
  437. a.SetString("LOCAL_LICENSE_PACKAGE_NAME", *base.commonProperties.Effective_package_name)
  438. } else if len(base.commonProperties.Effective_licenses) > 0 {
  439. a.SetString("LOCAL_LICENSE_PACKAGE_NAME", strings.Join(base.commonProperties.Effective_licenses, " "))
  440. }
  441. a.SetString("LOCAL_MODULE_CLASS", a.Class)
  442. a.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
  443. a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
  444. a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
  445. a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
  446. // If the install rule was generated by Soong tell Make about it.
  447. if len(base.katiInstalls) > 0 {
  448. // Assume the primary install file is last since it probably needs to depend on any other
  449. // installed files. If that is not the case we can add a method to specify the primary
  450. // installed file.
  451. a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", base.katiInstalls[len(base.katiInstalls)-1].to)
  452. a.SetString("LOCAL_SOONG_INSTALL_PAIRS", base.katiInstalls.BuiltInstalled())
  453. a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths())
  454. }
  455. if am, ok := mod.(ApexModule); ok {
  456. a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
  457. }
  458. archStr := base.Arch().ArchType.String()
  459. host := false
  460. switch base.Os().Class {
  461. case Host:
  462. if base.Target().HostCross {
  463. // Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
  464. if base.Arch().ArchType != Common {
  465. a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
  466. }
  467. } else {
  468. // Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
  469. if base.Arch().ArchType != Common {
  470. a.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
  471. }
  472. }
  473. host = true
  474. case Device:
  475. // Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
  476. if base.Arch().ArchType != Common {
  477. if base.Target().NativeBridge {
  478. hostArchStr := base.Target().NativeBridgeHostArchName
  479. if hostArchStr != "" {
  480. a.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
  481. }
  482. } else {
  483. a.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
  484. }
  485. }
  486. if !base.InRamdisk() && !base.InVendorRamdisk() {
  487. a.AddPaths("LOCAL_FULL_INIT_RC", base.initRcPaths)
  488. }
  489. if len(base.vintfFragmentsPaths) > 0 {
  490. a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", base.vintfFragmentsPaths)
  491. }
  492. a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
  493. if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
  494. a.SetString("LOCAL_VENDOR_MODULE", "true")
  495. }
  496. a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
  497. a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
  498. a.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
  499. if base.commonProperties.Owner != nil {
  500. a.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
  501. }
  502. }
  503. if len(base.noticeFiles) > 0 {
  504. a.SetString("LOCAL_NOTICE_FILE", strings.Join(base.noticeFiles.Strings(), " "))
  505. }
  506. if host {
  507. makeOs := base.Os().String()
  508. if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
  509. makeOs = "linux"
  510. }
  511. a.SetString("LOCAL_MODULE_HOST_OS", makeOs)
  512. a.SetString("LOCAL_IS_HOST_MODULE", "true")
  513. }
  514. prefix := ""
  515. if base.ArchSpecific() {
  516. switch base.Os().Class {
  517. case Host:
  518. if base.Target().HostCross {
  519. prefix = "HOST_CROSS_"
  520. } else {
  521. prefix = "HOST_"
  522. }
  523. case Device:
  524. prefix = "TARGET_"
  525. }
  526. if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
  527. prefix = "2ND_" + prefix
  528. }
  529. }
  530. if ctx.ModuleHasProvider(mod, LicenseMetadataProvider) {
  531. licenseMetadata := ctx.ModuleProvider(mod, LicenseMetadataProvider).(*LicenseMetadataInfo)
  532. a.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath)
  533. }
  534. extraCtx := &androidMkExtraEntriesContext{
  535. ctx: ctx,
  536. mod: mod,
  537. }
  538. for _, extra := range a.ExtraEntries {
  539. extra(extraCtx, a)
  540. }
  541. // Write to footer.
  542. fmt.Fprintln(&a.footer, "include "+a.Include)
  543. blueprintDir := ctx.ModuleDir(mod)
  544. for _, footerFunc := range a.ExtraFooters {
  545. footerFunc(&a.footer, name, prefix, blueprintDir)
  546. }
  547. }
  548. // write flushes the AndroidMkEntries's in-struct data populated by AndroidMkEntries into the
  549. // given Writer object.
  550. func (a *AndroidMkEntries) write(w io.Writer) {
  551. if a.Disabled {
  552. return
  553. }
  554. if !a.OutputFile.Valid() {
  555. return
  556. }
  557. w.Write(a.header.Bytes())
  558. for _, name := range a.entryOrder {
  559. fmt.Fprintln(w, name+" := "+strings.Join(a.EntryMap[name], " "))
  560. }
  561. w.Write(a.footer.Bytes())
  562. }
  563. func (a *AndroidMkEntries) FooterLinesForTests() []string {
  564. return strings.Split(string(a.footer.Bytes()), "\n")
  565. }
  566. // AndroidMkSingleton is a singleton to collect Android.mk data from all modules and dump them into
  567. // the final Android-<product_name>.mk file output.
  568. func AndroidMkSingleton() Singleton {
  569. return &androidMkSingleton{}
  570. }
  571. type androidMkSingleton struct{}
  572. func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
  573. // Skip if Soong wasn't invoked from Make.
  574. if !ctx.Config().KatiEnabled() {
  575. return
  576. }
  577. var androidMkModulesList []blueprint.Module
  578. ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
  579. androidMkModulesList = append(androidMkModulesList, module)
  580. })
  581. // Sort the module list by the module names to eliminate random churns, which may erroneously
  582. // invoke additional build processes.
  583. sort.SliceStable(androidMkModulesList, func(i, j int) bool {
  584. return ctx.ModuleName(androidMkModulesList[i]) < ctx.ModuleName(androidMkModulesList[j])
  585. })
  586. transMk := PathForOutput(ctx, "Android"+String(ctx.Config().productVariables.Make_suffix)+".mk")
  587. if ctx.Failed() {
  588. return
  589. }
  590. err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList)
  591. if err != nil {
  592. ctx.Errorf(err.Error())
  593. }
  594. ctx.Build(pctx, BuildParams{
  595. Rule: blueprint.Phony,
  596. Output: transMk,
  597. })
  598. }
  599. func translateAndroidMk(ctx SingletonContext, absMkFile string, mods []blueprint.Module) error {
  600. buf := &bytes.Buffer{}
  601. fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))")
  602. typeStats := make(map[string]int)
  603. for _, mod := range mods {
  604. err := translateAndroidMkModule(ctx, buf, mod)
  605. if err != nil {
  606. os.Remove(absMkFile)
  607. return err
  608. }
  609. if amod, ok := mod.(Module); ok && ctx.PrimaryModule(amod) == amod {
  610. typeStats[ctx.ModuleType(amod)] += 1
  611. }
  612. }
  613. keys := []string{}
  614. fmt.Fprintln(buf, "\nSTATS.SOONG_MODULE_TYPE :=")
  615. for k := range typeStats {
  616. keys = append(keys, k)
  617. }
  618. sort.Strings(keys)
  619. for _, mod_type := range keys {
  620. fmt.Fprintln(buf, "STATS.SOONG_MODULE_TYPE +=", mod_type)
  621. fmt.Fprintf(buf, "STATS.SOONG_MODULE_TYPE.%s := %d\n", mod_type, typeStats[mod_type])
  622. }
  623. return pathtools.WriteFileIfChanged(absMkFile, buf.Bytes(), 0666)
  624. }
  625. func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
  626. defer func() {
  627. if r := recover(); r != nil {
  628. panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s",
  629. r, ctx.ModuleName(mod), ctx.ModuleSubDir(mod)))
  630. }
  631. }()
  632. // Additional cases here require review for correct license propagation to make.
  633. switch x := mod.(type) {
  634. case AndroidMkDataProvider:
  635. return translateAndroidModule(ctx, w, mod, x)
  636. case bootstrap.GoBinaryTool:
  637. return translateGoBinaryModule(ctx, w, mod, x)
  638. case AndroidMkEntriesProvider:
  639. return translateAndroidMkEntriesModule(ctx, w, mod, x)
  640. default:
  641. // Not exported to make so no make variables to set.
  642. return nil
  643. }
  644. }
  645. // A simple, special Android.mk entry output func to make it possible to build blueprint tools using
  646. // m by making them phony targets.
  647. func translateGoBinaryModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
  648. goBinary bootstrap.GoBinaryTool) error {
  649. name := ctx.ModuleName(mod)
  650. fmt.Fprintln(w, ".PHONY:", name)
  651. fmt.Fprintln(w, name+":", goBinary.InstallPath())
  652. fmt.Fprintln(w, "")
  653. // Assuming no rules in make include go binaries in distributables.
  654. // If the assumption is wrong, make will fail to build without the necessary .meta_lic and .meta_module files.
  655. // In that case, add the targets and rules here to build a .meta_lic file for `name` and a .meta_module for
  656. // `goBinary.InstallPath()` pointing to the `name`.meta_lic file.
  657. return nil
  658. }
  659. func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Module) {
  660. // Get the preamble content through AndroidMkEntries logic.
  661. data.Entries = AndroidMkEntries{
  662. Class: data.Class,
  663. SubName: data.SubName,
  664. DistFiles: data.DistFiles,
  665. OutputFile: data.OutputFile,
  666. Disabled: data.Disabled,
  667. Include: data.Include,
  668. Required: data.Required,
  669. Host_required: data.Host_required,
  670. Target_required: data.Target_required,
  671. }
  672. data.Entries.fillInEntries(ctx, mod)
  673. // copy entries back to data since it is used in Custom
  674. data.Required = data.Entries.Required
  675. data.Host_required = data.Entries.Host_required
  676. data.Target_required = data.Entries.Target_required
  677. }
  678. // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider
  679. // instead.
  680. func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
  681. provider AndroidMkDataProvider) error {
  682. amod := mod.(Module).base()
  683. if shouldSkipAndroidMkProcessing(amod) {
  684. return nil
  685. }
  686. data := provider.AndroidMk()
  687. if data.Include == "" {
  688. data.Include = "$(BUILD_PREBUILT)"
  689. }
  690. data.fillInData(ctx, mod)
  691. prefix := ""
  692. if amod.ArchSpecific() {
  693. switch amod.Os().Class {
  694. case Host:
  695. if amod.Target().HostCross {
  696. prefix = "HOST_CROSS_"
  697. } else {
  698. prefix = "HOST_"
  699. }
  700. case Device:
  701. prefix = "TARGET_"
  702. }
  703. if amod.Arch().ArchType != ctx.Config().Targets[amod.Os()][0].Arch.ArchType {
  704. prefix = "2ND_" + prefix
  705. }
  706. }
  707. name := provider.BaseModuleName()
  708. blueprintDir := filepath.Dir(ctx.BlueprintFile(mod))
  709. if data.Custom != nil {
  710. // List of module types allowed to use .Custom(...)
  711. // Additions to the list require careful review for proper license handling.
  712. switch reflect.TypeOf(mod).String() { // ctx.ModuleType(mod) doesn't work: aidl_interface creates phony without type
  713. case "*aidl.aidlApi": // writes non-custom before adding .phony
  714. case "*aidl.aidlMapping": // writes non-custom before adding .phony
  715. case "*android.customModule": // appears in tests only
  716. case "*android_sdk.sdkRepoHost": // doesn't go through base_rules
  717. case "*apex.apexBundle": // license properties written
  718. case "*bpf.bpf": // license properties written (both for module and objs)
  719. case "*genrule.Module": // writes non-custom before adding .phony
  720. case "*java.SystemModules": // doesn't go through base_rules
  721. case "*java.systemModulesImport": // doesn't go through base_rules
  722. case "*phony.phony": // license properties written
  723. case "*selinux.selinuxContextsModule": // license properties written
  724. case "*sysprop.syspropLibrary": // license properties written
  725. default:
  726. if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
  727. return fmt.Errorf("custom make rules not allowed for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), ctx.ModuleName(mod))
  728. }
  729. }
  730. data.Custom(w, name, prefix, blueprintDir, data)
  731. } else {
  732. WriteAndroidMkData(w, data)
  733. }
  734. return nil
  735. }
  736. // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider
  737. // instead.
  738. func WriteAndroidMkData(w io.Writer, data AndroidMkData) {
  739. if data.Disabled {
  740. return
  741. }
  742. if !data.OutputFile.Valid() {
  743. return
  744. }
  745. // write preamble via Entries
  746. data.Entries.footer = bytes.Buffer{}
  747. data.Entries.write(w)
  748. for _, extra := range data.Extra {
  749. extra(w, data.OutputFile.Path())
  750. }
  751. fmt.Fprintln(w, "include "+data.Include)
  752. }
  753. func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
  754. provider AndroidMkEntriesProvider) error {
  755. if shouldSkipAndroidMkProcessing(mod.(Module).base()) {
  756. return nil
  757. }
  758. // Any new or special cases here need review to verify correct propagation of license information.
  759. for _, entries := range provider.AndroidMkEntries() {
  760. entries.fillInEntries(ctx, mod)
  761. entries.write(w)
  762. }
  763. return nil
  764. }
  765. func ShouldSkipAndroidMkProcessing(module Module) bool {
  766. return shouldSkipAndroidMkProcessing(module.base())
  767. }
  768. func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
  769. if !module.commonProperties.NamespaceExportedToMake {
  770. // TODO(jeffrygaston) do we want to validate that there are no modules being
  771. // exported to Kati that depend on this module?
  772. return true
  773. }
  774. // On Mac, only expose host darwin modules to Make, as that's all we claim to support.
  775. // In reality, some of them depend on device-built (Java) modules, so we can't disable all
  776. // device modules in Soong, but we can hide them from Make (and thus the build user interface)
  777. if runtime.GOOS == "darwin" && module.Os() != Darwin {
  778. return true
  779. }
  780. // Only expose the primary Darwin target, as Make does not understand Darwin+Arm64
  781. if module.Os() == Darwin && module.Target().HostCross {
  782. return true
  783. }
  784. return !module.Enabled() ||
  785. module.commonProperties.HideFromMake ||
  786. // Make does not understand LinuxBionic
  787. module.Os() == LinuxBionic
  788. }
  789. // A utility func to format LOCAL_TEST_DATA outputs. See the comments on DataPath to understand how
  790. // to use this func.
  791. func AndroidMkDataPaths(data []DataPath) []string {
  792. var testFiles []string
  793. for _, d := range data {
  794. rel := d.SrcPath.Rel()
  795. path := d.SrcPath.String()
  796. // LOCAL_TEST_DATA requires the rel portion of the path to be removed from the path.
  797. if !strings.HasSuffix(path, rel) {
  798. panic(fmt.Errorf("path %q does not end with %q", path, rel))
  799. }
  800. path = strings.TrimSuffix(path, rel)
  801. testFileString := path + ":" + rel
  802. if len(d.RelativeInstallPath) > 0 {
  803. testFileString += ":" + d.RelativeInstallPath
  804. }
  805. testFiles = append(testFiles, testFileString)
  806. }
  807. return testFiles
  808. }