Home | History | Annotate | Download | only in cc
      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 
     15 package cc
     16 
     17 import (
     18 	"fmt"
     19 	"path/filepath"
     20 	"strings"
     21 
     22 	"github.com/google/blueprint/proptools"
     23 
     24 	"android/soong/android"
     25 	"android/soong/cc/config"
     26 )
     27 
     28 // This file contains the basic C/C++/assembly to .o compliation steps
     29 
     30 type BaseCompilerProperties struct {
     31 	// list of source files used to compile the C/C++ module.  May be .c, .cpp, or .S files.
     32 	// srcs may reference the outputs of other modules that produce source files like genrule
     33 	// or filegroup using the syntax ":module".
     34 	Srcs []string `android:"path,arch_variant"`
     35 
     36 	// list of source files that should not be used to build the C/C++ module.
     37 	// This is most useful in the arch/multilib variants to remove non-common files
     38 	Exclude_srcs []string `android:"path,arch_variant"`
     39 
     40 	// list of module-specific flags that will be used for C and C++ compiles.
     41 	Cflags []string `android:"arch_variant"`
     42 
     43 	// list of module-specific flags that will be used for C++ compiles
     44 	Cppflags []string `android:"arch_variant"`
     45 
     46 	// list of module-specific flags that will be used for C compiles
     47 	Conlyflags []string `android:"arch_variant"`
     48 
     49 	// list of module-specific flags that will be used for .S compiles
     50 	Asflags []string `android:"arch_variant"`
     51 
     52 	// list of module-specific flags that will be used for C and C++ compiles when
     53 	// compiling with clang
     54 	Clang_cflags []string `android:"arch_variant"`
     55 
     56 	// list of module-specific flags that will be used for .S compiles when
     57 	// compiling with clang
     58 	Clang_asflags []string `android:"arch_variant"`
     59 
     60 	// list of module-specific flags that will be used for .y and .yy compiles
     61 	Yaccflags []string
     62 
     63 	// the instruction set architecture to use to compile the C/C++
     64 	// module.
     65 	Instruction_set *string `android:"arch_variant"`
     66 
     67 	// list of directories relative to the root of the source tree that will
     68 	// be added to the include path using -I.
     69 	// If possible, don't use this.  If adding paths from the current directory use
     70 	// local_include_dirs, if adding paths from other modules use export_include_dirs in
     71 	// that module.
     72 	Include_dirs []string `android:"arch_variant,variant_prepend"`
     73 
     74 	// list of directories relative to the Blueprints file that will
     75 	// be added to the include path using -I
     76 	Local_include_dirs []string `android:"arch_variant,variant_prepend"`
     77 
     78 	// Add the directory containing the Android.bp file to the list of include
     79 	// directories. Defaults to true.
     80 	Include_build_directory *bool
     81 
     82 	// list of generated sources to compile. These are the names of gensrcs or
     83 	// genrule modules.
     84 	Generated_sources []string `android:"arch_variant"`
     85 
     86 	// list of generated headers to add to the include path. These are the names
     87 	// of genrule modules.
     88 	Generated_headers []string `android:"arch_variant"`
     89 
     90 	// pass -frtti instead of -fno-rtti
     91 	Rtti *bool
     92 
     93 	// C standard version to use. Can be a specific version (such as "gnu11"),
     94 	// "experimental" (which will use draft versions like C1x when available),
     95 	// or the empty string (which will use the default).
     96 	C_std *string
     97 
     98 	// C++ standard version to use. Can be a specific version (such as
     99 	// "gnu++11"), "experimental" (which will use draft versions like C++1z when
    100 	// available), or the empty string (which will use the default).
    101 	Cpp_std *string
    102 
    103 	// if set to false, use -std=c++* instead of -std=gnu++*
    104 	Gnu_extensions *bool
    105 
    106 	Aidl struct {
    107 		// list of directories that will be added to the aidl include paths.
    108 		Include_dirs []string
    109 
    110 		// list of directories relative to the Blueprints file that will
    111 		// be added to the aidl include paths.
    112 		Local_include_dirs []string
    113 
    114 		// whether to generate traces (for systrace) for this interface
    115 		Generate_traces *bool
    116 	}
    117 
    118 	Renderscript struct {
    119 		// list of directories that will be added to the llvm-rs-cc include paths
    120 		Include_dirs []string
    121 
    122 		// list of flags that will be passed to llvm-rs-cc
    123 		Flags []string
    124 
    125 		// Renderscript API level to target
    126 		Target_api *string
    127 	}
    128 
    129 	Debug, Release struct {
    130 		// list of module-specific flags that will be used for C and C++ compiles in debug or
    131 		// release builds
    132 		Cflags []string `android:"arch_variant"`
    133 	} `android:"arch_variant"`
    134 
    135 	Target struct {
    136 		Vendor struct {
    137 			// list of source files that should only be used in the
    138 			// vendor variant of the C/C++ module.
    139 			Srcs []string `android:"path"`
    140 
    141 			// list of source files that should not be used to
    142 			// build the vendor variant of the C/C++ module.
    143 			Exclude_srcs []string `android:"path"`
    144 
    145 			// List of additional cflags that should be used to build the vendor
    146 			// variant of the C/C++ module.
    147 			Cflags []string
    148 		}
    149 		Recovery struct {
    150 			// list of source files that should only be used in the
    151 			// recovery variant of the C/C++ module.
    152 			Srcs []string `android:"path"`
    153 
    154 			// list of source files that should not be used to
    155 			// build the recovery variant of the C/C++ module.
    156 			Exclude_srcs []string `android:"path"`
    157 
    158 			// List of additional cflags that should be used to build the recovery
    159 			// variant of the C/C++ module.
    160 			Cflags []string
    161 		}
    162 	}
    163 
    164 	Proto struct {
    165 		// Link statically against the protobuf runtime
    166 		Static *bool `android:"arch_variant"`
    167 	} `android:"arch_variant"`
    168 
    169 	// Stores the original list of source files before being cleared by library reuse
    170 	OriginalSrcs []string `blueprint:"mutated"`
    171 
    172 	// Build and link with OpenMP
    173 	Openmp *bool `android:"arch_variant"`
    174 }
    175 
    176 func NewBaseCompiler() *baseCompiler {
    177 	return &baseCompiler{}
    178 }
    179 
    180 type baseCompiler struct {
    181 	Properties BaseCompilerProperties
    182 	Proto      android.ProtoProperties
    183 	cFlagsDeps android.Paths
    184 	pathDeps   android.Paths
    185 	flags      builderFlags
    186 
    187 	// Sources that were passed to the C/C++ compiler
    188 	srcs android.Paths
    189 
    190 	// Sources that were passed in the Android.bp file, including generated sources generated by
    191 	// other modules and filegroups. May include source files that have not yet been translated to
    192 	// C/C++ (.aidl, .proto, etc.)
    193 	srcsBeforeGen android.Paths
    194 }
    195 
    196 var _ compiler = (*baseCompiler)(nil)
    197 
    198 type CompiledInterface interface {
    199 	Srcs() android.Paths
    200 }
    201 
    202 func (compiler *baseCompiler) Srcs() android.Paths {
    203 	return append(android.Paths{}, compiler.srcs...)
    204 }
    205 
    206 func (compiler *baseCompiler) appendCflags(flags []string) {
    207 	compiler.Properties.Cflags = append(compiler.Properties.Cflags, flags...)
    208 }
    209 
    210 func (compiler *baseCompiler) appendAsflags(flags []string) {
    211 	compiler.Properties.Asflags = append(compiler.Properties.Asflags, flags...)
    212 }
    213 
    214 func (compiler *baseCompiler) compilerProps() []interface{} {
    215 	return []interface{}{&compiler.Properties, &compiler.Proto}
    216 }
    217 
    218 func (compiler *baseCompiler) compilerInit(ctx BaseModuleContext) {}
    219 
    220 func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
    221 	deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
    222 	deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
    223 
    224 	android.ProtoDeps(ctx, &compiler.Proto)
    225 	if compiler.hasSrcExt(".proto") {
    226 		deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static))
    227 	}
    228 
    229 	if compiler.hasSrcExt(".sysprop") {
    230 		deps.HeaderLibs = append(deps.HeaderLibs, "libbase_headers")
    231 		deps.SharedLibs = append(deps.SharedLibs, "liblog")
    232 	}
    233 
    234 	if Bool(compiler.Properties.Openmp) {
    235 		deps.StaticLibs = append(deps.StaticLibs, "libomp")
    236 	}
    237 
    238 	return deps
    239 }
    240 
    241 // Return true if the module is in the WarningAllowedProjects.
    242 func warningsAreAllowed(subdir string) bool {
    243 	subdir += "/"
    244 	for _, prefix := range config.WarningAllowedProjects {
    245 		if strings.HasPrefix(subdir, prefix) {
    246 			return true
    247 		}
    248 	}
    249 	return false
    250 }
    251 
    252 func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) {
    253 	getNamedMapForConfig(ctx.Config(), key).Store(module, true)
    254 }
    255 
    256 // Create a Flags struct that collects the compile flags from global values,
    257 // per-target values, module type values, and per-module Blueprints properties
    258 func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
    259 	tc := ctx.toolchain()
    260 
    261 	compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
    262 	compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
    263 
    264 	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
    265 	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
    266 	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
    267 	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
    268 	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
    269 	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
    270 
    271 	esc := proptools.NinjaAndShellEscapeList
    272 
    273 	flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Cflags)...)
    274 	flags.CppFlags = append(flags.CppFlags, esc(compiler.Properties.Cppflags)...)
    275 	flags.ConlyFlags = append(flags.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
    276 	flags.AsFlags = append(flags.AsFlags, esc(compiler.Properties.Asflags)...)
    277 	flags.YasmFlags = append(flags.YasmFlags, esc(compiler.Properties.Asflags)...)
    278 	flags.YaccFlags = append(flags.YaccFlags, esc(compiler.Properties.Yaccflags)...)
    279 
    280 	// Include dir cflags
    281 	localIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs)
    282 	if len(localIncludeDirs) > 0 {
    283 		f := includeDirsToFlags(localIncludeDirs)
    284 		flags.GlobalFlags = append(flags.GlobalFlags, f)
    285 		flags.YasmFlags = append(flags.YasmFlags, f)
    286 	}
    287 	rootIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Include_dirs)
    288 	if len(rootIncludeDirs) > 0 {
    289 		f := includeDirsToFlags(rootIncludeDirs)
    290 		flags.GlobalFlags = append(flags.GlobalFlags, f)
    291 		flags.YasmFlags = append(flags.YasmFlags, f)
    292 	}
    293 
    294 	if compiler.Properties.Include_build_directory == nil ||
    295 		*compiler.Properties.Include_build_directory {
    296 		flags.GlobalFlags = append(flags.GlobalFlags, "-I"+android.PathForModuleSrc(ctx).String())
    297 		flags.YasmFlags = append(flags.YasmFlags, "-I"+android.PathForModuleSrc(ctx).String())
    298 	}
    299 
    300 	if !(ctx.useSdk() || ctx.useVndk()) || ctx.Host() {
    301 		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
    302 			"${config.CommonGlobalIncludes}",
    303 			tc.IncludeFlags(),
    304 			"${config.CommonNativehelperInclude}")
    305 	}
    306 
    307 	if ctx.useSdk() {
    308 		// TODO: Switch to --sysroot.
    309 		// The NDK headers are installed to a common sysroot. While a more
    310 		// typical Soong approach would be to only make the headers for the
    311 		// library you're using available, we're trying to emulate the NDK
    312 		// behavior here, and the NDK always has all the NDK headers available.
    313 		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
    314 			"-isystem "+getCurrentIncludePath(ctx).String(),
    315 			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
    316 
    317 		// TODO: Migrate to API suffixed triple?
    318 		// Traditionally this has come from android/api-level.h, but with the
    319 		// libc headers unified it must be set by the build system since we
    320 		// don't have per-API level copies of that header now.
    321 		version := ctx.sdkVersion()
    322 		if version == "current" {
    323 			version = "__ANDROID_API_FUTURE__"
    324 		}
    325 		flags.GlobalFlags = append(flags.GlobalFlags,
    326 			"-D__ANDROID_API__="+version)
    327 	}
    328 
    329 	if ctx.useVndk() {
    330 		// sdkVersion() returns VNDK version for vendor modules.
    331 		version := ctx.sdkVersion()
    332 		if version == "current" {
    333 			version = "__ANDROID_API_FUTURE__"
    334 		}
    335 		flags.GlobalFlags = append(flags.GlobalFlags,
    336 			"-D__ANDROID_API__="+version, "-D__ANDROID_VNDK__")
    337 	}
    338 
    339 	if ctx.inRecovery() {
    340 		flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_RECOVERY__")
    341 	}
    342 
    343 	if ctx.apexName() != "" {
    344 		flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_APEX__="+ctx.apexName())
    345 	}
    346 
    347 	instructionSet := String(compiler.Properties.Instruction_set)
    348 	if flags.RequiredInstructionSet != "" {
    349 		instructionSet = flags.RequiredInstructionSet
    350 	}
    351 	instructionSetFlags, err := tc.ClangInstructionSetFlags(instructionSet)
    352 	if err != nil {
    353 		ctx.ModuleErrorf("%s", err)
    354 	}
    355 
    356 	CheckBadCompilerFlags(ctx, "release.cflags", compiler.Properties.Release.Cflags)
    357 
    358 	// TODO: debug
    359 	flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Release.Cflags)...)
    360 
    361 	CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
    362 	CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
    363 
    364 	flags.CFlags = config.ClangFilterUnknownCflags(flags.CFlags)
    365 	flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Clang_cflags)...)
    366 	flags.AsFlags = append(flags.AsFlags, esc(compiler.Properties.Clang_asflags)...)
    367 	flags.CppFlags = config.ClangFilterUnknownCflags(flags.CppFlags)
    368 	flags.ConlyFlags = config.ClangFilterUnknownCflags(flags.ConlyFlags)
    369 	flags.LdFlags = config.ClangFilterUnknownCflags(flags.LdFlags)
    370 
    371 	target := "-target " + tc.ClangTriple()
    372 	gccPrefix := "-B" + config.ToolPath(tc)
    373 
    374 	flags.CFlags = append(flags.CFlags, target, gccPrefix)
    375 	flags.AsFlags = append(flags.AsFlags, target, gccPrefix)
    376 	flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
    377 
    378 	hod := "Host"
    379 	if ctx.Os().Class == android.Device {
    380 		hod = "Device"
    381 	}
    382 
    383 	flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags)
    384 	flags.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.ConlyFlags...)
    385 	flags.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.CppFlags...)
    386 
    387 	flags.AsFlags = append(flags.AsFlags, tc.ClangAsflags())
    388 	flags.CppFlags = append([]string{"${config.CommonClangGlobalCppflags}"}, flags.CppFlags...)
    389 	flags.GlobalFlags = append(flags.GlobalFlags,
    390 		tc.ClangCflags(),
    391 		"${config.CommonClangGlobalCflags}",
    392 		fmt.Sprintf("${config.%sClangGlobalCflags}", hod))
    393 
    394 	if strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "external/") {
    395 		flags.GlobalFlags = append([]string{"${config.ClangExternalCflags}"}, flags.GlobalFlags...)
    396 	}
    397 
    398 	if tc.Bionic() {
    399 		if Bool(compiler.Properties.Rtti) {
    400 			flags.CppFlags = append(flags.CppFlags, "-frtti")
    401 		} else {
    402 			flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
    403 		}
    404 	}
    405 
    406 	flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__")
    407 
    408 	flags.CppFlags = append(flags.CppFlags, tc.ClangCppflags())
    409 
    410 	flags.YasmFlags = append(flags.YasmFlags, tc.YasmFlags())
    411 
    412 	flags.GlobalFlags = append(flags.GlobalFlags, tc.ToolchainClangCflags())
    413 
    414 	cStd := config.CStdVersion
    415 	if String(compiler.Properties.C_std) == "experimental" {
    416 		cStd = config.ExperimentalCStdVersion
    417 	} else if String(compiler.Properties.C_std) != "" {
    418 		cStd = String(compiler.Properties.C_std)
    419 	}
    420 
    421 	cppStd := String(compiler.Properties.Cpp_std)
    422 	switch String(compiler.Properties.Cpp_std) {
    423 	case "":
    424 		cppStd = config.CppStdVersion
    425 	case "experimental":
    426 		cppStd = config.ExperimentalCppStdVersion
    427 	}
    428 
    429 	if compiler.Properties.Gnu_extensions != nil && *compiler.Properties.Gnu_extensions == false {
    430 		cStd = gnuToCReplacer.Replace(cStd)
    431 		cppStd = gnuToCReplacer.Replace(cppStd)
    432 	}
    433 
    434 	flags.ConlyFlags = append([]string{"-std=" + cStd}, flags.ConlyFlags...)
    435 	flags.CppFlags = append([]string{"-std=" + cppStd}, flags.CppFlags...)
    436 
    437 	if ctx.useVndk() {
    438 		flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
    439 	}
    440 
    441 	if ctx.inRecovery() {
    442 		flags.CFlags = append(flags.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
    443 	}
    444 
    445 	// We can enforce some rules more strictly in the code we own. strict
    446 	// indicates if this is code that we can be stricter with. If we have
    447 	// rules that we want to apply to *our* code (but maybe can't for
    448 	// vendor/device specific things), we could extend this to be a ternary
    449 	// value.
    450 	strict := true
    451 	if strings.HasPrefix(android.PathForModuleSrc(ctx).String(), "external/") {
    452 		strict = false
    453 	}
    454 
    455 	// Can be used to make some annotations stricter for code we can fix
    456 	// (such as when we mark functions as deprecated).
    457 	if strict {
    458 		flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT")
    459 	}
    460 
    461 	if compiler.hasSrcExt(".proto") {
    462 		flags = protoFlags(ctx, flags, &compiler.Proto)
    463 	}
    464 
    465 	if compiler.hasSrcExt(".y") || compiler.hasSrcExt(".yy") {
    466 		flags.GlobalFlags = append(flags.GlobalFlags,
    467 			"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
    468 	}
    469 
    470 	if compiler.hasSrcExt(".mc") {
    471 		flags.GlobalFlags = append(flags.GlobalFlags,
    472 			"-I"+android.PathForModuleGen(ctx, "windmc", ctx.ModuleDir()).String())
    473 	}
    474 
    475 	if compiler.hasSrcExt(".aidl") {
    476 		if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
    477 			localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs)
    478 			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(localAidlIncludeDirs))
    479 		}
    480 		if len(compiler.Properties.Aidl.Include_dirs) > 0 {
    481 			rootAidlIncludeDirs := android.PathsForSource(ctx, compiler.Properties.Aidl.Include_dirs)
    482 			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
    483 		}
    484 
    485 		if Bool(compiler.Properties.Aidl.Generate_traces) {
    486 			flags.aidlFlags = append(flags.aidlFlags, "-t")
    487 		}
    488 
    489 		flags.GlobalFlags = append(flags.GlobalFlags,
    490 			"-I"+android.PathForModuleGen(ctx, "aidl").String())
    491 	}
    492 
    493 	if compiler.hasSrcExt(".rs") || compiler.hasSrcExt(".fs") {
    494 		flags = rsFlags(ctx, flags, &compiler.Properties)
    495 	}
    496 
    497 	if compiler.hasSrcExt(".sysprop") {
    498 		flags.GlobalFlags = append(flags.GlobalFlags,
    499 			"-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
    500 	}
    501 
    502 	if len(compiler.Properties.Srcs) > 0 {
    503 		module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
    504 		if inList("-Wno-error", flags.CFlags) || inList("-Wno-error", flags.CppFlags) {
    505 			addToModuleList(ctx, modulesUsingWnoErrorKey, module)
    506 		} else if !inList("-Werror", flags.CFlags) && !inList("-Werror", flags.CppFlags) {
    507 			if warningsAreAllowed(ctx.ModuleDir()) {
    508 				addToModuleList(ctx, modulesAddedWallKey, module)
    509 				flags.CFlags = append([]string{"-Wall"}, flags.CFlags...)
    510 			} else {
    511 				flags.CFlags = append([]string{"-Wall", "-Werror"}, flags.CFlags...)
    512 			}
    513 		}
    514 	}
    515 
    516 	if Bool(compiler.Properties.Openmp) {
    517 		flags.CFlags = append(flags.CFlags, "-fopenmp")
    518 	}
    519 
    520 	return flags
    521 }
    522 
    523 func (compiler *baseCompiler) hasSrcExt(ext string) bool {
    524 	for _, src := range compiler.srcsBeforeGen {
    525 		if src.Ext() == ext {
    526 			return true
    527 		}
    528 	}
    529 	for _, src := range compiler.Properties.Srcs {
    530 		if filepath.Ext(src) == ext {
    531 			return true
    532 		}
    533 	}
    534 	for _, src := range compiler.Properties.OriginalSrcs {
    535 		if filepath.Ext(src) == ext {
    536 			return true
    537 		}
    538 	}
    539 
    540 	return false
    541 }
    542 
    543 var gnuToCReplacer = strings.NewReplacer("gnu", "c")
    544 
    545 func ndkPathDeps(ctx ModuleContext) android.Paths {
    546 	if ctx.useSdk() {
    547 		// The NDK sysroot timestamp file depends on all the NDK sysroot files
    548 		// (headers and libraries).
    549 		return android.Paths{getNdkBaseTimestampFile(ctx)}
    550 	}
    551 	return nil
    552 }
    553 
    554 func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
    555 	pathDeps := deps.GeneratedHeaders
    556 	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
    557 
    558 	buildFlags := flagsToBuilderFlags(flags)
    559 
    560 	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
    561 
    562 	srcs, genDeps := genSources(ctx, srcs, buildFlags)
    563 	pathDeps = append(pathDeps, genDeps...)
    564 
    565 	compiler.pathDeps = pathDeps
    566 	compiler.cFlagsDeps = flags.CFlagsDeps
    567 
    568 	// Save src, buildFlags and context
    569 	compiler.srcs = srcs
    570 
    571 	// Compile files listed in c.Properties.Srcs into objects
    572 	objs := compileObjs(ctx, buildFlags, "", srcs, pathDeps, compiler.cFlagsDeps)
    573 
    574 	if ctx.Failed() {
    575 		return Objects{}
    576 	}
    577 
    578 	return objs
    579 }
    580 
    581 // Compile a list of source files into objects a specified subdirectory
    582 func compileObjs(ctx android.ModuleContext, flags builderFlags,
    583 	subdir string, srcFiles, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
    584 
    585 	return TransformSourceToObj(ctx, subdir, srcFiles, flags, pathDeps, cFlagsDeps)
    586 }
    587