• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 requiresGlobalIncludes(ctx ModuleContext) bool {
328	return !(ctx.useSdk() || ctx.InVendorOrProduct()) || ctx.Host()
329}
330
331func useGnuExtensions(gnuExtensions *bool) bool {
332	return proptools.BoolDefault(gnuExtensions, true)
333}
334
335func maybeReplaceGnuToC(gnuExtensions *bool, cStd string, cppStd string) (string, string) {
336	if !useGnuExtensions(gnuExtensions) {
337		cStd = gnuToCReplacer.Replace(cStd)
338		cppStd = gnuToCReplacer.Replace(cppStd)
339	}
340	return cStd, cppStd
341}
342
343func parseCppStd(cppStdPtr *string) string {
344	cppStd := String(cppStdPtr)
345	switch cppStd {
346	case "":
347		return config.CppStdVersion
348	case "experimental":
349		return config.ExperimentalCppStdVersion
350	default:
351		return cppStd
352	}
353}
354
355func parseCStd(cStdPtr *string) string {
356	cStd := String(cStdPtr)
357	switch cStd {
358	case "":
359		return config.CStdVersion
360	case "experimental":
361		return config.ExperimentalCStdVersion
362	default:
363		return cStd
364	}
365}
366
367func AddTargetFlags(ctx android.ModuleContext, flags Flags, tc config.Toolchain, version string, bpf bool) Flags {
368	target := "-target " + tc.ClangTriple()
369	if ctx.Os().Class == android.Device {
370		if version == "" || version == "current" {
371			target += strconv.Itoa(android.FutureApiLevelInt)
372		} else {
373			apiLevel := nativeApiLevelOrPanic(ctx, version)
374			target += strconv.Itoa(apiLevel.FinalOrFutureInt())
375		}
376	}
377
378	// bpf targets don't need the default target triple. b/308826679
379	if bpf {
380		target = "--target=bpf"
381	}
382
383	flags.Global.CFlags = append(flags.Global.CFlags, target)
384	flags.Global.AsFlags = append(flags.Global.AsFlags, target)
385	flags.Global.LdFlags = append(flags.Global.LdFlags, target)
386
387	return flags
388}
389
390// Create a Flags struct that collects the compile flags from global values,
391// per-target values, module type values, and per-module Blueprints properties
392func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
393	tc := ctx.toolchain()
394	modulePath := ctx.ModuleDir()
395
396	reuseObjs := false
397	if len(ctx.GetDirectDepsProxyWithTag(reuseObjTag)) > 0 {
398		reuseObjs = true
399	}
400
401	// If a reuseObjTag dependency exists then this module is reusing the objects (generally the shared variant
402	// reusing objects from the static variant), and doesn't need to compile any sources of its own.
403	var srcs []string
404	if !reuseObjs {
405		srcs = compiler.Properties.Srcs.GetOrDefault(ctx, nil)
406		exclude_srcs := compiler.Properties.Exclude_srcs.GetOrDefault(ctx, nil)
407		compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, srcs, exclude_srcs)
408		compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
409	}
410
411	cflags := compiler.Properties.Cflags.GetOrDefault(ctx, nil)
412	cppflags := compiler.Properties.Cppflags.GetOrDefault(ctx, nil)
413	CheckBadCompilerFlags(ctx, "cflags", cflags)
414	CheckBadCompilerFlags(ctx, "cppflags", cppflags)
415	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
416	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
417	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
418	CheckBadCompilerFlags(ctx, "product.cflags", compiler.Properties.Target.Product.Cflags)
419	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
420	CheckBadCompilerFlags(ctx, "ramdisk.cflags", compiler.Properties.Target.Ramdisk.Cflags)
421	CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
422	CheckBadCompilerFlags(ctx, "platform.cflags", compiler.Properties.Target.Platform.Cflags)
423
424	esc := proptools.NinjaAndShellEscapeList
425
426	flags.Local.CFlags = append(flags.Local.CFlags, esc(cflags)...)
427	flags.Local.CppFlags = append(flags.Local.CppFlags, esc(cppflags)...)
428	flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
429	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
430	flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
431
432	flags.Yacc = compiler.Properties.Yacc
433	flags.Lex = compiler.Properties.Lex
434
435	flags.ClangVerify = compiler.Properties.Clang_verify
436	if compiler.Properties.Clang_verify {
437		flags.Local.CFlags = append(flags.Local.CFlags, "-Xclang", "-verify")
438	}
439
440	// Include dir cflags
441	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs.GetOrDefault(ctx, nil))
442	if len(localIncludeDirs) > 0 {
443		f := includeDirsToFlags(localIncludeDirs)
444		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
445		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
446	}
447	rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs.GetOrDefault(ctx, nil))
448	if len(rootIncludeDirs) > 0 {
449		f := includeDirsToFlags(rootIncludeDirs)
450		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
451		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
452	}
453
454	if compiler.includeBuildDirectory() {
455		flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+modulePath)
456		flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+modulePath)
457	}
458
459	if requiresGlobalIncludes(ctx) {
460		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
461			"${config.CommonGlobalIncludes}",
462			tc.IncludeFlags())
463	}
464
465	if ctx.useSdk() {
466		// The NDK headers are installed to a common sysroot. While a more
467		// typical Soong approach would be to only make the headers for the
468		// library you're using available, we're trying to emulate the NDK
469		// behavior here, and the NDK always has all the NDK headers available.
470		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
471			"--sysroot "+getNdkSysrootBase(ctx).String())
472	} else if ctx.Device() {
473		flags.Global.CommonFlags = append(flags.Global.CFlags, "-nostdlibinc")
474	}
475
476	if ctx.InVendorOrProduct() {
477		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VNDK__")
478		if ctx.inVendor() {
479			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VENDOR__")
480		} else if ctx.inProduct() {
481			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_PRODUCT__")
482		}
483
484		// Define __ANDROID_VENDOR_API__ for both product and vendor variants
485		// because they both use the same LLNDK libraries.
486		vendorApiLevel := ctx.Config().VendorApiLevel()
487		if vendorApiLevel == "" {
488			// TODO(b/314036847): This is a fallback for UDC targets.
489			// This must be a build failure when UDC is no longer built
490			// from this source tree.
491			vendorApiLevel = ctx.Config().PlatformSdkVersion().String()
492		}
493		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VENDOR_API__="+vendorApiLevel)
494	}
495
496	if ctx.inRecovery() {
497		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__")
498	}
499
500	if ctx.inRecovery() || ctx.inRamdisk() || ctx.inVendorRamdisk() {
501		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RAMDISK__")
502	}
503
504	if ctx.apexVariationName() != "" {
505		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
506	}
507
508	if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
509		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_NATIVE_BRIDGE__")
510	}
511
512	instructionSet := String(compiler.Properties.Instruction_set)
513	if flags.RequiredInstructionSet != "" {
514		instructionSet = flags.RequiredInstructionSet
515	}
516	instructionSetFlags, err := tc.InstructionSetFlags(instructionSet)
517	if err != nil {
518		ctx.ModuleErrorf("%s", err)
519	}
520
521	if !ctx.DeviceConfig().BuildBrokenClangCFlags() && len(compiler.Properties.Clang_cflags) != 0 {
522		ctx.PropertyErrorf("clang_cflags", "property is deprecated, see Changes.md file")
523	} else {
524		CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
525	}
526	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() && len(compiler.Properties.Clang_asflags) != 0 {
527		ctx.PropertyErrorf("clang_asflags", "property is deprecated, see Changes.md file")
528	} else {
529		CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
530	}
531
532	flags.Local.CFlags = config.ClangFilterUnknownCflags(flags.Local.CFlags)
533	if !ctx.DeviceConfig().BuildBrokenClangCFlags() {
534		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...)
535	}
536	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() {
537		flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...)
538	}
539	flags.Local.CppFlags = config.ClangFilterUnknownCflags(flags.Local.CppFlags)
540	flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
541	flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
542
543	flags = AddTargetFlags(ctx, flags, tc, ctx.minSdkVersion(), Bool(compiler.Properties.Bpf_target))
544
545	hod := "Host"
546	if ctx.Os().Class == android.Device {
547		hod = "Device"
548	}
549
550	flags.Global.CommonFlags = append(flags.Global.CommonFlags, instructionSetFlags)
551	flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...)
552	flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...)
553
554	flags.Global.AsFlags = append(flags.Global.AsFlags, tc.Asflags())
555	flags.Global.CppFlags = append([]string{"${config.CommonGlobalCppflags}"}, flags.Global.CppFlags...)
556
557	// bpf targets don't need the target specific toolchain cflags. b/308826679
558	if !proptools.Bool(compiler.Properties.Bpf_target) {
559		flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.Cflags())
560	}
561	flags.Global.CommonFlags = append(flags.Global.CommonFlags,
562		"${config.CommonGlobalCflags}",
563		fmt.Sprintf("${config.%sGlobalCflags}", hod))
564
565	if android.IsThirdPartyPath(modulePath) {
566		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ExternalCflags}")
567	}
568
569	if Bool(compiler.Properties.Rtti) {
570		flags.Local.CppFlags = append(flags.Local.CppFlags, "-frtti")
571	} else {
572		flags.Local.CppFlags = append(flags.Local.CppFlags, "-fno-rtti")
573	}
574
575	flags.Global.AsFlags = append(flags.Global.AsFlags, "${config.CommonGlobalAsflags}")
576
577	flags.Global.CppFlags = append(flags.Global.CppFlags, tc.Cppflags())
578
579	flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags())
580
581	// bpf targets don't need the target specific toolchain cflags. b/308826679
582	if !proptools.Bool(compiler.Properties.Bpf_target) {
583		flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
584	}
585
586	cStd := parseCStd(compiler.Properties.C_std)
587	cppStd := parseCppStd(compiler.Properties.Cpp_std)
588
589	cStd, cppStd = maybeReplaceGnuToC(compiler.Properties.Gnu_extensions, cStd, cppStd)
590
591	flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...)
592	flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...)
593
594	if ctx.inVendor() {
595		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
596	}
597
598	if ctx.inProduct() {
599		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Product.Cflags)...)
600	}
601
602	if ctx.inRecovery() {
603		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
604	}
605
606	if ctx.inVendorRamdisk() {
607		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor_ramdisk.Cflags)...)
608	}
609	if ctx.inRamdisk() {
610		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Ramdisk.Cflags)...)
611	}
612	if !ctx.useSdk() {
613		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Platform.Cflags)...)
614	}
615
616	// We can enforce some rules more strictly in the code we own. strict
617	// indicates if this is code that we can be stricter with. If we have
618	// rules that we want to apply to *our* code (but maybe can't for
619	// vendor/device specific things), we could extend this to be a ternary
620	// value.
621	strict := true
622	if strings.HasPrefix(modulePath, "external/") {
623		strict = false
624	}
625
626	// Can be used to make some annotations stricter for code we can fix
627	// (such as when we mark functions as deprecated).
628	if strict {
629		flags.Global.CFlags = append(flags.Global.CFlags, "-DANDROID_STRICT")
630	}
631
632	if compiler.hasSrcExt(ctx, ".proto") {
633		flags = protoFlags(ctx, flags, &compiler.Proto)
634	}
635
636	if compiler.hasSrcExt(ctx, ".y") || compiler.hasSrcExt(ctx, ".yy") {
637		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
638			"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
639	}
640
641	if len(compiler.Properties.Aidl.Libs) > 0 &&
642		(len(compiler.Properties.Aidl.Include_dirs) > 0 || len(compiler.Properties.Aidl.Local_include_dirs) > 0) {
643		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")
644	}
645
646	if compiler.hasAidl(ctx, deps) {
647		flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
648		if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
649			localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs)
650			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(localAidlIncludeDirs))
651		}
652		if len(compiler.Properties.Aidl.Include_dirs) > 0 {
653			rootAidlIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Aidl.Include_dirs)
654			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
655		}
656
657		var rootAidlIncludeDirs android.Paths
658		for _, aidlLibraryInfo := range deps.AidlLibraryInfos {
659			rootAidlIncludeDirs = append(rootAidlIncludeDirs, aidlLibraryInfo.IncludeDirs.ToList()...)
660		}
661		if len(rootAidlIncludeDirs) > 0 {
662			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
663		}
664
665		if proptools.BoolDefault(compiler.Properties.Aidl.Generate_traces, true) {
666			flags.aidlFlags = append(flags.aidlFlags, "-t")
667		}
668
669		aidlMinSdkVersion := ctx.minSdkVersion()
670		if aidlMinSdkVersion == "" {
671			aidlMinSdkVersion = "platform_apis"
672		}
673		flags.aidlFlags = append(flags.aidlFlags, "--min_sdk_version="+aidlMinSdkVersion)
674
675		if compiler.hasSrcExt(ctx, ".aidl") {
676			flags.Local.CommonFlags = append(flags.Local.CommonFlags,
677				"-I"+android.PathForModuleGen(ctx, "aidl").String())
678		}
679		if len(deps.AidlLibraryInfos) > 0 {
680			flags.Local.CommonFlags = append(flags.Local.CommonFlags,
681				"-I"+android.PathForModuleGen(ctx, "aidl_library").String())
682		}
683	}
684
685	if compiler.hasSrcExt(ctx, ".rscript") || compiler.hasSrcExt(ctx, ".fs") {
686		flags = rsFlags(ctx, flags, &compiler.Properties)
687	}
688
689	if compiler.hasSrcExt(ctx, ".sysprop") {
690		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
691			"-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
692	}
693
694	if len(srcs) > 0 {
695		module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
696		if inList("-Wno-error", flags.Local.CFlags) || inList("-Wno-error", flags.Local.CppFlags) {
697			ctx.getOrCreateMakeVarsInfo().UsingWnoError = module
698		} else if !inList("-Werror", flags.Local.CFlags) && !inList("-Werror", flags.Local.CppFlags) {
699			if warningsAreAllowed(ctx.ModuleDir()) {
700				ctx.getOrCreateMakeVarsInfo().WarningsAllowed = module
701			} else {
702				flags.Local.CFlags = append([]string{"-Werror"}, flags.Local.CFlags...)
703			}
704		}
705	}
706
707	if Bool(compiler.Properties.Openmp) {
708		flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp")
709	}
710
711	if ctx.optimizeForSize() {
712		flags.Local.CFlags = append(flags.Local.CFlags, "-Oz")
713		if !ctx.Config().IsEnvFalse("THINLTO_USE_MLGO") {
714			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release")
715		}
716	}
717
718	// Exclude directories from manual binder interface allowed list.
719	//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
720	if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
721		flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
722	}
723
724	flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideGlobalCflags}")
725
726	if flags.Toolchain.Is64Bit() {
727		flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverride64GlobalCflags}")
728	}
729
730	if android.IsThirdPartyPath(ctx.ModuleDir()) {
731		flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideExternalGlobalCflags}")
732	}
733
734	return flags
735}
736
737func (compiler *baseCompiler) hasSrcExt(ctx BaseModuleContext, ext string) bool {
738	for _, src := range compiler.srcsBeforeGen {
739		if src.Ext() == ext {
740			return true
741		}
742	}
743	for _, src := range compiler.Properties.Srcs.GetOrDefault(ctx, nil) {
744		if filepath.Ext(src) == ext {
745			return true
746		}
747	}
748
749	return false
750}
751
752var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
753
754// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
755// For example, com.android.foo => COM_ANDROID_FOO
756func makeDefineString(name string) string {
757	return invalidDefineCharRegex.ReplaceAllString(strings.ToUpper(name), "_")
758}
759
760var gnuToCReplacer = strings.NewReplacer("gnu", "c")
761
762func ndkPathDeps(ctx ModuleContext) android.Paths {
763	if ctx.Module().(*Module).IsSdkVariant() {
764		// The NDK sysroot timestamp file depends on all the NDK sysroot header files
765		// for compiling src to obj files.
766		return android.Paths{getNdkHeadersTimestampFile(ctx)}
767	}
768	return nil
769}
770
771func (compiler *baseCompiler) hasAidl(ctx BaseModuleContext, deps PathDeps) bool {
772	return len(deps.AidlLibraryInfos) > 0 || compiler.hasSrcExt(ctx, ".aidl")
773}
774
775func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
776	pathDeps := deps.GeneratedDeps
777	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
778
779	buildFlags := flagsToBuilderFlags(flags)
780
781	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
782
783	srcs, genDeps, info := genSources(ctx, deps.AidlLibraryInfos, srcs, buildFlags)
784	pathDeps = append(pathDeps, genDeps...)
785
786	compiler.pathDeps = pathDeps
787	compiler.generatedSourceInfo = info
788	compiler.cFlagsDeps = flags.CFlagsDeps
789
790	// Save src, buildFlags and context
791	compiler.srcs = srcs
792
793	// Compile files listed in c.Properties.Srcs into objects
794	objs := compileObjs(ctx, buildFlags, "", srcs,
795		append(android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_disabled_srcs), compiler.generatedSources...),
796		android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_timeout_srcs),
797		pathDeps, compiler.cFlagsDeps, ctx.getSharedFlags())
798
799	if ctx.Failed() {
800		return Objects{}
801	}
802
803	return objs
804}
805
806// Compile a list of source files into objects a specified subdirectory
807func compileObjs(ctx android.ModuleContext, flags builderFlags, subdir string,
808	srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths,
809	sharedFlags *SharedFlags) Objects {
810
811	return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps,
812		sharedFlags)
813}
814
815// Properties for rust_bindgen related to generating rust bindings.
816// This exists here so these properties can be included in a cc_default
817// which can be used in both cc and rust modules.
818type RustBindgenClangProperties struct {
819	// list of directories relative to the Blueprints file that will
820	// be added to the include path using -I
821	Local_include_dirs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
822
823	// list of static libraries that provide headers for this binding.
824	Static_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
825
826	// list of shared libraries that provide headers for this binding.
827	Shared_libs proptools.Configurable[[]string] `android:"arch_variant"`
828
829	// List of libraries which export include paths required for this module
830	Header_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
831
832	// list of clang flags required to correctly interpret the headers.
833	Cflags proptools.Configurable[[]string] `android:"arch_variant"`
834
835	// list of c++ specific clang flags required to correctly interpret the headers.
836	// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
837	Cppflags proptools.Configurable[[]string] `android:"arch_variant"`
838
839	// C standard version to use. Can be a specific version (such as "gnu11"),
840	// "experimental" (which will use draft versions like C1x when available),
841	// or the empty string (which will use the default).
842	//
843	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
844	// to "default" will use the build system default version. This cannot be set at the same time as cpp_std.
845	C_std *string
846
847	// C++ standard version to use. Can be a specific version (such as
848	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
849	// available), or the empty string (which will use the default).
850	//
851	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
852	// to "default" will use the build system default version. This cannot be set at the same time as c_std.
853	Cpp_std *string
854
855	//TODO(b/161141999) Add support for headers from cc_library_header modules.
856}
857