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 15package cc 16 17import ( 18 "fmt" 19 "io" 20 "path/filepath" 21 "strings" 22 23 "android/soong/android" 24) 25 26var ( 27 vendorSuffix = ".vendor" 28 recoverySuffix = ".recovery" 29) 30 31type AndroidMkContext interface { 32 Name() string 33 Target() android.Target 34 subAndroidMk(*android.AndroidMkData, interface{}) 35 Arch() android.Arch 36 Os() android.OsType 37 Host() bool 38 useVndk() bool 39 static() bool 40 inRecovery() bool 41} 42 43type subAndroidMkProvider interface { 44 AndroidMk(AndroidMkContext, *android.AndroidMkData) 45} 46 47func (c *Module) subAndroidMk(data *android.AndroidMkData, obj interface{}) { 48 if c.subAndroidMkOnce == nil { 49 c.subAndroidMkOnce = make(map[subAndroidMkProvider]bool) 50 } 51 if androidmk, ok := obj.(subAndroidMkProvider); ok { 52 if !c.subAndroidMkOnce[androidmk] { 53 c.subAndroidMkOnce[androidmk] = true 54 androidmk.AndroidMk(c, data) 55 } 56 } 57} 58 59func (c *Module) AndroidMk() android.AndroidMkData { 60 if c.Properties.HideFromMake || !c.IsForPlatform() { 61 return android.AndroidMkData{ 62 Disabled: true, 63 } 64 } 65 66 ret := android.AndroidMkData{ 67 OutputFile: c.outputFile, 68 // TODO(jiyong): add the APEXes providing shared libs to the required modules 69 // Currently, adding c.Properties.ApexesProvidingSharedLibs is causing multiple 70 // runtime APEXes (com.android.runtime.debug|release) to be installed. And this 71 // is breaking some older devices (like marlin) where system.img is small. 72 Required: c.Properties.AndroidMkRuntimeLibs, 73 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk", 74 75 Extra: []android.AndroidMkExtraFunc{ 76 func(w io.Writer, outputFile android.Path) { 77 if len(c.Properties.Logtags) > 0 { 78 fmt.Fprintln(w, "LOCAL_LOGTAGS_FILES :=", strings.Join(c.Properties.Logtags, " ")) 79 } 80 if len(c.Properties.AndroidMkSharedLibs) > 0 { 81 fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " ")) 82 } 83 if len(c.Properties.AndroidMkStaticLibs) > 0 { 84 fmt.Fprintln(w, "LOCAL_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkStaticLibs, " ")) 85 } 86 if len(c.Properties.AndroidMkWholeStaticLibs) > 0 { 87 fmt.Fprintln(w, "LOCAL_WHOLE_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkWholeStaticLibs, " ")) 88 } 89 fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.getMakeLinkType()) 90 if c.useVndk() { 91 fmt.Fprintln(w, "LOCAL_USE_VNDK := true") 92 } 93 }, 94 }, 95 } 96 97 for _, feature := range c.features { 98 c.subAndroidMk(&ret, feature) 99 } 100 101 c.subAndroidMk(&ret, c.compiler) 102 c.subAndroidMk(&ret, c.linker) 103 if c.sanitize != nil { 104 c.subAndroidMk(&ret, c.sanitize) 105 } 106 c.subAndroidMk(&ret, c.installer) 107 108 if c.useVndk() && c.hasVendorVariant() { 109 // .vendor suffix is added only when we will have two variants: core and vendor. 110 // The suffix is not added for vendor-only module. 111 ret.SubName += vendorSuffix 112 } else if c.inRecovery() && !c.onlyInRecovery() { 113 ret.SubName += recoverySuffix 114 } 115 116 return ret 117} 118 119func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, ret *android.AndroidMkData) { 120 var testFiles []string 121 for _, d := range data { 122 rel := d.Rel() 123 path := d.String() 124 if !strings.HasSuffix(path, rel) { 125 panic(fmt.Errorf("path %q does not end with %q", path, rel)) 126 } 127 path = strings.TrimSuffix(path, rel) 128 testFiles = append(testFiles, path+":"+rel) 129 } 130 if len(testFiles) > 0 { 131 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 132 fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(testFiles, " ")) 133 }) 134 } 135} 136 137func (library *libraryDecorator) androidMkWriteExportedFlags(w io.Writer) { 138 exportedFlags := library.exportedFlags() 139 if len(exportedFlags) > 0 { 140 fmt.Fprintln(w, "LOCAL_EXPORT_CFLAGS :=", strings.Join(exportedFlags, " ")) 141 } 142 exportedFlagsDeps := library.exportedFlagsDeps() 143 if len(exportedFlagsDeps) > 0 { 144 fmt.Fprintln(w, "LOCAL_EXPORT_C_INCLUDE_DEPS :=", strings.Join(exportedFlagsDeps.Strings(), " ")) 145 } 146} 147 148func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 149 if library.static() { 150 ret.Class = "STATIC_LIBRARIES" 151 } else if library.shared() { 152 ret.Class = "SHARED_LIBRARIES" 153 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 154 fmt.Fprintln(w, "LOCAL_SOONG_TOC :=", library.toc().String()) 155 if !library.buildStubs() { 156 fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", library.unstrippedOutputFile.String()) 157 } 158 if len(library.Properties.Overrides) > 0 { 159 fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(library.Properties.Overrides, " ")) 160 } 161 if len(library.post_install_cmds) > 0 { 162 fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := "+strings.Join(library.post_install_cmds, "&& ")) 163 } 164 }) 165 } else if library.header() { 166 ret.Class = "HEADER_LIBRARIES" 167 } 168 169 ret.DistFile = library.distFile 170 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 171 library.androidMkWriteExportedFlags(w) 172 fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES := ") 173 if library.sAbiOutputFile.Valid() { 174 fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES += ", library.sAbiOutputFile.String()) 175 if library.sAbiDiff.Valid() && !library.static() { 176 fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES += ", library.sAbiDiff.String()) 177 fmt.Fprintln(w, "HEADER_ABI_DIFFS += ", library.sAbiDiff.String()) 178 } 179 } 180 181 _, _, ext := splitFileExt(outputFile.Base()) 182 183 fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext) 184 185 if library.coverageOutputFile.Valid() { 186 fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", library.coverageOutputFile.String()) 187 } 188 189 if library.useCoreVariant { 190 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true") 191 fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true") 192 fmt.Fprintln(w, "LOCAL_VNDK_DEPEND_ON_CORE_VARIANT := true") 193 } 194 }) 195 196 if library.shared() && !library.buildStubs() { 197 ctx.subAndroidMk(ret, library.baseInstaller) 198 } else { 199 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 200 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true") 201 if library.buildStubs() { 202 fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true") 203 } 204 }) 205 } 206 if len(library.Properties.Stubs.Versions) > 0 && 207 android.DirectlyInAnyApex(ctx, ctx.Name()) && !ctx.inRecovery() && !ctx.useVndk() && 208 !ctx.static() { 209 if !library.buildStubs() { 210 ret.SubName = ".bootstrap" 211 } 212 } 213} 214 215func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 216 ret.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { 217 out := ret.OutputFile.Path() 218 varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, data.SubName) 219 220 fmt.Fprintf(w, "\n%s := %s\n", varname, out.String()) 221 fmt.Fprintln(w, ".KATI_READONLY: "+varname) 222 } 223} 224 225func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 226 ctx.subAndroidMk(ret, binary.baseInstaller) 227 228 ret.Class = "EXECUTABLES" 229 ret.DistFile = binary.distFile 230 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 231 fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", binary.unstrippedOutputFile.String()) 232 if len(binary.symlinks) > 0 { 233 fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(binary.symlinks, " ")) 234 } 235 236 if binary.coverageOutputFile.Valid() { 237 fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", binary.coverageOutputFile.String()) 238 } 239 240 if len(binary.Properties.Overrides) > 0 { 241 fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(binary.Properties.Overrides, " ")) 242 } 243 if len(binary.post_install_cmds) > 0 { 244 fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := "+strings.Join(binary.post_install_cmds, "&& ")) 245 } 246 }) 247} 248 249func (benchmark *benchmarkDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 250 ctx.subAndroidMk(ret, benchmark.binaryDecorator) 251 ret.Class = "NATIVE_TESTS" 252 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 253 if len(benchmark.Properties.Test_suites) > 0 { 254 fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=", 255 strings.Join(benchmark.Properties.Test_suites, " ")) 256 } 257 if benchmark.testConfig != nil { 258 fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=", benchmark.testConfig.String()) 259 } 260 fmt.Fprintln(w, "LOCAL_NATIVE_BENCHMARK := true") 261 }) 262 263 androidMkWriteTestData(benchmark.data, ctx, ret) 264} 265 266func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 267 ctx.subAndroidMk(ret, test.binaryDecorator) 268 ret.Class = "NATIVE_TESTS" 269 if Bool(test.Properties.Test_per_src) { 270 ret.SubName = "_" + String(test.binaryDecorator.Properties.Stem) 271 } 272 273 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 274 if len(test.Properties.Test_suites) > 0 { 275 fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=", 276 strings.Join(test.Properties.Test_suites, " ")) 277 } 278 if test.testConfig != nil { 279 fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=", test.testConfig.String()) 280 } 281 }) 282 283 androidMkWriteTestData(test.data, ctx, ret) 284} 285 286func (test *testLibrary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 287 ctx.subAndroidMk(ret, test.libraryDecorator) 288} 289 290func (library *toolchainLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 291 ret.Class = "STATIC_LIBRARIES" 292 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 293 _, suffix, _ := splitFileExt(outputFile.Base()) 294 fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix) 295 }) 296} 297 298func (installer *baseInstaller) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 299 // Soong installation is only supported for host modules. Have Make 300 // installation trigger Soong installation. 301 if ctx.Target().Os.Class == android.Host { 302 ret.OutputFile = android.OptionalPathForPath(installer.path) 303 } 304 305 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 306 path := installer.path.RelPathString() 307 dir, file := filepath.Split(path) 308 stem, suffix, _ := splitFileExt(file) 309 fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix) 310 fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir)) 311 fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) 312 }) 313} 314 315func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 316 ret.SubName = ndkLibrarySuffix + "." + c.properties.ApiLevel 317 ret.Class = "SHARED_LIBRARIES" 318 319 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 320 path, file := filepath.Split(c.installPath.String()) 321 stem, suffix, _ := splitFileExt(file) 322 fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix) 323 fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path) 324 fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) 325 fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true") 326 }) 327} 328 329func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 330 ret.Class = "SHARED_LIBRARIES" 331 ret.SubName = vendorSuffix 332 333 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 334 c.libraryDecorator.androidMkWriteExportedFlags(w) 335 _, _, ext := splitFileExt(outputFile.Base()) 336 337 fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext) 338 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true") 339 fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true") 340 fmt.Fprintln(w, "LOCAL_SOONG_TOC :=", c.toc().String()) 341 }) 342} 343 344func (c *vndkPrebuiltLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 345 ret.Class = "SHARED_LIBRARIES" 346 347 ret.SubName = c.NameSuffix() 348 349 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 350 c.libraryDecorator.androidMkWriteExportedFlags(w) 351 352 path := c.path.RelPathString() 353 dir, file := filepath.Split(path) 354 stem, suffix, ext := splitFileExt(file) 355 fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext) 356 fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix) 357 fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir)) 358 fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) 359 }) 360} 361 362func (c *ndkPrebuiltStlLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 363 ret.Class = "SHARED_LIBRARIES" 364} 365 366func (c *vendorPublicLibraryStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 367 ret.Class = "SHARED_LIBRARIES" 368 ret.SubName = vendorPublicLibrarySuffix 369 370 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 371 c.libraryDecorator.androidMkWriteExportedFlags(w) 372 _, _, ext := splitFileExt(outputFile.Base()) 373 374 fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext) 375 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true") 376 fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true") 377 }) 378} 379 380func (p *prebuiltLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 381 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 382 if p.properties.Check_elf_files != nil { 383 fmt.Fprintln(w, "LOCAL_CHECK_ELF_FILES :=", *p.properties.Check_elf_files) 384 } else { 385 // soong_cc_prebuilt.mk does not include check_elf_file.mk by default 386 // because cc_library_shared and cc_binary use soong_cc_prebuilt.mk as well. 387 // In order to turn on prebuilt ABI checker, set `LOCAL_CHECK_ELF_FILES` to 388 // true if `p.properties.Check_elf_files` is not specified. 389 fmt.Fprintln(w, "LOCAL_CHECK_ELF_FILES := true") 390 } 391 }) 392} 393 394func (p *prebuiltLibraryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 395 ctx.subAndroidMk(ret, p.libraryDecorator) 396 if p.shared() { 397 ctx.subAndroidMk(ret, &p.prebuiltLinker) 398 androidMkWriteAllowUndefinedSymbols(p.baseLinker, ret) 399 } 400} 401 402func (p *prebuiltBinaryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { 403 ctx.subAndroidMk(ret, p.binaryDecorator) 404 ctx.subAndroidMk(ret, &p.prebuiltLinker) 405 androidMkWriteAllowUndefinedSymbols(p.baseLinker, ret) 406} 407 408func androidMkWriteAllowUndefinedSymbols(linker *baseLinker, ret *android.AndroidMkData) { 409 ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { 410 allow := linker.Properties.Allow_undefined_symbols 411 if allow != nil { 412 fmt.Fprintln(w, "LOCAL_ALLOW_UNDEFINED_SYMBOLS :=", *allow) 413 } 414 }) 415} 416