androidmk.go 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  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.RegisterParallelSingletonType("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. // Provides data typically stored by Context objects that are commonly needed by
  134. //AndroidMkEntries objects.
  135. entryContext AndroidMkEntriesContext
  136. }
  137. type AndroidMkEntriesContext interface {
  138. Config() Config
  139. }
  140. type AndroidMkExtraEntriesContext interface {
  141. Provider(provider blueprint.ProviderKey) interface{}
  142. }
  143. type androidMkExtraEntriesContext struct {
  144. ctx fillInEntriesContext
  145. mod blueprint.Module
  146. }
  147. func (a *androidMkExtraEntriesContext) Provider(provider blueprint.ProviderKey) interface{} {
  148. return a.ctx.ModuleProvider(a.mod, provider)
  149. }
  150. type AndroidMkExtraEntriesFunc func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries)
  151. type AndroidMkExtraFootersFunc func(w io.Writer, name, prefix, moduleDir string)
  152. // Utility funcs to manipulate Android.mk variable entries.
  153. // SetString sets a Make variable with the given name to the given value.
  154. func (a *AndroidMkEntries) SetString(name, value string) {
  155. if _, ok := a.EntryMap[name]; !ok {
  156. a.entryOrder = append(a.entryOrder, name)
  157. }
  158. a.EntryMap[name] = []string{value}
  159. }
  160. // SetPath sets a Make variable with the given name to the given path string.
  161. func (a *AndroidMkEntries) SetPath(name string, path Path) {
  162. if _, ok := a.EntryMap[name]; !ok {
  163. a.entryOrder = append(a.entryOrder, name)
  164. }
  165. a.EntryMap[name] = []string{path.String()}
  166. }
  167. // SetOptionalPath sets a Make variable with the given name to the given path string if it is valid.
  168. // It is a no-op if the given path is invalid.
  169. func (a *AndroidMkEntries) SetOptionalPath(name string, path OptionalPath) {
  170. if path.Valid() {
  171. a.SetPath(name, path.Path())
  172. }
  173. }
  174. // AddPath appends the given path string to a Make variable with the given name.
  175. func (a *AndroidMkEntries) AddPath(name string, path Path) {
  176. if _, ok := a.EntryMap[name]; !ok {
  177. a.entryOrder = append(a.entryOrder, name)
  178. }
  179. a.EntryMap[name] = append(a.EntryMap[name], path.String())
  180. }
  181. // AddOptionalPath appends the given path string to a Make variable with the given name if it is
  182. // valid. It is a no-op if the given path is invalid.
  183. func (a *AndroidMkEntries) AddOptionalPath(name string, path OptionalPath) {
  184. if path.Valid() {
  185. a.AddPath(name, path.Path())
  186. }
  187. }
  188. // SetPaths sets a Make variable with the given name to a slice of the given path strings.
  189. func (a *AndroidMkEntries) SetPaths(name string, paths Paths) {
  190. if _, ok := a.EntryMap[name]; !ok {
  191. a.entryOrder = append(a.entryOrder, name)
  192. }
  193. a.EntryMap[name] = paths.Strings()
  194. }
  195. // SetOptionalPaths sets a Make variable with the given name to a slice of the given path strings
  196. // only if there are a non-zero amount of paths.
  197. func (a *AndroidMkEntries) SetOptionalPaths(name string, paths Paths) {
  198. if len(paths) > 0 {
  199. a.SetPaths(name, paths)
  200. }
  201. }
  202. // AddPaths appends the given path strings to a Make variable with the given name.
  203. func (a *AndroidMkEntries) AddPaths(name string, paths Paths) {
  204. if _, ok := a.EntryMap[name]; !ok {
  205. a.entryOrder = append(a.entryOrder, name)
  206. }
  207. a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
  208. }
  209. // SetBoolIfTrue sets a Make variable with the given name to true if the given flag is true.
  210. // It is a no-op if the given flag is false.
  211. func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
  212. if flag {
  213. if _, ok := a.EntryMap[name]; !ok {
  214. a.entryOrder = append(a.entryOrder, name)
  215. }
  216. a.EntryMap[name] = []string{"true"}
  217. }
  218. }
  219. // SetBool sets a Make variable with the given name to if the given bool flag value.
  220. func (a *AndroidMkEntries) SetBool(name string, flag bool) {
  221. if _, ok := a.EntryMap[name]; !ok {
  222. a.entryOrder = append(a.entryOrder, name)
  223. }
  224. if flag {
  225. a.EntryMap[name] = []string{"true"}
  226. } else {
  227. a.EntryMap[name] = []string{"false"}
  228. }
  229. }
  230. // AddStrings appends the given strings to a Make variable with the given name.
  231. func (a *AndroidMkEntries) AddStrings(name string, value ...string) {
  232. if len(value) == 0 {
  233. return
  234. }
  235. if _, ok := a.EntryMap[name]; !ok {
  236. a.entryOrder = append(a.entryOrder, name)
  237. }
  238. a.EntryMap[name] = append(a.EntryMap[name], value...)
  239. }
  240. // AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling
  241. // for partial MTS test suites.
  242. func (a *AndroidMkEntries) AddCompatibilityTestSuites(suites ...string) {
  243. // MTS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
  244. // To reduce repetition, if we find a partial MTS test suite without an full MTS test suite,
  245. // we add the full test suite to our list.
  246. if PrefixInList(suites, "mts-") && !InList("mts", suites) {
  247. suites = append(suites, "mts")
  248. }
  249. a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
  250. }
  251. // The contributions to the dist.
  252. type distContributions struct {
  253. // Path to license metadata file.
  254. licenseMetadataFile Path
  255. // List of goals and the dist copy instructions.
  256. copiesForGoals []*copiesForGoals
  257. }
  258. // getCopiesForGoals returns a copiesForGoals into which copy instructions that
  259. // must be processed when building one or more of those goals can be added.
  260. func (d *distContributions) getCopiesForGoals(goals string) *copiesForGoals {
  261. copiesForGoals := &copiesForGoals{goals: goals}
  262. d.copiesForGoals = append(d.copiesForGoals, copiesForGoals)
  263. return copiesForGoals
  264. }
  265. // Associates a list of dist copy instructions with a set of goals for which they
  266. // should be run.
  267. type copiesForGoals struct {
  268. // goals are a space separated list of build targets that will trigger the
  269. // copy instructions.
  270. goals string
  271. // A list of instructions to copy a module's output files to somewhere in the
  272. // dist directory.
  273. copies []distCopy
  274. }
  275. // Adds a copy instruction.
  276. func (d *copiesForGoals) addCopyInstruction(from Path, dest string) {
  277. d.copies = append(d.copies, distCopy{from, dest})
  278. }
  279. // Instruction on a path that must be copied into the dist.
  280. type distCopy struct {
  281. // The path to copy from.
  282. from Path
  283. // The destination within the dist directory to copy to.
  284. dest string
  285. }
  286. // Compute the contributions that the module makes to the dist.
  287. func (a *AndroidMkEntries) getDistContributions(mod blueprint.Module) *distContributions {
  288. amod := mod.(Module).base()
  289. name := amod.BaseModuleName()
  290. // Collate the set of associated tag/paths available for copying to the dist.
  291. // Start with an empty (nil) set.
  292. var availableTaggedDists TaggedDistFiles
  293. // Then merge in any that are provided explicitly by the module.
  294. if a.DistFiles != nil {
  295. // Merge the DistFiles into the set.
  296. availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
  297. }
  298. // If no paths have been provided for the DefaultDistTag and the output file is
  299. // valid then add that as the default dist path.
  300. if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
  301. availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
  302. }
  303. // If the distFiles created by GenerateTaggedDistFiles contains paths for the
  304. // DefaultDistTag then that takes priority so delete any existing paths.
  305. if _, ok := amod.distFiles[DefaultDistTag]; ok {
  306. delete(availableTaggedDists, DefaultDistTag)
  307. }
  308. // Finally, merge the distFiles created by GenerateTaggedDistFiles.
  309. availableTaggedDists = availableTaggedDists.merge(amod.distFiles)
  310. if len(availableTaggedDists) == 0 {
  311. // Nothing dist-able for this module.
  312. return nil
  313. }
  314. // Collate the contributions this module makes to the dist.
  315. distContributions := &distContributions{}
  316. if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
  317. distContributions.licenseMetadataFile = amod.licenseMetadataFile
  318. }
  319. // Iterate over this module's dist structs, merged from the dist and dists properties.
  320. for _, dist := range amod.Dists() {
  321. // Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
  322. goals := strings.Join(dist.Targets, " ")
  323. // Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
  324. var tag string
  325. if dist.Tag == nil {
  326. // If the dist struct does not specify a tag, use the default output files tag.
  327. tag = DefaultDistTag
  328. } else {
  329. tag = *dist.Tag
  330. }
  331. // Get the paths of the output files to be dist'd, represented by the tag.
  332. // Can be an empty list.
  333. tagPaths := availableTaggedDists[tag]
  334. if len(tagPaths) == 0 {
  335. // Nothing to dist for this tag, continue to the next dist.
  336. continue
  337. }
  338. if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
  339. errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
  340. "file for %q goals tag %q in module %s. The list of dist files, " +
  341. "which should have a single element, is:\n%s"
  342. panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
  343. }
  344. copiesForGoals := distContributions.getCopiesForGoals(goals)
  345. // Iterate over each path adding a copy instruction to copiesForGoals
  346. for _, path := range tagPaths {
  347. // It's possible that the Path is nil from errant modules. Be defensive here.
  348. if path == nil {
  349. tagName := "default" // for error message readability
  350. if dist.Tag != nil {
  351. tagName = *dist.Tag
  352. }
  353. panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
  354. }
  355. dest := filepath.Base(path.String())
  356. if dist.Dest != nil {
  357. var err error
  358. if dest, err = validateSafePath(*dist.Dest); err != nil {
  359. // This was checked in ModuleBase.GenerateBuildActions
  360. panic(err)
  361. }
  362. }
  363. ext := filepath.Ext(dest)
  364. suffix := ""
  365. if dist.Suffix != nil {
  366. suffix = *dist.Suffix
  367. }
  368. productString := ""
  369. if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product {
  370. productString = fmt.Sprintf("_%s", a.entryContext.Config().DeviceProduct())
  371. }
  372. if suffix != "" || productString != "" {
  373. dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext
  374. }
  375. if dist.Dir != nil {
  376. var err error
  377. if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
  378. // This was checked in ModuleBase.GenerateBuildActions
  379. panic(err)
  380. }
  381. }
  382. copiesForGoals.addCopyInstruction(path, dest)
  383. }
  384. }
  385. return distContributions
  386. }
  387. // generateDistContributionsForMake generates make rules that will generate the
  388. // dist according to the instructions in the supplied distContribution.
  389. func generateDistContributionsForMake(distContributions *distContributions) []string {
  390. var ret []string
  391. for _, d := range distContributions.copiesForGoals {
  392. ret = append(ret, fmt.Sprintf(".PHONY: %s\n", d.goals))
  393. // Create dist-for-goals calls for each of the copy instructions.
  394. for _, c := range d.copies {
  395. if distContributions.licenseMetadataFile != nil {
  396. ret = append(
  397. ret,
  398. fmt.Sprintf("$(if $(strip $(ALL_TARGETS.%s.META_LIC)),,$(eval ALL_TARGETS.%s.META_LIC := %s))\n",
  399. c.from.String(), c.from.String(), distContributions.licenseMetadataFile.String()))
  400. }
  401. ret = append(
  402. ret,
  403. fmt.Sprintf("$(call dist-for-goals,%s,%s:%s)\n", d.goals, c.from.String(), c.dest))
  404. }
  405. }
  406. return ret
  407. }
  408. // Compute the list of Make strings to declare phony goals and dist-for-goals
  409. // calls from the module's dist and dists properties.
  410. func (a *AndroidMkEntries) GetDistForGoals(mod blueprint.Module) []string {
  411. distContributions := a.getDistContributions(mod)
  412. if distContributions == nil {
  413. return nil
  414. }
  415. return generateDistContributionsForMake(distContributions)
  416. }
  417. // Write the license variables to Make for AndroidMkData.Custom(..) methods that do not call WriteAndroidMkData(..)
  418. // It's required to propagate the license metadata even for module types that have non-standard interfaces to Make.
  419. func (a *AndroidMkEntries) WriteLicenseVariables(w io.Writer) {
  420. AndroidMkEmitAssignList(w, "LOCAL_LICENSE_KINDS", a.EntryMap["LOCAL_LICENSE_KINDS"])
  421. AndroidMkEmitAssignList(w, "LOCAL_LICENSE_CONDITIONS", a.EntryMap["LOCAL_LICENSE_CONDITIONS"])
  422. AndroidMkEmitAssignList(w, "LOCAL_NOTICE_FILE", a.EntryMap["LOCAL_NOTICE_FILE"])
  423. if pn, ok := a.EntryMap["LOCAL_LICENSE_PACKAGE_NAME"]; ok {
  424. AndroidMkEmitAssignList(w, "LOCAL_LICENSE_PACKAGE_NAME", pn)
  425. }
  426. }
  427. // fillInEntries goes through the common variable processing and calls the extra data funcs to
  428. // generate and fill in AndroidMkEntries's in-struct data, ready to be flushed to a file.
  429. type fillInEntriesContext interface {
  430. ModuleDir(module blueprint.Module) string
  431. ModuleSubDir(module blueprint.Module) string
  432. Config() Config
  433. ModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{}
  434. ModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool
  435. ModuleType(module blueprint.Module) string
  436. }
  437. func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
  438. a.entryContext = ctx
  439. a.EntryMap = make(map[string][]string)
  440. amod := mod.(Module)
  441. base := amod.base()
  442. name := base.BaseModuleName()
  443. if a.OverrideName != "" {
  444. name = a.OverrideName
  445. }
  446. if a.Include == "" {
  447. a.Include = "$(BUILD_PREBUILT)"
  448. }
  449. a.Required = append(a.Required, amod.RequiredModuleNames()...)
  450. a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
  451. a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
  452. for _, distString := range a.GetDistForGoals(mod) {
  453. fmt.Fprintf(&a.header, distString)
  454. }
  455. fmt.Fprintf(&a.header, "\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod))
  456. // Collect make variable assignment entries.
  457. a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
  458. a.SetString("LOCAL_MODULE", name+a.SubName)
  459. a.AddStrings("LOCAL_LICENSE_KINDS", base.commonProperties.Effective_license_kinds...)
  460. a.AddStrings("LOCAL_LICENSE_CONDITIONS", base.commonProperties.Effective_license_conditions...)
  461. a.AddStrings("LOCAL_NOTICE_FILE", base.commonProperties.Effective_license_text.Strings()...)
  462. // TODO(b/151177513): Does this code need to set LOCAL_MODULE_IS_CONTAINER ?
  463. if base.commonProperties.Effective_package_name != nil {
  464. a.SetString("LOCAL_LICENSE_PACKAGE_NAME", *base.commonProperties.Effective_package_name)
  465. } else if len(base.commonProperties.Effective_licenses) > 0 {
  466. a.SetString("LOCAL_LICENSE_PACKAGE_NAME", strings.Join(base.commonProperties.Effective_licenses, " "))
  467. }
  468. a.SetString("LOCAL_MODULE_CLASS", a.Class)
  469. a.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
  470. a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
  471. a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
  472. a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
  473. a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
  474. // If the install rule was generated by Soong tell Make about it.
  475. if len(base.katiInstalls) > 0 {
  476. // Assume the primary install file is last since it probably needs to depend on any other
  477. // installed files. If that is not the case we can add a method to specify the primary
  478. // installed file.
  479. a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", base.katiInstalls[len(base.katiInstalls)-1].to)
  480. a.SetString("LOCAL_SOONG_INSTALL_PAIRS", base.katiInstalls.BuiltInstalled())
  481. a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths())
  482. }
  483. if am, ok := mod.(ApexModule); ok {
  484. a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
  485. }
  486. archStr := base.Arch().ArchType.String()
  487. host := false
  488. switch base.Os().Class {
  489. case Host:
  490. if base.Target().HostCross {
  491. // Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
  492. if base.Arch().ArchType != Common {
  493. a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
  494. }
  495. } else {
  496. // Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
  497. if base.Arch().ArchType != Common {
  498. a.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
  499. }
  500. }
  501. host = true
  502. case Device:
  503. // Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
  504. if base.Arch().ArchType != Common {
  505. if base.Target().NativeBridge {
  506. hostArchStr := base.Target().NativeBridgeHostArchName
  507. if hostArchStr != "" {
  508. a.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
  509. }
  510. } else {
  511. a.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
  512. }
  513. }
  514. if !base.InVendorRamdisk() {
  515. a.AddPaths("LOCAL_FULL_INIT_RC", base.initRcPaths)
  516. }
  517. if len(base.vintfFragmentsPaths) > 0 {
  518. a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", base.vintfFragmentsPaths)
  519. }
  520. a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
  521. if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
  522. a.SetString("LOCAL_VENDOR_MODULE", "true")
  523. }
  524. a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
  525. a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
  526. a.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
  527. if base.commonProperties.Owner != nil {
  528. a.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
  529. }
  530. }
  531. if host {
  532. makeOs := base.Os().String()
  533. if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
  534. makeOs = "linux"
  535. }
  536. a.SetString("LOCAL_MODULE_HOST_OS", makeOs)
  537. a.SetString("LOCAL_IS_HOST_MODULE", "true")
  538. }
  539. prefix := ""
  540. if base.ArchSpecific() {
  541. switch base.Os().Class {
  542. case Host:
  543. if base.Target().HostCross {
  544. prefix = "HOST_CROSS_"
  545. } else {
  546. prefix = "HOST_"
  547. }
  548. case Device:
  549. prefix = "TARGET_"
  550. }
  551. if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
  552. prefix = "2ND_" + prefix
  553. }
  554. }
  555. if ctx.ModuleHasProvider(mod, LicenseMetadataProvider) {
  556. licenseMetadata := ctx.ModuleProvider(mod, LicenseMetadataProvider).(*LicenseMetadataInfo)
  557. a.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath)
  558. }
  559. extraCtx := &androidMkExtraEntriesContext{
  560. ctx: ctx,
  561. mod: mod,
  562. }
  563. for _, extra := range a.ExtraEntries {
  564. extra(extraCtx, a)
  565. }
  566. // Write to footer.
  567. fmt.Fprintln(&a.footer, "include "+a.Include)
  568. blueprintDir := ctx.ModuleDir(mod)
  569. for _, footerFunc := range a.ExtraFooters {
  570. footerFunc(&a.footer, name, prefix, blueprintDir)
  571. }
  572. }
  573. // write flushes the AndroidMkEntries's in-struct data populated by AndroidMkEntries into the
  574. // given Writer object.
  575. func (a *AndroidMkEntries) write(w io.Writer) {
  576. if a.Disabled {
  577. return
  578. }
  579. if !a.OutputFile.Valid() {
  580. return
  581. }
  582. w.Write(a.header.Bytes())
  583. for _, name := range a.entryOrder {
  584. AndroidMkEmitAssignList(w, name, a.EntryMap[name])
  585. }
  586. w.Write(a.footer.Bytes())
  587. }
  588. func (a *AndroidMkEntries) FooterLinesForTests() []string {
  589. return strings.Split(string(a.footer.Bytes()), "\n")
  590. }
  591. // AndroidMkSingleton is a singleton to collect Android.mk data from all modules and dump them into
  592. // the final Android-<product_name>.mk file output.
  593. func AndroidMkSingleton() Singleton {
  594. return &androidMkSingleton{}
  595. }
  596. type androidMkSingleton struct{}
  597. func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
  598. // Skip if Soong wasn't invoked from Make.
  599. if !ctx.Config().KatiEnabled() {
  600. return
  601. }
  602. var androidMkModulesList []blueprint.Module
  603. ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
  604. androidMkModulesList = append(androidMkModulesList, module)
  605. })
  606. // Sort the module list by the module names to eliminate random churns, which may erroneously
  607. // invoke additional build processes.
  608. sort.SliceStable(androidMkModulesList, func(i, j int) bool {
  609. return ctx.ModuleName(androidMkModulesList[i]) < ctx.ModuleName(androidMkModulesList[j])
  610. })
  611. transMk := PathForOutput(ctx, "Android"+String(ctx.Config().productVariables.Make_suffix)+".mk")
  612. if ctx.Failed() {
  613. return
  614. }
  615. err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList)
  616. if err != nil {
  617. ctx.Errorf(err.Error())
  618. }
  619. ctx.Build(pctx, BuildParams{
  620. Rule: blueprint.Phony,
  621. Output: transMk,
  622. })
  623. }
  624. func translateAndroidMk(ctx SingletonContext, absMkFile string, mods []blueprint.Module) error {
  625. buf := &bytes.Buffer{}
  626. fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))")
  627. typeStats := make(map[string]int)
  628. for _, mod := range mods {
  629. err := translateAndroidMkModule(ctx, buf, mod)
  630. if err != nil {
  631. os.Remove(absMkFile)
  632. return err
  633. }
  634. if amod, ok := mod.(Module); ok && ctx.PrimaryModule(amod) == amod {
  635. typeStats[ctx.ModuleType(amod)] += 1
  636. }
  637. }
  638. keys := []string{}
  639. fmt.Fprintln(buf, "\nSTATS.SOONG_MODULE_TYPE :=")
  640. for k := range typeStats {
  641. keys = append(keys, k)
  642. }
  643. sort.Strings(keys)
  644. for _, mod_type := range keys {
  645. fmt.Fprintln(buf, "STATS.SOONG_MODULE_TYPE +=", mod_type)
  646. fmt.Fprintf(buf, "STATS.SOONG_MODULE_TYPE.%s := %d\n", mod_type, typeStats[mod_type])
  647. }
  648. return pathtools.WriteFileIfChanged(absMkFile, buf.Bytes(), 0666)
  649. }
  650. func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
  651. defer func() {
  652. if r := recover(); r != nil {
  653. panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s",
  654. r, ctx.ModuleName(mod), ctx.ModuleSubDir(mod)))
  655. }
  656. }()
  657. // Additional cases here require review for correct license propagation to make.
  658. switch x := mod.(type) {
  659. case AndroidMkDataProvider:
  660. return translateAndroidModule(ctx, w, mod, x)
  661. case bootstrap.GoBinaryTool:
  662. return translateGoBinaryModule(ctx, w, mod, x)
  663. case AndroidMkEntriesProvider:
  664. return translateAndroidMkEntriesModule(ctx, w, mod, x)
  665. default:
  666. // Not exported to make so no make variables to set.
  667. return nil
  668. }
  669. }
  670. // A simple, special Android.mk entry output func to make it possible to build blueprint tools using
  671. // m by making them phony targets.
  672. func translateGoBinaryModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
  673. goBinary bootstrap.GoBinaryTool) error {
  674. name := ctx.ModuleName(mod)
  675. fmt.Fprintln(w, ".PHONY:", name)
  676. fmt.Fprintln(w, name+":", goBinary.InstallPath())
  677. fmt.Fprintln(w, "")
  678. // Assuming no rules in make include go binaries in distributables.
  679. // If the assumption is wrong, make will fail to build without the necessary .meta_lic and .meta_module files.
  680. // In that case, add the targets and rules here to build a .meta_lic file for `name` and a .meta_module for
  681. // `goBinary.InstallPath()` pointing to the `name`.meta_lic file.
  682. return nil
  683. }
  684. func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Module) {
  685. // Get the preamble content through AndroidMkEntries logic.
  686. data.Entries = AndroidMkEntries{
  687. Class: data.Class,
  688. SubName: data.SubName,
  689. DistFiles: data.DistFiles,
  690. OutputFile: data.OutputFile,
  691. Disabled: data.Disabled,
  692. Include: data.Include,
  693. Required: data.Required,
  694. Host_required: data.Host_required,
  695. Target_required: data.Target_required,
  696. }
  697. data.Entries.fillInEntries(ctx, mod)
  698. // copy entries back to data since it is used in Custom
  699. data.Required = data.Entries.Required
  700. data.Host_required = data.Entries.Host_required
  701. data.Target_required = data.Entries.Target_required
  702. }
  703. // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider
  704. // instead.
  705. func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
  706. provider AndroidMkDataProvider) error {
  707. amod := mod.(Module).base()
  708. if shouldSkipAndroidMkProcessing(amod) {
  709. return nil
  710. }
  711. data := provider.AndroidMk()
  712. if data.Include == "" {
  713. data.Include = "$(BUILD_PREBUILT)"
  714. }
  715. data.fillInData(ctx, mod)
  716. prefix := ""
  717. if amod.ArchSpecific() {
  718. switch amod.Os().Class {
  719. case Host:
  720. if amod.Target().HostCross {
  721. prefix = "HOST_CROSS_"
  722. } else {
  723. prefix = "HOST_"
  724. }
  725. case Device:
  726. prefix = "TARGET_"
  727. }
  728. if amod.Arch().ArchType != ctx.Config().Targets[amod.Os()][0].Arch.ArchType {
  729. prefix = "2ND_" + prefix
  730. }
  731. }
  732. name := provider.BaseModuleName()
  733. blueprintDir := filepath.Dir(ctx.BlueprintFile(mod))
  734. if data.Custom != nil {
  735. // List of module types allowed to use .Custom(...)
  736. // Additions to the list require careful review for proper license handling.
  737. switch reflect.TypeOf(mod).String() { // ctx.ModuleType(mod) doesn't work: aidl_interface creates phony without type
  738. case "*aidl.aidlApi": // writes non-custom before adding .phony
  739. case "*aidl.aidlMapping": // writes non-custom before adding .phony
  740. case "*android.customModule": // appears in tests only
  741. case "*android_sdk.sdkRepoHost": // doesn't go through base_rules
  742. case "*apex.apexBundle": // license properties written
  743. case "*bpf.bpf": // license properties written (both for module and objs)
  744. case "*genrule.Module": // writes non-custom before adding .phony
  745. case "*java.SystemModules": // doesn't go through base_rules
  746. case "*java.systemModulesImport": // doesn't go through base_rules
  747. case "*phony.phony": // license properties written
  748. case "*selinux.selinuxContextsModule": // license properties written
  749. case "*sysprop.syspropLibrary": // license properties written
  750. default:
  751. if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
  752. return fmt.Errorf("custom make rules not allowed for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), ctx.ModuleName(mod))
  753. }
  754. }
  755. data.Custom(w, name, prefix, blueprintDir, data)
  756. } else {
  757. WriteAndroidMkData(w, data)
  758. }
  759. return nil
  760. }
  761. // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider
  762. // instead.
  763. func WriteAndroidMkData(w io.Writer, data AndroidMkData) {
  764. if data.Disabled {
  765. return
  766. }
  767. if !data.OutputFile.Valid() {
  768. return
  769. }
  770. // write preamble via Entries
  771. data.Entries.footer = bytes.Buffer{}
  772. data.Entries.write(w)
  773. for _, extra := range data.Extra {
  774. extra(w, data.OutputFile.Path())
  775. }
  776. fmt.Fprintln(w, "include "+data.Include)
  777. }
  778. func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
  779. provider AndroidMkEntriesProvider) error {
  780. if shouldSkipAndroidMkProcessing(mod.(Module).base()) {
  781. return nil
  782. }
  783. // Any new or special cases here need review to verify correct propagation of license information.
  784. for _, entries := range provider.AndroidMkEntries() {
  785. entries.fillInEntries(ctx, mod)
  786. entries.write(w)
  787. }
  788. return nil
  789. }
  790. func ShouldSkipAndroidMkProcessing(module Module) bool {
  791. return shouldSkipAndroidMkProcessing(module.base())
  792. }
  793. func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
  794. if !module.commonProperties.NamespaceExportedToMake {
  795. // TODO(jeffrygaston) do we want to validate that there are no modules being
  796. // exported to Kati that depend on this module?
  797. return true
  798. }
  799. // On Mac, only expose host darwin modules to Make, as that's all we claim to support.
  800. // In reality, some of them depend on device-built (Java) modules, so we can't disable all
  801. // device modules in Soong, but we can hide them from Make (and thus the build user interface)
  802. if runtime.GOOS == "darwin" && module.Os() != Darwin {
  803. return true
  804. }
  805. // Only expose the primary Darwin target, as Make does not understand Darwin+Arm64
  806. if module.Os() == Darwin && module.Target().HostCross {
  807. return true
  808. }
  809. return !module.Enabled() ||
  810. module.commonProperties.HideFromMake ||
  811. // Make does not understand LinuxBionic
  812. module.Os() == LinuxBionic ||
  813. // Make does not understand LinuxMusl, except when we are building with USE_HOST_MUSL=true
  814. // and all host binaries are LinuxMusl
  815. (module.Os() == LinuxMusl && module.Target().HostCross)
  816. }
  817. // A utility func to format LOCAL_TEST_DATA outputs. See the comments on DataPath to understand how
  818. // to use this func.
  819. func AndroidMkDataPaths(data []DataPath) []string {
  820. var testFiles []string
  821. for _, d := range data {
  822. rel := d.SrcPath.Rel()
  823. path := d.SrcPath.String()
  824. // LOCAL_TEST_DATA requires the rel portion of the path to be removed from the path.
  825. if !strings.HasSuffix(path, rel) {
  826. panic(fmt.Errorf("path %q does not end with %q", path, rel))
  827. }
  828. path = strings.TrimSuffix(path, rel)
  829. testFileString := path + ":" + rel
  830. if len(d.RelativeInstallPath) > 0 {
  831. testFileString += ":" + d.RelativeInstallPath
  832. }
  833. testFiles = append(testFiles, testFileString)
  834. }
  835. return testFiles
  836. }
  837. // AndroidMkEmitAssignList emits the line
  838. //
  839. // VAR := ITEM ...
  840. //
  841. // Items are the elements to the given set of lists
  842. // If all the passed lists are empty, no line will be emitted
  843. func AndroidMkEmitAssignList(w io.Writer, varName string, lists ...[]string) {
  844. doPrint := false
  845. for _, l := range lists {
  846. if doPrint = len(l) > 0; doPrint {
  847. break
  848. }
  849. }
  850. if !doPrint {
  851. return
  852. }
  853. fmt.Fprint(w, varName, " :=")
  854. for _, l := range lists {
  855. for _, item := range l {
  856. fmt.Fprint(w, " ", item)
  857. }
  858. }
  859. fmt.Fprintln(w)
  860. }