• 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 useGnuExtensions(gnuExtensions *bool) bool {
299	return proptools.BoolDefault(gnuExtensions, true)
300}
301
302func maybeReplaceGnuToC(gnuExtensions *bool, cStd string, cppStd string) (string, string) {
303	if !useGnuExtensions(gnuExtensions) {
304		cStd = gnuToCReplacer.Replace(cStd)
305		cppStd = gnuToCReplacer.Replace(cppStd)
306	}
307	return cStd, cppStd
308}
309
310func parseCppStd(cppStdPtr *string) string {
311	cppStd := String(cppStdPtr)
312	switch cppStd {
313	case "":
314		return config.CppStdVersion
315	case "experimental":
316		return config.ExperimentalCppStdVersion
317	default:
318		return cppStd
319	}
320}
321
322func parseCStd(cStdPtr *string) string {
323	cStd := String(cStdPtr)
324	switch cStd {
325	case "":
326		return config.CStdVersion
327	case "experimental":
328		return config.ExperimentalCStdVersion
329	default:
330		return cStd
331	}
332}
333
334// Create a Flags struct that collects the compile flags from global values,
335// per-target values, module type values, and per-module Blueprints properties
336func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
337	tc := ctx.toolchain()
338	modulePath := android.PathForModuleSrc(ctx).String()
339
340	compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
341	compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
342
343	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
344	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
345	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
346	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
347	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
348	CheckBadCompilerFlags(ctx, "product.cflags", compiler.Properties.Target.Product.Cflags)
349	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
350	CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
351	CheckBadCompilerFlags(ctx, "platform.cflags", compiler.Properties.Target.Platform.Cflags)
352
353	esc := proptools.NinjaAndShellEscapeList
354
355	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Cflags)...)
356	flags.Local.CppFlags = append(flags.Local.CppFlags, esc(compiler.Properties.Cppflags)...)
357	flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
358	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
359	flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
360
361	flags.Yacc = compiler.Properties.Yacc
362	flags.Lex = compiler.Properties.Lex
363
364	// Include dir cflags
365	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
366	if len(localIncludeDirs) > 0 {
367		f := includeDirsToFlags(localIncludeDirs)
368		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
369		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
370	}
371	rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
372	if len(rootIncludeDirs) > 0 {
373		f := includeDirsToFlags(rootIncludeDirs)
374		flags.Local.CommonFlags = append(flags.Local.CommonFlags, f)
375		flags.Local.YasmFlags = append(flags.Local.YasmFlags, f)
376	}
377
378	if compiler.includeBuildDirectory() {
379		flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+modulePath)
380		flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+modulePath)
381	}
382
383	if !(ctx.useSdk() || ctx.useVndk()) || ctx.Host() {
384		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
385			"${config.CommonGlobalIncludes}",
386			tc.IncludeFlags())
387	}
388
389	if ctx.useSdk() {
390		// TODO: Switch to --sysroot.
391		// The NDK headers are installed to a common sysroot. While a more
392		// typical Soong approach would be to only make the headers for the
393		// library you're using available, we're trying to emulate the NDK
394		// behavior here, and the NDK always has all the NDK headers available.
395		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
396			"-isystem "+getCurrentIncludePath(ctx).String(),
397			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
398	}
399
400	if ctx.useVndk() {
401		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VNDK__")
402		if ctx.inVendor() {
403			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VENDOR__")
404		} else if ctx.inProduct() {
405			flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_PRODUCT__")
406		}
407	}
408
409	if ctx.inRecovery() {
410		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__")
411	}
412
413	if ctx.inRecovery() || ctx.inRamdisk() || ctx.inVendorRamdisk() {
414		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RAMDISK__")
415	}
416
417	if ctx.apexVariationName() != "" {
418		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
419	}
420
421	if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
422		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_NATIVE_BRIDGE__")
423	}
424
425	instructionSet := String(compiler.Properties.Instruction_set)
426	if flags.RequiredInstructionSet != "" {
427		instructionSet = flags.RequiredInstructionSet
428	}
429	instructionSetFlags, err := tc.InstructionSetFlags(instructionSet)
430	if err != nil {
431		ctx.ModuleErrorf("%s", err)
432	}
433
434	CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags)
435
436	// TODO: debug
437	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Release.Cflags)...)
438
439	if !ctx.DeviceConfig().BuildBrokenClangCFlags() && len(compiler.Properties.Clang_cflags) != 0 {
440		ctx.PropertyErrorf("clang_cflags", "property is deprecated, see Changes.md file")
441	} else {
442		CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
443	}
444	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() && len(compiler.Properties.Clang_asflags) != 0 {
445		ctx.PropertyErrorf("clang_asflags", "property is deprecated, see Changes.md file")
446	} else {
447		CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
448	}
449
450	flags.Local.CFlags = config.ClangFilterUnknownCflags(flags.Local.CFlags)
451	if !ctx.DeviceConfig().BuildBrokenClangCFlags() {
452		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...)
453	}
454	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() {
455		flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...)
456	}
457	flags.Local.CppFlags = config.ClangFilterUnknownCflags(flags.Local.CppFlags)
458	flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
459	flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
460
461	target := "-target " + tc.ClangTriple()
462	if ctx.Os().Class == android.Device {
463		version := ctx.minSdkVersion()
464		if version == "" || version == "current" {
465			target += strconv.Itoa(android.FutureApiLevelInt)
466		} else {
467			apiLevel := nativeApiLevelOrPanic(ctx, version)
468			target += apiLevel.String()
469		}
470	}
471
472	flags.Global.CFlags = append(flags.Global.CFlags, target)
473	flags.Global.AsFlags = append(flags.Global.AsFlags, target)
474	flags.Global.LdFlags = append(flags.Global.LdFlags, target)
475
476	hod := "Host"
477	if ctx.Os().Class == android.Device {
478		hod = "Device"
479	}
480
481	flags.Global.CommonFlags = append(flags.Global.CommonFlags, instructionSetFlags)
482	flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...)
483	flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...)
484
485	flags.Global.AsFlags = append(flags.Global.AsFlags, tc.Asflags())
486	flags.Global.CppFlags = append([]string{"${config.CommonGlobalCppflags}"}, flags.Global.CppFlags...)
487	flags.Global.CommonFlags = append(flags.Global.CommonFlags,
488		tc.Cflags(),
489		"${config.CommonGlobalCflags}",
490		fmt.Sprintf("${config.%sGlobalCflags}", hod))
491
492	if android.IsThirdPartyPath(modulePath) {
493		flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ExternalCflags}")
494	}
495
496	if tc.Bionic() {
497		if Bool(compiler.Properties.Rtti) {
498			flags.Local.CppFlags = append(flags.Local.CppFlags, "-frtti")
499		} else {
500			flags.Local.CppFlags = append(flags.Local.CppFlags, "-fno-rtti")
501		}
502	}
503
504	flags.Global.AsFlags = append(flags.Global.AsFlags, "${config.CommonGlobalAsflags}")
505
506	flags.Global.CppFlags = append(flags.Global.CppFlags, tc.Cppflags())
507
508	flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags())
509
510	flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
511
512	cStd := parseCStd(compiler.Properties.C_std)
513	cppStd := parseCppStd(compiler.Properties.Cpp_std)
514
515	cStd, cppStd = maybeReplaceGnuToC(compiler.Properties.Gnu_extensions, cStd, cppStd)
516
517	flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...)
518	flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...)
519
520	if ctx.inVendor() {
521		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
522	}
523
524	if ctx.inProduct() {
525		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Product.Cflags)...)
526	}
527
528	if ctx.inRecovery() {
529		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
530	}
531
532	if ctx.inVendorRamdisk() {
533		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor_ramdisk.Cflags)...)
534	}
535	if !ctx.useSdk() {
536		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Platform.Cflags)...)
537	}
538
539	// We can enforce some rules more strictly in the code we own. strict
540	// indicates if this is code that we can be stricter with. If we have
541	// rules that we want to apply to *our* code (but maybe can't for
542	// vendor/device specific things), we could extend this to be a ternary
543	// value.
544	strict := true
545	if strings.HasPrefix(modulePath, "external/") {
546		strict = false
547	}
548
549	// Can be used to make some annotations stricter for code we can fix
550	// (such as when we mark functions as deprecated).
551	if strict {
552		flags.Global.CFlags = append(flags.Global.CFlags, "-DANDROID_STRICT")
553	}
554
555	if compiler.hasSrcExt(".proto") {
556		flags = protoFlags(ctx, flags, &compiler.Proto)
557	}
558
559	if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") {
560		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
561			"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
562	}
563
564	if compiler.hasSrcExt(".aidl") {
565		flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
566		if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
567			localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs)
568			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(localAidlIncludeDirs))
569		}
570		if len(compiler.Properties.Aidl.Include_dirs) > 0 {
571			rootAidlIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Aidl.Include_dirs)
572			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
573		}
574
575		if proptools.BoolDefault(compiler.Properties.Aidl.Generate_traces, true) {
576			flags.aidlFlags = append(flags.aidlFlags, "-t")
577		}
578
579		aidlMinSdkVersion := ctx.minSdkVersion()
580		if aidlMinSdkVersion == "" {
581			aidlMinSdkVersion = "platform_apis"
582		}
583		flags.aidlFlags = append(flags.aidlFlags, "--min_sdk_version="+aidlMinSdkVersion)
584
585		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
586			"-I"+android.PathForModuleGen(ctx, "aidl").String())
587	}
588
589	if compiler.hasSrcExt(".rscript") || compiler.hasSrcExt(".fs") {
590		flags = rsFlags(ctx, flags, &compiler.Properties)
591	}
592
593	if compiler.hasSrcExt(".sysprop") {
594		flags.Local.CommonFlags = append(flags.Local.CommonFlags,
595			"-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
596	}
597
598	if len(compiler.Properties.Srcs) > 0 {
599		module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
600		if inList("-Wno-error", flags.Local.CFlags) || inList("-Wno-error", flags.Local.CppFlags) {
601			addToModuleList(ctx, modulesUsingWnoErrorKey, module)
602		} else if !inList("-Werror", flags.Local.CFlags) && !inList("-Werror", flags.Local.CppFlags) {
603			if warningsAreAllowed(ctx.ModuleDir()) {
604				addToModuleList(ctx, modulesWarningsAllowedKey, module)
605			} else {
606				flags.Local.CFlags = append([]string{"-Werror"}, flags.Local.CFlags...)
607			}
608		}
609	}
610
611	if Bool(compiler.Properties.Openmp) {
612		flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp")
613	}
614
615	// Exclude directories from manual binder interface allowed list.
616	//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
617	if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
618		flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
619	}
620
621	return flags
622}
623
624func (compiler *baseCompiler) hasSrcExt(ext string) bool {
625	for _, src := range compiler.srcsBeforeGen {
626		if src.Ext() == ext {
627			return true
628		}
629	}
630	for _, src := range compiler.Properties.Srcs {
631		if filepath.Ext(src) == ext {
632			return true
633		}
634	}
635	for _, src := range compiler.Properties.OriginalSrcs {
636		if filepath.Ext(src) == ext {
637			return true
638		}
639	}
640
641	return false
642}
643
644var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
645
646// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
647// For example, com.android.foo => COM_ANDROID_FOO
648func makeDefineString(name string) string {
649	return invalidDefineCharRegex.ReplaceAllString(strings.ToUpper(name), "_")
650}
651
652var gnuToCReplacer = strings.NewReplacer("gnu", "c")
653
654func ndkPathDeps(ctx ModuleContext) android.Paths {
655	if ctx.Module().(*Module).IsSdkVariant() {
656		// The NDK sysroot timestamp file depends on all the NDK sysroot header files
657		// for compiling src to obj files.
658		return android.Paths{getNdkHeadersTimestampFile(ctx)}
659	}
660	return nil
661}
662
663func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
664	pathDeps := deps.GeneratedDeps
665	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
666
667	buildFlags := flagsToBuilderFlags(flags)
668
669	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
670
671	srcs, genDeps, info := genSources(ctx, srcs, buildFlags)
672	pathDeps = append(pathDeps, genDeps...)
673
674	compiler.pathDeps = pathDeps
675	compiler.generatedSourceInfo = info
676	compiler.cFlagsDeps = flags.CFlagsDeps
677
678	// Save src, buildFlags and context
679	compiler.srcs = srcs
680
681	// Compile files listed in c.Properties.Srcs into objects
682	objs := compileObjs(ctx, buildFlags, "", srcs,
683		android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_disabled_srcs),
684		android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_timeout_srcs),
685		pathDeps, compiler.cFlagsDeps)
686
687	if ctx.Failed() {
688		return Objects{}
689	}
690
691	return objs
692}
693
694// Compile a list of source files into objects a specified subdirectory
695func compileObjs(ctx ModuleContext, flags builderFlags, subdir string,
696	srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
697
698	return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps)
699}
700
701// Properties for rust_bindgen related to generating rust bindings.
702// This exists here so these properties can be included in a cc_default
703// which can be used in both cc and rust modules.
704type RustBindgenClangProperties struct {
705	// list of directories relative to the Blueprints file that will
706	// be added to the include path using -I
707	Local_include_dirs []string `android:"arch_variant,variant_prepend"`
708
709	// list of static libraries that provide headers for this binding.
710	Static_libs []string `android:"arch_variant,variant_prepend"`
711
712	// list of shared libraries that provide headers for this binding.
713	Shared_libs []string `android:"arch_variant"`
714
715	// List of libraries which export include paths required for this module
716	Header_libs []string `android:"arch_variant,variant_prepend"`
717
718	// list of clang flags required to correctly interpret the headers.
719	Cflags []string `android:"arch_variant"`
720
721	// list of c++ specific clang flags required to correctly interpret the headers.
722	// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
723	Cppflags []string `android:"arch_variant"`
724
725	// C standard version to use. Can be a specific version (such as "gnu11"),
726	// "experimental" (which will use draft versions like C1x when available),
727	// or the empty string (which will use the default).
728	//
729	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
730	// to "default" will use the build system default version. This cannot be set at the same time as cpp_std.
731	C_std *string
732
733	// C++ standard version to use. Can be a specific version (such as
734	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
735	// available), or the empty string (which will use the default).
736	//
737	// If this is set, the file extension will be ignored and this will be used as the std version value. Setting this
738	// to "default" will use the build system default version. This cannot be set at the same time as c_std.
739	Cpp_std *string
740
741	//TODO(b/161141999) Add support for headers from cc_library_header modules.
742}
743