blob: 476d805ecd222da601a8d42dd7d438d35700ead5 [file] [log] [blame]
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001// Copyright 2016 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 (
Kris Alderf979ee32019-10-22 10:52:01 -070018 "encoding/json"
Mitch Phillips4de896e2019-08-28 16:04:36 -070019 "path/filepath"
Mitch Phillipse1ee1a12019-10-17 19:20:41 -070020 "sort"
Mitch Phillipsa0a5e192019-09-27 14:00:06 -070021 "strings"
Mitch Phillips4de896e2019-08-28 16:04:36 -070022
Mitch Phillipsda9a4632019-07-15 09:34:09 -070023 "android/soong/android"
24 "android/soong/cc/config"
25)
26
Kris Alderf979ee32019-10-22 10:52:01 -070027type FuzzConfig struct {
28 // Email address of people to CC on bugs or contact about this fuzz target.
29 Cc []string `json:"cc,omitempty"`
30 // Boolean specifying whether to disable the fuzz target from running
31 // automatically in continuous fuzzing infrastructure.
32 Disable *bool `json:"disable,omitempty"`
33 // Component in Google's bug tracking system that bugs should be filed to.
34 Componentid *int64 `json:"componentid,omitempty"`
35 // Hotlists in Google's bug tracking system that bugs should be marked with.
36 Hotlists []string `json:"hotlists,omitempty"`
37}
38
39func (f *FuzzConfig) String() string {
40 b, err := json.Marshal(f)
41 if err != nil {
42 panic(err)
43 }
44
45 return string(b)
46}
47
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070048type FuzzProperties struct {
49 // Optional list of seed files to be installed to the fuzz target's output
50 // directory.
51 Corpus []string `android:"path"`
52 // Optional dictionary to be installed to the fuzz target's output directory.
53 Dictionary *string `android:"path"`
Kris Alderf979ee32019-10-22 10:52:01 -070054 // Config for running the target on fuzzing infrastructure.
55 Fuzz_config *FuzzConfig
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070056}
57
Mitch Phillipsda9a4632019-07-15 09:34:09 -070058func init() {
59 android.RegisterModuleType("cc_fuzz", FuzzFactory)
Mitch Phillipsd3254b42019-09-24 13:03:28 -070060 android.RegisterSingletonType("cc_fuzz_packaging", fuzzPackagingFactory)
Mitch Phillipsda9a4632019-07-15 09:34:09 -070061}
62
63// cc_fuzz creates a host/device fuzzer binary. Host binaries can be found at
64// $ANDROID_HOST_OUT/fuzz/, and device binaries can be found at /data/fuzz on
65// your device, or $ANDROID_PRODUCT_OUT/data/fuzz in your build tree.
66func FuzzFactory() android.Module {
67 module := NewFuzz(android.HostAndDeviceSupported)
68 return module.Init()
69}
70
71func NewFuzzInstaller() *baseInstaller {
72 return NewBaseInstaller("fuzz", "fuzz", InstallInData)
73}
74
75type fuzzBinary struct {
76 *binaryDecorator
77 *baseCompiler
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070078
Mitch Phillips8a2bc0b2019-10-17 15:04:01 -070079 Properties FuzzProperties
80 dictionary android.Path
81 corpus android.Paths
82 corpusIntermediateDir android.Path
Kris Alderf979ee32019-10-22 10:52:01 -070083 config android.Path
Mitch Phillipse1ee1a12019-10-17 19:20:41 -070084 installedSharedDeps []string
Mitch Phillipsda9a4632019-07-15 09:34:09 -070085}
86
87func (fuzz *fuzzBinary) linkerProps() []interface{} {
88 props := fuzz.binaryDecorator.linkerProps()
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070089 props = append(props, &fuzz.Properties)
Mitch Phillipsda9a4632019-07-15 09:34:09 -070090 return props
91}
92
93func (fuzz *fuzzBinary) linkerInit(ctx BaseModuleContext) {
Mitch Phillipsda9a4632019-07-15 09:34:09 -070094 fuzz.binaryDecorator.linkerInit(ctx)
95}
96
97func (fuzz *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
98 deps.StaticLibs = append(deps.StaticLibs,
99 config.LibFuzzerRuntimeLibrary(ctx.toolchain()))
100 deps = fuzz.binaryDecorator.linkerDeps(ctx, deps)
101 return deps
102}
103
104func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
105 flags = fuzz.binaryDecorator.linkerFlags(ctx, flags)
Mitch Phillips1f7f54f2019-11-14 14:50:47 -0800106 // RunPaths on devices isn't instantiated by the base linker. `../lib` for
107 // installed fuzz targets (both host and device), and `./lib` for fuzz
108 // target packages.
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700109 flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`)
Mitch Phillips1f7f54f2019-11-14 14:50:47 -0800110 flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`)
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700111 return flags
112}
113
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700114// This function performs a breadth-first search over the provided module's
115// dependencies using `visitDirectDeps` to enumerate all shared library
116// dependencies. We require breadth-first expansion, as otherwise we may
117// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
118// from a dependency. This may cause issues when dependencies have explicit
119// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
120func collectAllSharedDependencies(
121 module android.Module,
122 sharedDeps map[string]android.Path,
123 ctx android.SingletonContext) {
124 var fringe []android.Module
125
126 // Enumerate the first level of dependencies, as we discard all non-library
127 // modules in the BFS loop below.
128 ctx.VisitDirectDeps(module, func(dep android.Module) {
Mitch Phillipsf50bddb2019-11-12 14:03:31 -0800129 if isValidSharedDependency(dep, sharedDeps) {
130 fringe = append(fringe, dep)
131 }
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700132 })
133
134 for i := 0; i < len(fringe); i++ {
135 module := fringe[i]
Mitch Phillipsf50bddb2019-11-12 14:03:31 -0800136 if _, exists := sharedDeps[module.Name()]; exists {
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700137 continue
138 }
139
140 ccModule := module.(*Module)
141 sharedDeps[ccModule.Name()] = ccModule.UnstrippedOutputFile()
142 ctx.VisitDirectDeps(module, func(dep android.Module) {
Mitch Phillipsf50bddb2019-11-12 14:03:31 -0800143 if isValidSharedDependency(dep, sharedDeps) {
144 fringe = append(fringe, dep)
145 }
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700146 })
147 }
148}
149
150// This function takes a module and determines if it is a unique shared library
151// that should be installed in the fuzz target output directories. This function
152// returns true, unless:
153// - The module already exists in `sharedDeps`, or
154// - The module is not a shared library, or
155// - The module is a header, stub, or vendor-linked library.
156func isValidSharedDependency(
157 dependency android.Module,
158 sharedDeps map[string]android.Path) bool {
159 // TODO(b/144090547): We should be parsing these modules using
160 // ModuleDependencyTag instead of the current brute-force checking.
161
162 if linkable, ok := dependency.(LinkableInterface); !ok || // Discard non-linkables.
163 !linkable.CcLibraryInterface() || !linkable.Shared() || // Discard static libs.
164 linkable.UseVndk() || // Discard vendor linked libraries.
Mitch Phillipsf50bddb2019-11-12 14:03:31 -0800165 // Discard stubs libs (only CCLibrary variants). Prebuilt libraries should not
166 // be excluded on the basis of they're not CCLibrary()'s.
167 (linkable.CcLibrary() && linkable.BuildStubs()) {
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700168 return false
169 }
170
Mitch Phillipsf50bddb2019-11-12 14:03:31 -0800171 // We discarded module stubs libraries above, but the LLNDK prebuilts stubs
172 // libraries must be handled differently - by looking for the stubDecorator.
173 // Discard LLNDK prebuilts stubs as well.
174 if ccLibrary, isCcLibrary := dependency.(*Module); isCcLibrary {
175 if _, isLLndkStubLibrary := ccLibrary.linker.(*stubDecorator); isLLndkStubLibrary {
176 return false
177 }
178 }
179
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700180 // If this library has already been traversed, we don't need to do any more work.
181 if _, exists := sharedDeps[dependency.Name()]; exists {
182 return false
183 }
184 return true
185}
186
187func sharedLibraryInstallLocation(
188 libraryPath android.Path, isHost bool, archString string) string {
189 installLocation := "$(PRODUCT_OUT)/data"
190 if isHost {
191 installLocation = "$(HOST_OUT)"
192 }
193 installLocation = filepath.Join(
194 installLocation, "fuzz", archString, "lib", libraryPath.Base())
195 return installLocation
196}
197
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700198func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -0700199 fuzz.binaryDecorator.baseInstaller.dir = filepath.Join(
200 "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
201 fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join(
202 "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700203 fuzz.binaryDecorator.baseInstaller.install(ctx, file)
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -0700204
205 fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus)
Mitch Phillips8a2bc0b2019-10-17 15:04:01 -0700206 builder := android.NewRuleBuilder()
207 intermediateDir := android.PathForModuleOut(ctx, "corpus")
208 for _, entry := range fuzz.corpus {
209 builder.Command().Text("cp").
210 Input(entry).
211 Output(intermediateDir.Join(ctx, entry.Base()))
212 }
213 builder.Build(pctx, ctx, "copy_corpus", "copy corpus")
214 fuzz.corpusIntermediateDir = intermediateDir
215
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -0700216 if fuzz.Properties.Dictionary != nil {
217 fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary)
218 if fuzz.dictionary.Ext() != ".dict" {
219 ctx.PropertyErrorf("dictionary",
220 "Fuzzer dictionary %q does not have '.dict' extension",
221 fuzz.dictionary.String())
222 }
223 }
Kris Alderf979ee32019-10-22 10:52:01 -0700224
225 if fuzz.Properties.Fuzz_config != nil {
Kris Alderdb97af42019-10-30 10:17:04 -0700226 configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
Kris Alderf979ee32019-10-22 10:52:01 -0700227 ctx.Build(pctx, android.BuildParams{
228 Rule: android.WriteFile,
229 Description: "fuzzer infrastructure configuration",
230 Output: configPath,
231 Args: map[string]string{
232 "content": fuzz.Properties.Fuzz_config.String(),
233 },
234 })
235 fuzz.config = configPath
236 }
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700237
238 // Grab the list of required shared libraries.
239 sharedLibraries := make(map[string]android.Path)
240 ctx.WalkDeps(func(child, parent android.Module) bool {
241 if isValidSharedDependency(child, sharedLibraries) {
242 sharedLibraries[child.Name()] = child.(*Module).UnstrippedOutputFile()
243 return true
244 }
245 return false
246 })
247
248 for _, lib := range sharedLibraries {
249 fuzz.installedSharedDeps = append(fuzz.installedSharedDeps,
250 sharedLibraryInstallLocation(
251 lib, ctx.Host(), ctx.Arch().ArchType.String()))
252 }
Mitch Phillips0553ba32019-11-11 07:03:42 -0800253
254 sort.Strings(fuzz.installedSharedDeps)
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700255}
256
257func NewFuzz(hod android.HostOrDeviceSupported) *Module {
258 module, binary := NewBinary(hod)
259
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700260 binary.baseInstaller = NewFuzzInstaller()
261 module.sanitize.SetSanitizer(fuzzer, true)
262
263 fuzz := &fuzzBinary{
264 binaryDecorator: binary,
265 baseCompiler: NewBaseCompiler(),
266 }
267 module.compiler = fuzz
268 module.linker = fuzz
269 module.installer = fuzz
Colin Crosseec9b282019-07-18 16:20:52 -0700270
271 // The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin.
272 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
Alex Light71123ec2019-07-24 13:34:19 -0700273 disableDarwinAndLinuxBionic := struct {
Colin Crosseec9b282019-07-18 16:20:52 -0700274 Target struct {
275 Darwin struct {
276 Enabled *bool
277 }
Alex Light71123ec2019-07-24 13:34:19 -0700278 Linux_bionic struct {
279 Enabled *bool
280 }
Colin Crosseec9b282019-07-18 16:20:52 -0700281 }
282 }{}
Alex Light71123ec2019-07-24 13:34:19 -0700283 disableDarwinAndLinuxBionic.Target.Darwin.Enabled = BoolPtr(false)
284 disableDarwinAndLinuxBionic.Target.Linux_bionic.Enabled = BoolPtr(false)
285 ctx.AppendProperties(&disableDarwinAndLinuxBionic)
Colin Crosseec9b282019-07-18 16:20:52 -0700286 })
287
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700288 return module
289}
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700290
291// Responsible for generating GNU Make rules that package fuzz targets into
292// their architecture & target/host specific zip file.
293type fuzzPackager struct {
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700294 packages android.Paths
295 sharedLibInstallStrings []string
296 fuzzTargets map[string]bool
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700297}
298
299func fuzzPackagingFactory() android.Singleton {
300 return &fuzzPackager{}
301}
302
303type fileToZip struct {
304 SourceFilePath android.Path
305 DestinationPathPrefix string
306}
307
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700308type archAndLibraryKey struct {
309 ArchDir android.OutputPath
310 Library android.Path
311}
312
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700313func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
314 // Map between each architecture + host/device combination, and the files that
315 // need to be packaged (in the tuple of {source file, destination folder in
316 // archive}).
317 archDirs := make(map[android.OutputPath][]fileToZip)
318
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700319 // List of shared library dependencies for each architecture + host/device combo.
320 archSharedLibraryDeps := make(map[archAndLibraryKey]bool)
321
322 // List of individual fuzz targets, so that 'make fuzz' also installs the targets
323 // to the correct output directories as well.
324 s.fuzzTargets = make(map[string]bool)
325
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700326 ctx.VisitAllModules(func(module android.Module) {
327 // Discard non-fuzz targets.
328 ccModule, ok := module.(*Module)
329 if !ok {
330 return
331 }
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700332
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700333 fuzzModule, ok := ccModule.compiler.(*fuzzBinary)
334 if !ok {
335 return
336 }
337
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800338 // Discard vendor-NDK-linked + recovery modules, they're duplicates of
339 // fuzz targets we're going to package anyway.
340 if !ccModule.Enabled() || ccModule.Properties.PreventInstall ||
341 ccModule.UseVndk() || ccModule.InRecovery() {
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700342 return
343 }
344
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700345 s.fuzzTargets[module.Name()] = true
346
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700347 hostOrTargetString := "target"
348 if ccModule.Host() {
349 hostOrTargetString = "host"
350 }
351
352 archString := ccModule.Arch().ArchType.String()
353 archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
354
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700355 // Grab the list of required shared libraries.
356 sharedLibraries := make(map[string]android.Path)
357 collectAllSharedDependencies(module, sharedLibraries, ctx)
358
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800359 var files []fileToZip
360 builder := android.NewRuleBuilder()
361
362 // Package the corpora into a zipfile.
363 if fuzzModule.corpus != nil {
364 corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip")
365 command := builder.Command().BuiltTool(ctx, "soong_zip").
366 Flag("-j").
367 FlagWithOutput("-o ", corpusZip)
368 command.FlagWithRspFileInputList("-l ", fuzzModule.corpus)
369 files = append(files, fileToZip{corpusZip, ""})
370 }
371
372 // Find and mark all the transiently-dependent shared libraries for
373 // packaging.
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700374 for _, library := range sharedLibraries {
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800375 files = append(files, fileToZip{library, "lib"})
Mitch Phillips13ed3f52019-11-12 11:12:10 -0800376
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700377 if _, exists := archSharedLibraryDeps[archAndLibraryKey{archDir, library}]; exists {
378 continue
379 }
380
381 // For each architecture-specific shared library dependency, we need to
382 // install it to the output directory. Setup the install destination here,
383 // which will be used by $(copy-many-files) in the Make backend.
384 archSharedLibraryDeps[archAndLibraryKey{archDir, library}] = true
385 installDestination := sharedLibraryInstallLocation(
386 library, ccModule.Host(), archString)
387 // Escape all the variables, as the install destination here will be called
388 // via. $(eval) in Make.
389 installDestination = strings.ReplaceAll(
390 installDestination, "$", "$$")
391 s.sharedLibInstallStrings = append(s.sharedLibInstallStrings,
392 library.String()+":"+installDestination)
393 }
394
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700395 // The executable.
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800396 files = append(files, fileToZip{ccModule.UnstrippedOutputFile(), ""})
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700397
398 // The dictionary.
399 if fuzzModule.dictionary != nil {
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800400 files = append(files, fileToZip{fuzzModule.dictionary, ""})
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700401 }
Kris Alderf979ee32019-10-22 10:52:01 -0700402
403 // Additional fuzz config.
404 if fuzzModule.config != nil {
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800405 files = append(files, fileToZip{fuzzModule.config, ""})
Kris Alderf979ee32019-10-22 10:52:01 -0700406 }
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800407
408 fuzzZip := archDir.Join(ctx, module.Name()+".zip")
409 command := builder.Command().BuiltTool(ctx, "soong_zip").
410 Flag("-j").
411 FlagWithOutput("-o ", fuzzZip)
412 for _, file := range files {
413 if file.DestinationPathPrefix != "" {
414 command.FlagWithArg("-P ", file.DestinationPathPrefix)
415 } else {
416 command.Flag("-P ''")
417 }
418 command.FlagWithInput("-f ", file.SourceFilePath)
419 }
420
421 builder.Build(pctx, ctx, "create-"+fuzzZip.String(),
422 "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
423
424 archDirs[archDir] = append(archDirs[archDir], fileToZip{fuzzZip, ""})
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700425 })
426
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700427 for archDir, filesToZip := range archDirs {
428 arch := archDir.Base()
429 hostOrTarget := filepath.Base(filepath.Dir(archDir.String()))
430 builder := android.NewRuleBuilder()
431 outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip")
Mitch Phillipsa0a5e192019-09-27 14:00:06 -0700432 s.packages = append(s.packages, outputFile)
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700433
434 command := builder.Command().BuiltTool(ctx, "soong_zip").
435 Flag("-j").
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800436 FlagWithOutput("-o ", outputFile).
437 Flag("-L 0") // No need to try and re-compress the zipfiles.
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700438
439 for _, fileToZip := range filesToZip {
Mitch Phillips2edbe8e2019-11-13 08:36:07 -0800440 if fileToZip.DestinationPathPrefix != "" {
441 command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
442 } else {
443 command.Flag("-P ''")
444 }
445 command.FlagWithInput("-f ", fileToZip.SourceFilePath)
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700446 }
447
448 builder.Build(pctx, ctx, "create-fuzz-package-"+arch+"-"+hostOrTarget,
449 "Create fuzz target packages for "+arch+"-"+hostOrTarget)
450 }
Mitch Phillipsa0a5e192019-09-27 14:00:06 -0700451}
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700452
Mitch Phillipsa0a5e192019-09-27 14:00:06 -0700453func (s *fuzzPackager) MakeVars(ctx android.MakeVarsContext) {
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700454 packages := s.packages.Strings()
455 sort.Strings(packages)
456 sort.Strings(s.sharedLibInstallStrings)
Mitch Phillipsa0a5e192019-09-27 14:00:06 -0700457 // TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's
458 // ready to handle phony targets created in Soong. In the meantime, this
459 // exports the phony 'fuzz' target and dependencies on packages to
460 // core/main.mk so that we can use dist-for-goals.
Mitch Phillipse1ee1a12019-10-17 19:20:41 -0700461 ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
462 ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
463 strings.Join(s.sharedLibInstallStrings, " "))
464
465 // Preallocate the slice of fuzz targets to minimise memory allocations.
466 fuzzTargets := make([]string, 0, len(s.fuzzTargets))
467 for target, _ := range s.fuzzTargets {
468 fuzzTargets = append(fuzzTargets, target)
469 }
470 sort.Strings(fuzzTargets)
471 ctx.Strict("ALL_FUZZ_TARGETS", strings.Join(fuzzTargets, " "))
Mitch Phillipsd3254b42019-09-24 13:03:28 -0700472}