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