xref: /aosp_15_r20/build/soong/cc/compiler.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// 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 (
18	"fmt"
19	"path/filepath"
20	"regexp"
21	"strconv"
22	"strings"
23
24	"github.com/google/blueprint/proptools"
25
26	"android/soong/android"
27	"android/soong/cc/config"
28)
29
30var (
31	allowedManualInterfacePaths = []string{"vendor/", "hardware/"}
32)
33
34// This file contains the basic C/C++/assembly to .o compliation steps
35
36type BaseCompilerProperties struct {
37	// list of source files used to compile the C/C++ module.  May be .c, .cpp, or .S files.
38	// srcs may reference the outputs of other modules that produce source files like genrule
39	// or filegroup using the syntax ":module".
40	Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
41
42	// list of source files that should not be compiled with clang-tidy.
43	Tidy_disabled_srcs []string `android:"path,arch_variant"`
44
45	// list of source files that should not be compiled by clang-tidy when TIDY_TIMEOUT is set.
46	Tidy_timeout_srcs []string `android:"path,arch_variant"`
47
48	// list of source files that should not be used to build the C/C++ module.
49	// This is most useful in the arch/multilib variants to remove non-common files
50	Exclude_srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
51
52	// list of module-specific flags that will be used for C and C++ compiles.
53	Cflags proptools.Configurable[[]string] `android:"arch_variant"`
54
55	// list of module-specific flags that will be used for C++ compiles
56	Cppflags proptools.Configurable[[]string] `android:"arch_variant"`
57
58	// list of module-specific flags that will be used for C compiles
59	Conlyflags []string `android:"arch_variant"`
60
61	// list of module-specific flags that will be used for .S compiles
62	Asflags []string `android:"arch_variant"`
63
64	// list of module-specific flags that will be used for C and C++ compiles when
65	// compiling with clang
66	Clang_cflags []string `android:"arch_variant"`
67
68	// list of module-specific flags that will be used for .S compiles when
69	// compiling with clang
70	Clang_asflags []string `android:"arch_variant"`
71
72	// the instruction set architecture to use to compile the C/C++
73	// module.
74	Instruction_set *string `android:"arch_variant"`
75
76	// list of directories relative to the root of the source tree that will
77	// be added to the include path using -I.
78	// If possible, don't use this.  If adding paths from the current directory use
79	// local_include_dirs, if adding paths from other modules use export_include_dirs in
80	// that module.
81	Include_dirs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
82
83	// list of directories relative to the Blueprints file that will
84	// be added to the include path using -I
85	Local_include_dirs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
86
87	// Add the directory containing the Android.bp file to the list of include
88	// directories. Defaults to true.
89	Include_build_directory *bool
90
91	// list of generated sources to compile. These are the names of gensrcs or
92	// genrule modules.
93	Generated_sources []string `android:"arch_variant"`
94
95	// list of generated sources that should not be used to build the C/C++ module.
96	// This is most useful in the arch/multilib variants to remove non-common files
97	Exclude_generated_sources []string `android:"arch_variant"`
98
99	// list of generated headers to add to the include path. These are the names
100	// of genrule modules.
101	Generated_headers proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
102
103	// Same as generated_headers, but the dependencies will be added based on the first supported
104	// arch variant and the device os variant. This can be useful for creating a host tool that
105	// embeds a copy of a device tool, that it then extracts and pushes to a device at runtime.
106	Device_first_generated_headers proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
107
108	// pass -frtti instead of -fno-rtti
109	Rtti *bool `android:"arch_variant"`
110
111	// C standard version to use. Can be a specific version (such as "gnu11"),
112	// "experimental" (which will use draft versions like C1x when available),
113	// or the empty string (which will use the default).
114	C_std *string
115
116	// C++ standard version to use. Can be a specific version (such as
117	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
118	// available), or the empty string (which will use the default).
119	Cpp_std *string
120
121	// if set to false, use -std=c++* instead of -std=gnu++*
122	Gnu_extensions *bool
123
124	// cc Build rules targeting BPF must set this to true. The correct fix is to
125	// ban targeting bpf in cc rules instead use bpf_rules. (b/323415017)
126	Bpf_target *bool
127
128	// Add "-Xclang -verify" to the cflags and appends "touch $out" to
129	// the clang command line.
130	Clang_verify bool
131
132	Yacc *YaccProperties
133	Lex  *LexProperties
134
135	Aidl struct {
136		// List of aidl_library modules
137		Libs []string
138
139		// list of directories that will be added to the aidl include paths.
140		Include_dirs []string
141
142		// list of directories relative to the Blueprints file that will
143		// be added to the aidl include paths.
144		Local_include_dirs []string
145
146		// whether to generate traces (for systrace) for this interface
147		Generate_traces *bool
148
149		// list of flags that will be passed to the AIDL compiler
150		Flags []string
151	}
152
153	// Populated by aidl_interface CPP backend to let other modules (e.g. cc_cmake_snapshot)
154	// access actual source files and not generated cpp intermediary sources.
155	AidlInterface struct {
156		// list of aidl_interface sources
157		Sources []string `blueprint:"mutated"`
158
159		// root directory of AIDL sources
160		AidlRoot string `blueprint:"mutated"`
161
162		// AIDL backend language (e.g. "cpp", "ndk")
163		Lang string `blueprint:"mutated"`
164
165		// list of flags passed to AIDL generator
166		Flags []string `blueprint:"mutated"`
167	} `blueprint:"mutated"`
168
169	Renderscript struct {
170		// list of directories that will be added to the llvm-rs-cc include paths
171		Include_dirs []string
172
173		// list of flags that will be passed to llvm-rs-cc
174		Flags []string
175
176		// Renderscript API level to target
177		Target_api *string
178	}
179
180	Target struct {
181		Vendor, Product struct {
182			// list of source files that should only be used in vendor or
183			// product variant of the C/C++ module.
184			Srcs []string `android:"path"`
185
186			// list of source files that should not be used to build vendor
187			// or product variant of the C/C++ module.
188			Exclude_srcs []string `android:"path"`
189
190			// List of additional cflags that should be used to build vendor
191			// or product variant of the C/C++ module.
192			Cflags []string
193
194			// list of generated sources that should not be used to build
195			// vendor or product variant of the C/C++ module.
196			Exclude_generated_sources []string
197		}
198		Recovery struct {
199			// list of source files that should only be used in the
200			// recovery variant of the C/C++ module.
201			Srcs []string `android:"path"`
202
203			// list of source files that should not be used to
204			// build the recovery variant of the C/C++ module.
205			Exclude_srcs []string `android:"path"`
206
207			// List of additional cflags that should be used to build the recovery
208			// variant of the C/C++ module.
209			Cflags []string
210
211			// list of generated sources that should not be used to
212			// build the recovery variant of the C/C++ module.
213			Exclude_generated_sources []string
214		}
215		Ramdisk, Vendor_ramdisk struct {
216			// list of source files that should not be used to
217			// build the ramdisk variants of the C/C++ module.
218			Exclude_srcs []string `android:"path"`
219
220			// List of additional cflags that should be used to build the ramdisk
221			// variants of the C/C++ module.
222			Cflags []string
223		}
224		Platform struct {
225			// List of additional cflags that should be used to build the platform
226			// variant of the C/C++ module.
227			Cflags []string
228		}
229	}
230
231	Proto struct {
232		// Link statically against the protobuf runtime
233		Static *bool `android:"arch_variant"`
234	} `android:"arch_variant"`
235
236	// Build and link with OpenMP
237	Openmp *bool `android:"arch_variant"`
238}
239
240func NewBaseCompiler() *baseCompiler {
241	return &baseCompiler{}
242}
243
244type baseCompiler struct {
245	Properties BaseCompilerProperties
246	Proto      android.ProtoProperties
247	cFlagsDeps android.Paths
248	pathDeps   android.Paths
249	flags      builderFlags
250
251	// Sources that were passed to the C/C++ compiler
252	srcs android.Paths
253
254	// Sources that were passed in the Android.bp file, including generated sources generated by
255	// other modules and filegroups. May include source files that have not yet been translated to
256	// C/C++ (.aidl, .proto, etc.)
257	srcsBeforeGen android.Paths
258
259	generatedSourceInfo
260}
261
262var _ compiler = (*baseCompiler)(nil)
263
264type CompiledInterface interface {
265	Srcs() android.Paths
266}
267
268func (compiler *baseCompiler) Srcs() android.Paths {
269	return append(android.Paths{}, compiler.srcs...)
270}
271
272func (compiler *baseCompiler) appendCflags(flags []string) {
273	compiler.Properties.Cflags.AppendSimpleValue(flags)
274}
275
276func (compiler *baseCompiler) appendAsflags(flags []string) {
277	compiler.Properties.Asflags = append(compiler.Properties.Asflags, flags...)
278}
279
280func (compiler *baseCompiler) compilerProps() []interface{} {
281	return []interface{}{&compiler.Properties, &compiler.Proto}
282}
283
284func (compiler *baseCompiler) baseCompilerProps() BaseCompilerProperties {
285	return compiler.Properties
286}
287
288func includeBuildDirectory(prop *bool) bool {
289	return proptools.BoolDefault(prop, true)
290}
291
292func (compiler *baseCompiler) includeBuildDirectory() bool {
293	return includeBuildDirectory(compiler.Properties.Include_build_directory)
294}
295
296func (compiler *baseCompiler) compilerInit(ctx BaseModuleContext) {}
297
298func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
299	deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
300	deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources)
301	deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers.GetOrDefault(ctx, nil)...)
302	deps.DeviceFirstGeneratedHeaders = append(deps.DeviceFirstGeneratedHeaders, compiler.Properties.Device_first_generated_headers.GetOrDefault(ctx, nil)...)
303	deps.AidlLibs = append(deps.AidlLibs, compiler.Properties.Aidl.Libs...)
304
305	android.ProtoDeps(ctx, &compiler.Proto)
306	if compiler.hasSrcExt(ctx, ".proto") {
307		deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static))
308	}
309
310	if Bool(compiler.Properties.Openmp) {
311		deps.StaticLibs = append(deps.StaticLibs, "libomp")
312	}
313
314	return deps
315}
316
317// Return true if the module is in the WarningAllowedProjects.
318func warningsAreAllowed(subdir string) bool {
319	subdir += "/"
320	return android.HasAnyPrefix(subdir, config.WarningAllowedProjects)
321}
322
323func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) {
324	getNamedMapForConfig(ctx.Config(), key).Store(module, true)
325}
326
327func useGnuExtensions(gnuExtensions *bool) bool {
328	return proptools.BoolDefault(gnuExtensions, true)
329}
330
331func maybeReplaceGnuToC(gnuExtensions *bool, cStd string, cppStd string) (string, string) {
332	if !useGnuExtensions(gnuExtensions) {
333		cStd = gnuToCReplacer.Replace(cStd)
334		cppStd = gnuToCReplacer.Replace(cppStd)
335	}
336	return cStd, cppStd
337}
338
339func parseCppStd(cppStdPtr *string) string {
340	cppStd := String(cppStdPtr)
341	switch cppStd {
342	case "":
343		return config.CppStdVersion
344	case "experimental":
345		return config.ExperimentalCppStdVersion
346	default:
347		return cppStd
348	}
349}
350
351func parseCStd(cStdPtr *string) string {
352	cStd := String(cStdPtr)
353	switch cStd {
354	case "":
355		return config.CStdVersion
356	case "experimental":
357		return config.ExperimentalCStdVersion
358	default:
359		return cStd
360	}
361}
362
363// Create a Flags struct that collects the compile flags from global values,
364// per-target values, module type values, and per-module Blueprints properties
365func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
366	tc := ctx.toolchain()
367	modulePath := ctx.ModuleDir()
368
369	reuseObjs := false
370	if len(ctx.GetDirectDepsWithTag(reuseObjTag)) > 0 {
371		reuseObjs = true
372	}
373
374	// If a reuseObjTag dependency exists then this module is reusing the objects (generally the shared variant
375	// reusing objects from the static variant), and doesn't need to compile any sources of its own.
376	var srcs []string
377	if !reuseObjs {
378		srcs = compiler.Properties.Srcs.GetOrDefault(ctx, nil)
379		exclude_srcs := compiler.Properties.Exclude_srcs.GetOrDefault(ctx, nil)
380		compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, srcs, exclude_srcs)
381		compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
382	}
383
384	cflags := compiler.Properties.Cflags.GetOrDefault(ctx, nil)
385	cppflags := compiler.Properties.Cppflags.GetOrDefault(ctx, nil)
386	CheckBadCompilerFlags(ctx, "cflags", cflags)
387	CheckBadCompilerFlags(ctx, "cppflags", cppflags)
388	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
389	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
390	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
391	CheckBadCompilerFlags(ctx, "product.cflags", compiler.Properties.Target.Product.Cflags)
392	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
393	CheckBadCompilerFlags(ctx, "ramdisk.cflags", compiler.Properties.Target.Ramdisk.Cflags)
394	CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
395	CheckBadCompilerFlags(ctx, "platform.cflags", compiler.Properties.Target.Platform.Cflags)
396
397	esc := proptools.NinjaAndShellEscapeList
398
399	flags.Local.CFlags = append(flags.Local.CFlags, esc(cflags)...)
400	flags.Local.CppFlags = append(flags.Local.CppFlags, esc(cppflags)...)
401	flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
402	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
403	flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
404
405	flags.Yacc = compiler.Properties.Yacc
406	flags.Lex = compiler.Properties.Lex
407
408	flags.ClangVerify = compiler.Properties.Clang_verify
409	if compiler.Properties.Clang_verify {
410		flags.Local.CFlags = append(flags.Local.CFlags, "-Xclang", "-verify")
411	}
412
413	// Include dir cflags
414	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs.GetOrDefault(ctx, nil))
415	if len(localIncludeDirs) > 0 {
416		f := includeDirsToFlags(localIncludeDirs)
417		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
418		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
419	}
420	rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs.GetOrDefault(ctx, nil))
421	if len(rootIncludeDirs) > 0 {
422		f := includeDirsToFlags(rootIncludeDirs)
423		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
424		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
425	}
426
427	if compiler.includeBuildDirectory() {
428		flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+modulePath)
429		flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+modulePath)
430	}
431
432	if !(ctx.useSdk() || ctx.InVendorOrProduct()) || ctx.Host() {
433		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
434			"${config.CommonGlobalIncludes}",
435			tc.IncludeFlags())
436	}
437
438	if ctx.useSdk() {
439		// The NDK headers are installed to a common sysroot. While a more
440		// typical Soong approach would be to only make the headers for the
441		// library you're using available, we're trying to emulate the NDK
442		// behavior here, and the NDK always has all the NDK headers available.
443		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
444			"--sysroot "+getNdkSysrootBase(ctx).String())
445	} else if ctx.Device() {
446		flags.Global.CommonFlags = append(flags.Global.CFlags, "-nostdlibinc")
447	}
448
449	if ctx.InVendorOrProduct() {
450		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VNDK__")
451		if ctx.inVendor() {
452			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VENDOR__")
453		} else if ctx.inProduct() {
454			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_PRODUCT__")
455		}
456
457		// Define __ANDROID_VENDOR_API__ for both product and vendor variants
458		// because they both use the same LLNDK libraries.
459		vendorApiLevel := ctx.Config().VendorApiLevel()
460		if vendorApiLevel == "" {
461			// TODO(b/314036847): This is a fallback for UDC targets.
462			// This must be a build failure when UDC is no longer built
463			// from this source tree.
464			vendorApiLevel = ctx.Config().PlatformSdkVersion().String()
465		}
466		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VENDOR_API__="+vendorApiLevel)
467	}
468
469	if ctx.inRecovery() {
470		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__")
471	}
472
473	if ctx.inRecovery() || ctx.inRamdisk() || ctx.inVendorRamdisk() {
474		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RAMDISK__")
475	}
476
477	if ctx.apexVariationName() != "" {
478		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
479	}
480
481	if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
482		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_NATIVE_BRIDGE__")
483	}
484
485	instructionSet := String(compiler.Properties.Instruction_set)
486	if flags.RequiredInstructionSet != "" {
487		instructionSet = flags.RequiredInstructionSet
488	}
489	instructionSetFlags, err := tc.InstructionSetFlags(instructionSet)
490	if err != nil {
491		ctx.ModuleErrorf("%s", err)
492	}
493
494	if !ctx.DeviceConfig().BuildBrokenClangCFlags() && len(compiler.Properties.Clang_cflags) != 0 {
495		ctx.PropertyErrorf("clang_cflags", "property is deprecated, see Changes.md file")
496	} else {
497		CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
498	}
499	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() && len(compiler.Properties.Clang_asflags) != 0 {
500		ctx.PropertyErrorf("clang_asflags", "property is deprecated, see Changes.md file")
501	} else {
502		CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
503	}
504
505	flags.Local.CFlags = config.ClangFilterUnknownCflags(flags.Local.CFlags)
506	if !ctx.DeviceConfig().BuildBrokenClangCFlags() {
507		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...)
508	}
509	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() {
510		flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...)
511	}
512	flags.Local.CppFlags = config.ClangFilterUnknownCflags(flags.Local.CppFlags)
513	flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
514	flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
515
516	target := "-target " + tc.ClangTriple()
517	if ctx.Os().Class == android.Device {
518		version := ctx.minSdkVersion()
519		if version == "" || version == "current" {
520			target += strconv.Itoa(android.FutureApiLevelInt)
521		} else {
522			apiLevel := nativeApiLevelOrPanic(ctx, version)
523			target += strconv.Itoa(apiLevel.FinalOrFutureInt())
524		}
525	}
526
527	// bpf targets don't need the default target triple. b/308826679
528	if proptools.Bool(compiler.Properties.Bpf_target) {
529		target = "--target=bpf"
530	}
531
532	flags.Global.CFlags = append(flags.Global.CFlags, target)
533	flags.Global.AsFlags = append(flags.Global.AsFlags, target)
534	flags.Global.LdFlags = append(flags.Global.LdFlags, target)
535
536	hod := "Host"
537	if ctx.Os().Class == android.Device {
538		hod = "Device"
539	}
540
541	flags.Global.CommonFlags = append(flags.Global.CommonFlags, instructionSetFlags)
542	flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...)
543	flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...)
544
545	flags.Global.AsFlags = append(flags.Global.AsFlags, tc.Asflags())
546	flags.Global.CppFlags = append([]string{"${config.CommonGlobalCppflags}"}, flags.Global.CppFlags...)
547
548	// bpf targets don't need the target specific toolchain cflags. b/308826679
549	if !proptools.Bool(compiler.Properties.Bpf_target) {
550		flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.Cflags())
551	}
552	flags.Global.CommonFlags = append(flags.Global.CommonFlags,
553		"${config.CommonGlobalCflags}",
554		fmt.Sprintf("${config.%sGlobalCflags}", hod))
555
556	if android.IsThirdPartyPath(modulePath) {
557		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ExternalCflags}")
558	}
559
560	if Bool(compiler.Properties.Rtti) {
561		flags.Local.CppFlags = append(flags.Local.CppFlags, "-frtti")
562	} else {
563		flags.Local.CppFlags = append(flags.Local.CppFlags, "-fno-rtti")
564	}
565
566	flags.Global.AsFlags = append(flags.Global.AsFlags, "${config.CommonGlobalAsflags}")
567
568	flags.Global.CppFlags = append(flags.Global.CppFlags, tc.Cppflags())
569
570	flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags())
571
572	// bpf targets don't need the target specific toolchain cflags. b/308826679
573	if !proptools.Bool(compiler.Properties.Bpf_target) {
574		flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
575	}
576
577	cStd := parseCStd(compiler.Properties.C_std)
578	cppStd := parseCppStd(compiler.Properties.Cpp_std)
579
580	cStd, cppStd = maybeReplaceGnuToC(compiler.Properties.Gnu_extensions, cStd, cppStd)
581
582	flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...)
583	flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...)
584
585	if ctx.inVendor() {
586		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
587	}
588
589	if ctx.inProduct() {
590		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Product.Cflags)...)
591	}
592
593	if ctx.inRecovery() {
594		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
595	}
596
597	if ctx.inVendorRamdisk() {
598		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor_ramdisk.Cflags)...)
599	}
600	if ctx.inRamdisk() {
601		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Ramdisk.Cflags)...)
602	}
603	if !ctx.useSdk() {
604		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Platform.Cflags)...)
605	}
606
607	// We can enforce some rules more strictly in the code we own. strict
608	// indicates if this is code that we can be stricter with. If we have
609	// rules that we want to apply to *our* code (but maybe can't for
610	// vendor/device specific things), we could extend this to be a ternary
611	// value.
612	strict := true
613	if strings.HasPrefix(modulePath, "external/") {
614		strict = false
615	}
616
617	// Can be used to make some annotations stricter for code we can fix
618	// (such as when we mark functions as deprecated).
619	if strict {
620		flags.Global.CFlags = append(flags.Global.CFlags, "-DANDROID_STRICT")
621	}
622
623	if compiler.hasSrcExt(ctx, ".proto") {
624		flags = protoFlags(ctx, flags, &compiler.Proto)
625	}
626
627	if compiler.hasSrcExt(ctx, ".y") || compiler.hasSrcExt(ctx, ".yy") {
628		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
629			"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
630	}
631
632	if len(compiler.Properties.Aidl.Libs) > 0 &&
633		(len(compiler.Properties.Aidl.Include_dirs) > 0 || len(compiler.Properties.Aidl.Local_include_dirs) > 0) {
634		ctx.ModuleErrorf("aidl.libs and (aidl.include_dirs or aidl.local_include_dirs) can't be set at the same time. For aidl headers, please only use aidl.libs prop")
635	}
636
637	if compiler.hasAidl(ctx, deps) {
638		flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
639		if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
640			localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs)
641			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(localAidlIncludeDirs))
642		}
643		if len(compiler.Properties.Aidl.Include_dirs) > 0 {
644			rootAidlIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Aidl.Include_dirs)
645			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
646		}
647
648		var rootAidlIncludeDirs android.Paths
649		for _, aidlLibraryInfo := range deps.AidlLibraryInfos {
650			rootAidlIncludeDirs = append(rootAidlIncludeDirs, aidlLibraryInfo.IncludeDirs.ToList()...)
651		}
652		if len(rootAidlIncludeDirs) > 0 {
653			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
654		}
655
656		if proptools.BoolDefault(compiler.Properties.Aidl.Generate_traces, true) {
657			flags.aidlFlags = append(flags.aidlFlags, "-t")
658		}
659
660		aidlMinSdkVersion := ctx.minSdkVersion()
661		if aidlMinSdkVersion == "" {
662			aidlMinSdkVersion = "platform_apis"
663		}
664		flags.aidlFlags = append(flags.aidlFlags, "--min_sdk_version="+aidlMinSdkVersion)
665
666		if compiler.hasSrcExt(ctx, ".aidl") {
667			flags.Local.CommonFlags = append(flags.Local.CommonFlags,
668				"-I"+android.PathForModuleGen(ctx, "aidl").String())
669		}
670		if len(deps.AidlLibraryInfos) > 0 {
671			flags.Local.CommonFlags = append(flags.Local.CommonFlags,
672				"-I"+android.PathForModuleGen(ctx, "aidl_library").String())
673		}
674	}
675
676	if compiler.hasSrcExt(ctx, ".rscript") || compiler.hasSrcExt(ctx, ".fs") {
677		flags = rsFlags(ctx, flags, &compiler.Properties)
678	}
679
680	if compiler.hasSrcExt(ctx, ".sysprop") {
681		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
682			"-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
683	}
684
685	if len(srcs) > 0 {
686		module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
687		if inList("-Wno-error", flags.Local.CFlags) || inList("-Wno-error", flags.Local.CppFlags) {
688			ctx.getOrCreateMakeVarsInfo().UsingWnoError = module
689		} else if !inList("-Werror", flags.Local.CFlags) && !inList("-Werror", flags.Local.CppFlags) {
690			if warningsAreAllowed(ctx.ModuleDir()) {
691				ctx.getOrCreateMakeVarsInfo().WarningsAllowed = module
692			} else {
693				flags.Local.CFlags = append([]string{"-Werror"}, flags.Local.CFlags...)
694			}
695		}
696	}
697
698	if Bool(compiler.Properties.Openmp) {
699		flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp")
700	}
701
702	if ctx.optimizeForSize() {
703		flags.Local.CFlags = append(flags.Local.CFlags, "-Oz")
704		if !ctx.Config().IsEnvFalse("THINLTO_USE_MLGO") {
705			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release")
706		}
707	}
708
709	// Exclude directories from manual binder interface allowed list.
710	//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
711	if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
712		flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
713	}
714
715	flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideGlobalCflags}")
716
717	if flags.Toolchain.Is64Bit() {
718		flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverride64GlobalCflags}")
719	}
720
721	if android.IsThirdPartyPath(ctx.ModuleDir()) {
722		flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideExternalGlobalCflags}")
723	}
724
725	return flags
726}
727
728func (compiler *baseCompiler) hasSrcExt(ctx BaseModuleContext, ext string) bool {
729	for _, src := range compiler.srcsBeforeGen {
730		if src.Ext() == ext {
731			return true
732		}
733	}
734	for _, src := range compiler.Properties.Srcs.GetOrDefault(ctx, nil) {
735		if filepath.Ext(src) == ext {
736			return true
737		}
738	}
739
740	return false
741}
742
743var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
744
745// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
746// For example, com.android.foo => COM_ANDROID_FOO
747func makeDefineString(name string) string {
748	return invalidDefineCharRegex.ReplaceAllString(strings.ToUpper(name), "_")
749}
750
751var gnuToCReplacer = strings.NewReplacer("gnu", "c")
752
753func ndkPathDeps(ctx ModuleContext) android.Paths {
754	if ctx.Module().(*Module).IsSdkVariant() {
755		// The NDK sysroot timestamp file depends on all the NDK sysroot header files
756		// for compiling src to obj files.
757		return android.Paths{getNdkHeadersTimestampFile(ctx)}
758	}
759	return nil
760}
761
762func (compiler *baseCompiler) hasAidl(ctx BaseModuleContext, deps PathDeps) bool {
763	return len(deps.AidlLibraryInfos) > 0 || compiler.hasSrcExt(ctx, ".aidl")
764}
765
766func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
767	pathDeps := deps.GeneratedDeps
768	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
769
770	buildFlags := flagsToBuilderFlags(flags)
771
772	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
773
774	srcs, genDeps, info := genSources(ctx, deps.AidlLibraryInfos, srcs, buildFlags)
775	pathDeps = append(pathDeps, genDeps...)
776
777	compiler.pathDeps = pathDeps
778	compiler.generatedSourceInfo = info
779	compiler.cFlagsDeps = flags.CFlagsDeps
780
781	// Save src, buildFlags and context
782	compiler.srcs = srcs
783
784	// Compile files listed in c.Properties.Srcs into objects
785	objs := compileObjs(ctx, buildFlags, "", srcs,
786		append(android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_disabled_srcs), compiler.generatedSources...),
787		android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_timeout_srcs),
788		pathDeps, compiler.cFlagsDeps)
789
790	if ctx.Failed() {
791		return Objects{}
792	}
793
794	return objs
795}
796
797// Compile a list of source files into objects a specified subdirectory
798func compileObjs(ctx ModuleContext, flags builderFlags, subdir string,
799	srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
800
801	return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps)
802}
803
804// Properties for rust_bindgen related to generating rust bindings.
805// This exists here so these properties can be included in a cc_default
806// which can be used in both cc and rust modules.
807type RustBindgenClangProperties struct {
808	// list of directories relative to the Blueprints file that will
809	// be added to the include path using -I
810	Local_include_dirs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
811
812	// list of static libraries that provide headers for this binding.
813	Static_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
814
815	// list of shared libraries that provide headers for this binding.
816	Shared_libs proptools.Configurable[[]string] `android:"arch_variant"`
817
818	// List of libraries which export include paths required for this module
819	Header_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
820
821	// list of clang flags required to correctly interpret the headers.
822	Cflags proptools.Configurable[[]string] `android:"arch_variant"`
823
824	// list of c++ specific clang flags required to correctly interpret the headers.
825	// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
826	Cppflags proptools.Configurable[[]string] `android:"arch_variant"`
827
828	// C standard version to use. Can be a specific version (such as "gnu11"),
829	// "experimental" (which will use draft versions like C1x when available),
830	// or the empty string (which will use the default).
831	//
832	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
833	// to "default" will use the build system default version. This cannot be set at the same time as cpp_std.
834	C_std *string
835
836	// C++ standard version to use. Can be a specific version (such as
837	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
838	// available), or the empty string (which will use the default).
839	//
840	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
841	// to "default" will use the build system default version. This cannot be set at the same time as c_std.
842	Cpp_std *string
843
844	//TODO(b/161141999) Add support for headers from cc_library_header modules.
845}
846