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 used to build the C/C++ module.
43	// This is most useful in the arch/multilib variants to remove non-common files
44	Exclude_srcs []string `android:"path,arch_variant"`
45
46	// list of module-specific flags that will be used for C and C++ compiles.
47	Cflags []string `android:"arch_variant"`
48
49	// list of module-specific flags that will be used for C++ compiles
50	Cppflags []string `android:"arch_variant"`
51
52	// list of module-specific flags that will be used for C compiles
53	Conlyflags []string `android:"arch_variant"`
54
55	// list of module-specific flags that will be used for .S compiles
56	Asflags []string `android:"arch_variant"`
57
58	// list of module-specific flags that will be used for C and C++ compiles when
59	// compiling with clang
60	Clang_cflags []string `android:"arch_variant"`
61
62	// list of module-specific flags that will be used for .S compiles when
63	// compiling with clang
64	Clang_asflags []string `android:"arch_variant"`
65
66	// the instruction set architecture to use to compile the C/C++
67	// module.
68	Instruction_set *string `android:"arch_variant"`
69
70	// list of directories relative to the root of the source tree that will
71	// be added to the include path using -I.
72	// If possible, don't use this.  If adding paths from the current directory use
73	// local_include_dirs, if adding paths from other modules use export_include_dirs in
74	// that module.
75	Include_dirs []string `android:"arch_variant,variant_prepend"`
76
77	// list of directories relative to the Blueprints file that will
78	// be added to the include path using -I
79	Local_include_dirs []string `android:"arch_variant,variant_prepend"`
80
81	// Add the directory containing the Android.bp file to the list of include
82	// directories. Defaults to true.
83	Include_build_directory *bool
84
85	// list of generated sources to compile. These are the names of gensrcs or
86	// genrule modules.
87	Generated_sources []string `android:"arch_variant"`
88
89	// list of generated sources that should not be used to build the C/C++ module.
90	// This is most useful in the arch/multilib variants to remove non-common files
91	Exclude_generated_sources []string `android:"arch_variant"`
92
93	// list of generated headers to add to the include path. These are the names
94	// of genrule modules.
95	Generated_headers []string `android:"arch_variant"`
96
97	// pass -frtti instead of -fno-rtti
98	Rtti *bool
99
100	// C standard version to use. Can be a specific version (such as "gnu11"),
101	// "experimental" (which will use draft versions like C1x when available),
102	// or the empty string (which will use the default).
103	C_std *string
104
105	// C++ standard version to use. Can be a specific version (such as
106	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
107	// available), or the empty string (which will use the default).
108	Cpp_std *string
109
110	// if set to false, use -std=c++* instead of -std=gnu++*
111	Gnu_extensions *bool
112
113	Yacc *YaccProperties
114	Lex  *LexProperties
115
116	Aidl struct {
117		// list of directories that will be added to the aidl include paths.
118		Include_dirs []string
119
120		// list of directories relative to the Blueprints file that will
121		// be added to the aidl include paths.
122		Local_include_dirs []string
123
124		// whether to generate traces (for systrace) for this interface
125		Generate_traces *bool
126
127		// list of flags that will be passed to the AIDL compiler
128		Flags []string
129	}
130
131	Renderscript struct {
132		// list of directories that will be added to the llvm-rs-cc include paths
133		Include_dirs []string
134
135		// list of flags that will be passed to llvm-rs-cc
136		Flags []string
137
138		// Renderscript API level to target
139		Target_api *string
140	}
141
142	Debug, Release struct {
143		// list of module-specific flags that will be used for C and C++ compiles in debug or
144		// release builds
145		Cflags []string `android:"arch_variant"`
146	} `android:"arch_variant"`
147
148	Target struct {
149		Vendor, Product struct {
150			// list of source files that should only be used in vendor or
151			// product variant of the C/C++ module.
152			Srcs []string `android:"path"`
153
154			// list of source files that should not be used to build vendor
155			// or product variant of the C/C++ module.
156			Exclude_srcs []string `android:"path"`
157
158			// List of additional cflags that should be used to build vendor
159			// or product variant of the C/C++ module.
160			Cflags []string
161
162			// list of generated sources that should not be used to build
163			// vendor or product variant of the C/C++ module.
164			Exclude_generated_sources []string
165		}
166		Recovery struct {
167			// list of source files that should only be used in the
168			// recovery variant of the C/C++ module.
169			Srcs []string `android:"path"`
170
171			// list of source files that should not be used to
172			// build the recovery variant of the C/C++ module.
173			Exclude_srcs []string `android:"path"`
174
175			// List of additional cflags that should be used to build the recovery
176			// variant of the C/C++ module.
177			Cflags []string
178
179			// list of generated sources that should not be used to
180			// build the recovery variant of the C/C++ module.
181			Exclude_generated_sources []string
182		}
183		Vendor_ramdisk struct {
184			// list of source files that should not be used to
185			// build the vendor ramdisk variant of the C/C++ module.
186			Exclude_srcs []string `android:"path"`
187
188			// List of additional cflags that should be used to build the vendor ramdisk
189			// variant of the C/C++ module.
190			Cflags []string
191		}
192	}
193
194	Proto struct {
195		// Link statically against the protobuf runtime
196		Static *bool `android:"arch_variant"`
197	} `android:"arch_variant"`
198
199	// Stores the original list of source files before being cleared by library reuse
200	OriginalSrcs []string `blueprint:"mutated"`
201
202	// Build and link with OpenMP
203	Openmp *bool `android:"arch_variant"`
204
205	// Deprecated.
206	// Adds __ANDROID_APEX_<APEX_MODULE_NAME>__ macro defined for apex variants in addition to __ANDROID_APEX__
207	Use_apex_name_macro *bool
208
209	// Adds two macros for apex variants in addition to __ANDROID_APEX__
210	// * __ANDROID_APEX_COM_ANDROID_FOO__
211	// * __ANDROID_APEX_NAME__="com.android.foo"
212	UseApexNameMacro bool `blueprint:"mutated"`
213}
214
215func NewBaseCompiler() *baseCompiler {
216	return &baseCompiler{}
217}
218
219type baseCompiler struct {
220	Properties BaseCompilerProperties
221	Proto      android.ProtoProperties
222	cFlagsDeps android.Paths
223	pathDeps   android.Paths
224	flags      builderFlags
225
226	// Sources that were passed to the C/C++ compiler
227	srcs android.Paths
228
229	// Sources that were passed in the Android.bp file, including generated sources generated by
230	// other modules and filegroups. May include source files that have not yet been translated to
231	// C/C++ (.aidl, .proto, etc.)
232	srcsBeforeGen android.Paths
233
234	generatedSourceInfo
235}
236
237var _ compiler = (*baseCompiler)(nil)
238
239type CompiledInterface interface {
240	Srcs() android.Paths
241}
242
243func (compiler *baseCompiler) Srcs() android.Paths {
244	return append(android.Paths{}, compiler.srcs...)
245}
246
247func (compiler *baseCompiler) appendCflags(flags []string) {
248	compiler.Properties.Cflags = append(compiler.Properties.Cflags, flags...)
249}
250
251func (compiler *baseCompiler) appendAsflags(flags []string) {
252	compiler.Properties.Asflags = append(compiler.Properties.Asflags, flags...)
253}
254
255func (compiler *baseCompiler) compilerProps() []interface{} {
256	return []interface{}{&compiler.Properties, &compiler.Proto}
257}
258
259func (compiler *baseCompiler) includeBuildDirectory() bool {
260	return proptools.BoolDefault(compiler.Properties.Include_build_directory, true)
261}
262
263func (compiler *baseCompiler) compilerInit(ctx BaseModuleContext) {}
264
265func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
266	deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
267	deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources)
268	deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
269
270	android.ProtoDeps(ctx, &compiler.Proto)
271	if compiler.hasSrcExt(".proto") {
272		deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static))
273	}
274
275	if Bool(compiler.Properties.Openmp) {
276		deps.StaticLibs = append(deps.StaticLibs, "libomp")
277	}
278
279	return deps
280}
281
282func (compiler *baseCompiler) useApexNameMacro() bool {
283	return Bool(compiler.Properties.Use_apex_name_macro) || compiler.Properties.UseApexNameMacro
284}
285
286// Return true if the module is in the WarningAllowedProjects.
287func warningsAreAllowed(subdir string) bool {
288	subdir += "/"
289	return android.HasAnyPrefix(subdir, config.WarningAllowedProjects)
290}
291
292func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) {
293	getNamedMapForConfig(ctx.Config(), key).Store(module, true)
294}
295
296// Create a Flags struct that collects the compile flags from global values,
297// per-target values, module type values, and per-module Blueprints properties
298func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
299	tc := ctx.toolchain()
300	modulePath := android.PathForModuleSrc(ctx).String()
301
302	compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
303	compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
304
305	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
306	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
307	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
308	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
309	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
310	CheckBadCompilerFlags(ctx, "product.cflags", compiler.Properties.Target.Product.Cflags)
311	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
312	CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
313
314	esc := proptools.NinjaAndShellEscapeList
315
316	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Cflags)...)
317	flags.Local.CppFlags = append(flags.Local.CppFlags, esc(compiler.Properties.Cppflags)...)
318	flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
319	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
320	flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
321
322	flags.Yacc = compiler.Properties.Yacc
323	flags.Lex = compiler.Properties.Lex
324
325	// Include dir cflags
326	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
327	if len(localIncludeDirs) > 0 {
328		f := includeDirsToFlags(localIncludeDirs)
329		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
330		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
331	}
332	rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
333	if len(rootIncludeDirs) > 0 {
334		f := includeDirsToFlags(rootIncludeDirs)
335		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
336		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
337	}
338
339	if compiler.includeBuildDirectory() {
340		flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+modulePath)
341		flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+modulePath)
342	}
343
344	if !(ctx.useSdk() || ctx.useVndk()) || ctx.Host() {
345		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
346			"${config.CommonGlobalIncludes}",
347			tc.IncludeFlags())
348	}
349
350	if ctx.useSdk() {
351		// TODO: Switch to --sysroot.
352		// The NDK headers are installed to a common sysroot. While a more
353		// typical Soong approach would be to only make the headers for the
354		// library you're using available, we're trying to emulate the NDK
355		// behavior here, and the NDK always has all the NDK headers available.
356		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
357			"-isystem "+getCurrentIncludePath(ctx).String(),
358			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
359	}
360
361	if ctx.useVndk() {
362		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VNDK__")
363		if ctx.inVendor() {
364			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VENDOR__")
365		} else if ctx.inProduct() {
366			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_PRODUCT__")
367		}
368	}
369
370	if ctx.inRecovery() {
371		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__")
372	}
373
374	if ctx.apexVariationName() != "" {
375		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
376		if compiler.useApexNameMacro() {
377			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexVariationName())+"__")
378			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_NAME__='\""+ctx.apexVariationName()+"\"'")
379		}
380		if ctx.Device() {
381			flags.Global.CommonFlags = append(flags.Global.CommonFlags,
382				fmt.Sprintf("-D__ANDROID_APEX_MIN_SDK_VERSION__=%d",
383					ctx.apexSdkVersion().FinalOrFutureInt()))
384		}
385	}
386
387	if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
388		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_NATIVE_BRIDGE__")
389	}
390
391	instructionSet := String(compiler.Properties.Instruction_set)
392	if flags.RequiredInstructionSet != "" {
393		instructionSet = flags.RequiredInstructionSet
394	}
395	instructionSetFlags, err := tc.ClangInstructionSetFlags(instructionSet)
396	if err != nil {
397		ctx.ModuleErrorf("%s", err)
398	}
399
400	CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags)
401
402	// TODO: debug
403	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Release.Cflags)...)
404
405	CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
406	CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
407
408	flags.Local.CFlags = config.ClangFilterUnknownCflags(flags.Local.CFlags)
409	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...)
410	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...)
411	flags.Local.CppFlags = config.ClangFilterUnknownCflags(flags.Local.CppFlags)
412	flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
413	flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
414
415	target := "-target " + tc.ClangTriple()
416	if ctx.Os().Class == android.Device {
417		version := ctx.minSdkVersion()
418		if version == "" || version == "current" {
419			target += strconv.Itoa(android.FutureApiLevelInt)
420		} else {
421			target += version
422		}
423	}
424
425	gccPrefix := "-B" + config.ToolPath(tc)
426
427	flags.Global.CFlags = append(flags.Global.CFlags, target, gccPrefix)
428	flags.Global.AsFlags = append(flags.Global.AsFlags, target, gccPrefix)
429	flags.Global.LdFlags = append(flags.Global.LdFlags, target, gccPrefix)
430
431	hod := "Host"
432	if ctx.Os().Class == android.Device {
433		hod = "Device"
434	}
435
436	flags.Global.CommonFlags = append(flags.Global.CommonFlags, instructionSetFlags)
437	flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...)
438	flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...)
439
440	flags.Global.AsFlags = append(flags.Global.AsFlags, tc.ClangAsflags())
441	flags.Global.CppFlags = append([]string{"${config.CommonClangGlobalCppflags}"}, flags.Global.CppFlags...)
442	flags.Global.CommonFlags = append(flags.Global.CommonFlags,
443		tc.ClangCflags(),
444		"${config.CommonClangGlobalCflags}",
445		fmt.Sprintf("${config.%sClangGlobalCflags}", hod))
446
447	if isThirdParty(modulePath) {
448		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ClangExternalCflags}")
449	}
450
451	if tc.Bionic() {
452		if Bool(compiler.Properties.Rtti) {
453			flags.Local.CppFlags = append(flags.Local.CppFlags, "-frtti")
454		} else {
455			flags.Local.CppFlags = append(flags.Local.CppFlags, "-fno-rtti")
456		}
457	}
458
459	flags.Global.AsFlags = append(flags.Global.AsFlags, "-D__ASSEMBLY__")
460
461	flags.Global.CppFlags = append(flags.Global.CppFlags, tc.ClangCppflags())
462
463	flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags())
464
465	flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainClangCflags())
466
467	cStd := config.CStdVersion
468	if String(compiler.Properties.C_std) == "experimental" {
469		cStd = config.ExperimentalCStdVersion
470	} else if String(compiler.Properties.C_std) != "" {
471		cStd = String(compiler.Properties.C_std)
472	}
473
474	cppStd := String(compiler.Properties.Cpp_std)
475	switch String(compiler.Properties.Cpp_std) {
476	case "":
477		cppStd = config.CppStdVersion
478	case "experimental":
479		cppStd = config.ExperimentalCppStdVersion
480	}
481
482	if compiler.Properties.Gnu_extensions != nil && *compiler.Properties.Gnu_extensions == false {
483		cStd = gnuToCReplacer.Replace(cStd)
484		cppStd = gnuToCReplacer.Replace(cppStd)
485	}
486
487	flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...)
488	flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...)
489
490	if ctx.inVendor() {
491		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
492	}
493
494	if ctx.inProduct() {
495		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Product.Cflags)...)
496	}
497
498	if ctx.inRecovery() {
499		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
500	}
501
502	if ctx.inVendorRamdisk() {
503		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor_ramdisk.Cflags)...)
504	}
505
506	// We can enforce some rules more strictly in the code we own. strict
507	// indicates if this is code that we can be stricter with. If we have
508	// rules that we want to apply to *our* code (but maybe can't for
509	// vendor/device specific things), we could extend this to be a ternary
510	// value.
511	strict := true
512	if strings.HasPrefix(modulePath, "external/") {
513		strict = false
514	}
515
516	// Can be used to make some annotations stricter for code we can fix
517	// (such as when we mark functions as deprecated).
518	if strict {
519		flags.Global.CFlags = append(flags.Global.CFlags, "-DANDROID_STRICT")
520	}
521
522	if compiler.hasSrcExt(".proto") {
523		flags = protoFlags(ctx, flags, &compiler.Proto)
524	}
525
526	if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") {
527		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
528			"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
529	}
530
531	if compiler.hasSrcExt(".mc") {
532		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
533			"-I"+android.PathForModuleGen(ctx, "windmc", ctx.ModuleDir()).String())
534	}
535
536	if compiler.hasSrcExt(".aidl") {
537		flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
538		if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
539			localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs)
540			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(localAidlIncludeDirs))
541		}
542		if len(compiler.Properties.Aidl.Include_dirs) > 0 {
543			rootAidlIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Aidl.Include_dirs)
544			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
545		}
546
547		if Bool(compiler.Properties.Aidl.Generate_traces) {
548			flags.aidlFlags = append(flags.aidlFlags, "-t")
549		}
550
551		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
552			"-I"+android.PathForModuleGen(ctx, "aidl").String())
553	}
554
555	if compiler.hasSrcExt(".rscript") || compiler.hasSrcExt(".fs") {
556		flags = rsFlags(ctx, flags, &compiler.Properties)
557	}
558
559	if compiler.hasSrcExt(".sysprop") {
560		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
561			"-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
562	}
563
564	if len(compiler.Properties.Srcs) > 0 {
565		module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
566		if inList("-Wno-error", flags.Local.CFlags) || inList("-Wno-error", flags.Local.CppFlags) {
567			addToModuleList(ctx, modulesUsingWnoErrorKey, module)
568		} else if !inList("-Werror", flags.Local.CFlags) && !inList("-Werror", flags.Local.CppFlags) {
569			if warningsAreAllowed(ctx.ModuleDir()) {
570				addToModuleList(ctx, modulesAddedWallKey, module)
571				flags.Local.CFlags = append([]string{"-Wall"}, flags.Local.CFlags...)
572			} else {
573				flags.Local.CFlags = append([]string{"-Wall", "-Werror"}, flags.Local.CFlags...)
574			}
575		}
576	}
577
578	if Bool(compiler.Properties.Openmp) {
579		flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp")
580	}
581
582	// Exclude directories from manual binder interface allowed list.
583	//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
584	if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
585		flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
586	}
587
588	return flags
589}
590
591func (compiler *baseCompiler) hasSrcExt(ext string) bool {
592	for _, src := range compiler.srcsBeforeGen {
593		if src.Ext() == ext {
594			return true
595		}
596	}
597	for _, src := range compiler.Properties.Srcs {
598		if filepath.Ext(src) == ext {
599			return true
600		}
601	}
602	for _, src := range compiler.Properties.OriginalSrcs {
603		if filepath.Ext(src) == ext {
604			return true
605		}
606	}
607
608	return false
609}
610
611func (compiler *baseCompiler) uniqueApexVariations() bool {
612	return compiler.useApexNameMacro()
613}
614
615var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
616
617// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
618// For example, com.android.foo => COM_ANDROID_FOO
619func makeDefineString(name string) string {
620	return invalidDefineCharRegex.ReplaceAllString(strings.ToUpper(name), "_")
621}
622
623var gnuToCReplacer = strings.NewReplacer("gnu", "c")
624
625func ndkPathDeps(ctx ModuleContext) android.Paths {
626	if ctx.Module().(*Module).IsSdkVariant() {
627		// The NDK sysroot timestamp file depends on all the NDK sysroot files
628		// (headers and libraries).
629		return android.Paths{getNdkBaseTimestampFile(ctx)}
630	}
631	return nil
632}
633
634func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
635	pathDeps := deps.GeneratedDeps
636	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
637
638	buildFlags := flagsToBuilderFlags(flags)
639
640	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
641
642	srcs, genDeps, info := genSources(ctx, srcs, buildFlags)
643	pathDeps = append(pathDeps, genDeps...)
644
645	compiler.pathDeps = pathDeps
646	compiler.generatedSourceInfo = info
647	compiler.cFlagsDeps = flags.CFlagsDeps
648
649	// Save src, buildFlags and context
650	compiler.srcs = srcs
651
652	// Compile files listed in c.Properties.Srcs into objects
653	objs := compileObjs(ctx, buildFlags, "", srcs, pathDeps, compiler.cFlagsDeps)
654
655	if ctx.Failed() {
656		return Objects{}
657	}
658
659	return objs
660}
661
662// Compile a list of source files into objects a specified subdirectory
663func compileObjs(ctx android.ModuleContext, flags builderFlags,
664	subdir string, srcFiles, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
665
666	return transformSourceToObj(ctx, subdir, srcFiles, flags, pathDeps, cFlagsDeps)
667}
668
669var thirdPartyDirPrefixExceptions = []*regexp.Regexp{
670	regexp.MustCompile("^vendor/[^/]*google[^/]*/"),
671	regexp.MustCompile("^hardware/google/"),
672	regexp.MustCompile("^hardware/interfaces/"),
673	regexp.MustCompile("^hardware/libhardware[^/]*/"),
674	regexp.MustCompile("^hardware/ril/"),
675}
676
677func isThirdParty(path string) bool {
678	thirdPartyDirPrefixes := []string{"external/", "vendor/", "hardware/"}
679
680	if android.HasAnyPrefix(path, thirdPartyDirPrefixes) {
681		for _, prefix := range thirdPartyDirPrefixExceptions {
682			if prefix.MatchString(path) {
683				return false
684			}
685		}
686	}
687	return true
688}
689
690// Properties for rust_bindgen related to generating rust bindings.
691// This exists here so these properties can be included in a cc_default
692// which can be used in both cc and rust modules.
693type RustBindgenClangProperties struct {
694	// list of directories relative to the Blueprints file that will
695	// be added to the include path using -I
696	Local_include_dirs []string `android:"arch_variant,variant_prepend"`
697
698	// list of static libraries that provide headers for this binding.
699	Static_libs []string `android:"arch_variant,variant_prepend"`
700
701	// list of shared libraries that provide headers for this binding.
702	Shared_libs []string `android:"arch_variant"`
703
704	// List of libraries which export include paths required for this module
705	Header_libs []string `android:"arch_variant,variant_prepend"`
706
707	// list of clang flags required to correctly interpret the headers.
708	Cflags []string `android:"arch_variant"`
709
710	// list of c++ specific clang flags required to correctly interpret the headers.
711	// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
712	Cppflags []string `android:"arch_variant"`
713
714	// C standard version to use. Can be a specific version (such as "gnu11"),
715	// "experimental" (which will use draft versions like C1x when available),
716	// or the empty string (which will use the default).
717	//
718	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
719	// to "default" will use the build system default version. This cannot be set at the same time as cpp_std.
720	C_std *string
721
722	// C++ standard version to use. Can be a specific version (such as
723	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
724	// available), or the empty string (which will use the default).
725	//
726	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
727	// to "default" will use the build system default version. This cannot be set at the same time as c_std.
728	Cpp_std *string
729
730	//TODO(b/161141999) Add support for headers from cc_library_header modules.
731}
732