prebuilt_kernel_modules.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright (C) 2021 The Android Open Source Project
  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 kernel
  15. import (
  16. "fmt"
  17. "path/filepath"
  18. "strings"
  19. "android/soong/android"
  20. _ "android/soong/cc/config"
  21. "github.com/google/blueprint"
  22. "github.com/google/blueprint/proptools"
  23. )
  24. func init() {
  25. pctx.Import("android/soong/cc/config")
  26. registerKernelBuildComponents(android.InitRegistrationContext)
  27. }
  28. func registerKernelBuildComponents(ctx android.RegistrationContext) {
  29. ctx.RegisterModuleType("prebuilt_kernel_modules", prebuiltKernelModulesFactory)
  30. }
  31. type prebuiltKernelModules struct {
  32. android.ModuleBase
  33. properties prebuiltKernelModulesProperties
  34. installDir android.InstallPath
  35. }
  36. type prebuiltKernelModulesProperties struct {
  37. // List or filegroup of prebuilt kernel module files. Should have .ko suffix.
  38. Srcs []string `android:"path,arch_variant"`
  39. // Kernel version that these modules are for. Kernel modules are installed to
  40. // /lib/modules/<kernel_version> directory in the corresponding partition. Default is "".
  41. Kernel_version *string
  42. }
  43. // prebuilt_kernel_modules installs a set of prebuilt kernel module files to the correct directory.
  44. // In addition, this module builds modules.load, modules.dep, modules.softdep and modules.alias
  45. // using depmod and installs them as well.
  46. func prebuiltKernelModulesFactory() android.Module {
  47. module := &prebuiltKernelModules{}
  48. module.AddProperties(&module.properties)
  49. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
  50. return module
  51. }
  52. func (pkm *prebuiltKernelModules) KernelVersion() string {
  53. return proptools.StringDefault(pkm.properties.Kernel_version, "")
  54. }
  55. func (pkm *prebuiltKernelModules) DepsMutator(ctx android.BottomUpMutatorContext) {
  56. // do nothing
  57. }
  58. func (pkm *prebuiltKernelModules) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  59. modules := android.PathsForModuleSrc(ctx, pkm.properties.Srcs)
  60. depmodOut := runDepmod(ctx, modules)
  61. strippedModules := stripDebugSymbols(ctx, modules)
  62. installDir := android.PathForModuleInstall(ctx, "lib", "modules")
  63. if pkm.KernelVersion() != "" {
  64. installDir = installDir.Join(ctx, pkm.KernelVersion())
  65. }
  66. for _, m := range strippedModules {
  67. ctx.InstallFile(installDir, filepath.Base(m.String()), m)
  68. }
  69. ctx.InstallFile(installDir, "modules.load", depmodOut.modulesLoad)
  70. ctx.InstallFile(installDir, "modules.dep", depmodOut.modulesDep)
  71. ctx.InstallFile(installDir, "modules.softdep", depmodOut.modulesSoftdep)
  72. ctx.InstallFile(installDir, "modules.alias", depmodOut.modulesAlias)
  73. }
  74. var (
  75. pctx = android.NewPackageContext("android/soong/kernel")
  76. stripRule = pctx.AndroidStaticRule("strip",
  77. blueprint.RuleParams{
  78. Command: "$stripCmd -o $out --strip-debug $in",
  79. CommandDeps: []string{"$stripCmd"},
  80. }, "stripCmd")
  81. )
  82. func stripDebugSymbols(ctx android.ModuleContext, modules android.Paths) android.OutputPaths {
  83. dir := android.PathForModuleOut(ctx, "stripped").OutputPath
  84. var outputs android.OutputPaths
  85. for _, m := range modules {
  86. stripped := dir.Join(ctx, filepath.Base(m.String()))
  87. ctx.Build(pctx, android.BuildParams{
  88. Rule: stripRule,
  89. Input: m,
  90. Output: stripped,
  91. Args: map[string]string{
  92. "stripCmd": "${config.ClangBin}/llvm-strip",
  93. },
  94. })
  95. outputs = append(outputs, stripped)
  96. }
  97. return outputs
  98. }
  99. type depmodOutputs struct {
  100. modulesLoad android.OutputPath
  101. modulesDep android.OutputPath
  102. modulesSoftdep android.OutputPath
  103. modulesAlias android.OutputPath
  104. }
  105. func runDepmod(ctx android.ModuleContext, modules android.Paths) depmodOutputs {
  106. baseDir := android.PathForModuleOut(ctx, "depmod").OutputPath
  107. fakeVer := "0.0" // depmod demands this anyway
  108. modulesDir := baseDir.Join(ctx, "lib", "modules", fakeVer)
  109. builder := android.NewRuleBuilder(pctx, ctx)
  110. // Copy the module files to a temporary dir
  111. builder.Command().Text("rm").Flag("-rf").Text(modulesDir.String())
  112. builder.Command().Text("mkdir").Flag("-p").Text(modulesDir.String())
  113. for _, m := range modules {
  114. builder.Command().Text("cp").Input(m).Text(modulesDir.String())
  115. }
  116. // Enumerate modules to load
  117. modulesLoad := modulesDir.Join(ctx, "modules.load")
  118. var basenames []string
  119. for _, m := range modules {
  120. basenames = append(basenames, filepath.Base(m.String()))
  121. }
  122. builder.Command().
  123. Text("echo").Flag("\"" + strings.Join(basenames, " ") + "\"").
  124. Text("|").Text("tr").Flag("\" \"").Flag("\"\\n\"").
  125. Text(">").Output(modulesLoad)
  126. // Run depmod to build modules.dep/softdep/alias files
  127. modulesDep := modulesDir.Join(ctx, "modules.dep")
  128. modulesSoftdep := modulesDir.Join(ctx, "modules.softdep")
  129. modulesAlias := modulesDir.Join(ctx, "modules.alias")
  130. builder.Command().
  131. BuiltTool("depmod").
  132. FlagWithArg("-b ", baseDir.String()).
  133. Text(fakeVer).
  134. ImplicitOutput(modulesDep).
  135. ImplicitOutput(modulesSoftdep).
  136. ImplicitOutput(modulesAlias)
  137. builder.Build("depmod", fmt.Sprintf("depmod %s", ctx.ModuleName()))
  138. return depmodOutputs{modulesLoad, modulesDep, modulesSoftdep, modulesAlias}
  139. }