From 06fa588d1ae8b9961549a676072807da75392c73 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 29 Oct 2020 18:21:38 -0700 Subject: [PATCH 1/4] Store SingletonMakeVarsProviders in the config Store SingletonMakeVarsProviders in the config instead of a global variable to avoid races between tests running in parallel. Test: all soong tests Change-Id: I2ab64f368b5ac673fd985399d4421ed018abc562 --- android/makevars.go | 51 +++++++++++++++++++-------------------------- android/register.go | 22 +++++++++---------- android/testing.go | 2 +- java/java_test.go | 4 ++-- 4 files changed, 35 insertions(+), 44 deletions(-) diff --git a/android/makevars.go b/android/makevars.go index 3ca7792d4..f78439596 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -139,15 +139,24 @@ type SingletonMakeVarsProvider interface { MakeVars(ctx MakeVarsContext) } -// registerSingletonMakeVarsProvider adds a singleton that implements SingletonMakeVarsProvider to the list of -// MakeVarsProviders to run. -func registerSingletonMakeVarsProvider(singleton SingletonMakeVarsProvider) { - singletonMakeVarsProviders = append(singletonMakeVarsProviders, - makeVarsProvider{pctx, SingletonmakeVarsProviderAdapter(singleton)}) +var singletonMakeVarsProvidersKey = NewOnceKey("singletonMakeVarsProvidersKey") + +// registerSingletonMakeVarsProvider adds a singleton that implements SingletonMakeVarsProvider to +// the list of MakeVarsProviders to run. +func registerSingletonMakeVarsProvider(config Config, singleton SingletonMakeVarsProvider) { + // Singletons are registered on the Context and may be different between different Contexts, + // for example when running multiple tests. Store the SingletonMakeVarsProviders in the + // Config so they are attached to the Context. + singletonMakeVarsProviders := config.Once(singletonMakeVarsProvidersKey, func() interface{} { + return &[]makeVarsProvider{} + }).(*[]makeVarsProvider) + + *singletonMakeVarsProviders = append(*singletonMakeVarsProviders, + makeVarsProvider{pctx, singletonMakeVarsProviderAdapter(singleton)}) } -// SingletonmakeVarsProviderAdapter converts a SingletonMakeVarsProvider to a MakeVarsProvider. -func SingletonmakeVarsProviderAdapter(singleton SingletonMakeVarsProvider) MakeVarsProvider { +// singletonMakeVarsProviderAdapter converts a SingletonMakeVarsProvider to a MakeVarsProvider. +func singletonMakeVarsProviderAdapter(singleton SingletonMakeVarsProvider) MakeVarsProvider { return func(ctx MakeVarsContext) { singleton.MakeVars(ctx) } } @@ -175,9 +184,6 @@ type makeVarsProvider struct { // Collection of makevars providers that are registered in init() methods. var makeVarsInitProviders []makeVarsProvider -// Collection of singleton makevars providers that are not registered as part of init() methods. -var singletonMakeVarsProviders []makeVarsProvider - type makeVarsContext struct { SingletonContext config Config @@ -224,7 +230,11 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { var vars []makeVarsVariable var dists []dist var phonies []phony - for _, provider := range append(makeVarsInitProviders) { + + providers := append([]makeVarsProvider(nil), makeVarsInitProviders...) + providers = append(providers, *ctx.Config().Get(singletonMakeVarsProvidersKey).(*[]makeVarsProvider)...) + + for _, provider := range providers { mctx := &makeVarsContext{ SingletonContext: ctx, pctx: provider.pctx, @@ -237,25 +247,6 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { dists = append(dists, mctx.dists...) } - for _, provider := range append(singletonMakeVarsProviders) { - mctx := &makeVarsContext{ - SingletonContext: ctx, - pctx: provider.pctx, - } - - provider.call(mctx) - - vars = append(vars, mctx.vars...) - phonies = append(phonies, mctx.phonies...) - dists = append(dists, mctx.dists...) - } - - // Clear singleton makevars providers after use. Since these are in-memory - // singletons, this ensures state is reset if the build tree is processed - // multiple times. - // TODO(cparsons): Clean up makeVarsProviders to be part of the context. - singletonMakeVarsProviders = nil - ctx.VisitAllModules(func(m Module) { if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled() { mctx := &makeVarsContext{ diff --git a/android/register.go b/android/register.go index bd824c9c1..b33ad40b1 100644 --- a/android/register.go +++ b/android/register.go @@ -29,7 +29,7 @@ var moduleTypes []moduleType type singleton struct { name string - factory blueprint.SingletonFactory + factory SingletonFactory } var singletons []singleton @@ -57,11 +57,11 @@ type SingletonFactory func() Singleton // SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting // a Singleton into a blueprint.Singleton -func SingletonFactoryAdaptor(factory SingletonFactory) blueprint.SingletonFactory { +func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory { return func() blueprint.Singleton { singleton := factory() if makevars, ok := singleton.(SingletonMakeVarsProvider); ok { - registerSingletonMakeVarsProvider(makevars) + registerSingletonMakeVarsProvider(ctx.config, makevars) } return &singletonAdaptor{Singleton: singleton} } @@ -72,11 +72,11 @@ func RegisterModuleType(name string, factory ModuleFactory) { } func RegisterSingletonType(name string, factory SingletonFactory) { - singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)}) + singletons = append(singletons, singleton{name, factory}) } func RegisterPreSingletonType(name string, factory SingletonFactory) { - preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)}) + preSingletons = append(preSingletons, singleton{name, factory}) } type Context struct { @@ -92,7 +92,7 @@ func NewContext(config Config) *Context { func (ctx *Context) Register() { for _, t := range preSingletons { - ctx.RegisterPreSingletonType(t.name, t.factory) + ctx.RegisterPreSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory)) } for _, t := range moduleTypes { @@ -100,21 +100,21 @@ func (ctx *Context) Register() { } for _, t := range singletons { - ctx.RegisterSingletonType(t.name, t.factory) + ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory)) } registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps) - ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(BazelSingleton)) + ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(ctx, BazelSingleton)) // Register phony just before makevars so it can write out its phony rules as Make rules - ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory)) + ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(ctx, phonySingletonFactory)) // Register makevars after other singletons so they can export values through makevars - ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc)) + ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(ctx, makeVarsSingletonFunc)) // Register env last so that it can track all used environment variables - ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton)) + ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(ctx, EnvSingleton)) } func ModuleTypeFactories() map[string]ModuleFactory { diff --git a/android/testing.go b/android/testing.go index d83cecc43..1e2ae130a 100644 --- a/android/testing.go +++ b/android/testing.go @@ -104,7 +104,7 @@ func (ctx *TestContext) RegisterModuleType(name string, factory ModuleFactory) { } func (ctx *TestContext) RegisterSingletonType(name string, factory SingletonFactory) { - ctx.Context.RegisterSingletonType(name, SingletonFactoryAdaptor(factory)) + ctx.Context.RegisterSingletonType(name, SingletonFactoryAdaptor(ctx.Context, factory)) } func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule { diff --git a/java/java_test.go b/java/java_test.go index 87d6ebbd4..5cc97b38e 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -92,8 +92,8 @@ func testContext(config android.Config) *android.TestContext { ctx.PreDepsMutators(python.RegisterPythonPreDepsMutators) ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators) - ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory)) - ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory)) + ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(ctx.Context, OverlaySingletonFactory)) + ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(ctx.Context, sdkPreSingletonFactory)) android.RegisterPrebuiltMutators(ctx) From 121292911ada0a830f2ad6d83e2f393997939149 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 29 Oct 2020 18:23:58 -0700 Subject: [PATCH 2/4] Store ninja file deps from PackageVarContext in the config Store ninja file deps from ExistentPathForSource on a PackageVarContext in the config instead of the PackageContext, as the PackageContext may be shared between multiple tests running in parallel. Test: all soong tests Change-Id: Ib1809a4dd4a82696e0fe48a87eac21a44684ecb5 --- android/Android.bp | 2 + android/config.go | 2 + android/ninja_deps.go | 43 ++++++++++++++++++++++ android/ninja_deps_test.go | 75 ++++++++++++++++++++++++++++++++++++++ android/package_ctx.go | 2 +- android/register.go | 4 +- 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 android/ninja_deps.go create mode 100644 android/ninja_deps_test.go diff --git a/android/Android.bp b/android/Android.bp index 7bd145080..8673ab242 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -32,6 +32,7 @@ bootstrap_go_package { "mutator.go", "namespace.go", "neverallow.go", + "ninja_deps.go", "notices.go", "onceper.go", "override_module.go", @@ -73,6 +74,7 @@ bootstrap_go_package { "mutator_test.go", "namespace_test.go", "neverallow_test.go", + "ninja_deps_test.go", "onceper_test.go", "package_test.go", "path_properties_test.go", diff --git a/android/config.go b/android/config.go index e87a4ac2a..d833c5c4d 100644 --- a/android/config.go +++ b/android/config.go @@ -126,6 +126,8 @@ type config struct { // in tests when a path doesn't exist. testAllowNonExistentPaths bool + ninjaFileDepsSet sync.Map + OncePer } diff --git a/android/ninja_deps.go b/android/ninja_deps.go new file mode 100644 index 000000000..2f442d5f0 --- /dev/null +++ b/android/ninja_deps.go @@ -0,0 +1,43 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 android + +import "sort" + +func (c *config) addNinjaFileDeps(deps ...string) { + for _, dep := range deps { + c.ninjaFileDepsSet.Store(dep, true) + } +} + +func (c *config) ninjaFileDeps() []string { + var deps []string + c.ninjaFileDepsSet.Range(func(key, value interface{}) bool { + deps = append(deps, key.(string)) + return true + }) + sort.Strings(deps) + return deps +} + +func ninjaDepsSingletonFactory() Singleton { + return &ninjaDepsSingleton{} +} + +type ninjaDepsSingleton struct{} + +func (ninjaDepsSingleton) GenerateBuildActions(ctx SingletonContext) { + ctx.AddNinjaFileDeps(ctx.Config().ninjaFileDeps()...) +} diff --git a/android/ninja_deps_test.go b/android/ninja_deps_test.go new file mode 100644 index 000000000..d3775edd9 --- /dev/null +++ b/android/ninja_deps_test.go @@ -0,0 +1,75 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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 android + +import ( + "testing" +) + +func init() { + // This variable uses ExistentPathForSource on a PackageVarContext, which is a PathContext + // that is not a PathGlobContext. That requires the deps to be stored in the Config. + pctx.VariableFunc("test_ninja_deps_variable", func(ctx PackageVarContext) string { + // Using ExistentPathForSource to look for a file that does not exist in a directory that + // does exist (test_ninja_deps) from a PackageVarContext adds a dependency from build.ninja + // to the directory. + if ExistentPathForSource(ctx, "test_ninja_deps/does_not_exist").Valid() { + return "true" + } else { + return "false" + } + }) +} + +func testNinjaDepsSingletonFactory() Singleton { + return testNinjaDepsSingleton{} +} + +type testNinjaDepsSingleton struct{} + +func (testNinjaDepsSingleton) GenerateBuildActions(ctx SingletonContext) { + // Reference the test_ninja_deps_variable in a build statement so Blueprint is forced to + // evaluate it. + ctx.Build(pctx, BuildParams{ + Rule: Cp, + Input: PathForTesting("foo"), + Output: PathForOutput(ctx, "test_ninja_deps_out"), + Args: map[string]string{ + "cpFlags": "${test_ninja_deps_variable}", + }, + }) +} + +func TestNinjaDeps(t *testing.T) { + fs := map[string][]byte{ + "test_ninja_deps/exists": nil, + } + config := TestConfig(buildDir, nil, "", fs) + + ctx := NewTestContext(config) + ctx.RegisterSingletonType("test_ninja_deps_singleton", testNinjaDepsSingletonFactory) + ctx.RegisterSingletonType("ninja_deps_singleton", ninjaDepsSingletonFactory) + ctx.Register() + + _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) + FailIfErrored(t, errs) + ninjaDeps, errs := ctx.PrepareBuildActions(config) + FailIfErrored(t, errs) + + // Verify that the ninja file has a dependency on the test_ninja_deps directory. + if g, w := ninjaDeps, "test_ninja_deps"; !InList(w, g) { + t.Errorf("expected %q in %q", w, g) + } +} diff --git a/android/package_ctx.go b/android/package_ctx.go index 0de356e1c..6d0fcb33f 100644 --- a/android/package_ctx.go +++ b/android/package_ctx.go @@ -56,7 +56,7 @@ func (e *configErrorWrapper) Errorf(format string, args ...interface{}) { e.errors = append(e.errors, fmt.Errorf(format, args...)) } func (e *configErrorWrapper) AddNinjaFileDeps(deps ...string) { - e.pctx.AddNinjaFileDeps(deps...) + e.config.addNinjaFileDeps(deps...) } type PackageVarContext interface { diff --git a/android/register.go b/android/register.go index b33ad40b1..08e47b330 100644 --- a/android/register.go +++ b/android/register.go @@ -113,8 +113,10 @@ func (ctx *Context) Register() { // Register makevars after other singletons so they can export values through makevars ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(ctx, makeVarsSingletonFunc)) - // Register env last so that it can track all used environment variables + // Register env and ninjadeps last so that they can track all used environment variables and + // Ninja file dependencies stored in the config. ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(ctx, EnvSingleton)) + ctx.RegisterSingletonType("ninjadeps", SingletonFactoryAdaptor(ctx, ninjaDepsSingletonFactory)) } func ModuleTypeFactories() map[string]ModuleFactory { From 5789858aa86c014e14fad0d50e0b3af274907032 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 29 Oct 2020 18:25:19 -0700 Subject: [PATCH 3/4] Register the kythe singleton on the Context instead of globally Test: all soong tests Change-Id: Ief43ff51e66db2d3c895b2a6952385e31b9d669b --- cc/cc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cc/cc.go b/cc/cc.go index 5e4faf268..e887fcfe8 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -88,7 +88,7 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel() }) - android.RegisterSingletonType("kythe_extract_all", kytheExtractAllFactory) + ctx.RegisterSingletonType("kythe_extract_all", kytheExtractAllFactory) } type Deps struct { From 95f1ca07ceda4d79468ec9e014db77929472f65a Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 29 Oct 2020 20:47:22 -0700 Subject: [PATCH 4/4] Store ndkKnownLibs in the config Storing ndkKnownLibs prevents multiple tests from running in parallel as one may be writing to the list while another is reading from it. Store it in the config so each test has its own copy. Test: go test -race ./apex Change-Id: Iba57c9494012c9e0ae9e5ffaa63b9b2bd2c77492 --- cc/cc.go | 12 ++++++------ cc/library.go | 6 +++--- cc/makevars.go | 1 + cc/ndk_library.go | 14 ++++++++++---- java/app.go | 2 +- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index e887fcfe8..26742fbf8 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -368,7 +368,7 @@ type ModuleContextIntf interface { useSdk() bool sdkVersion() string useVndk() bool - isNdk() bool + isNdk(config android.Config) bool isLlndk(config android.Config) bool isLlndkPublic(config android.Config) bool isVndkPrivate(config android.Config) bool @@ -938,8 +938,8 @@ func (c *Module) isCoverageVariant() bool { return c.coverage.Properties.IsCoverageVariant } -func (c *Module) IsNdk() bool { - return inList(c.BaseModuleName(), ndkKnownLibs) +func (c *Module) IsNdk(config android.Config) bool { + return inList(c.BaseModuleName(), *getNDKKnownLibs(config)) } func (c *Module) isLlndk(config android.Config) bool { @@ -1140,8 +1140,8 @@ func (ctx *moduleContextImpl) useVndk() bool { return ctx.mod.UseVndk() } -func (ctx *moduleContextImpl) isNdk() bool { - return ctx.mod.IsNdk() +func (ctx *moduleContextImpl) isNdk(config android.Config) bool { + return ctx.mod.IsNdk(config) } func (ctx *moduleContextImpl) isLlndk(config android.Config) bool { @@ -1761,7 +1761,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { for _, entry := range list { // strip #version suffix out name, _ := StubsLibNameAndVersion(entry) - if ctx.useSdk() && inList(name, ndkKnownLibs) { + if ctx.useSdk() && inList(name, *getNDKKnownLibs(ctx.Config())) { variantLibs = append(variantLibs, name+ndkLibrarySuffix) } else if ctx.useVndk() { nonvariantLibs = append(nonvariantLibs, rewriteVendorLibs(entry)) diff --git a/cc/library.go b/cc/library.go index eeddd90d6..2127c08da 100644 --- a/cc/library.go +++ b/cc/library.go @@ -567,7 +567,7 @@ func (library *libraryDecorator) classifySourceAbiDump(ctx ModuleContext) string return "" } // Return NDK if the library is both NDK and LLNDK. - if ctx.isNdk() { + if ctx.isNdk(ctx.Config()) { return "NDK" } if ctx.isLlndkPublic(ctx.Config()) { @@ -1099,7 +1099,7 @@ func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath { func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path { // The logic must be consistent with classifySourceAbiDump. - isNdk := ctx.isNdk() + isNdk := ctx.isNdk(ctx.Config()) isLlndkOrVndk := ctx.isLlndkPublic(ctx.Config()) || (ctx.useVndk() && ctx.isVndk()) refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false) @@ -1153,7 +1153,7 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(), refAbiDumpFile, fileName, exportedHeaderFlags, Bool(library.Properties.Header_abi_checker.Check_all_apis), - ctx.isLlndk(ctx.Config()), ctx.isNdk(), ctx.isVndkExt()) + ctx.isLlndk(ctx.Config()), ctx.isNdk(ctx.Config()), ctx.isVndkExt()) } } } diff --git a/cc/makevars.go b/cc/makevars.go index dcfd6d8ef..bd8aab532 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -171,6 +171,7 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.StrictRaw("SRC_HEADERS", strings.Join(includes, " ")) ctx.StrictRaw("SRC_SYSTEM_HEADERS", strings.Join(systemIncludes, " ")) + ndkKnownLibs := *getNDKKnownLibs(ctx.Config()) sort.Strings(ndkKnownLibs) ctx.Strict("NDK_KNOWN_LIBS", strings.Join(ndkKnownLibs, " ")) diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 9097e7bbc..a5c43fe21 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -45,8 +45,7 @@ var ( ndkLibrarySuffix = ".ndk" - // Added as a variation dependency via depsMutator. - ndkKnownLibs = []string{} + ndkKnownLibsKey = android.NewOnceKey("ndkKnownLibsKey") // protects ndkKnownLibs writes during parallel BeginMutator. ndkKnownLibsLock sync.Mutex ) @@ -158,6 +157,12 @@ func (this *stubDecorator) initializeProperties(ctx BaseModuleContext) bool { return true } +func getNDKKnownLibs(config android.Config) *[]string { + return config.Once(ndkKnownLibsKey, func() interface{} { + return &[]string{} + }).(*[]string) +} + func (c *stubDecorator) compilerInit(ctx BaseModuleContext) { c.baseCompiler.compilerInit(ctx) @@ -168,12 +173,13 @@ func (c *stubDecorator) compilerInit(ctx BaseModuleContext) { ndkKnownLibsLock.Lock() defer ndkKnownLibsLock.Unlock() - for _, lib := range ndkKnownLibs { + ndkKnownLibs := getNDKKnownLibs(ctx.Config()) + for _, lib := range *ndkKnownLibs { if lib == name { return } } - ndkKnownLibs = append(ndkKnownLibs, name) + *ndkKnownLibs = append(*ndkKnownLibs, name) } func addStubLibraryCompilerFlags(flags Flags) Flags { diff --git a/java/app.go b/java/app.go index 17de8b9a5..3446739f3 100755 --- a/java/app.go +++ b/java/app.go @@ -890,7 +890,7 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) { if dep, ok := module.(*cc.Module); ok { - if dep.IsNdk() || dep.IsStubs() { + if dep.IsNdk(ctx.Config()) || dep.IsStubs() { return false }