Revert^2 "Verify that ndk_headers headers are valid C."

181934cc26

Change-Id: I7720331ee8132ead8d0b5624a0b99841884300d3
This commit is contained in:
Dan Albert
2024-08-13 22:01:23 +00:00
committed by Gerrit Code Review
parent 181934cc26
commit 266f991cc5
2 changed files with 104 additions and 2 deletions

View File

@@ -54,7 +54,22 @@ package cc
import (
"android/soong/android"
"fmt"
"path/filepath"
"strings"
"github.com/google/blueprint"
)
var (
verifyCCompat = pctx.AndroidStaticRule("verifyCCompat",
blueprint.RuleParams{
Command: "$ccCmd -x c -fsyntax-only $flags $in && touch $out",
CommandDeps: []string{"$ccCmd"},
},
"ccCmd",
"flags",
)
)
func init() {
@@ -103,6 +118,45 @@ func getNdkABIHeadersFile(ctx android.PathContext) android.WritablePath {
return android.PathForOutput(ctx, "ndk_abi_headers.txt")
}
func verifyNdkHeaderIsCCompatible(ctx android.SingletonContext,
src android.Path, dest android.Path) android.Path {
sysrootInclude := getCurrentIncludePath(ctx)
baseOutputDir := android.PathForOutput(ctx, "c-compat-verification")
installRelPath, err := filepath.Rel(sysrootInclude.String(), dest.String())
if err != nil {
ctx.Errorf("filepath.Rel(%q, %q) failed: %s", dest, sysrootInclude, err)
}
output := baseOutputDir.Join(ctx, installRelPath)
ctx.Build(pctx, android.BuildParams{
Rule: verifyCCompat,
Description: fmt.Sprintf("Verifying C compatibility of %s", src),
Output: output,
Input: dest,
// Ensures that all the headers in the sysroot are already installed
// before testing any of the headers for C compatibility, and also that
// the check will be re-run whenever the sysroot changes. This is
// necessary because many of the NDK headers depend on other NDK
// headers, but we don't have explicit dependency tracking for that.
Implicits: []android.Path{getNdkHeadersTimestampFile(ctx)},
Args: map[string]string{
"ccCmd": "${config.ClangBin}/clang",
"flags": fmt.Sprintf(
// Ideally we'd check each ABI, multiple API levels,
// fortify/non-fortify, and a handful of other variations. It's
// a lot more difficult to do that though, and would eat up more
// build time. All the problems we've seen so far that this
// check would catch have been in arch-generic and
// minSdkVersion-generic code in frameworks though, so this is a
// good place to start.
"-target aarch64-linux-android%d --sysroot %s",
android.FutureApiLevel.FinalOrFutureInt(),
getNdkSysrootBase(ctx).String(),
),
},
})
return output
}
func NdkSingleton() android.Singleton {
return &ndkSingleton{}
}
@@ -143,10 +197,17 @@ func writeNdkAbiSrcFilter(ctx android.BuilderContext,
type ndkSingleton struct{}
type srcDestPair struct {
src android.Path
dest android.Path
}
func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var staticLibInstallPaths android.Paths
var headerSrcPaths android.Paths
var headerInstallPaths android.Paths
var headersToVerify []srcDestPair
var headerCCompatVerificationTimestampPaths android.Paths
var installPaths android.Paths
var licensePaths android.Paths
ctx.VisitAllModules(func(module android.Module) {
@@ -157,6 +218,14 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
if m, ok := module.(*headerModule); ok {
headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
headerInstallPaths = append(headerInstallPaths, m.installPaths...)
if !Bool(m.properties.Skip_verification) {
for i, installPath := range m.installPaths {
headersToVerify = append(headersToVerify, srcDestPair{
src: m.srcPaths[i],
dest: installPath,
})
}
}
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath)
}
@@ -164,6 +233,10 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
if m, ok := module.(*versionedHeaderModule); ok {
headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
headerInstallPaths = append(headerInstallPaths, m.installPaths...)
// Verification intentionally not done for headers that go through
// versioner. It'd be nice to have, but the only user is bionic, and
// that one module would also need to use skip_verification, so it
// wouldn't help at all.
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath)
}
@@ -171,6 +244,14 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
if m, ok := module.(*preprocessedHeadersModule); ok {
headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
headerInstallPaths = append(headerInstallPaths, m.installPaths...)
if !Bool(m.properties.Skip_verification) {
for i, installPath := range m.installPaths {
headersToVerify = append(headersToVerify, srcDestPair{
src: m.srcPaths[i],
dest: installPath,
})
}
}
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath)
}
@@ -223,6 +304,12 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Implicits: headerInstallPaths,
})
for _, srcDestPair := range headersToVerify {
headerCCompatVerificationTimestampPaths = append(
headerCCompatVerificationTimestampPaths,
verifyNdkHeaderIsCCompatible(ctx, srcDestPair.src, srcDestPair.dest))
}
writeNdkAbiSrcFilter(ctx, headerSrcPaths, getNdkABIHeadersFile(ctx))
fullDepPaths := append(staticLibInstallPaths, getNdkBaseTimestampFile(ctx))
@@ -235,6 +322,6 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
ctx.Build(pctx, android.BuildParams{
Rule: android.Touch,
Output: getNdkFullTimestampFile(ctx),
Implicits: fullDepPaths,
Implicits: append(fullDepPaths, headerCCompatVerificationTimestampPaths...),
})
}