diff options
Diffstat (limited to 'cc')
| -rw-r--r-- | cc/binary.go | 127 | ||||
| -rw-r--r-- | cc/bp2build.go | 164 | ||||
| -rw-r--r-- | cc/builder.go | 22 | ||||
| -rw-r--r-- | cc/cc.go | 10 | ||||
| -rw-r--r-- | cc/compiler.go | 26 | ||||
| -rw-r--r-- | cc/config/bp2build.go | 144 | ||||
| -rw-r--r-- | cc/config/bp2build_test.go | 46 | ||||
| -rw-r--r-- | cc/config/global.go | 64 | ||||
| -rw-r--r-- | cc/config/toolchain.go | 6 | ||||
| -rw-r--r-- | cc/config/vndk.go | 1 | ||||
| -rw-r--r-- | cc/config/x86_darwin_host.go | 42 | ||||
| -rw-r--r-- | cc/config/x86_linux_host.go | 56 | ||||
| -rw-r--r-- | cc/config/x86_windows_host.go | 8 | ||||
| -rw-r--r-- | cc/fuzz.go | 136 | ||||
| -rw-r--r-- | cc/gen.go | 31 | ||||
| -rw-r--r-- | cc/installer.go | 9 | ||||
| -rw-r--r-- | cc/library.go | 33 | ||||
| -rw-r--r-- | cc/library_headers.go | 2 | ||||
| -rw-r--r-- | cc/linkable.go | 1 | ||||
| -rw-r--r-- | cc/lto.go | 90 | ||||
| -rw-r--r-- | cc/object.go | 2 | ||||
| -rw-r--r-- | cc/prebuilt.go | 5 |
22 files changed, 630 insertions, 395 deletions
diff --git a/cc/binary.go b/cc/binary.go index b423c50ae..4d1301bb4 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -20,6 +20,7 @@ import ( "github.com/google/blueprint" "android/soong/android" + "android/soong/bazel" ) type BinaryLinkerProperties struct { @@ -62,7 +63,7 @@ func init() { func RegisterBinaryBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_binary", BinaryFactory) - ctx.RegisterModuleType("cc_binary_host", binaryHostFactory) + ctx.RegisterModuleType("cc_binary_host", BinaryHostFactory) } // cc_binary produces a binary that is runnable on a device. @@ -72,7 +73,7 @@ func BinaryFactory() android.Module { } // cc_binary_host produces a binary that is runnable on a host. -func binaryHostFactory() android.Module { +func BinaryHostFactory() android.Module { module, _ := NewBinary(android.HostSupported) return module.Init() } @@ -541,3 +542,125 @@ func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, lin }, }) } + +func init() { + android.RegisterBp2BuildMutator("cc_binary", BinaryBp2build) + android.RegisterBp2BuildMutator("cc_binary_host", BinaryHostBp2build) +} + +func BinaryBp2build(ctx android.TopDownMutatorContext) { + binaryBp2build(ctx, "cc_binary") +} + +func BinaryHostBp2build(ctx android.TopDownMutatorContext) { + binaryBp2build(ctx, "cc_binary_host") +} + +func binaryBp2build(ctx android.TopDownMutatorContext, typ string) { + m, ok := ctx.Module().(*Module) + if !ok { + // Not a cc module + return + } + if !m.ConvertWithBp2build(ctx) { + return + } + + if ctx.ModuleType() != typ { + return + } + + var compatibleWith bazel.StringListAttribute + if typ == "cc_binary_host" { + //incompatible with android OS + compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, []string{"@platforms//:incompatible"}) + compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, bazel.ConditionsDefaultConfigKey, []string{}) + } + + compilerAttrs := bp2BuildParseCompilerProps(ctx, m) + linkerAttrs := bp2BuildParseLinkerProps(ctx, m) + + attrs := &binaryAttributes{ + binaryLinkerAttrs: bp2buildBinaryLinkerProps(ctx, m), + + Srcs: compilerAttrs.srcs, + Srcs_c: compilerAttrs.cSrcs, + Srcs_as: compilerAttrs.asSrcs, + + Copts: compilerAttrs.copts, + Cppflags: compilerAttrs.cppFlags, + Conlyflags: compilerAttrs.conlyFlags, + Asflags: compilerAttrs.asFlags, + + Deps: linkerAttrs.implementationDeps, + Dynamic_deps: linkerAttrs.implementationDynamicDeps, + Whole_archive_deps: linkerAttrs.wholeArchiveDeps, + System_deps: linkerAttrs.systemDynamicDeps, + + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, + Linkopts: linkerAttrs.linkopts, + Link_crt: linkerAttrs.linkCrt, + Use_libcrt: linkerAttrs.useLibcrt, + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + + Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, + + Strip: stripAttributes{ + Keep_symbols: linkerAttrs.stripKeepSymbols, + Keep_symbols_and_debug_frame: linkerAttrs.stripKeepSymbolsAndDebugFrame, + Keep_symbols_list: linkerAttrs.stripKeepSymbolsList, + All: linkerAttrs.stripAll, + None: linkerAttrs.stripNone, + }, + + Target_compatible_with: compatibleWith, + Features: linkerAttrs.features, + } + + ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{ + Rule_class: "cc_binary", + Bzl_load_location: "//build/bazel/rules:cc_binary.bzl", + }, + android.CommonAttributes{Name: m.Name()}, + attrs) +} + +// binaryAttributes contains Bazel attributes corresponding to a cc binary +type binaryAttributes struct { + binaryLinkerAttrs + Srcs bazel.LabelListAttribute + Srcs_c bazel.LabelListAttribute + Srcs_as bazel.LabelListAttribute + + Copts bazel.StringListAttribute + Cppflags bazel.StringListAttribute + Conlyflags bazel.StringListAttribute + Asflags bazel.StringListAttribute + + Deps bazel.LabelListAttribute + Dynamic_deps bazel.LabelListAttribute + Whole_archive_deps bazel.LabelListAttribute + System_deps bazel.LabelListAttribute + + Local_includes bazel.StringListAttribute + Absolute_includes bazel.StringListAttribute + + Linkopts bazel.StringListAttribute + Additional_linker_inputs bazel.LabelListAttribute + + Link_crt bazel.BoolAttribute + Use_libcrt bazel.BoolAttribute + + Rtti bazel.BoolAttribute + Stl *string + Cpp_std *string + + Strip stripAttributes + + Features bazel.StringListAttribute + + Target_compatible_with bazel.StringListAttribute +} diff --git a/cc/bp2build.go b/cc/bp2build.go index 0b2c133b9..3c238b5d2 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -14,6 +14,7 @@ package cc import ( + "fmt" "path/filepath" "strings" @@ -25,6 +26,12 @@ import ( "github.com/google/blueprint/proptools" ) +const ( + cSrcPartition = "c" + asSrcPartition = "as" + cppSrcPartition = "cpp" +) + // staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties -- // properties which apply to either the shared or static version of a cc_library module. type staticOrSharedAttributes struct { @@ -42,7 +49,7 @@ type staticOrSharedAttributes struct { System_dynamic_deps bazel.LabelListAttribute } -func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) { +func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute { // Check that a module is a filegroup type named <label>. isFilegroupNamed := func(m android.Module, fullLabel string) bool { if ctx.OtherModuleType(m) != "filegroup" { @@ -74,17 +81,14 @@ func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelLis // TODO(b/190006308): Handle language detection of sources in a Bazel rule. partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{ - "c": bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")}, - "as": bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")}, + cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")}, + asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")}, // C++ is the "catch-all" group, and comprises generated sources because we don't // know the language of these sources until the genrule is executed. - "cpp": bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true}, + cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true}, }) - cSrcs = partitioned["c"] - asSrcs = partitioned["as"] - cppSrcs = partitioned["cpp"] - return + return partitioned } // bp2BuildParseLibProps returns the attributes for a variant of a cc_library. @@ -113,7 +117,13 @@ type depsPartition struct { type bazelLabelForDepsFn func(android.TopDownMutatorContext, []string) bazel.LabelList -func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition { +func maybePartitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition { + if !exportsDeps { + return depsPartition{ + implementation: fn(ctx, allDeps), + } + } + implementation, export := android.FilterList(allDeps, exportedDeps) return depsPartition{ @@ -124,7 +134,12 @@ func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, type bazelLabelForDepsExcludesFn func(android.TopDownMutatorContext, []string, []string) bazel.LabelList -func partitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition { +func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition { + if !exportsDeps { + return depsPartition{ + implementation: fn(ctx, allDeps, excludes), + } + } implementation, export := android.FilterList(allDeps, exportedDeps) return depsPartition{ @@ -141,11 +156,11 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs)) attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs)) - staticDeps := partitionExportedAndImplementationsDeps(ctx, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps) + staticDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps) attrs.Deps.SetSelectValue(axis, config, staticDeps.export) attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation) - sharedDeps := partitionExportedAndImplementationsDeps(ctx, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps) + sharedDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps) attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export) attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation) @@ -174,10 +189,10 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module } } - cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs) - attrs.Srcs = cppSrcs - attrs.Srcs_c = cSrcs - attrs.Srcs_as = asSrcs + partitionedSrcs := groupSrcsByExtension(ctx, attrs.Srcs) + attrs.Srcs = partitionedSrcs[cppSrcPartition] + attrs.Srcs_c = partitionedSrcs[cSrcPartition] + attrs.Srcs_as = partitionedSrcs[asSrcPartition] return attrs } @@ -226,7 +241,10 @@ type compilerAttributes struct { srcs bazel.LabelListAttribute rtti bazel.BoolAttribute - stl *string + + // Not affected by arch variants + stl *string + cppStd *string localIncludes bazel.StringListAttribute absoluteIncludes bazel.StringListAttribute @@ -235,6 +253,7 @@ type compilerAttributes struct { // bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes. func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes { var srcs bazel.LabelListAttribute + var implementationHdrs bazel.LabelListAttribute var copts bazel.StringListAttribute var asFlags bazel.StringListAttribute var conlyFlags bazel.StringListAttribute @@ -242,6 +261,8 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul var rtti bazel.BoolAttribute var localIncludes bazel.StringListAttribute var absoluteIncludes bazel.StringListAttribute + var stl *string = nil + var cppStd *string = nil parseCommandLineFlags := func(soongFlags []string) []string { var result []string @@ -255,15 +276,20 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul } // Parse srcs from an arch or OS's props value. - parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList { + parseSrcs := func(props *BaseCompilerProperties) (bazel.LabelList, bool) { + anySrcs := false // Add srcs-like dependencies such as generated files. // First create a LabelList containing these dependencies, then merge the values with srcs. - generatedHdrsAndSrcs := baseCompilerProps.Generated_headers - generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...) - generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs) + generatedSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, props.Generated_sources, props.Exclude_generated_sources) + if len(props.Generated_sources) > 0 || len(props.Exclude_generated_sources) > 0 { + anySrcs = true + } - allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs) - return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList) + allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, props.Srcs, props.Exclude_srcs) + if len(props.Srcs) > 0 || len(props.Exclude_srcs) > 0 { + anySrcs = true + } + return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedSrcsLabelList), anySrcs } archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) @@ -272,12 +298,13 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { // If there's arch specific srcs or exclude_srcs, generate a select entry for it. // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too. - if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { - srcsList := parseSrcs(baseCompilerProps) + if srcsList, ok := parseSrcs(baseCompilerProps); ok { srcs.SetSelectValue(axis, config, srcsList) } + if len(baseCompilerProps.Generated_headers) > 0 { + implementationHdrs.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, baseCompilerProps.Generated_headers)) + } - var archVariantCopts []string if axis == bazel.NoConfigAxis { // If cpp_std is not specified, don't generate it in the // BUILD file. For readability purposes, cpp_std and gnu_extensions are @@ -289,11 +316,14 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul // These transformations are shared with compiler.go. cppStdVal := parseCppStd(baseCompilerProps.Cpp_std) _, cppStdVal = maybeReplaceGnuToC(baseCompilerProps.Gnu_extensions, "", cppStdVal) - archVariantCopts = append(archVariantCopts, "-std="+cppStdVal) + cppStd = &cppStdVal } else if baseCompilerProps.Gnu_extensions != nil && !*baseCompilerProps.Gnu_extensions { - archVariantCopts = append(archVariantCopts, "-std=c++17") + cppStdVal := "c++17" + cppStd = &cppStdVal } } + + var archVariantCopts []string archVariantCopts = append(archVariantCopts, parseCommandLineFlags(baseCompilerProps.Cflags)...) archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags) @@ -315,6 +345,21 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul } srcs.ResolveExcludes() + partitionedSrcs := groupSrcsByExtension(ctx, srcs) + + for p, lla := range partitionedSrcs { + // if there are no sources, there is no need for headers + if lla.IsEmpty() { + continue + } + lla.Append(implementationHdrs) + partitionedSrcs[p] = lla + } + + srcs = partitionedSrcs[cppSrcPartition] + cSrcs := partitionedSrcs[cSrcPartition] + asSrcs := partitionedSrcs[asSrcPartition] + absoluteIncludes.DeduplicateAxesFromBase() localIncludes.DeduplicateAxesFromBase() @@ -337,9 +382,6 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul } } - srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs) - - var stl *string = nil stlPropsByArch := module.GetArchVariantProperties(ctx, &StlProperties{}) for _, configToProps := range stlPropsByArch { for _, props := range configToProps { @@ -367,6 +409,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul cppFlags: cppFlags, rtti: rtti, stl: stl, + cppStd: cppStd, localIncludes: localIncludes, absoluteIncludes: absoluteIncludes, } @@ -384,7 +427,7 @@ type linkerAttributes struct { linkCrt bazel.BoolAttribute useLibcrt bazel.BoolAttribute linkopts bazel.StringListAttribute - versionScript bazel.LabelAttribute + additionalLinkerInputs bazel.LabelListAttribute stripKeepSymbols bazel.BoolAttribute stripKeepSymbolsAndDebugFrame bazel.BoolAttribute stripKeepSymbolsList bazel.StringListAttribute @@ -407,8 +450,8 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true} var linkopts bazel.StringListAttribute - var versionScript bazel.LabelAttribute var linkCrt bazel.BoolAttribute + var additionalLinkerInputs bazel.LabelListAttribute var useLibcrt bazel.BoolAttribute var stripKeepSymbols bazel.BoolAttribute @@ -433,6 +476,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module var disallowedArchVariantCrt bool + isBinary := module.Binary() for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) { for config, props := range configToProps { @@ -442,7 +486,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) // Excludes to parallel Soong: // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs) - staticDeps := partitionExportedAndImplementationsDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes) + staticDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes) deps.SetSelectValue(axis, config, staticDeps.export) implementationDeps.SetSelectValue(axis, config, staticDeps.implementation) @@ -459,17 +503,16 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs)) sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) - sharedDeps := partitionExportedAndImplementationsDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes) + sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes) dynamicDeps.SetSelectValue(axis, config, sharedDeps.export) implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation) headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs) - hDeps := partitionExportedAndImplementationsDeps(ctx, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps) + hDeps := maybePartitionExportedAndImplementationsDeps(ctx, !isBinary, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps) headerDeps.SetSelectValue(axis, config, hDeps.export) implementationHeaderDeps.SetSelectValue(axis, config, hDeps.implementation) - linkopts.SetSelectValue(axis, config, baseLinkerProps.Ldflags) if !BoolDefault(baseLinkerProps.Pack_relocations, packRelocationsDefault) { axisFeatures = append(axisFeatures, "disable_pack_relocations") } @@ -478,9 +521,20 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) axisFeatures = append(axisFeatures, "-no_undefined_symbols") } + var linkerFlags []string + if len(baseLinkerProps.Ldflags) > 0 { + linkerFlags = append(linkerFlags, baseLinkerProps.Ldflags...) + // binaries remove static flag if -shared is in the linker flags + if module.Binary() && android.InList("-shared", linkerFlags) { + axisFeatures = append(axisFeatures, "-static_flag") + } + } if baseLinkerProps.Version_script != nil { - versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) + label := android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script) + additionalLinkerInputs.SetSelectValue(axis, config, bazel.LabelList{Includes: []bazel.Label{label}}) + linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--version-script,$(location %s)", label.Label)) } + linkopts.SetSelectValue(axis, config, linkerFlags) useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt()) // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it. @@ -572,10 +626,10 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) wholeArchiveDeps: wholeArchiveDeps, systemDynamicDeps: systemSharedDeps, - linkCrt: linkCrt, - linkopts: linkopts, - useLibcrt: useLibcrt, - versionScript: versionScript, + linkCrt: linkCrt, + linkopts: linkopts, + useLibcrt: useLibcrt, + additionalLinkerInputs: additionalLinkerInputs, // Strip properties stripKeepSymbols: stripKeepSymbols, @@ -708,3 +762,29 @@ func bazelLabelForHeaderDeps(ctx android.TopDownMutatorContext, modules []string func bazelLabelForSharedDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList { return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule) } + +type binaryLinkerAttrs struct { + Linkshared *bool +} + +func bp2buildBinaryLinkerProps(ctx android.TopDownMutatorContext, m *Module) binaryLinkerAttrs { + attrs := binaryLinkerAttrs{} + archVariantProps := m.GetArchVariantProperties(ctx, &BinaryLinkerProperties{}) + for axis, configToProps := range archVariantProps { + for _, p := range configToProps { + props := p.(*BinaryLinkerProperties) + staticExecutable := props.Static_executable + if axis == bazel.NoConfigAxis { + if linkBinaryShared := !proptools.Bool(staticExecutable); !linkBinaryShared { + attrs.Linkshared = &linkBinaryShared + } + } else if staticExecutable != nil { + // TODO(b/202876379): Static_executable is arch-variant; however, linkshared is a + // nonconfigurable attribute. Only 4 AOSP modules use this feature, defer handling + ctx.ModuleErrorf("bp2build cannot migrate a module with arch/target-specific static_executable values") + } + } + } + + return attrs +} diff --git a/cc/builder.go b/cc/builder.go index b494f7bab..082a70cf7 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -238,14 +238,6 @@ var ( }, "asFlags") - // Rule to invoke windres, for interaction with Windows resources. - windres = pctx.AndroidStaticRule("windres", - blueprint.RuleParams{ - Command: "$windresCmd $flags -I$$(dirname $in) -i $in -o $out --preprocessor \"${config.ClangBin}/clang -E -xc-header -DRC_INVOKED\"", - CommandDeps: []string{"$windresCmd"}, - }, - "windresCmd", "flags") - _ = pctx.SourcePathVariable("sAbiDumper", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-dumper") // -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information. @@ -577,20 +569,6 @@ func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, no }, }) continue - case ".rc": - ctx.Build(pctx, android.BuildParams{ - Rule: windres, - Description: "windres " + srcFile.Rel(), - Output: objFile, - Input: srcFile, - Implicits: cFlagsDeps, - OrderOnly: pathDeps, - Args: map[string]string{ - "windresCmd": mingwCmd(flags.toolchain, "windres"), - "flags": shareFlags("flags", flags.toolchain.WindresFlags()), - }, - }) - continue case ".o": objFiles[i] = srcFile continue @@ -3249,16 +3249,6 @@ func (c *Module) TestFor() []string { return c.Properties.Test_for } -func (c *Module) UniqueApexVariations() bool { - if u, ok := c.compiler.(interface { - uniqueApexVariations() bool - }); ok { - return u.uniqueApexVariations() - } else { - return false - } -} - func (c *Module) EverInstallable() bool { return c.installer != nil && // Check to see whether the module is actually ever installable. diff --git a/cc/compiler.go b/cc/compiler.go index 4f96712e6..00df66912 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -209,15 +209,6 @@ type BaseCompilerProperties struct { // Build and link with OpenMP Openmp *bool `android:"arch_variant"` - - // Deprecated. - // Adds __ANDROID_APEX_<APEX_MODULE_NAME>__ macro defined for apex variants in addition to __ANDROID_APEX__ - Use_apex_name_macro *bool - - // Adds two macros for apex variants in addition to __ANDROID_APEX__ - // * __ANDROID_APEX_COM_ANDROID_FOO__ - // * __ANDROID_APEX_NAME__="com.android.foo" - UseApexNameMacro bool `blueprint:"mutated"` } func NewBaseCompiler() *baseCompiler { @@ -291,10 +282,6 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { return deps } -func (compiler *baseCompiler) useApexNameMacro() bool { - return Bool(compiler.Properties.Use_apex_name_macro) || compiler.Properties.UseApexNameMacro -} - // Return true if the module is in the WarningAllowedProjects. func warningsAreAllowed(subdir string) bool { subdir += "/" @@ -405,10 +392,6 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps if ctx.apexVariationName() != "" { flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__") - if compiler.useApexNameMacro() { - flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexVariationName())+"__") - flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_NAME__='\""+ctx.apexVariationName()+"\"'") - } if ctx.Device() { flags.Global.CommonFlags = append(flags.Global.CommonFlags, fmt.Sprintf("-D__ANDROID_APEX_MIN_SDK_VERSION__=%d", @@ -554,11 +537,6 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps "-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String()) } - if compiler.hasSrcExt(".mc") { - flags.Local.CommonFlags = append(flags.Local.CommonFlags, - "-I"+android.PathForModuleGen(ctx, "windmc", ctx.ModuleDir()).String()) - } - if compiler.hasSrcExt(".aidl") { flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...) if len(compiler.Properties.Aidl.Local_include_dirs) > 0 { @@ -634,10 +612,6 @@ func (compiler *baseCompiler) hasSrcExt(ext string) bool { return false } -func (compiler *baseCompiler) uniqueApexVariations() bool { - return compiler.useApexNameMacro() -} - var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]") // makeDefineString transforms a name of an APEX module into a value to be used as value for C define diff --git a/cc/config/bp2build.go b/cc/config/bp2build.go index d19f5ac8e..4797acca1 100644 --- a/cc/config/bp2build.go +++ b/cc/config/bp2build.go @@ -16,9 +16,13 @@ package config import ( "fmt" + "reflect" "regexp" "sort" "strings" + + "android/soong/android" + "github.com/google/blueprint" ) const ( @@ -26,18 +30,27 @@ const ( ) type bazelVarExporter interface { - asBazel(exportedStringVariables, exportedStringListVariables) []bazelConstant + asBazel(android.Config, exportedStringVariables, exportedStringListVariables, exportedConfigDependingVariables) []bazelConstant } // Helpers for exporting cc configuration information to Bazel. var ( - // Map containing toolchain variables that are independent of the + // Maps containing toolchain variables that are independent of the // environment variables of the build. exportedStringListVars = exportedStringListVariables{} exportedStringVars = exportedStringVariables{} exportedStringListDictVars = exportedStringListDictVariables{} + + /// Maps containing variables that are dependent on the build config. + exportedConfigDependingVars = exportedConfigDependingVariables{} ) +type exportedConfigDependingVariables map[string]interface{} + +func (m exportedConfigDependingVariables) Set(k string, v interface{}) { + m[k] = v +} + // Ensure that string s has no invalid characters to be generated into the bzl file. func validateCharacters(s string) string { for _, c := range []string{`\n`, `"`, `\`} { @@ -74,10 +87,14 @@ func printBazelList(items []string, indentLevel int) string { return strings.Join(list, "\n") } -func (m exportedStringVariables) asBazel(stringScope exportedStringVariables, stringListScope exportedStringListVariables) []bazelConstant { +func (m exportedStringVariables) asBazel(config android.Config, + stringVars exportedStringVariables, stringListVars exportedStringListVariables, cfgDepVars exportedConfigDependingVariables) []bazelConstant { ret := make([]bazelConstant, 0, len(m)) for k, variableValue := range m { - expandedVar := expandVar(variableValue, exportedStringVars, exportedStringListVars) + expandedVar, err := expandVar(config, variableValue, stringVars, stringListVars, cfgDepVars) + if err != nil { + panic(fmt.Errorf("error expanding config variable %s: %s", k, err)) + } if len(expandedVar) > 1 { panic(fmt.Errorf("%s expands to more than one string value: %s", variableValue, expandedVar)) } @@ -101,7 +118,9 @@ func (m exportedStringListVariables) Set(k string, v []string) { m[k] = v } -func (m exportedStringListVariables) asBazel(stringScope exportedStringVariables, stringListScope exportedStringListVariables) []bazelConstant { +func (m exportedStringListVariables) asBazel(config android.Config, + stringScope exportedStringVariables, stringListScope exportedStringListVariables, + exportedVars exportedConfigDependingVariables) []bazelConstant { ret := make([]bazelConstant, 0, len(m)) // For each exported variable, recursively expand elements in the variableValue // list to ensure that interpolated variables are expanded according to their values @@ -109,7 +128,11 @@ func (m exportedStringListVariables) asBazel(stringScope exportedStringVariables for k, variableValue := range m { var expandedVars []string for _, v := range variableValue { - expandedVars = append(expandedVars, expandVar(v, stringScope, stringListScope)...) + expandedVar, err := expandVar(config, v, stringScope, stringListScope, exportedVars) + if err != nil { + panic(fmt.Errorf("Error expanding config variable %s=%s: %s", k, v, err)) + } + expandedVars = append(expandedVars, expandedVar...) } // Assign the list as a bzl-private variable; this variable will be exported // out through a constants struct later. @@ -121,6 +144,18 @@ func (m exportedStringListVariables) asBazel(stringScope exportedStringVariables return ret } +// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain. +func exportVariableConfigMethod(name string, method interface{}) blueprint.Variable { + exportedConfigDependingVars.Set(name, method) + return pctx.VariableConfigMethod(name, method) +} + +// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain. +func exportSourcePathVariable(name string, value string) { + pctx.SourcePathVariable(name, value) + exportedStringVars.Set(name, value) +} + // Convenience function to declare a static variable and export it to Bazel's cc_toolchain. func exportStringListStaticVariable(name string, value []string) { pctx.StaticVariable(name, strings.Join(value, " ")) @@ -145,7 +180,8 @@ func printBazelStringListDict(dict map[string][]string) string { } // Since dictionaries are not supported in Ninja, we do not expand variables for dictionaries -func (m exportedStringListDictVariables) asBazel(_ exportedStringVariables, _ exportedStringListVariables) []bazelConstant { +func (m exportedStringListDictVariables) asBazel(_ android.Config, _ exportedStringVariables, + _ exportedStringListVariables, _ exportedConfigDependingVariables) []bazelConstant { ret := make([]bazelConstant, 0, len(m)) for k, dict := range m { ret = append(ret, bazelConstant{ @@ -158,19 +194,20 @@ func (m exportedStringListDictVariables) asBazel(_ exportedStringVariables, _ ex // BazelCcToolchainVars generates bzl file content containing variables for // Bazel's cc_toolchain configuration. -func BazelCcToolchainVars() string { +func BazelCcToolchainVars(config android.Config) string { return bazelToolchainVars( + config, exportedStringListDictVars, exportedStringListVars, exportedStringVars) } -func bazelToolchainVars(vars ...bazelVarExporter) string { +func bazelToolchainVars(config android.Config, vars ...bazelVarExporter) string { ret := "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.\n\n" results := []bazelConstant{} for _, v := range vars { - results = append(results, v.asBazel(exportedStringVars, exportedStringListVars)...) + results = append(results, v.asBazel(config, exportedStringVars, exportedStringListVars, exportedConfigDependingVars)...) } sort.Slice(results, func(i, j int) bool { return results[i].variableName < results[j].variableName }) @@ -201,34 +238,35 @@ func bazelToolchainVars(vars ...bazelVarExporter) string { // string slice than to handle a pass-by-referenced map, which would make it // quite complex to track depth-first interpolations. It's also unlikely the // interpolation stacks are deep (n > 1). -func expandVar(toExpand string, stringScope exportedStringVariables, stringListScope exportedStringListVariables) []string { +func expandVar(config android.Config, toExpand string, stringScope exportedStringVariables, + stringListScope exportedStringListVariables, exportedVars exportedConfigDependingVariables) ([]string, error) { // e.g. "${ExternalCflags}" r := regexp.MustCompile(`\${([a-zA-Z0-9_]+)}`) // Internal recursive function. - var expandVarInternal func(string, map[string]bool) []string - expandVarInternal = func(toExpand string, seenVars map[string]bool) []string { - var ret []string - for _, v := range strings.Split(toExpand, " ") { - matches := r.FindStringSubmatch(v) + var expandVarInternal func(string, map[string]bool) (string, error) + expandVarInternal = func(toExpand string, seenVars map[string]bool) (string, error) { + var ret string + remainingString := toExpand + for len(remainingString) > 0 { + matches := r.FindStringSubmatch(remainingString) if len(matches) == 0 { - return []string{v} + return ret + remainingString, nil } - if len(matches) != 2 { - panic(fmt.Errorf( - "Expected to only match 1 subexpression in %s, got %d", - v, - len(matches)-1)) + panic(fmt.Errorf("Expected to only match 1 subexpression in %s, got %d", remainingString, len(matches)-1)) } + matchIndex := strings.Index(remainingString, matches[0]) + ret += remainingString[:matchIndex] + remainingString = remainingString[matchIndex+len(matches[0]):] // Index 1 of FindStringSubmatch contains the subexpression match // (variable name) of the capture group. variable := matches[1] // toExpand contains a variable. if _, ok := seenVars[variable]; ok { - panic(fmt.Errorf( - "Unbounded recursive interpolation of variable: %s", variable)) + return ret, fmt.Errorf( + "Unbounded recursive interpolation of variable: %s", variable) } // A map is passed-by-reference. Create a new map for // this scope to prevent variables seen in one depth-first expansion @@ -239,15 +277,65 @@ func expandVar(toExpand string, stringScope exportedStringVariables, stringListS } newSeenVars[variable] = true if unexpandedVars, ok := stringListScope[variable]; ok { + expandedVars := []string{} for _, unexpandedVar := range unexpandedVars { - ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...) + expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars) + if err != nil { + return ret, err + } + expandedVars = append(expandedVars, expandedVar) } + ret += strings.Join(expandedVars, " ") } else if unexpandedVar, ok := stringScope[variable]; ok { - ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...) + expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars) + if err != nil { + return ret, err + } + ret += expandedVar + } else if unevaluatedVar, ok := exportedVars[variable]; ok { + evalFunc := reflect.ValueOf(unevaluatedVar) + validateVariableMethod(variable, evalFunc) + evaluatedResult := evalFunc.Call([]reflect.Value{reflect.ValueOf(config)}) + evaluatedValue := evaluatedResult[0].Interface().(string) + expandedVar, err := expandVarInternal(evaluatedValue, newSeenVars) + if err != nil { + return ret, err + } + ret += expandedVar + } else { + return "", fmt.Errorf("Unbound config variable %s", variable) } } - return ret + return ret, nil + } + var ret []string + for _, v := range strings.Split(toExpand, " ") { + val, err := expandVarInternal(v, map[string]bool{}) + if err != nil { + return ret, err + } + ret = append(ret, val) } - return expandVarInternal(toExpand, map[string]bool{}) + return ret, nil +} + +func validateVariableMethod(name string, methodValue reflect.Value) { + methodType := methodValue.Type() + if methodType.Kind() != reflect.Func { + panic(fmt.Errorf("method given for variable %s is not a function", + name)) + } + if n := methodType.NumIn(); n != 1 { + panic(fmt.Errorf("method for variable %s has %d inputs (should be 1)", + name, n)) + } + if n := methodType.NumOut(); n != 1 { + panic(fmt.Errorf("method for variable %s has %d outputs (should be 1)", + name, n)) + } + if kind := methodType.Out(0).Kind(); kind != reflect.String { + panic(fmt.Errorf("method for variable %s does not return a string", + name)) + } } diff --git a/cc/config/bp2build_test.go b/cc/config/bp2build_test.go index 883597ad3..3118df1f8 100644 --- a/cc/config/bp2build_test.go +++ b/cc/config/bp2build_test.go @@ -16,13 +16,21 @@ package config import ( "testing" + + "android/soong/android" ) func TestExpandVars(t *testing.T) { + android_arm64_config := android.TestConfig("out", nil, "", nil) + android_arm64_config.BuildOS = android.Android + android_arm64_config.BuildArch = android.Arm64 + testCases := []struct { description string + config android.Config stringScope exportedStringVariables stringListScope exportedStringListVariables + configVars exportedConfigDependingVariables toExpand string expectedValues []string }{ @@ -57,7 +65,7 @@ func TestExpandVars(t *testing.T) { "bar": []string{"baz", "${qux}"}, }, toExpand: "${foo}", - expectedValues: []string{"baz", "hello"}, + expectedValues: []string{"baz hello"}, }, { description: "double level expansion", @@ -75,7 +83,7 @@ func TestExpandVars(t *testing.T) { "b": []string{"d"}, }, toExpand: "${a}", - expectedValues: []string{"d", "c"}, + expectedValues: []string{"d c"}, }, { description: "double level expansion, with two variables in a string", @@ -85,7 +93,7 @@ func TestExpandVars(t *testing.T) { "c": []string{"e"}, }, toExpand: "${a}", - expectedValues: []string{"d", "e"}, + expectedValues: []string{"d e"}, }, { description: "triple level expansion with two variables in a string", @@ -96,13 +104,38 @@ func TestExpandVars(t *testing.T) { "d": []string{"foo"}, }, toExpand: "${a}", - expectedValues: []string{"foo", "foo", "foo"}, + expectedValues: []string{"foo foo foo"}, + }, + { + description: "expansion with config depending vars", + configVars: exportedConfigDependingVariables{ + "a": func(c android.Config) string { return c.BuildOS.String() }, + "b": func(c android.Config) string { return c.BuildArch.String() }, + }, + config: android_arm64_config, + toExpand: "${a}-${b}", + expectedValues: []string{"android-arm64"}, + }, + { + description: "double level multi type expansion", + stringListScope: exportedStringListVariables{ + "platform": []string{"${os}-${arch}"}, + "const": []string{"const"}, + }, + configVars: exportedConfigDependingVariables{ + "os": func(c android.Config) string { return c.BuildOS.String() }, + "arch": func(c android.Config) string { return c.BuildArch.String() }, + "foo": func(c android.Config) string { return "foo" }, + }, + config: android_arm64_config, + toExpand: "${const}/${platform}/${foo}", + expectedValues: []string{"const/android-arm64/foo"}, }, } for _, testCase := range testCases { t.Run(testCase.description, func(t *testing.T) { - output := expandVar(testCase.toExpand, testCase.stringScope, testCase.stringListScope) + output, _ := expandVar(testCase.config, testCase.toExpand, testCase.stringScope, testCase.stringListScope, testCase.configVars) if len(output) != len(testCase.expectedValues) { t.Errorf("Expected %d values, got %d", len(testCase.expectedValues), len(output)) } @@ -119,6 +152,7 @@ func TestExpandVars(t *testing.T) { func TestBazelToolchainVars(t *testing.T) { testCases := []struct { name string + config android.Config vars []bazelVarExporter expectedOut string }{ @@ -248,7 +282,7 @@ constants = struct( for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - out := bazelToolchainVars(tc.vars...) + out := bazelToolchainVars(tc.config, tc.vars...) if out != tc.expectedOut { t.Errorf("Expected \n%s, got \n%s", tc.expectedOut, out) } diff --git a/cc/config/global.go b/cc/config/global.go index 5f41f9e06..7abd2fc12 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -77,10 +77,6 @@ var ( // TODO: can we remove this now? "-Wno-reserved-id-macro", - // Workaround for ccache with clang. - // See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html. - "-Wno-unused-command-line-argument", - // Force clang to always output color diagnostics. Ninja will strip the ANSI // color codes if it is not running in a terminal. "-fcolor-diagnostics", @@ -274,8 +270,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r433403" - ClangDefaultShortVersion = "13.0.2" + ClangDefaultVersion = "clang-r433403b" + ClangDefaultShortVersion = "13.0.3" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ @@ -329,6 +325,12 @@ func init() { // Default to zero initialization. flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang") } + + // Workaround for ccache with clang. + // See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html. + if ctx.Config().IsEnvTrue("USE_CCACHE") { + flags = append(flags, "-Wno-unused-command-line-argument") + } return strings.Join(flags, " ") }) @@ -364,28 +366,12 @@ func init() { exportStringStaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion) exportStringStaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion) - pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase) - pctx.VariableFunc("ClangBase", func(ctx android.PackageVarContext) string { - if override := ctx.Config().Getenv("LLVM_PREBUILTS_BASE"); override != "" { - return override - } - return "${ClangDefaultBase}" - }) - pctx.VariableFunc("ClangVersion", func(ctx android.PackageVarContext) string { - if override := ctx.Config().Getenv("LLVM_PREBUILTS_VERSION"); override != "" { - return override - } - return ClangDefaultVersion - }) + pctx.StaticVariableWithEnvOverride("ClangBase", "LLVM_PREBUILTS_BASE", ClangDefaultBase) + pctx.StaticVariableWithEnvOverride("ClangVersion", "LLVM_PREBUILTS_VERSION", ClangDefaultVersion) pctx.StaticVariable("ClangPath", "${ClangBase}/${HostPrebuiltTag}/${ClangVersion}") pctx.StaticVariable("ClangBin", "${ClangPath}/bin") - pctx.VariableFunc("ClangShortVersion", func(ctx android.PackageVarContext) string { - if override := ctx.Config().Getenv("LLVM_RELEASE_VERSION"); override != "" { - return override - } - return ClangDefaultShortVersion - }) + pctx.StaticVariableWithEnvOverride("ClangShortVersion", "LLVM_RELEASE_VERSION", ClangDefaultShortVersion) pctx.StaticVariable("ClangAsanLibDir", "${ClangBase}/linux-x86/${ClangVersion}/lib64/clang/${ClangShortVersion}/lib/linux") // These are tied to the version of LLVM directly in external/llvm, so they might trail the host prebuilts @@ -418,4 +404,30 @@ func init() { pctx.StaticVariableWithEnvOverride("REAbiLinkerExecStrategy", "RBE_ABI_LINKER_EXEC_STRATEGY", remoteexec.LocalExecStrategy) } -var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS) +var HostPrebuiltTag = exportVariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS) + +func ClangPath(ctx android.PathContext, file string) android.SourcePath { + type clangToolKey string + + key := android.NewCustomOnceKey(clangToolKey(file)) + + return ctx.Config().OnceSourcePath(key, func() android.SourcePath { + return clangPath(ctx).Join(ctx, file) + }) +} + +var clangPathKey = android.NewOnceKey("clangPath") + +func clangPath(ctx android.PathContext) android.SourcePath { + return ctx.Config().OnceSourcePath(clangPathKey, func() android.SourcePath { + clangBase := ClangDefaultBase + if override := ctx.Config().Getenv("LLVM_PREBUILTS_BASE"); override != "" { + clangBase = override + } + clangVersion := ClangDefaultVersion + if override := ctx.Config().Getenv("LLVM_PREBUILTS_VERSION"); override != "" { + clangVersion = override + } + return android.PathForSource(ctx, clangBase, ctx.Config().PrebuiltOS(), clangVersion) + }) +} diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go index 20384a871..6320dbbbc 100644 --- a/cc/config/toolchain.go +++ b/cc/config/toolchain.go @@ -95,8 +95,6 @@ type Toolchain interface { YasmFlags() string - WindresFlags() string - Is64Bit() bool ShlibSuffix() string @@ -169,10 +167,6 @@ func (toolchainBase) YasmFlags() string { return "" } -func (toolchainBase) WindresFlags() string { - return "" -} - func (toolchainBase) LibclangRuntimeLibraryArch() string { return "" } diff --git a/cc/config/vndk.go b/cc/config/vndk.go index 3f30191ab..9577a8c1c 100644 --- a/cc/config/vndk.go +++ b/cc/config/vndk.go @@ -103,6 +103,7 @@ var VndkMustUseVendorVariantList = []string{ "android.system.keystore2-V1-ndk", "android.hardware.wifi.hostapd-V1-ndk", "android.hardware.wifi.hostapd-V1-ndk_platform", + "android.hardware.wifi.supplicant-V1-ndk", "android.system.keystore2-V1-ndk_platform", "android.system.keystore2-ndk_platform", "android.system.keystore2-unstable-ndk_platform", diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go index 0bb1a816e..ad82b9476 100644 --- a/cc/config/x86_darwin_host.go +++ b/cc/config/x86_darwin_host.go @@ -56,9 +56,7 @@ var ( "10.13", "10.14", "10.15", - "11.0", - "11.1", - "11.3", + "11", } darwinAvailableLibraries = append( @@ -113,6 +111,10 @@ func init() { pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64") } +func MacStripPath(ctx android.PathContext) string { + return getMacTools(ctx).stripPath +} + type macPlatformTools struct { once sync.Once err error @@ -125,7 +127,7 @@ type macPlatformTools struct { var macTools = &macPlatformTools{} -func getMacTools(ctx android.PackageVarContext) *macPlatformTools { +func getMacTools(ctx android.PathContext) *macPlatformTools { macTools.once.Do(func() { xcrunTool := "/usr/bin/xcrun" @@ -134,7 +136,7 @@ func getMacTools(ctx android.PackageVarContext) *macPlatformTools { return "" } - bytes, err := exec.Command(xcrunTool, args...).Output() + bytes, err := exec.Command(xcrunTool, append([]string{"--sdk", "macosx"}, args...)...).Output() if err != nil { macTools.err = fmt.Errorf("xcrun %q failed with: %q", args, err) return "" @@ -143,34 +145,26 @@ func getMacTools(ctx android.PackageVarContext) *macPlatformTools { return strings.TrimSpace(string(bytes)) } - xcrunSdk := func(arg string) string { - if selected := ctx.Config().Getenv("MAC_SDK_VERSION"); selected != "" { - if !inList(selected, darwinSupportedSdkVersions) { - macTools.err = fmt.Errorf("MAC_SDK_VERSION %s isn't supported: %q", selected, darwinSupportedSdkVersions) - return "" - } - - return xcrun("--sdk", "macosx"+selected, arg) + sdkVersion := xcrun("--show-sdk-version") + sdkVersionSupported := false + for _, version := range darwinSupportedSdkVersions { + if version == sdkVersion || strings.HasPrefix(sdkVersion, version+".") { + sdkVersionSupported = true } - - for _, sdk := range darwinSupportedSdkVersions { - bytes, err := exec.Command(xcrunTool, "--sdk", "macosx"+sdk, arg).Output() - if err == nil { - return strings.TrimSpace(string(bytes)) - } - } - macTools.err = fmt.Errorf("Could not find a supported mac sdk: %q", darwinSupportedSdkVersions) - return "" + } + if !sdkVersionSupported { + macTools.err = fmt.Errorf("Unsupported macOS SDK version %q not in %v", sdkVersion, darwinSupportedSdkVersions) + return } - macTools.sdkRoot = xcrunSdk("--show-sdk-path") + macTools.sdkRoot = xcrun("--show-sdk-path") macTools.arPath = xcrun("--find", "ar") macTools.stripPath = xcrun("--find", "strip") macTools.toolPath = filepath.Dir(xcrun("--find", "ld")) }) if macTools.err != nil { - ctx.Errorf("%q", macTools.err) + android.ReportPathErrorf(ctx, "%q", macTools.err) } return macTools } diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go index ac5d5f74e..43333fada 100644 --- a/cc/config/x86_linux_host.go +++ b/cc/config/x86_linux_host.go @@ -120,40 +120,40 @@ const ( ) func init() { - pctx.StaticVariable("LinuxGccVersion", linuxGccVersion) - pctx.StaticVariable("LinuxGlibcVersion", linuxGlibcVersion) + exportStringStaticVariable("LinuxGccVersion", linuxGccVersion) + exportStringStaticVariable("LinuxGlibcVersion", linuxGlibcVersion) + // Most places use the full GCC version. A few only use up to the first two numbers. if p := strings.Split(linuxGccVersion, "."); len(p) > 2 { - pctx.StaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], ".")) + exportStringStaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], ".")) } else { - pctx.StaticVariable("ShortLinuxGccVersion", linuxGccVersion) + exportStringStaticVariable("ShortLinuxGccVersion", linuxGccVersion) } - pctx.SourcePathVariable("LinuxGccRoot", - "prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}") - - pctx.StaticVariable("LinuxGccTriple", "x86_64-linux") - - pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " ")) - pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " ")) - pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLdflags, " ")) - - pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " ")) - pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " ")) - pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " ")) - pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " ")) - pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " ")) - pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " ")) + exportSourcePathVariable("LinuxGccRoot", + "prebuilts/gcc/linux-x86/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}") + + exportStringListStaticVariable("LinuxGccTriple", []string{"x86_64-linux"}) + + exportStringListStaticVariable("LinuxCflags", linuxCflags) + exportStringListStaticVariable("LinuxLdflags", linuxLdflags) + exportStringListStaticVariable("LinuxLldflags", linuxLdflags) + exportStringListStaticVariable("LinuxGlibcCflags", linuxGlibcCflags) + exportStringListStaticVariable("LinuxGlibcLdflags", linuxGlibcLdflags) + exportStringListStaticVariable("LinuxGlibcLldflags", linuxGlibcLdflags) + exportStringListStaticVariable("LinuxMuslCflags", linuxMuslCflags) + exportStringListStaticVariable("LinuxMuslLdflags", linuxMuslLdflags) + exportStringListStaticVariable("LinuxMuslLldflags", linuxMuslLdflags) + + exportStringListStaticVariable("LinuxX86Cflags", linuxX86Cflags) + exportStringListStaticVariable("LinuxX8664Cflags", linuxX8664Cflags) + exportStringListStaticVariable("LinuxX86Ldflags", linuxX86Ldflags) + exportStringListStaticVariable("LinuxX86Lldflags", linuxX86Ldflags) + exportStringListStaticVariable("LinuxX8664Ldflags", linuxX8664Ldflags) + exportStringListStaticVariable("LinuxX8664Lldflags", linuxX8664Ldflags) // Yasm flags - pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86") - pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64") - - pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " ")) - pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " ")) - pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " ")) - pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " ")) - pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " ")) - pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " ")) + exportStringListStaticVariable("LinuxX86YasmFlags", []string{"-f elf32 -m x86"}) + exportStringListStaticVariable("LinuxX8664YasmFlags", []string{"-f elf64 -m amd64"}) } type toolchainLinux struct { diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go index d9a7537f3..9daf40f95 100644 --- a/cc/config/x86_windows_host.go +++ b/cc/config/x86_windows_host.go @@ -188,14 +188,6 @@ func (t *toolchainWindows) IncludeFlags() string { return "${config.WindowsIncludeFlags}" } -func (t *toolchainWindowsX86) WindresFlags() string { - return "-F pe-i386" -} - -func (t *toolchainWindowsX8664) WindresFlags() string { - return "-F pe-x86-64" -} - func (t *toolchainWindowsX86) ClangTriple() string { return "i686-windows-gnu" } diff --git a/cc/fuzz.go b/cc/fuzz.go index 83f003741..40f16f358 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -79,54 +79,21 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { return flags } -// This function performs a breadth-first search over the provided module's -// dependencies using `visitDirectDeps` to enumerate all shared library -// dependencies. We require breadth-first expansion, as otherwise we may -// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.) -// from a dependency. This may cause issues when dependencies have explicit -// sanitizer tags, as we may get a dependency on an unsanitized libc, etc. -func collectAllSharedDependencies(ctx android.SingletonContext, module android.Module) android.Paths { - var fringe []android.Module - - seen := make(map[string]bool) - - // Enumerate the first level of dependencies, as we discard all non-library - // modules in the BFS loop below. - ctx.VisitDirectDeps(module, func(dep android.Module) { - if isValidSharedDependency(dep) { - fringe = append(fringe, dep) - } - }) - - var sharedLibraries android.Paths - - for i := 0; i < len(fringe); i++ { - module := fringe[i] - if seen[module.Name()] { - continue - } - seen[module.Name()] = true - - ccModule := module.(*Module) - sharedLibraries = append(sharedLibraries, ccModule.UnstrippedOutputFile()) - ctx.VisitDirectDeps(module, func(dep android.Module) { - if isValidSharedDependency(dep) && !seen[dep.Name()] { - fringe = append(fringe, dep) - } - }) +func UnstrippedOutputFile(module android.Module) android.Path { + if mod, ok := module.(LinkableInterface); ok { + return mod.UnstrippedOutputFile() } - - return sharedLibraries + panic("UnstrippedOutputFile called on non-LinkableInterface module: " + module.Name()) } -// This function takes a module and determines if it is a unique shared library +// IsValidSharedDependency takes a module and determines if it is a unique shared library // that should be installed in the fuzz target output directories. This function // returns true, unless: // - The module is not an installable shared library, or // - The module is a header or stub, or // - The module is a prebuilt and its source is available, or // - The module is a versioned member of an SDK snapshot. -func isValidSharedDependency(dependency android.Module) bool { +func IsValidSharedDependency(dependency android.Module) bool { // TODO(b/144090547): We should be parsing these modules using // ModuleDependencyTag instead of the current brute-force checking. @@ -246,7 +213,7 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { } seen[child.Name()] = true - if isValidSharedDependency(child) { + if IsValidSharedDependency(child) { sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile()) return true } @@ -304,7 +271,6 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { // their architecture & target/host specific zip file. type ccFuzzPackager struct { fuzz.FuzzPackager - sharedLibInstallStrings []string } func fuzzPackagingFactory() android.Singleton { @@ -317,14 +283,14 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { // archive}). archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip) - // Map tracking whether each shared library has an install rule to avoid duplicate install rules from - // multiple fuzzers that depend on the same shared library. - sharedLibraryInstalled := make(map[string]bool) - // List of individual fuzz targets, so that 'make fuzz' also installs the targets // to the correct output directories as well. s.FuzzTargets = make(map[string]bool) + // Map tracking whether each shared library has an install rule to avoid duplicate install rules from + // multiple fuzzers that depend on the same shared library. + sharedLibraryInstalled := make(map[string]bool) + ctx.VisitAllModules(func(module android.Module) { ccModule, ok := module.(*Module) if !ok || ccModule.Properties.PreventInstall { @@ -351,7 +317,7 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} // Grab the list of required shared libraries. - sharedLibraries := collectAllSharedDependencies(ctx, module) + sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, UnstrippedOutputFile, IsValidSharedDependency) var files []fuzz.FileToZip builder := android.NewRuleBuilder(pctx, ctx) @@ -359,39 +325,8 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { // Package the corpus, data, dict and config into a zipfile. files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) - // Find and mark all the transiently-dependent shared libraries for - // packaging. - for _, library := range sharedLibraries { - files = append(files, fuzz.FileToZip{library, "lib"}) - - // For each architecture-specific shared library dependency, we need to - // install it to the output directory. Setup the install destination here, - // which will be used by $(copy-many-files) in the Make backend. - installDestination := sharedLibraryInstallLocation( - library, ccModule.Host(), archString) - if sharedLibraryInstalled[installDestination] { - continue - } - sharedLibraryInstalled[installDestination] = true - - // Escape all the variables, as the install destination here will be called - // via. $(eval) in Make. - installDestination = strings.ReplaceAll( - installDestination, "$", "$$") - s.sharedLibInstallStrings = append(s.sharedLibInstallStrings, - library.String()+":"+installDestination) - - // Ensure that on device, the library is also reinstalled to the /symbols/ - // dir. Symbolized DSO's are always installed to the device when fuzzing, but - // we want symbolization tools (like `stack`) to be able to find the symbols - // in $ANDROID_PRODUCT_OUT/symbols automagically. - if !ccModule.Host() { - symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString) - symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$") - s.sharedLibInstallStrings = append(s.sharedLibInstallStrings, - library.String()+":"+symbolsInstallDestination) - } - } + // Package shared libraries + files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...) // The executable. files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""}) @@ -409,15 +344,54 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { packages := s.Packages.Strings() sort.Strings(packages) - sort.Strings(s.sharedLibInstallStrings) + sort.Strings(s.FuzzPackager.SharedLibInstallStrings) // TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's // ready to handle phony targets created in Soong. In the meantime, this // exports the phony 'fuzz' target and dependencies on packages to // core/main.mk so that we can use dist-for-goals. ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " ")) ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", - strings.Join(s.sharedLibInstallStrings, " ")) + strings.Join(s.FuzzPackager.SharedLibInstallStrings, " ")) // Preallocate the slice of fuzz targets to minimise memory allocations. s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS") } + +// GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for +// packaging. +func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip { + var files []fuzz.FileToZip + + for _, library := range sharedLibraries { + files = append(files, fuzz.FileToZip{library, "lib"}) + + // For each architecture-specific shared library dependency, we need to + // install it to the output directory. Setup the install destination here, + // which will be used by $(copy-many-files) in the Make backend. + installDestination := sharedLibraryInstallLocation( + library, module.Host(), archString) + if (*sharedLibraryInstalled)[installDestination] { + continue + } + (*sharedLibraryInstalled)[installDestination] = true + + // Escape all the variables, as the install destination here will be called + // via. $(eval) in Make. + installDestination = strings.ReplaceAll( + installDestination, "$", "$$") + s.SharedLibInstallStrings = append(s.SharedLibInstallStrings, + library.String()+":"+installDestination) + + // Ensure that on device, the library is also reinstalled to the /symbols/ + // dir. Symbolized DSO's are always installed to the device when fuzzing, but + // we want symbolization tools (like `stack`) to be able to find the symbols + // in $ANDROID_PRODUCT_OUT/symbols automagically. + if !module.Host() { + symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString) + symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$") + s.SharedLibInstallStrings = append(s.SharedLibInstallStrings, + library.String()+":"+symbolsInstallDestination) + } + } + return files +} @@ -45,13 +45,6 @@ var ( CommandDeps: []string{"$syspropCmd"}, }, "headerOutDir", "publicOutDir", "srcOutDir", "includeName") - - windmc = pctx.AndroidStaticRule("windmc", - blueprint.RuleParams{ - Command: "$windmcCmd -r$$(dirname $out) -h$$(dirname $out) $in", - CommandDeps: []string{"$windmcCmd"}, - }, - "windmcCmd") ) type YaccProperties struct { @@ -200,26 +193,6 @@ func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Pa return cppFile, headers.Paths() } -func genWinMsg(ctx android.ModuleContext, srcFile android.Path, flags builderFlags) (android.Path, android.Path) { - headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h") - rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc") - - windmcCmd := mingwCmd(flags.toolchain, "windmc") - - ctx.Build(pctx, android.BuildParams{ - Rule: windmc, - Description: "windmc " + srcFile.Rel(), - Output: rcFile, - ImplicitOutput: headerFile, - Input: srcFile, - Args: map[string]string{ - "windmcCmd": windmcCmd, - }, - }) - - return rcFile, headerFile -} - // Used to communicate information from the genSources method back to the library code that uses // it. type generatedSourceInfo struct { @@ -305,10 +278,6 @@ func genSources(ctx android.ModuleContext, srcFiles android.Paths, cppFile := rsGeneratedCppFile(ctx, srcFile) rsFiles = append(rsFiles, srcFiles[i]) srcFiles[i] = cppFile - case ".mc": - rcFile, headerFile := genWinMsg(ctx, srcFile, buildFlags) - srcFiles[i] = rcFile - deps = append(deps, headerFile) case ".sysprop": cppFile, headerFiles := genSysprop(ctx, srcFile) srcFiles[i] = cppFile diff --git a/cc/installer.go b/cc/installer.go index f95b49346..2522610d9 100644 --- a/cc/installer.go +++ b/cc/installer.go @@ -29,6 +29,9 @@ type InstallerProperties struct { // Install output directly in {partition}/, not in any subdir. This is only intended for use by // init_first_stage. Install_in_root *bool `android:"arch_variant"` + + // Install output directly in {partition}/xbin + Install_in_xbin *bool `android:"arch_vvariant"` } type installLocation int @@ -73,6 +76,8 @@ func (installer *baseInstaller) installDir(ctx ModuleContext) android.InstallPat if installer.installInRoot() { dir = "" + } else if installer.installInXbin() { + dir = "xbin" } if ctx.Target().NativeBridge == android.NativeBridgeEnabled { @@ -123,3 +128,7 @@ func (installer *baseInstaller) makeUninstallable(mod *Module) { func (installer *baseInstaller) installInRoot() bool { return Bool(installer.Properties.Install_in_root) } + +func (installer *baseInstaller) installInXbin() bool { + return Bool(installer.Properties.Install_in_xbin) +} diff --git a/cc/library.go b/cc/library.go index 0cffd5667..d63acfbf7 100644 --- a/cc/library.go +++ b/cc/library.go @@ -248,11 +248,13 @@ type bazelCcLibraryAttributes struct { Linkopts bazel.StringListAttribute Use_libcrt bazel.BoolAttribute Rtti bazel.BoolAttribute - Stl *string + + Stl *string + Cpp_std *string // This is shared only. - Version_script bazel.LabelAttribute - Link_crt bazel.BoolAttribute + Link_crt bazel.BoolAttribute + Additional_linker_inputs bazel.LabelListAttribute // Common properties shared between both shared and static variants. Shared staticOrSharedAttributes @@ -328,8 +330,9 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { Use_libcrt: linkerAttrs.useLibcrt, Rtti: compilerAttrs.rtti, Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, - Version_script: linkerAttrs.versionScript, + Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, Strip: stripAttributes{ Keep_symbols: linkerAttrs.stripKeepSymbols, @@ -636,7 +639,7 @@ func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx androi func (handler *ccLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool { bazelCtx := ctx.Config().BazelContext - ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType) + ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx)) if err != nil { ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err) return false @@ -2399,10 +2402,10 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, attrs = &bazelCcLibraryStaticAttributes{ staticOrSharedAttributes: commonAttrs, - Linkopts: linkerAttrs.linkopts, Use_libcrt: linkerAttrs.useLibcrt, Rtti: compilerAttrs.rtti, Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, Export_includes: exportedIncludes.Includes, Export_system_includes: exportedIncludes.SystemIncludes, Local_includes: compilerAttrs.localIncludes, @@ -2427,12 +2430,13 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, Use_libcrt: linkerAttrs.useLibcrt, Rtti: compilerAttrs.rtti, Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, - Export_includes: exportedIncludes.Includes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, - Version_script: linkerAttrs.versionScript, + Export_includes: exportedIncludes.Includes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, + Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, Strip: stripAttributes{ Keep_symbols: linkerAttrs.stripKeepSymbols, @@ -2458,10 +2462,10 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, type bazelCcLibraryStaticAttributes struct { staticOrSharedAttributes - Linkopts bazel.StringListAttribute Use_libcrt bazel.BoolAttribute Rtti bazel.BoolAttribute Stl *string + Cpp_std *string Export_includes bazel.StringListAttribute Export_system_includes bazel.StringListAttribute @@ -2489,6 +2493,7 @@ type bazelCcLibrarySharedAttributes struct { Use_libcrt bazel.BoolAttribute Rtti bazel.BoolAttribute Stl *string + Cpp_std *string Export_includes bazel.StringListAttribute Export_system_includes bazel.StringListAttribute @@ -2496,8 +2501,8 @@ type bazelCcLibrarySharedAttributes struct { Absolute_includes bazel.StringListAttribute Hdrs bazel.LabelListAttribute - Strip stripAttributes - Version_script bazel.LabelAttribute + Strip stripAttributes + Additional_linker_inputs bazel.LabelListAttribute Cppflags bazel.StringListAttribute Conlyflags bazel.StringListAttribute diff --git a/cc/library_headers.go b/cc/library_headers.go index 51c1eb828..b2b3dbce9 100644 --- a/cc/library_headers.go +++ b/cc/library_headers.go @@ -57,7 +57,7 @@ type libraryHeaderBazelHander struct { func (h *libraryHeaderBazelHander) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool { bazelCtx := ctx.Config().BazelContext - ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType) + ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx)) if err != nil { ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err) return false diff --git a/cc/linkable.go b/cc/linkable.go index b510508a7..560c9debe 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -110,6 +110,7 @@ type LinkableInterface interface { BaseModuleName() string OutputFile() android.OptionalPath + UnstrippedOutputFile() android.Path CoverageFiles() android.Paths NonCcVariants() bool @@ -49,8 +49,9 @@ type LTOProperties struct { // Dep properties indicate that this module needs to be built with LTO // since it is an object dependency of an LTO module. - FullDep bool `blueprint:"mutated"` - ThinDep bool `blueprint:"mutated"` + FullDep bool `blueprint:"mutated"` + ThinDep bool `blueprint:"mutated"` + NoLtoDep bool `blueprint:"mutated"` // Use clang lld instead of gnu ld. Use_clang_lld *bool @@ -70,15 +71,6 @@ func (lto *lto) props() []interface{} { func (lto *lto) begin(ctx BaseModuleContext) { if ctx.Config().IsEnvTrue("DISABLE_LTO") { lto.Properties.Lto.Never = proptools.BoolPtr(true) - } else if ctx.Config().IsEnvTrue("GLOBAL_THINLTO") { - staticLib := ctx.static() && !ctx.staticBinary() - hostBin := ctx.Host() - vndk := ctx.isVndk() // b/169217596 - if !staticLib && !hostBin && !vndk { - if !lto.Never() && !lto.FullLTO() { - lto.Properties.Lto.Thin = proptools.BoolPtr(true) - } - } } } @@ -96,22 +88,27 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { return flags } - if lto.LTO() { - var ltoFlag string + if lto.LTO(ctx) { + var ltoCFlag string + var ltoLdFlag string if lto.ThinLTO() { - ltoFlag = "-flto=thin -fsplit-lto-unit" + ltoCFlag = "-flto=thin -fsplit-lto-unit" + } else if lto.FullLTO() { + ltoCFlag = "-flto" } else { - ltoFlag = "-flto" + ltoCFlag = "-flto=thin -fsplit-lto-unit" + ltoLdFlag = "-Wl,--lto-O0" } - flags.Local.CFlags = append(flags.Local.CFlags, ltoFlag) - flags.Local.LdFlags = append(flags.Local.LdFlags, ltoFlag) + flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlag) + flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlag) if Bool(lto.Properties.Whole_program_vtables) { flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables") } - if lto.ThinLTO() && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) { + if (lto.DefaultThinLTO(ctx) || lto.ThinLTO()) && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) { // Set appropriate ThinLTO cache policy cacheDirFormat := "-Wl,--thinlto-cache-dir=" cacheDir := android.PathForOutput(ctx, "thinlto-cache").String() @@ -134,33 +131,41 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { return flags } -// Can be called with a null receiver -func (lto *lto) LTO() bool { - if lto == nil || lto.Never() { - return false - } +func (lto *lto) LTO(ctx BaseModuleContext) bool { + return lto.ThinLTO() || lto.FullLTO() || lto.DefaultThinLTO(ctx) +} - return lto.FullLTO() || lto.ThinLTO() +func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool { + host := ctx.Host() + test := ctx.testBinary() + vndk := ctx.isVndk() // b/169217596 + return GlobalThinLTO(ctx) && !lto.Never() && !host && !test && !vndk } func (lto *lto) FullLTO() bool { - return Bool(lto.Properties.Lto.Full) + return lto != nil && Bool(lto.Properties.Lto.Full) } func (lto *lto) ThinLTO() bool { - return Bool(lto.Properties.Lto.Thin) + return lto != nil && Bool(lto.Properties.Lto.Thin) } -// Is lto.never explicitly set to true? func (lto *lto) Never() bool { - return Bool(lto.Properties.Lto.Never) + return lto != nil && Bool(lto.Properties.Lto.Never) +} + +func GlobalThinLTO(ctx android.BaseModuleContext) bool { + return ctx.Config().IsEnvTrue("GLOBAL_THINLTO") } // Propagate lto requirements down from binaries func ltoDepsMutator(mctx android.TopDownMutatorContext) { - if m, ok := mctx.Module().(*Module); ok && m.lto.LTO() { + globalThinLTO := GlobalThinLTO(mctx) + + if m, ok := mctx.Module().(*Module); ok { full := m.lto.FullLTO() thin := m.lto.ThinLTO() + never := m.lto.Never() if full && thin { mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive") } @@ -180,14 +185,16 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) { } } - if dep, ok := dep.(*Module); ok && dep.lto != nil && - !dep.lto.Never() { + if dep, ok := dep.(*Module); ok { if full && !dep.lto.FullLTO() { dep.lto.Properties.FullDep = true } - if thin && !dep.lto.ThinLTO() { + if !globalThinLTO && thin && !dep.lto.ThinLTO() { dep.lto.Properties.ThinDep = true } + if globalThinLTO && never && !dep.lto.Never() { + dep.lto.Properties.NoLtoDep = true + } } // Recursively walk static dependencies @@ -198,6 +205,8 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) { // Create lto variants for modules that need them func ltoMutator(mctx android.BottomUpMutatorContext) { + globalThinLTO := GlobalThinLTO(mctx) + if m, ok := mctx.Module().(*Module); ok && m.lto != nil { // Create variations for LTO types required as static // dependencies @@ -205,18 +214,25 @@ func ltoMutator(mctx android.BottomUpMutatorContext) { if m.lto.Properties.FullDep && !m.lto.FullLTO() { variationNames = append(variationNames, "lto-full") } - if m.lto.Properties.ThinDep && !m.lto.ThinLTO() { + if !globalThinLTO && m.lto.Properties.ThinDep && !m.lto.ThinLTO() { variationNames = append(variationNames, "lto-thin") } + if globalThinLTO && m.lto.Properties.NoLtoDep && !m.lto.Never() { + variationNames = append(variationNames, "lto-none") + } // Use correct dependencies if LTO property is explicitly set // (mutually exclusive) if m.lto.FullLTO() { mctx.SetDependencyVariation("lto-full") } - if m.lto.ThinLTO() { + if !globalThinLTO && m.lto.ThinLTO() { mctx.SetDependencyVariation("lto-thin") } + // Never must be the last, it overrides Thin or Full. + if globalThinLTO && m.lto.Never() { + mctx.SetDependencyVariation("lto-none") + } if len(variationNames) > 1 { modules := mctx.CreateVariations(variationNames...) @@ -232,16 +248,18 @@ func ltoMutator(mctx android.BottomUpMutatorContext) { // LTO properties for dependencies if name == "lto-full" { variation.lto.Properties.Lto.Full = proptools.BoolPtr(true) - variation.lto.Properties.Lto.Thin = proptools.BoolPtr(false) } if name == "lto-thin" { - variation.lto.Properties.Lto.Full = proptools.BoolPtr(false) variation.lto.Properties.Lto.Thin = proptools.BoolPtr(true) } + if name == "lto-none" { + variation.lto.Properties.Lto.Never = proptools.BoolPtr(true) + } variation.Properties.PreventInstall = true variation.Properties.HideFromMake = true variation.lto.Properties.FullDep = false variation.lto.Properties.ThinDep = false + variation.lto.Properties.NoLtoDep = false } } } diff --git a/cc/object.go b/cc/object.go index d8bb08fac..43abb3a3c 100644 --- a/cc/object.go +++ b/cc/object.go @@ -54,7 +54,7 @@ type objectBazelHandler struct { func (handler *objectBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool { bazelCtx := ctx.Config().BazelContext - objPaths, ok := bazelCtx.GetOutputFiles(label, ctx.Arch().ArchType) + objPaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx)) if ok { if len(objPaths) != 1 { ctx.ModuleErrorf("expected exactly one object file for '%s', but got %s", label, objPaths) diff --git a/cc/prebuilt.go b/cc/prebuilt.go index d324241e0..4a2c451f5 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -16,7 +16,6 @@ package cc import ( "path/filepath" - "strings" "android/soong/android" ) @@ -232,7 +231,7 @@ func (p *prebuiltLibraryLinker) disablePrebuilt() { // Implements versionedInterface func (p *prebuiltLibraryLinker) implementationModuleName(name string) string { - return strings.TrimPrefix(name, "prebuilt_") + return android.RemoveOptionalPrebuiltPrefix(name) } func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { @@ -330,7 +329,7 @@ type prebuiltStaticLibraryBazelHandler struct { func (h *prebuiltStaticLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool { bazelCtx := ctx.Config().BazelContext - ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType) + ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx)) if err != nil { ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err) } |