2019-11-15 01:59:12 +01:00
|
|
|
// Copyright 2020 The Android Open Source Project
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
2022-08-16 19:27:33 +02:00
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
2019-11-15 01:59:12 +01:00
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
package cc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"android/soong/android"
|
2021-07-07 05:42:39 +02:00
|
|
|
"android/soong/snapshot"
|
2019-11-15 01:59:12 +01:00
|
|
|
)
|
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
// This file defines how to capture cc modules into snapshot package.
|
2020-11-13 21:07:36 +01:00
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
// Checks if the target image would contain VNDK
|
|
|
|
func includeVndk(image snapshot.SnapshotImage) bool {
|
|
|
|
if image.ImageName() == snapshot.VendorSnapshotImageName {
|
2020-09-01 01:07:58 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
// Check if the module is VNDK private
|
|
|
|
func isPrivate(image snapshot.SnapshotImage, m LinkableInterface) bool {
|
|
|
|
if image.ImageName() == snapshot.VendorSnapshotImageName && m.IsVndkPrivate() {
|
2020-12-11 22:36:29 +01:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
return false
|
|
|
|
}
|
2020-12-11 22:36:29 +01:00
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
// Checks if target image supports VNDK Ext
|
|
|
|
func supportsVndkExt(image snapshot.SnapshotImage) bool {
|
|
|
|
if image.ImageName() == snapshot.VendorSnapshotImageName {
|
|
|
|
return true
|
2020-12-11 22:36:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-12-02 05:14:28 +01:00
|
|
|
// Determines if the module is a candidate for snapshot.
|
2021-07-07 05:42:39 +02:00
|
|
|
func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshot.SnapshotImage) bool {
|
2021-04-01 15:49:36 +02:00
|
|
|
if !m.Enabled() || m.HiddenFromMake() {
|
2019-11-15 01:59:12 +01:00
|
|
|
return false
|
|
|
|
}
|
2020-09-10 02:46:05 +02:00
|
|
|
// When android/prebuilt.go selects between source and prebuilt, it sets
|
2020-12-16 19:20:23 +01:00
|
|
|
// HideFromMake on the other one to avoid duplicate install rules in make.
|
|
|
|
if m.IsHideFromMake() {
|
2020-09-10 02:46:05 +02:00
|
|
|
return false
|
|
|
|
}
|
2020-11-13 21:07:36 +01:00
|
|
|
// skip proprietary modules, but (for the vendor snapshot only)
|
|
|
|
// include all VNDK (static)
|
2021-07-07 05:42:39 +02:00
|
|
|
if inProprietaryPath && (!includeVndk(image) || !m.IsVndk()) {
|
2020-09-01 01:07:58 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
// If the module would be included based on its path, check to see if
|
|
|
|
// the module is marked to be excluded. If so, skip it.
|
2021-07-07 05:42:39 +02:00
|
|
|
if image.ExcludeFromSnapshot(m) {
|
2019-11-15 01:59:12 +01:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
if m.Target().Os.Class != android.Device {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if m.Target().NativeBridge == android.NativeBridgeEnabled {
|
|
|
|
return false
|
|
|
|
}
|
2020-12-02 05:14:28 +01:00
|
|
|
// the module must be installed in target image
|
2021-07-07 05:42:39 +02:00
|
|
|
if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.InImage(m)() {
|
2019-11-15 01:59:12 +01:00
|
|
|
return false
|
|
|
|
}
|
2020-06-11 06:55:45 +02:00
|
|
|
// skip kernel_headers which always depend on vendor
|
2021-04-01 15:49:36 +02:00
|
|
|
if m.KernelHeadersDecorator() {
|
2020-06-11 06:55:45 +02:00
|
|
|
return false
|
|
|
|
}
|
2021-04-01 15:49:36 +02:00
|
|
|
|
2020-12-17 01:46:01 +01:00
|
|
|
if m.IsLlndk() {
|
|
|
|
return false
|
|
|
|
}
|
2019-11-15 01:59:12 +01:00
|
|
|
|
|
|
|
// Libraries
|
2021-04-01 15:49:36 +02:00
|
|
|
if sanitizable, ok := m.(PlatformSanitizeable); ok && sanitizable.IsSnapshotLibrary() {
|
|
|
|
if sanitizable.SanitizePropDefined() {
|
2022-12-15 13:45:35 +01:00
|
|
|
// scs exports both sanitized and unsanitized variants for static and header
|
|
|
|
// Always use unsanitized variant of it.
|
2023-07-31 20:01:26 +02:00
|
|
|
if !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(scs) {
|
2022-12-15 13:45:35 +01:00
|
|
|
return false
|
2020-06-01 14:53:49 +02:00
|
|
|
}
|
2023-09-25 16:07:49 +02:00
|
|
|
// cfi and hwasan cannot be enabled at the same time.
|
|
|
|
// Skip variants that have both cfi and hwasan enabled.
|
|
|
|
if sanitizable.IsSanitizerEnabled(cfi) && sanitizable.IsSanitizerEnabled(Hwasan) {
|
|
|
|
return false
|
|
|
|
}
|
2022-12-15 13:45:35 +01:00
|
|
|
// cfi and hwasan also export both variants. But for static, we capture both.
|
2020-12-02 05:14:28 +01:00
|
|
|
// This is because cfi static libraries can't be linked from non-cfi modules,
|
2022-12-15 13:45:35 +01:00
|
|
|
// and vice versa.
|
|
|
|
// hwasan is captured as well to support hwasan build.
|
|
|
|
if !sanitizable.Static() &&
|
|
|
|
!sanitizable.Shared() &&
|
|
|
|
(sanitizable.IsSanitizerEnabled(cfi) || sanitizable.IsSanitizerEnabled(Hwasan)) {
|
Add cfi static libraries to vendor snapshot
CFI modules can't link against non-CFI static libraries, and vice versa.
So without capturing both CFI and non-CFI static libraries, vendor
modules won't be able to use CFI, which will be a critical security
hole.
This captures both CFI and non-CFI variants of all static libraries for
vendor snapshot, except for those whose cfi are explicitly disabled.
For example, suppose that "libfoo" is defined as follows.
cc_library_static {
name: "libfoo",
vendor_available: true,
}
As it doesn't have cfi disabled, two libraries "libfoo.a" and
"libfoo.cfi.a" will be captured. When installed, vendor snapshot module
for "libfoo" will look like:
vendor_snapshot_static {
name: "libfoo",
src: "libfoo.a",
cfi: {
src: "libfoo.cfi.a",
},
}
The build system will recognize the "cfi" property, and will create both
CFI and non-CFI variant, allowing any modules to link against "libfoo"
safely, no matter whether CFI is enabled or not.
Two clarification:
1) The reason why we don't create separate modules is that DepsMutator
runs before sanitize mutators. CFI and non-CFI variant of a library
should exist in a single module.
2) We can't capture CFI variant if the source module explicitly disables
cfi variant by specifying the following.
sanitize: {
cfi: false,
}
In this case, only non-CFI variant will be created for the vendor
snapshot module.
Bug: 65377115
Test: m dist vendor-snapshot && install && build against snapshot
Change-Id: Idbf3e3205d581800d6093c8d6cf6152374129ba4
2020-07-29 13:32:10 +02:00
|
|
|
return false
|
|
|
|
}
|
2020-06-01 14:53:49 +02:00
|
|
|
}
|
2023-07-13 17:01:41 +02:00
|
|
|
if sanitizable.Static() || sanitizable.Rlib() {
|
2021-07-07 05:42:39 +02:00
|
|
|
return sanitizable.OutputFile().Valid() && !isPrivate(image, m)
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
2023-07-13 17:01:41 +02:00
|
|
|
if sanitizable.Shared() || sanitizable.Dylib() {
|
2021-04-01 15:49:36 +02:00
|
|
|
if !sanitizable.OutputFile().Valid() {
|
2020-06-30 01:49:15 +02:00
|
|
|
return false
|
|
|
|
}
|
2021-07-07 05:42:39 +02:00
|
|
|
if includeVndk(image) {
|
2021-04-01 15:49:36 +02:00
|
|
|
if !sanitizable.IsVndk() {
|
2020-11-13 21:07:36 +01:00
|
|
|
return true
|
|
|
|
}
|
2021-04-01 15:49:36 +02:00
|
|
|
return sanitizable.IsVndkExt()
|
2020-06-30 01:49:15 +02:00
|
|
|
}
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-06-01 16:23:05 +02:00
|
|
|
// Binaries and Objects
|
2021-04-01 15:49:36 +02:00
|
|
|
if m.Binary() || m.Object() {
|
|
|
|
return m.OutputFile().Valid()
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
2020-06-01 14:53:49 +02:00
|
|
|
|
|
|
|
return false
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
|
2021-08-10 22:42:03 +02:00
|
|
|
// Extend the snapshot.SnapshotJsonFlags to include cc specific fields.
|
2020-12-02 05:14:28 +01:00
|
|
|
type snapshotJsonFlags struct {
|
2021-08-10 22:42:03 +02:00
|
|
|
snapshot.SnapshotJsonFlags
|
2020-12-02 05:14:28 +01:00
|
|
|
// library flags
|
|
|
|
ExportedDirs []string `json:",omitempty"`
|
|
|
|
ExportedSystemDirs []string `json:",omitempty"`
|
|
|
|
ExportedFlags []string `json:",omitempty"`
|
|
|
|
Sanitize string `json:",omitempty"`
|
|
|
|
SanitizeMinimalDep bool `json:",omitempty"`
|
|
|
|
SanitizeUbsanDep bool `json:",omitempty"`
|
|
|
|
|
|
|
|
// binary flags
|
2021-06-29 13:50:37 +02:00
|
|
|
Symlinks []string `json:",omitempty"`
|
|
|
|
StaticExecutable bool `json:",omitempty"`
|
2022-03-07 23:07:59 +01:00
|
|
|
InstallInRoot bool `json:",omitempty"`
|
2020-12-02 05:14:28 +01:00
|
|
|
|
|
|
|
// dependencies
|
|
|
|
SharedLibs []string `json:",omitempty"`
|
2021-06-29 13:50:37 +02:00
|
|
|
StaticLibs []string `json:",omitempty"`
|
2020-12-02 05:14:28 +01:00
|
|
|
RuntimeLibs []string `json:",omitempty"`
|
2023-07-13 17:01:41 +02:00
|
|
|
Dylibs []string `json:",omitempty"`
|
|
|
|
Rlibs []string `json:",omitempty"`
|
2020-12-02 05:14:28 +01:00
|
|
|
|
|
|
|
// extra config files
|
|
|
|
InitRc []string `json:",omitempty"`
|
|
|
|
VintfFragments []string `json:",omitempty"`
|
2023-04-18 04:30:22 +02:00
|
|
|
MinSdkVersion string `json:",omitempty"`
|
2020-12-02 05:14:28 +01:00
|
|
|
}
|
|
|
|
|
2023-04-11 11:20:07 +02:00
|
|
|
var ccSnapshotAction snapshot.GenerateSnapshotAction = func(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) snapshot.SnapshotPaths {
|
2019-11-15 01:59:12 +01:00
|
|
|
/*
|
2021-07-07 05:42:39 +02:00
|
|
|
Vendor snapshot zipped artifacts directory structure for cc modules:
|
2019-11-15 01:59:12 +01:00
|
|
|
{SNAPSHOT_ARCH}/
|
|
|
|
arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
|
|
|
|
shared/
|
|
|
|
(.so shared libraries)
|
|
|
|
static/
|
|
|
|
(.a static libraries)
|
|
|
|
header/
|
|
|
|
(header only libraries)
|
|
|
|
binary/
|
|
|
|
(executable binaries)
|
2020-06-01 16:23:05 +02:00
|
|
|
object/
|
|
|
|
(.o object files)
|
2019-11-15 01:59:12 +01:00
|
|
|
arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
|
|
|
|
shared/
|
|
|
|
(.so shared libraries)
|
|
|
|
static/
|
|
|
|
(.a static libraries)
|
|
|
|
header/
|
|
|
|
(header only libraries)
|
|
|
|
binary/
|
|
|
|
(executable binaries)
|
2020-06-01 16:23:05 +02:00
|
|
|
object/
|
|
|
|
(.o object files)
|
2019-11-15 01:59:12 +01:00
|
|
|
NOTICE_FILES/
|
|
|
|
(notice files, e.g. libbase.txt)
|
|
|
|
configs/
|
|
|
|
(config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
|
|
|
|
include/
|
|
|
|
(header files of same directory structure with source tree)
|
|
|
|
*/
|
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
var snapshotOutputs android.Paths
|
2023-04-11 11:20:07 +02:00
|
|
|
var snapshotNotices android.Paths
|
2019-11-15 01:59:12 +01:00
|
|
|
|
|
|
|
includeDir := filepath.Join(snapshotArchDir, "include")
|
|
|
|
configsDir := filepath.Join(snapshotArchDir, "configs")
|
|
|
|
|
|
|
|
installedNotices := make(map[string]bool)
|
|
|
|
installedConfigs := make(map[string]bool)
|
|
|
|
|
|
|
|
var headers android.Paths
|
|
|
|
|
2021-02-03 23:23:15 +01:00
|
|
|
copyFile := func(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
|
|
|
|
if fake {
|
|
|
|
// All prebuilt binaries and headers are installed by copyFile function. This makes a fake
|
|
|
|
// snapshot just touch prebuilts and headers, rather than installing real files.
|
2021-07-19 04:38:04 +02:00
|
|
|
return snapshot.WriteStringToFileRule(ctx, "", out)
|
2021-02-03 23:23:15 +01:00
|
|
|
} else {
|
2021-07-19 04:38:04 +02:00
|
|
|
return snapshot.CopyFileRule(pctx, ctx, path, out)
|
2021-01-05 12:03:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-02 05:14:28 +01:00
|
|
|
// installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
|
|
|
|
// For executables, init_rc and vintf_fragments files are also copied.
|
2021-04-01 15:49:36 +02:00
|
|
|
installSnapshot := func(m LinkableInterface, fake bool) android.Paths {
|
2019-11-15 01:59:12 +01:00
|
|
|
targetArch := "arch-" + m.Target().Arch.ArchType.String()
|
|
|
|
if m.Target().Arch.ArchVariant != "" {
|
|
|
|
targetArch += "-" + m.Target().Arch.ArchVariant
|
|
|
|
}
|
|
|
|
|
|
|
|
var ret android.Paths
|
|
|
|
|
2020-12-02 05:14:28 +01:00
|
|
|
prop := snapshotJsonFlags{}
|
2019-11-15 01:59:12 +01:00
|
|
|
|
|
|
|
// Common properties among snapshots.
|
2023-04-11 11:20:07 +02:00
|
|
|
prop.InitBaseSnapshotPropsWithName(m, ctx.ModuleName(m))
|
2021-07-07 05:42:39 +02:00
|
|
|
if supportsVndkExt(s.Image) && m.IsVndkExt() {
|
2020-06-30 01:49:15 +02:00
|
|
|
// vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
|
2021-04-01 15:49:36 +02:00
|
|
|
if m.IsVndkSp() {
|
2020-06-30 01:49:15 +02:00
|
|
|
prop.RelativeInstallPath = "vndk-sp"
|
|
|
|
} else {
|
|
|
|
prop.RelativeInstallPath = "vndk"
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
prop.RelativeInstallPath = m.RelativeInstallPath()
|
|
|
|
}
|
2021-04-01 15:49:36 +02:00
|
|
|
prop.RuntimeLibs = m.SnapshotRuntimeLibs()
|
2019-11-15 01:59:12 +01:00
|
|
|
prop.Required = m.RequiredModuleNames()
|
2022-10-04 07:42:02 +02:00
|
|
|
if o, ok := m.(overridable); ok {
|
|
|
|
prop.Overrides = o.overriddenModules()
|
|
|
|
}
|
2019-11-15 01:59:12 +01:00
|
|
|
for _, path := range m.InitRc() {
|
|
|
|
prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
|
|
|
|
}
|
|
|
|
for _, path := range m.VintfFragments() {
|
|
|
|
prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
|
|
|
|
}
|
2023-05-08 14:06:59 +02:00
|
|
|
if m.IsPrebuilt() {
|
|
|
|
prop.MinSdkVersion = "apex_inherit"
|
|
|
|
} else {
|
|
|
|
prop.MinSdkVersion = m.MinSdkVersion()
|
|
|
|
}
|
2019-11-15 01:59:12 +01:00
|
|
|
|
|
|
|
// install config files. ignores any duplicates.
|
|
|
|
for _, path := range append(m.InitRc(), m.VintfFragments()...) {
|
|
|
|
out := filepath.Join(configsDir, path.Base())
|
|
|
|
if !installedConfigs[out] {
|
|
|
|
installedConfigs[out] = true
|
2021-02-03 23:23:15 +01:00
|
|
|
ret = append(ret, copyFile(ctx, path, out, fake))
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var propOut string
|
|
|
|
|
2021-04-01 15:49:36 +02:00
|
|
|
if m.IsSnapshotLibrary() {
|
2023-12-14 23:46:23 +01:00
|
|
|
exporterInfo, _ := android.SingletonModuleProvider(ctx, m.Module(), FlagExporterInfoProvider)
|
Add cfi static libraries to vendor snapshot
CFI modules can't link against non-CFI static libraries, and vice versa.
So without capturing both CFI and non-CFI static libraries, vendor
modules won't be able to use CFI, which will be a critical security
hole.
This captures both CFI and non-CFI variants of all static libraries for
vendor snapshot, except for those whose cfi are explicitly disabled.
For example, suppose that "libfoo" is defined as follows.
cc_library_static {
name: "libfoo",
vendor_available: true,
}
As it doesn't have cfi disabled, two libraries "libfoo.a" and
"libfoo.cfi.a" will be captured. When installed, vendor snapshot module
for "libfoo" will look like:
vendor_snapshot_static {
name: "libfoo",
src: "libfoo.a",
cfi: {
src: "libfoo.cfi.a",
},
}
The build system will recognize the "cfi" property, and will create both
CFI and non-CFI variant, allowing any modules to link against "libfoo"
safely, no matter whether CFI is enabled or not.
Two clarification:
1) The reason why we don't create separate modules is that DepsMutator
runs before sanitize mutators. CFI and non-CFI variant of a library
should exist in a single module.
2) We can't capture CFI variant if the source module explicitly disables
cfi variant by specifying the following.
sanitize: {
cfi: false,
}
In this case, only non-CFI variant will be created for the vendor
snapshot module.
Bug: 65377115
Test: m dist vendor-snapshot && install && build against snapshot
Change-Id: Idbf3e3205d581800d6093c8d6cf6152374129ba4
2020-07-29 13:32:10 +02:00
|
|
|
|
2019-11-15 01:59:12 +01:00
|
|
|
// library flags
|
2020-09-18 23:15:30 +02:00
|
|
|
prop.ExportedFlags = exporterInfo.Flags
|
|
|
|
for _, dir := range exporterInfo.IncludeDirs {
|
2019-11-15 01:59:12 +01:00
|
|
|
prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
|
|
|
|
}
|
2020-09-18 23:15:30 +02:00
|
|
|
for _, dir := range exporterInfo.SystemIncludeDirs {
|
2019-11-15 01:59:12 +01:00
|
|
|
prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
|
|
|
|
}
|
2021-04-01 15:49:36 +02:00
|
|
|
|
2019-11-15 01:59:12 +01:00
|
|
|
// shared libs dependencies aren't meaningful on static or header libs
|
2021-04-01 15:49:36 +02:00
|
|
|
if m.Shared() {
|
|
|
|
prop.SharedLibs = m.SnapshotSharedLibs()
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
2023-07-13 17:01:41 +02:00
|
|
|
|
|
|
|
// dylibs collect both shared and dylib dependencies.
|
|
|
|
if m.Dylib() {
|
|
|
|
prop.SharedLibs = m.SnapshotSharedLibs()
|
|
|
|
prop.Dylibs = m.SnapshotDylibs()
|
|
|
|
}
|
|
|
|
|
|
|
|
// static and rlib libs dependencies are required to collect the NOTICE files.
|
2021-06-29 13:50:37 +02:00
|
|
|
prop.StaticLibs = m.SnapshotStaticLibs()
|
2023-07-13 17:01:41 +02:00
|
|
|
prop.Rlibs = m.SnapshotRlibs()
|
|
|
|
|
2021-04-01 15:49:36 +02:00
|
|
|
if sanitizable, ok := m.(PlatformSanitizeable); ok {
|
|
|
|
if sanitizable.Static() && sanitizable.SanitizePropDefined() {
|
|
|
|
prop.SanitizeMinimalDep = sanitizable.MinimalRuntimeDep() || sanitizable.MinimalRuntimeNeeded()
|
|
|
|
prop.SanitizeUbsanDep = sanitizable.UbsanRuntimeDep() || sanitizable.UbsanRuntimeNeeded()
|
|
|
|
}
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var libType string
|
2021-04-01 15:49:36 +02:00
|
|
|
if m.Static() {
|
2019-11-15 01:59:12 +01:00
|
|
|
libType = "static"
|
2021-04-01 15:49:36 +02:00
|
|
|
} else if m.Shared() {
|
2019-11-15 01:59:12 +01:00
|
|
|
libType = "shared"
|
2021-06-01 21:09:53 +02:00
|
|
|
} else if m.Rlib() {
|
|
|
|
libType = "rlib"
|
2023-07-13 17:01:41 +02:00
|
|
|
} else if m.Dylib() {
|
|
|
|
libType = "dylib"
|
2019-11-15 01:59:12 +01:00
|
|
|
} else {
|
|
|
|
libType = "header"
|
|
|
|
}
|
|
|
|
|
|
|
|
var stem string
|
|
|
|
|
2023-07-13 17:01:41 +02:00
|
|
|
// install .a, .rlib, .dylib.so, or .so
|
2019-11-15 01:59:12 +01:00
|
|
|
if libType != "header" {
|
2021-04-01 15:49:36 +02:00
|
|
|
libPath := m.OutputFile().Path()
|
2019-11-15 01:59:12 +01:00
|
|
|
stem = libPath.Base()
|
2021-04-01 15:49:36 +02:00
|
|
|
if sanitizable, ok := m.(PlatformSanitizeable); ok {
|
2022-12-15 13:45:35 +01:00
|
|
|
if (sanitizable.Static() || sanitizable.Rlib()) && sanitizable.SanitizePropDefined() {
|
|
|
|
if sanitizable.IsSanitizerEnabled(cfi) {
|
|
|
|
// both cfi and non-cfi variant for static libraries can exist.
|
|
|
|
// attach .cfi to distinguish between cfi and non-cfi.
|
|
|
|
// e.g. libbase.a -> libbase.cfi.a
|
|
|
|
ext := filepath.Ext(stem)
|
|
|
|
stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
|
|
|
|
prop.Sanitize = "cfi"
|
|
|
|
prop.ModuleName += ".cfi"
|
|
|
|
} else if sanitizable.IsSanitizerEnabled(Hwasan) {
|
|
|
|
// Same for the hwasan
|
|
|
|
ext := filepath.Ext(stem)
|
|
|
|
stem = strings.TrimSuffix(stem, ext) + ".hwasan" + ext
|
|
|
|
prop.Sanitize = "hwasan"
|
|
|
|
prop.ModuleName += ".hwasan"
|
|
|
|
}
|
2021-04-01 15:49:36 +02:00
|
|
|
}
|
Add cfi static libraries to vendor snapshot
CFI modules can't link against non-CFI static libraries, and vice versa.
So without capturing both CFI and non-CFI static libraries, vendor
modules won't be able to use CFI, which will be a critical security
hole.
This captures both CFI and non-CFI variants of all static libraries for
vendor snapshot, except for those whose cfi are explicitly disabled.
For example, suppose that "libfoo" is defined as follows.
cc_library_static {
name: "libfoo",
vendor_available: true,
}
As it doesn't have cfi disabled, two libraries "libfoo.a" and
"libfoo.cfi.a" will be captured. When installed, vendor snapshot module
for "libfoo" will look like:
vendor_snapshot_static {
name: "libfoo",
src: "libfoo.a",
cfi: {
src: "libfoo.cfi.a",
},
}
The build system will recognize the "cfi" property, and will create both
CFI and non-CFI variant, allowing any modules to link against "libfoo"
safely, no matter whether CFI is enabled or not.
Two clarification:
1) The reason why we don't create separate modules is that DepsMutator
runs before sanitize mutators. CFI and non-CFI variant of a library
should exist in a single module.
2) We can't capture CFI variant if the source module explicitly disables
cfi variant by specifying the following.
sanitize: {
cfi: false,
}
In this case, only non-CFI variant will be created for the vendor
snapshot module.
Bug: 65377115
Test: m dist vendor-snapshot && install && build against snapshot
Change-Id: Idbf3e3205d581800d6093c8d6cf6152374129ba4
2020-07-29 13:32:10 +02:00
|
|
|
}
|
2023-07-13 17:01:41 +02:00
|
|
|
if m.Rlib() && m.RlibStd() {
|
|
|
|
// rlibs produce both rlib-std and dylib-std variants
|
|
|
|
ext := filepath.Ext(stem)
|
|
|
|
stem = strings.TrimSuffix(stem, ext) + ".rlib-std" + ext
|
|
|
|
prop.ModuleName += ".rlib-std"
|
|
|
|
}
|
2023-05-02 07:56:38 +02:00
|
|
|
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, m.RelativeInstallPath(), stem)
|
2021-02-03 23:23:15 +01:00
|
|
|
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut, fake))
|
2019-11-15 01:59:12 +01:00
|
|
|
} else {
|
|
|
|
stem = ctx.ModuleName(m)
|
|
|
|
}
|
|
|
|
|
2023-05-02 07:56:38 +02:00
|
|
|
propOut = filepath.Join(snapshotArchDir, targetArch, libType, m.RelativeInstallPath(), stem+".json")
|
2021-04-01 15:49:36 +02:00
|
|
|
} else if m.Binary() {
|
2019-11-15 01:59:12 +01:00
|
|
|
// binary flags
|
|
|
|
prop.Symlinks = m.Symlinks()
|
2021-06-29 13:50:37 +02:00
|
|
|
prop.StaticExecutable = m.StaticExecutable()
|
2022-03-07 23:07:59 +01:00
|
|
|
prop.InstallInRoot = m.InstallInRoot()
|
2021-04-01 15:49:36 +02:00
|
|
|
prop.SharedLibs = m.SnapshotSharedLibs()
|
2023-07-13 17:01:41 +02:00
|
|
|
prop.Dylibs = m.SnapshotDylibs()
|
|
|
|
|
|
|
|
// static and rlib dependencies are required to collect the NOTICE files.
|
2021-06-29 13:50:37 +02:00
|
|
|
prop.StaticLibs = m.SnapshotStaticLibs()
|
2023-07-13 17:01:41 +02:00
|
|
|
prop.Rlibs = m.SnapshotRlibs()
|
|
|
|
|
2019-11-15 01:59:12 +01:00
|
|
|
// install bin
|
2021-04-01 15:49:36 +02:00
|
|
|
binPath := m.OutputFile().Path()
|
2019-11-15 01:59:12 +01:00
|
|
|
snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
|
2021-02-03 23:23:15 +01:00
|
|
|
ret = append(ret, copyFile(ctx, binPath, snapshotBinOut, fake))
|
2019-11-15 01:59:12 +01:00
|
|
|
propOut = snapshotBinOut + ".json"
|
2021-04-01 15:49:36 +02:00
|
|
|
} else if m.Object() {
|
2020-06-01 16:23:05 +02:00
|
|
|
// object files aren't installed to the device, so their names can conflict.
|
|
|
|
// Use module name as stem.
|
2021-04-01 15:49:36 +02:00
|
|
|
objPath := m.OutputFile().Path()
|
2020-06-01 16:23:05 +02:00
|
|
|
snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
|
|
|
|
ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
|
2021-02-03 23:23:15 +01:00
|
|
|
ret = append(ret, copyFile(ctx, objPath, snapshotObjOut, fake))
|
2020-06-01 16:23:05 +02:00
|
|
|
propOut = snapshotObjOut + ".json"
|
2020-06-01 14:53:49 +02:00
|
|
|
} else {
|
|
|
|
ctx.Errorf("unknown module %q in vendor snapshot", m.String())
|
|
|
|
return nil
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
j, err := json.Marshal(prop)
|
|
|
|
if err != nil {
|
|
|
|
ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
|
|
|
|
return nil
|
|
|
|
}
|
2021-07-19 04:38:04 +02:00
|
|
|
ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
|
2019-11-15 01:59:12 +01:00
|
|
|
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.VisitAllModules(func(module android.Module) {
|
2021-04-01 15:49:36 +02:00
|
|
|
m, ok := module.(LinkableInterface)
|
2020-03-03 14:06:32 +01:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
moduleDir := ctx.ModuleDir(module)
|
2021-07-07 05:42:39 +02:00
|
|
|
inProprietaryPath := s.Image.IsProprietaryPath(moduleDir, ctx.DeviceConfig())
|
2023-12-14 23:46:23 +01:00
|
|
|
apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider)
|
2020-09-01 01:07:58 +02:00
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
if s.Image.ExcludeFromSnapshot(m) {
|
2020-11-13 21:07:36 +01:00
|
|
|
if inProprietaryPath {
|
2020-09-01 01:07:58 +02:00
|
|
|
// Error: exclude_from_vendor_snapshot applies
|
|
|
|
// to framework-path modules only.
|
|
|
|
ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, s.Image) {
|
2019-11-15 01:59:12 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-03 23:23:15 +01:00
|
|
|
// If we are using directed snapshot and a module is not included in the
|
|
|
|
// list, we will still include the module as if it was a fake module.
|
|
|
|
// The reason is that soong needs all the dependencies to be present, even
|
|
|
|
// if they are not using during the build.
|
2021-07-07 05:42:39 +02:00
|
|
|
installAsFake := s.Fake
|
|
|
|
if s.Image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
|
2021-02-03 23:23:15 +01:00
|
|
|
installAsFake = true
|
|
|
|
}
|
2020-12-02 05:14:28 +01:00
|
|
|
|
2021-02-03 23:23:15 +01:00
|
|
|
// installSnapshot installs prebuilts and json flag files
|
|
|
|
snapshotOutputs = append(snapshotOutputs, installSnapshot(m, installAsFake)...)
|
2020-12-02 05:14:28 +01:00
|
|
|
// just gather headers and notice files here, because they are to be deduplicated
|
2021-04-01 15:49:36 +02:00
|
|
|
if m.IsSnapshotLibrary() {
|
|
|
|
headers = append(headers, m.SnapshotHeaders()...)
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
|
2023-04-11 11:20:07 +02:00
|
|
|
for _, notice := range m.EffectiveLicenseFiles() {
|
|
|
|
if _, ok := installedNotices[notice.String()]; !ok {
|
|
|
|
installedNotices[notice.String()] = true
|
|
|
|
snapshotNotices = append(snapshotNotices, notice)
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// install all headers after removing duplicates
|
|
|
|
for _, header := range android.FirstUniquePaths(headers) {
|
2021-07-07 05:42:39 +02:00
|
|
|
snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String()), s.Fake))
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
|
2023-04-11 11:20:07 +02:00
|
|
|
return snapshot.SnapshotPaths{OutputFiles: snapshotOutputs, NoticeFiles: snapshotNotices}
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|
|
|
|
|
2021-07-07 05:42:39 +02:00
|
|
|
func init() {
|
|
|
|
snapshot.RegisterSnapshotAction(ccSnapshotAction)
|
2019-11-15 01:59:12 +01:00
|
|
|
}
|