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