• 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 []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 []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 []string `android:"arch_variant,variant_prepend"`
102
103	// pass -frtti instead of -fno-rtti
104	Rtti *bool
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	Yacc *YaccProperties
120	Lex  *LexProperties
121
122	Aidl struct {
123		// list of directories that will be added to the aidl include paths.
124		Include_dirs []string
125
126		// list of directories relative to the Blueprints file that will
127		// be added to the aidl include paths.
128		Local_include_dirs []string
129
130		// whether to generate traces (for systrace) for this interface
131		Generate_traces *bool
132
133		// list of flags that will be passed to the AIDL compiler
134		Flags []string
135	}
136
137	Renderscript struct {
138		// list of directories that will be added to the llvm-rs-cc include paths
139		Include_dirs []string
140
141		// list of flags that will be passed to llvm-rs-cc
142		Flags []string
143
144		// Renderscript API level to target
145		Target_api *string
146	}
147
148	Debug, Release struct {
149		// list of module-specific flags that will be used for C and C++ compiles in debug or
150		// release builds
151		Cflags []string `android:"arch_variant"`
152	} `android:"arch_variant"`
153
154	Target struct {
155		Vendor, Product struct {
156			// list of source files that should only be used in vendor or
157			// product variant of the C/C++ module.
158			Srcs []string `android:"path"`
159
160			// list of source files that should not be used to build vendor
161			// or product variant of the C/C++ module.
162			Exclude_srcs []string `android:"path"`
163
164			// List of additional cflags that should be used to build vendor
165			// or product variant of the C/C++ module.
166			Cflags []string
167
168			// list of generated sources that should not be used to build
169			// vendor or product variant of the C/C++ module.
170			Exclude_generated_sources []string
171		}
172		Recovery struct {
173			// list of source files that should only be used in the
174			// recovery variant of the C/C++ module.
175			Srcs []string `android:"path"`
176
177			// list of source files that should not be used to
178			// build the recovery variant of the C/C++ module.
179			Exclude_srcs []string `android:"path"`
180
181			// List of additional cflags that should be used to build the recovery
182			// variant of the C/C++ module.
183			Cflags []string
184
185			// list of generated sources that should not be used to
186			// build the recovery variant of the C/C++ module.
187			Exclude_generated_sources []string
188		}
189		Vendor_ramdisk struct {
190			// list of source files that should not be used to
191			// build the vendor ramdisk variant of the C/C++ module.
192			Exclude_srcs []string `android:"path"`
193
194			// List of additional cflags that should be used to build the vendor ramdisk
195			// variant of the C/C++ module.
196			Cflags []string
197		}
198		Platform struct {
199			// List of additional cflags that should be used to build the platform
200			// variant of the C/C++ module.
201			Cflags []string
202		}
203	}
204
205	Proto struct {
206		// Link statically against the protobuf runtime
207		Static *bool `android:"arch_variant"`
208	} `android:"arch_variant"`
209
210	// Stores the original list of source files before being cleared by library reuse
211	OriginalSrcs []string `blueprint:"mutated"`
212
213	// Build and link with OpenMP
214	Openmp *bool `android:"arch_variant"`
215}
216
217func NewBaseCompiler() *baseCompiler {
218	return &baseCompiler{}
219}
220
221type baseCompiler struct {
222	Properties BaseCompilerProperties
223	Proto      android.ProtoProperties
224	cFlagsDeps android.Paths
225	pathDeps   android.Paths
226	flags      builderFlags
227
228	// Sources that were passed to the C/C++ compiler
229	srcs android.Paths
230
231	// Sources that were passed in the Android.bp file, including generated sources generated by
232	// other modules and filegroups. May include source files that have not yet been translated to
233	// C/C++ (.aidl, .proto, etc.)
234	srcsBeforeGen android.Paths
235
236	generatedSourceInfo
237}
238
239var _ compiler = (*baseCompiler)(nil)
240
241type CompiledInterface interface {
242	Srcs() android.Paths
243}
244
245func (compiler *baseCompiler) Srcs() android.Paths {
246	return append(android.Paths{}, compiler.srcs...)
247}
248
249func (compiler *baseCompiler) appendCflags(flags []string) {
250	compiler.Properties.Cflags = append(compiler.Properties.Cflags, flags...)
251}
252
253func (compiler *baseCompiler) appendAsflags(flags []string) {
254	compiler.Properties.Asflags = append(compiler.Properties.Asflags, flags...)
255}
256
257func (compiler *baseCompiler) compilerProps() []interface{} {
258	return []interface{}{&compiler.Properties, &compiler.Proto}
259}
260
261func includeBuildDirectory(prop *bool) bool {
262	return proptools.BoolDefault(prop, true)
263}
264
265func (compiler *baseCompiler) includeBuildDirectory() bool {
266	return includeBuildDirectory(compiler.Properties.Include_build_directory)
267}
268
269func (compiler *baseCompiler) compilerInit(ctx BaseModuleContext) {}
270
271func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
272	deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
273	deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources)
274	deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
275
276	android.ProtoDeps(ctx, &compiler.Proto)
277	if compiler.hasSrcExt(".proto") {
278		deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static))
279	}
280
281	if Bool(compiler.Properties.Openmp) {
282		deps.StaticLibs = append(deps.StaticLibs, "libomp")
283	}
284
285	return deps
286}
287
288// Return true if the module is in the WarningAllowedProjects.
289func warningsAreAllowed(subdir string) bool {
290	subdir += "/"
291	return android.HasAnyPrefix(subdir, config.WarningAllowedProjects)
292}
293
294func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) {
295	getNamedMapForConfig(ctx.Config(), key).Store(module, true)
296}
297
298func maybeReplaceGnuToC(gnuExtensions *bool, cStd string, cppStd string) (string, string) {
299	if gnuExtensions != nil && *gnuExtensions == false {
300		cStd = gnuToCReplacer.Replace(cStd)
301		cppStd = gnuToCReplacer.Replace(cppStd)
302	}
303	return cStd, cppStd
304}
305
306func parseCppStd(cppStdPtr *string) string {
307	cppStd := String(cppStdPtr)
308	switch cppStd {
309	case "":
310		return config.CppStdVersion
311	case "experimental":
312		return config.ExperimentalCppStdVersion
313	default:
314		return cppStd
315	}
316}
317
318func parseCStd(cStdPtr *string) string {
319	cStd := String(cStdPtr)
320	switch cStd {
321	case "":
322		return config.CStdVersion
323	case "experimental":
324		return config.ExperimentalCStdVersion
325	default:
326		return cStd
327	}
328}
329
330// Create a Flags struct that collects the compile flags from global values,
331// per-target values, module type values, and per-module Blueprints properties
332func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
333	tc := ctx.toolchain()
334	modulePath := android.PathForModuleSrc(ctx).String()
335
336	compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
337	compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
338
339	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
340	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
341	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
342	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
343	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
344	CheckBadCompilerFlags(ctx, "product.cflags", compiler.Properties.Target.Product.Cflags)
345	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
346	CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
347	CheckBadCompilerFlags(ctx, "platform.cflags", compiler.Properties.Target.Platform.Cflags)
348
349	esc := proptools.NinjaAndShellEscapeList
350
351	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Cflags)...)
352	flags.Local.CppFlags = append(flags.Local.CppFlags, esc(compiler.Properties.Cppflags)...)
353	flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
354	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
355	flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
356
357	flags.Yacc = compiler.Properties.Yacc
358	flags.Lex = compiler.Properties.Lex
359
360	// Include dir cflags
361	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
362	if len(localIncludeDirs) > 0 {
363		f := includeDirsToFlags(localIncludeDirs)
364		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
365		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
366	}
367	rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
368	if len(rootIncludeDirs) > 0 {
369		f := includeDirsToFlags(rootIncludeDirs)
370		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
371		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
372	}
373
374	if compiler.includeBuildDirectory() {
375		flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+modulePath)
376		flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+modulePath)
377	}
378
379	if !(ctx.useSdk() || ctx.useVndk()) || ctx.Host() {
380		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
381			"${config.CommonGlobalIncludes}",
382			tc.IncludeFlags())
383	}
384
385	if ctx.useSdk() {
386		// TODO: Switch to --sysroot.
387		// The NDK headers are installed to a common sysroot. While a more
388		// typical Soong approach would be to only make the headers for the
389		// library you're using available, we're trying to emulate the NDK
390		// behavior here, and the NDK always has all the NDK headers available.
391		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
392			"-isystem "+getCurrentIncludePath(ctx).String(),
393			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
394	}
395
396	if ctx.useVndk() {
397		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VNDK__")
398		if ctx.inVendor() {
399			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VENDOR__")
400		} else if ctx.inProduct() {
401			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_PRODUCT__")
402		}
403	}
404
405	if ctx.inRecovery() {
406		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__")
407	}
408
409	if ctx.inRecovery() || ctx.inRamdisk() || ctx.inVendorRamdisk() {
410		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RAMDISK__")
411	}
412
413	if ctx.apexVariationName() != "" {
414		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
415		if ctx.Device() {
416			flags.Global.CommonFlags = append(flags.Global.CommonFlags,
417				fmt.Sprintf("-D__ANDROID_APEX_MIN_SDK_VERSION__=%d",
418					ctx.apexSdkVersion().FinalOrFutureInt()))
419		}
420	}
421
422	if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
423		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_NATIVE_BRIDGE__")
424	}
425
426	instructionSet := String(compiler.Properties.Instruction_set)
427	if flags.RequiredInstructionSet != "" {
428		instructionSet = flags.RequiredInstructionSet
429	}
430	instructionSetFlags, err := tc.InstructionSetFlags(instructionSet)
431	if err != nil {
432		ctx.ModuleErrorf("%s", err)
433	}
434
435	CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags)
436
437	// TODO: debug
438	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Release.Cflags)...)
439
440	CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
441	CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
442
443	flags.Local.CFlags = config.ClangFilterUnknownCflags(flags.Local.CFlags)
444	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...)
445	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...)
446	flags.Local.CppFlags = config.ClangFilterUnknownCflags(flags.Local.CppFlags)
447	flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
448	flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
449
450	target := "-target " + tc.ClangTriple()
451	if ctx.Os().Class == android.Device {
452		version := ctx.minSdkVersion()
453		if version == "" || version == "current" {
454			target += strconv.Itoa(android.FutureApiLevelInt)
455		} else {
456			target += version
457		}
458	}
459
460	flags.Global.CFlags = append(flags.Global.CFlags, target)
461	flags.Global.AsFlags = append(flags.Global.AsFlags, target)
462	flags.Global.LdFlags = append(flags.Global.LdFlags, target)
463
464	hod := "Host"
465	if ctx.Os().Class == android.Device {
466		hod = "Device"
467	}
468
469	flags.Global.CommonFlags = append(flags.Global.CommonFlags, instructionSetFlags)
470	flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...)
471	flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...)
472
473	flags.Global.AsFlags = append(flags.Global.AsFlags, tc.Asflags())
474	flags.Global.CppFlags = append([]string{"${config.CommonGlobalCppflags}"}, flags.Global.CppFlags...)
475	flags.Global.CommonFlags = append(flags.Global.CommonFlags,
476		tc.Cflags(),
477		"${config.CommonGlobalCflags}",
478		fmt.Sprintf("${config.%sGlobalCflags}", hod))
479
480	if android.IsThirdPartyPath(modulePath) {
481		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ExternalCflags}")
482	}
483
484	if tc.Bionic() {
485		if Bool(compiler.Properties.Rtti) {
486			flags.Local.CppFlags = append(flags.Local.CppFlags, "-frtti")
487		} else {
488			flags.Local.CppFlags = append(flags.Local.CppFlags, "-fno-rtti")
489		}
490	}
491
492	flags.Global.AsFlags = append(flags.Global.AsFlags, "-D__ASSEMBLY__")
493
494	flags.Global.CppFlags = append(flags.Global.CppFlags, tc.Cppflags())
495
496	flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags())
497
498	flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
499
500	cStd := parseCStd(compiler.Properties.C_std)
501	cppStd := parseCppStd(compiler.Properties.Cpp_std)
502
503	cStd, cppStd = maybeReplaceGnuToC(compiler.Properties.Gnu_extensions, cStd, cppStd)
504
505	flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...)
506	flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...)
507
508	if ctx.inVendor() {
509		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
510	}
511
512	if ctx.inProduct() {
513		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Product.Cflags)...)
514	}
515
516	if ctx.inRecovery() {
517		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
518	}
519
520	if ctx.inVendorRamdisk() {
521		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor_ramdisk.Cflags)...)
522	}
523	if !ctx.useSdk() {
524		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Platform.Cflags)...)
525	}
526
527	// We can enforce some rules more strictly in the code we own. strict
528	// indicates if this is code that we can be stricter with. If we have
529	// rules that we want to apply to *our* code (but maybe can't for
530	// vendor/device specific things), we could extend this to be a ternary
531	// value.
532	strict := true
533	if strings.HasPrefix(modulePath, "external/") {
534		strict = false
535	}
536
537	// Can be used to make some annotations stricter for code we can fix
538	// (such as when we mark functions as deprecated).
539	if strict {
540		flags.Global.CFlags = append(flags.Global.CFlags, "-DANDROID_STRICT")
541	}
542
543	if compiler.hasSrcExt(".proto") {
544		flags = protoFlags(ctx, flags, &compiler.Proto)
545	}
546
547	if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") {
548		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
549			"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
550	}
551
552	if compiler.hasSrcExt(".aidl") {
553		flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
554		if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
555			localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs)
556			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(localAidlIncludeDirs))
557		}
558		if len(compiler.Properties.Aidl.Include_dirs) > 0 {
559			rootAidlIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Aidl.Include_dirs)
560			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
561		}
562
563		if Bool(compiler.Properties.Aidl.Generate_traces) {
564			flags.aidlFlags = append(flags.aidlFlags, "-t")
565		}
566
567		aidlMinSdkVersion := ctx.minSdkVersion()
568		if aidlMinSdkVersion == "" {
569			aidlMinSdkVersion = "platform_apis"
570		}
571		flags.aidlFlags = append(flags.aidlFlags, "--min_sdk_version="+aidlMinSdkVersion)
572
573		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
574			"-I"+android.PathForModuleGen(ctx, "aidl").String())
575	}
576
577	if compiler.hasSrcExt(".rscript") || compiler.hasSrcExt(".fs") {
578		flags = rsFlags(ctx, flags, &compiler.Properties)
579	}
580
581	if compiler.hasSrcExt(".sysprop") {
582		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
583			"-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
584	}
585
586	if len(compiler.Properties.Srcs) > 0 {
587		module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
588		if inList("-Wno-error", flags.Local.CFlags) || inList("-Wno-error", flags.Local.CppFlags) {
589			addToModuleList(ctx, modulesUsingWnoErrorKey, module)
590		} else if !inList("-Werror", flags.Local.CFlags) && !inList("-Werror", flags.Local.CppFlags) {
591			if warningsAreAllowed(ctx.ModuleDir()) {
592				addToModuleList(ctx, modulesAddedWallKey, module)
593				flags.Local.CFlags = append([]string{"-Wall"}, flags.Local.CFlags...)
594			} else {
595				flags.Local.CFlags = append([]string{"-Wall", "-Werror"}, flags.Local.CFlags...)
596			}
597		}
598	}
599
600	if Bool(compiler.Properties.Openmp) {
601		flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp")
602	}
603
604	// Exclude directories from manual binder interface allowed list.
605	//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
606	if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
607		flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
608	}
609
610	return flags
611}
612
613func (compiler *baseCompiler) hasSrcExt(ext string) bool {
614	for _, src := range compiler.srcsBeforeGen {
615		if src.Ext() == ext {
616			return true
617		}
618	}
619	for _, src := range compiler.Properties.Srcs {
620		if filepath.Ext(src) == ext {
621			return true
622		}
623	}
624	for _, src := range compiler.Properties.OriginalSrcs {
625		if filepath.Ext(src) == ext {
626			return true
627		}
628	}
629
630	return false
631}
632
633var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
634
635// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
636// For example, com.android.foo => COM_ANDROID_FOO
637func makeDefineString(name string) string {
638	return invalidDefineCharRegex.ReplaceAllString(strings.ToUpper(name), "_")
639}
640
641var gnuToCReplacer = strings.NewReplacer("gnu", "c")
642
643func ndkPathDeps(ctx ModuleContext) android.Paths {
644	if ctx.Module().(*Module).IsSdkVariant() {
645		// The NDK sysroot timestamp file depends on all the NDK sysroot header files
646		// for compiling src to obj files.
647		return android.Paths{getNdkHeadersTimestampFile(ctx)}
648	}
649	return nil
650}
651
652func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
653	pathDeps := deps.GeneratedDeps
654	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
655
656	buildFlags := flagsToBuilderFlags(flags)
657
658	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
659
660	srcs, genDeps, info := genSources(ctx, srcs, buildFlags)
661	pathDeps = append(pathDeps, genDeps...)
662
663	compiler.pathDeps = pathDeps
664	compiler.generatedSourceInfo = info
665	compiler.cFlagsDeps = flags.CFlagsDeps
666
667	// Save src, buildFlags and context
668	compiler.srcs = srcs
669
670	// Compile files listed in c.Properties.Srcs into objects
671	objs := compileObjs(ctx, buildFlags, "", srcs,
672		android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_disabled_srcs),
673		android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_timeout_srcs),
674		pathDeps, compiler.cFlagsDeps)
675
676	if ctx.Failed() {
677		return Objects{}
678	}
679
680	return objs
681}
682
683// Compile a list of source files into objects a specified subdirectory
684func compileObjs(ctx ModuleContext, flags builderFlags, subdir string,
685	srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
686
687	return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps)
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