diff options
Diffstat (limited to 'cc')
| -rw-r--r-- | cc/binary.go | 13 | ||||
| -rw-r--r-- | cc/bp2build.go | 95 | ||||
| -rw-r--r-- | cc/builder.go | 23 | ||||
| -rw-r--r-- | cc/cc.go | 16 | ||||
| -rw-r--r-- | cc/compiler.go | 6 | ||||
| -rw-r--r-- | cc/config/global.go | 4 | ||||
| -rw-r--r-- | cc/libbuildversion/Android.bp | 1 | ||||
| -rw-r--r-- | cc/libbuildversion/libbuildversion.cpp | 4 | ||||
| -rw-r--r-- | cc/library.go | 146 | ||||
| -rw-r--r-- | cc/library_test.go | 26 | ||||
| -rw-r--r-- | cc/linkable.go | 4 | ||||
| -rw-r--r-- | cc/ndk_sysroot.go | 15 | ||||
| -rw-r--r-- | cc/pgo.go | 8 | ||||
| -rw-r--r-- | cc/proto.go | 76 | ||||
| -rw-r--r-- | cc/sanitize.go | 4 | ||||
| -rw-r--r-- | cc/tidy.go | 152 |
16 files changed, 457 insertions, 136 deletions
diff --git a/cc/binary.go b/cc/binary.go index a5afb0725..3f951eca5 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -18,6 +18,7 @@ import ( "path/filepath" "github.com/google/blueprint" + "github.com/google/blueprint/proptools" "android/soong/android" "android/soong/bazel" @@ -388,7 +389,7 @@ func (binary *binaryDecorator) link(ctx ModuleContext, } } - var validations android.WritablePaths + var validations android.Paths // Handle host bionic linker symbols. if ctx.Os() == android.LinuxBionic && !binary.static() { @@ -411,6 +412,7 @@ func (binary *binaryDecorator) link(ctx ModuleContext, linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...) linkerDeps = append(linkerDeps, deps.SharedLibsDeps...) linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) + linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...) } validations = append(validations, objs.tidyFiles...) @@ -578,9 +580,16 @@ func binaryBp2build(ctx android.TopDownMutatorContext, typ string) { } baseAttrs := bp2BuildParseBaseProps(ctx, m) + binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m) + + if proptools.BoolDefault(binaryLinkerAttrs.Linkshared, true) { + baseAttrs.implementationDynamicDeps.Add(baseAttrs.protoDependency) + } else { + baseAttrs.implementationDeps.Add(baseAttrs.protoDependency) + } attrs := &binaryAttributes{ - binaryLinkerAttrs: bp2buildBinaryLinkerProps(ctx, m), + binaryLinkerAttrs: binaryLinkerAttrs, Srcs: baseAttrs.srcs, Srcs_c: baseAttrs.cSrcs, diff --git a/cc/bp2build.go b/cc/bp2build.go index 888c3bacb..f9bbe8752 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -27,9 +27,10 @@ import ( ) const ( - cSrcPartition = "c" - asSrcPartition = "as" - cppSrcPartition = "cpp" + cSrcPartition = "c" + asSrcPartition = "as" + cppSrcPartition = "cpp" + protoSrcPartition = "proto" ) // staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties -- @@ -41,52 +42,53 @@ type staticOrSharedAttributes struct { Hdrs bazel.LabelListAttribute Copts bazel.StringListAttribute - Deps bazel.LabelListAttribute - Implementation_deps bazel.LabelListAttribute - Dynamic_deps bazel.LabelListAttribute - Implementation_dynamic_deps bazel.LabelListAttribute - Whole_archive_deps bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Implementation_deps bazel.LabelListAttribute + Dynamic_deps bazel.LabelListAttribute + Implementation_dynamic_deps bazel.LabelListAttribute + Whole_archive_deps bazel.LabelListAttribute + Implementation_whole_archive_deps bazel.LabelListAttribute System_dynamic_deps bazel.LabelListAttribute } func groupSrcsByExtension(ctx android.BazelConversionPathContext, 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" { - return false - } - labelParts := strings.Split(fullLabel, ":") - if len(labelParts) > 2 { - // There should not be more than one colon in a label. - ctx.ModuleErrorf("%s is not a valid Bazel label for a filegroup", fullLabel) - } - return m.Name() == labelParts[len(labelParts)-1] + // Check that a module is a filegroup type + isFilegroup := func(m blueprint.Module) bool { + return ctx.OtherModuleType(m) == "filegroup" } // Convert filegroup dependencies into extension-specific filegroups filtered in the filegroup.bzl // macro. addSuffixForFilegroup := func(suffix string) bazel.LabelMapper { - return func(ctx bazel.OtherModuleContext, label string) (string, bool) { - m, exists := ctx.ModuleFromName(label) - if !exists { - return label, false + return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) { + m, exists := ctx.ModuleFromName(label.OriginalModuleName) + labelStr := label.Label + if !exists || !isFilegroup(m) { + return labelStr, false } - aModule, _ := m.(android.Module) - if !isFilegroupNamed(aModule, label) { - return label, false - } - return label + suffix, true + return labelStr + suffix, true } } + isProtoFilegroup := func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) { + m, exists := ctx.ModuleFromName(label.OriginalModuleName) + labelStr := label.Label + if !exists || !isFilegroup(m) { + return labelStr, false + } + likelyProtos := strings.HasSuffix(labelStr, "proto") || strings.HasSuffix(labelStr, "protos") + return labelStr, likelyProtos + } + // TODO(b/190006308): Handle language detection of sources in a Bazel rule. partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{ 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. - cppSrcPartition: 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}, + protoSrcPartition: bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup}, }) return partitioned @@ -195,6 +197,11 @@ func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, mo attrs.Srcs_c = partitionedSrcs[cSrcPartition] attrs.Srcs_as = partitionedSrcs[asSrcPartition] + if !partitionedSrcs[protoSrcPartition].IsEmpty() { + // TODO(b/208815215): determine whether this is used and add support if necessary + ctx.ModuleErrorf("Migrating static/shared only proto srcs is not currently supported") + } + return attrs } @@ -230,6 +237,8 @@ func Bp2BuildParsePrebuiltLibraryProps(ctx android.BazelConversionPathContext, m type baseAttributes struct { compilerAttributes linkerAttributes + + protoDependency *bazel.LabelAttribute } // Convenience struct to hold all attributes parsed from compiler properties. @@ -257,6 +266,8 @@ type compilerAttributes struct { localIncludes bazel.StringListAttribute absoluteIncludes bazel.StringListAttribute + + protoSrcs bazel.LabelListAttribute } func parseCommandLineFlags(soongFlags []string) []string { @@ -337,6 +348,8 @@ func (ca *compilerAttributes) finalize(ctx android.BazelConversionPathContext, i ca.srcs.ResolveExcludes() partitionedSrcs := groupSrcsByExtension(ctx, ca.srcs) + ca.protoSrcs = partitionedSrcs[protoSrcPartition] + for p, lla := range partitionedSrcs { // if there are no sources, there is no need for headers if lla.IsEmpty() { @@ -400,7 +413,7 @@ func bp2buildResolveCppStdValue(c_std *string, cpp_std *string, gnu_extensions * } // bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes. -func bp2BuildParseBaseProps(ctx android.BazelConversionPathContext, module *Module) baseAttributes { +func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes { archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) @@ -456,20 +469,30 @@ func bp2BuildParseBaseProps(ctx android.BazelConversionPathContext, module *Modu (&compilerAttrs).finalize(ctx, implementationHdrs) (&linkerAttrs).finalize() + protoDep := bp2buildProto(ctx, module, compilerAttrs.protoSrcs) + + // bp2buildProto will only set wholeStaticLib or implementationWholeStaticLib, but we don't know + // which. This will add the newly generated proto library to the appropriate attribute and nothing + // to the other + (&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib) + (&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib) + return baseAttributes{ compilerAttrs, linkerAttrs, + protoDep.protoDep, } } // Convenience struct to hold all attributes parsed from linker properties. type linkerAttributes struct { - deps bazel.LabelListAttribute - implementationDeps bazel.LabelListAttribute - dynamicDeps bazel.LabelListAttribute - implementationDynamicDeps bazel.LabelListAttribute - wholeArchiveDeps bazel.LabelListAttribute - systemDynamicDeps bazel.LabelListAttribute + deps bazel.LabelListAttribute + implementationDeps bazel.LabelListAttribute + dynamicDeps bazel.LabelListAttribute + implementationDynamicDeps bazel.LabelListAttribute + wholeArchiveDeps bazel.LabelListAttribute + implementationWholeArchiveDeps bazel.LabelListAttribute + systemDynamicDeps bazel.LabelListAttribute linkCrt bazel.BoolAttribute useLibcrt bazel.BoolAttribute diff --git a/cc/builder.go b/cc/builder.go index fea65d581..7161ccf83 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -413,7 +413,7 @@ type StripFlags struct { // Objects is a collection of file paths corresponding to outputs for C++ related build statements. type Objects struct { objFiles android.Paths - tidyFiles android.WritablePaths + tidyFiles android.Paths coverageFiles android.Paths sAbiDumpFiles android.Paths kytheFiles android.Paths @@ -422,7 +422,7 @@ type Objects struct { func (a Objects) Copy() Objects { return Objects{ objFiles: append(android.Paths{}, a.objFiles...), - tidyFiles: append(android.WritablePaths{}, a.tidyFiles...), + tidyFiles: append(android.Paths{}, a.tidyFiles...), coverageFiles: append(android.Paths{}, a.coverageFiles...), sAbiDumpFiles: append(android.Paths{}, a.sAbiDumpFiles...), kytheFiles: append(android.Paths{}, a.kytheFiles...), @@ -451,11 +451,11 @@ func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, no // Source files are one-to-one with tidy, coverage, or kythe files, if enabled. objFiles := make(android.Paths, len(srcFiles)) - var tidyFiles android.WritablePaths + var tidyFiles android.Paths noTidySrcsMap := make(map[android.Path]bool) var tidyVars string if flags.tidy { - tidyFiles = make(android.WritablePaths, 0, len(srcFiles)) + tidyFiles = make(android.Paths, 0, len(srcFiles)) for _, path := range noTidySrcs { noTidySrcsMap[path] = true } @@ -549,10 +549,6 @@ func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, no return "$" + kind + n } - // clang-tidy checks source files and does not need to link with libraries. - // tidyPathDeps should contain pathDeps but not libraries. - tidyPathDeps := skipNdkLibraryDeps(ctx, pathDeps) - for i, srcFile := range srcFiles { objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o") @@ -669,14 +665,13 @@ func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, no rule = clangTidyRE } - ctx.TidyFile(tidyFile) ctx.Build(pctx, android.BuildParams{ Rule: rule, Description: "clang-tidy " + srcFile.Rel(), Output: tidyFile, Input: srcFile, Implicits: cFlagsDeps, - OrderOnly: tidyPathDeps, + OrderOnly: pathDeps, Args: map[string]string{ "ccCmd": ccCmd, "cFlags": shareFlags("cFlags", escapeSingleQuotes(moduleToolingFlags)), @@ -723,7 +718,7 @@ func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, no // Generate a rule for compiling multiple .o files to a static library (.a) func transformObjToStaticLib(ctx android.ModuleContext, objFiles android.Paths, wholeStaticLibs android.Paths, - flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths, validations android.WritablePaths) { + flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths, validations android.Paths) { arCmd := "${config.ClangBin}/llvm-ar" arFlags := "" @@ -738,7 +733,7 @@ func transformObjToStaticLib(ctx android.ModuleContext, Output: outputFile, Inputs: objFiles, Implicits: deps, - Validations: validations.Paths(), + Validations: validations, Args: map[string]string{ "arFlags": "crsPD" + arFlags, "arCmd": arCmd, @@ -768,7 +763,7 @@ func transformObjToStaticLib(ctx android.ModuleContext, func transformObjToDynamicBinary(ctx android.ModuleContext, objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps, crtBegin, crtEnd android.Paths, groupLate bool, flags builderFlags, outputFile android.WritablePath, - implicitOutputs android.WritablePaths, validations android.WritablePaths) { + implicitOutputs android.WritablePaths, validations android.Paths) { ldCmd := "${config.ClangBin}/clang++" @@ -835,7 +830,7 @@ func transformObjToDynamicBinary(ctx android.ModuleContext, Inputs: objFiles, Implicits: deps, OrderOnly: sharedLibs, - Validations: validations.Paths(), + Validations: validations, Args: args, }) } @@ -815,6 +815,10 @@ type Module struct { makeLinkType string // Kythe (source file indexer) paths for this compilation module kytheFiles android.Paths + // Object .o file output paths for this compilation module + objFiles android.Paths + // Tidy .tidy file output paths for this compilation module + tidyFiles android.Paths // For apex variants, this is set as apex.min_sdk_version apexSdkVersion android.ApiLevel @@ -1713,7 +1717,15 @@ func (c *Module) setSubnameProperty(actx android.ModuleContext) { // Returns true if Bazel was successfully used for the analysis of this module. func (c *Module) maybeGenerateBazelActions(actx android.ModuleContext) bool { - bazelModuleLabel := c.GetBazelLabel(actx, c) + var bazelModuleLabel string + if actx.ModuleType() == "cc_library" && c.static() { + // cc_library is a special case in bp2build; two targets are generated -- one for each + // of the shared and static variants. The shared variant keeps the module name, but the + // static variant uses a different suffixed name. + bazelModuleLabel = bazelLabelForStaticModule(actx, c) + } else { + bazelModuleLabel = c.GetBazelLabel(actx, c) + } bazelActionsUsed := false // Mixed builds mode is disabled for modules outside of device OS. // TODO(b/200841190): Support non-device OS in mixed builds. @@ -1827,6 +1839,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { return } c.kytheFiles = objs.kytheFiles + c.objFiles = objs.objFiles + c.tidyFiles = objs.tidyFiles } if c.linker != nil { diff --git a/cc/compiler.go b/cc/compiler.go index 2e62b0002..8adc3ab16 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -637,9 +637,9 @@ var gnuToCReplacer = strings.NewReplacer("gnu", "c") func ndkPathDeps(ctx ModuleContext) android.Paths { if ctx.Module().(*Module).IsSdkVariant() { - // The NDK sysroot timestamp file depends on all the NDK sysroot files - // (headers and libraries). - return android.Paths{getNdkBaseTimestampFile(ctx)} + // The NDK sysroot timestamp file depends on all the NDK sysroot header files + // for compiling src to obj files. + return android.Paths{getNdkHeadersTimestampFile(ctx)} } return nil } diff --git a/cc/config/global.go b/cc/config/global.go index 0b229be76..a340e465e 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -46,7 +46,6 @@ var ( "-O2", "-g", - "-fdebug-info-for-profiling", "-fno-strict-aliasing", @@ -125,6 +124,9 @@ var ( "-Werror=sequence-point", "-Werror=format-security", "-nostdlibinc", + + // Emit additional debug info for AutoFDO + "-fdebug-info-for-profiling", } deviceGlobalCppflags = []string{ diff --git a/cc/libbuildversion/Android.bp b/cc/libbuildversion/Android.bp index 2cff99435..b105a3029 100644 --- a/cc/libbuildversion/Android.bp +++ b/cc/libbuildversion/Android.bp @@ -19,4 +19,5 @@ cc_library_static { "//apex_available:platform", "//apex_available:anyapex", ], + vendor_available: true, } diff --git a/cc/libbuildversion/libbuildversion.cpp b/cc/libbuildversion/libbuildversion.cpp index 5242025eb..1e01c1145 100644 --- a/cc/libbuildversion/libbuildversion.cpp +++ b/cc/libbuildversion/libbuildversion.cpp @@ -36,7 +36,11 @@ std::string GetBuildNumber() { return soong_build_number; } +#ifdef __ANDROID_VENDOR__ + const prop_info* pi = __system_property_find("ro.vendor.build.version.incremental"); +#else const prop_info* pi = __system_property_find("ro.build.version.incremental"); +#endif if (pi == nullptr) return ""; std::string property_value; diff --git a/cc/library.go b/cc/library.go index 3dceda0a3..e53aac0c6 100644 --- a/cc/library.go +++ b/cc/library.go @@ -236,12 +236,13 @@ type bazelCcLibraryAttributes struct { Hdrs bazel.LabelListAttribute - Deps bazel.LabelListAttribute - Implementation_deps bazel.LabelListAttribute - Dynamic_deps bazel.LabelListAttribute - Implementation_dynamic_deps bazel.LabelListAttribute - Whole_archive_deps bazel.LabelListAttribute - System_dynamic_deps bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Implementation_deps bazel.LabelListAttribute + Dynamic_deps bazel.LabelListAttribute + Implementation_dynamic_deps bazel.LabelListAttribute + Whole_archive_deps bazel.LabelListAttribute + Implementation_whole_archive_deps bazel.LabelListAttribute + System_dynamic_deps bazel.LabelListAttribute Export_includes bazel.StringListAttribute Export_system_includes bazel.StringListAttribute @@ -303,40 +304,83 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { srcs := compilerAttrs.srcs + sharedAttrs.Dynamic_deps.Add(baseAttributes.protoDependency) + staticAttrs.Deps.Add(baseAttributes.protoDependency) + asFlags := compilerAttrs.asFlags if compilerAttrs.asSrcs.IsEmpty() && sharedAttrs.Srcs_as.IsEmpty() && staticAttrs.Srcs_as.IsEmpty() { // Skip asflags for BUILD file simplicity if there are no assembly sources. asFlags = bazel.MakeStringListAttribute(nil) } - attrs := &bazelCcLibraryAttributes{ - Srcs: srcs, - Srcs_c: compilerAttrs.cSrcs, - Srcs_as: compilerAttrs.asSrcs, - Hdrs: compilerAttrs.hdrs, + staticCommonAttrs := staticOrSharedAttributes{ + Srcs: *srcs.Clone().Append(staticAttrs.Srcs), + Srcs_c: *compilerAttrs.cSrcs.Clone().Append(staticAttrs.Srcs_c), + Srcs_as: *compilerAttrs.asSrcs.Clone().Append(staticAttrs.Srcs_as), + Copts: *compilerAttrs.copts.Clone().Append(staticAttrs.Copts), + Hdrs: *compilerAttrs.hdrs.Clone().Append(staticAttrs.Hdrs), + + Deps: *linkerAttrs.deps.Clone().Append(staticAttrs.Deps), + Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(staticAttrs.Implementation_deps), + Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(staticAttrs.Dynamic_deps), + Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(staticAttrs.Implementation_dynamic_deps), + Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps, + Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(staticAttrs.Whole_archive_deps), + System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(staticAttrs.System_dynamic_deps), + } + + sharedCommonAttrs := staticOrSharedAttributes{ + Srcs: *srcs.Clone().Append(sharedAttrs.Srcs), + Srcs_c: *compilerAttrs.cSrcs.Clone().Append(sharedAttrs.Srcs_c), + Srcs_as: *compilerAttrs.asSrcs.Clone().Append(sharedAttrs.Srcs_as), + Copts: *compilerAttrs.copts.Clone().Append(sharedAttrs.Copts), + Hdrs: *compilerAttrs.hdrs.Clone().Append(sharedAttrs.Hdrs), + + Deps: *linkerAttrs.deps.Clone().Append(sharedAttrs.Deps), + Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(sharedAttrs.Implementation_deps), + Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(sharedAttrs.Dynamic_deps), + Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(sharedAttrs.Implementation_dynamic_deps), + Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(sharedAttrs.Whole_archive_deps), + System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps), + } + + staticTargetAttrs := &bazelCcLibraryStaticAttributes{ + staticOrSharedAttributes: staticCommonAttrs, - Copts: compilerAttrs.copts, Cppflags: compilerAttrs.cppFlags, Conlyflags: compilerAttrs.conlyFlags, Asflags: asFlags, - Implementation_deps: linkerAttrs.implementationDeps, - Deps: linkerAttrs.deps, - Implementation_dynamic_deps: linkerAttrs.implementationDynamicDeps, - Dynamic_deps: linkerAttrs.dynamicDeps, - Whole_archive_deps: linkerAttrs.wholeArchiveDeps, - System_dynamic_deps: linkerAttrs.systemDynamicDeps, - Export_includes: exportedIncludes.Includes, - Export_system_includes: exportedIncludes.SystemIncludes, - 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, - C_std: compilerAttrs.cStd, + Export_includes: exportedIncludes.Includes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, + Use_libcrt: linkerAttrs.useLibcrt, + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + C_std: compilerAttrs.cStd, + + Features: linkerAttrs.features, + } + + sharedTargetAttrs := &bazelCcLibrarySharedAttributes{ + staticOrSharedAttributes: sharedCommonAttrs, + Cppflags: compilerAttrs.cppFlags, + Conlyflags: compilerAttrs.conlyFlags, + Asflags: asFlags, + + Export_includes: exportedIncludes.Includes, + Export_system_includes: exportedIncludes.SystemIncludes, + 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, + C_std: compilerAttrs.cStd, Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, @@ -347,20 +391,20 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { All: linkerAttrs.stripAll, None: linkerAttrs.stripNone, }, - - Shared: sharedAttrs, - - Static: staticAttrs, - Features: linkerAttrs.features, } - props := bazel.BazelTargetModuleProperties{ - Rule_class: "cc_library", - Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl", + staticProps := bazel.BazelTargetModuleProperties{ + Rule_class: "cc_library_static", + Bzl_load_location: "//build/bazel/rules:cc_library_static.bzl", + } + sharedProps := bazel.BazelTargetModuleProperties{ + Rule_class: "cc_library_shared", + Bzl_load_location: "//build/bazel/rules:cc_library_shared.bzl", } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) + ctx.CreateBazelTargetModule(staticProps, android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"}, staticTargetAttrs) + ctx.CreateBazelTargetModule(sharedProps, android.CommonAttributes{Name: m.Name()}, sharedTargetAttrs) } // cc_library creates both static and/or shared libraries for a device and/or @@ -1322,11 +1366,21 @@ func (library *libraryDecorator) linkStatic(ctx ModuleContext, return outputFile } +func ndkSharedLibDeps(ctx ModuleContext) android.Paths { + if ctx.Module().(*Module).IsSdkVariant() { + // The NDK sysroot timestamp file depends on all the NDK + // sysroot header and shared library files. + return android.Paths{getNdkBaseTimestampFile(ctx)} + } + return nil +} + func (library *libraryDecorator) linkShared(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { var linkerDeps android.Paths linkerDeps = append(linkerDeps, flags.LdFlagsDeps...) + linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...) unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list") forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list") @@ -2405,16 +2459,18 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, Copts: compilerAttrs.copts, Hdrs: compilerAttrs.hdrs, - Deps: linkerAttrs.deps, - Implementation_deps: linkerAttrs.implementationDeps, - Dynamic_deps: linkerAttrs.dynamicDeps, - Implementation_dynamic_deps: linkerAttrs.implementationDynamicDeps, - Whole_archive_deps: linkerAttrs.wholeArchiveDeps, - System_dynamic_deps: linkerAttrs.systemDynamicDeps, + Deps: linkerAttrs.deps, + Implementation_deps: linkerAttrs.implementationDeps, + Dynamic_deps: linkerAttrs.dynamicDeps, + Implementation_dynamic_deps: linkerAttrs.implementationDynamicDeps, + Whole_archive_deps: linkerAttrs.wholeArchiveDeps, + Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps, + System_dynamic_deps: linkerAttrs.systemDynamicDeps, } var attrs interface{} if isStatic { + commonAttrs.Deps.Add(baseAttributes.protoDependency) attrs = &bazelCcLibraryStaticAttributes{ staticOrSharedAttributes: commonAttrs, @@ -2435,6 +2491,8 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, Features: linkerAttrs.features, } } else { + commonAttrs.Dynamic_deps.Add(baseAttributes.protoDependency) + attrs = &bazelCcLibrarySharedAttributes{ staticOrSharedAttributes: commonAttrs, diff --git a/cc/library_test.go b/cc/library_test.go index 7ddfaa7fd..d220e19f8 100644 --- a/cc/library_test.go +++ b/cc/library_test.go @@ -257,9 +257,16 @@ cc_library { CcObjectFiles: []string{"foo.o"}, Includes: []string{"include"}, SystemIncludes: []string{"system_include"}, - RootStaticArchives: []string{"foo.a"}, + Headers: []string{"foo.h"}, RootDynamicLibraries: []string{"foo.so"}, }, + "//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{ + CcObjectFiles: []string{"foo.o"}, + Includes: []string{"include"}, + SystemIncludes: []string{"system_include"}, + Headers: []string{"foo.h"}, + RootStaticArchives: []string{"foo.a"}, + }, }, } ctx := testCcWithConfig(t, config) @@ -273,18 +280,25 @@ cc_library { expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.a"} android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) + flagExporter := ctx.ModuleProvider(staticFoo, FlagExporterInfoProvider).(FlagExporterInfo) + android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs) + android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs) + android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders) + android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps) + sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module() outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("") if err != nil { - t.Errorf("Unexpected error getting cc_object outputfiles %s", err) + t.Errorf("Unexpected error getting cc_library outputfiles %s", err) } expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"} android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) - entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0] - expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"} - gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"] - android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags) + flagExporter = ctx.ModuleProvider(sharedFoo, FlagExporterInfoProvider).(FlagExporterInfo) + android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs) + android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs) + android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders) + android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps) } func TestLibraryVersionScript(t *testing.T) { diff --git a/cc/linkable.go b/cc/linkable.go index 560c9debe..02d7047bf 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -384,9 +384,13 @@ func flagExporterInfoFromCcInfo(ctx android.ModuleContext, ccInfo cquery.CcInfo) includes := android.PathsForBazelOut(ctx, ccInfo.Includes) systemIncludes := android.PathsForBazelOut(ctx, ccInfo.SystemIncludes) + headers := android.PathsForBazelOut(ctx, ccInfo.Headers) return FlagExporterInfo{ IncludeDirs: android.FirstUniquePaths(includes), SystemIncludeDirs: android.FirstUniquePaths(systemIncludes), + GeneratedHeaders: headers, + // necessary to ensure generated headers are considered implicit deps of dependent actions + Deps: headers, } } diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go index ee11db101..6c200f5dd 100644 --- a/cc/ndk_sysroot.go +++ b/cc/ndk_sysroot.go @@ -94,21 +94,6 @@ func getNdkFullTimestampFile(ctx android.PathContext) android.WritablePath { return android.PathForOutput(ctx, "ndk.timestamp") } -// Replace ndk_base.timestamp and ndk.timestamp with ndk_headers.timestamp. -func skipNdkLibraryDeps(ctx android.ModuleContext, paths android.Paths) android.Paths { - var newPaths android.Paths - baseTimestamp := getNdkBaseTimestampFile(ctx) - fullTimestamp := getNdkFullTimestampFile(ctx) - headersTimestamp := getNdkHeadersTimestampFile(ctx) - for _, path := range paths { - if path == baseTimestamp || path == fullTimestamp { - path = headersTimestamp - } - newPaths = append(newPaths, path) - } - return newPaths -} - func NdkSingleton() android.Singleton { return &ndkSingleton{} } @@ -96,10 +96,6 @@ func (props *PgoProperties) addInstrumentationProfileGatherFlags(ctx ModuleConte flags.Local.LdFlags = append(flags.Local.LdFlags, profileInstrumentFlag) return flags } -func (props *PgoProperties) addSamplingProfileGatherFlags(ctx ModuleContext, flags Flags) Flags { - flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...) - return flags -} func (props *PgoProperties) getPgoProfileFile(ctx BaseModuleContext) android.OptionalPath { profileFile := *props.Pgo.Profile_file @@ -313,10 +309,6 @@ func (pgo *pgo) flags(ctx ModuleContext, flags Flags) Flags { if (props.ShouldProfileModule && props.isInstrumentation()) || props.PgoInstrLink { // Instrumentation PGO use and gather flags cannot coexist. return props.addInstrumentationProfileGatherFlags(ctx, flags) - } else if props.ShouldProfileModule && props.isSampling() { - flags = props.addSamplingProfileGatherFlags(ctx, flags) - } else if ctx.DeviceConfig().SamplingPGO() { - flags = props.addSamplingProfileGatherFlags(ctx, flags) } if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") { diff --git a/cc/proto.go b/cc/proto.go index 44661447c..f3410bc2b 100644 --- a/cc/proto.go +++ b/cc/proto.go @@ -16,8 +16,14 @@ package cc import ( "github.com/google/blueprint/pathtools" + "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/bazel" +) + +const ( + protoTypeDefault = "lite" ) // genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns @@ -63,7 +69,7 @@ func protoDeps(ctx DepsContext, deps Deps, p *android.ProtoProperties, static bo var lib string if String(p.Proto.Plugin) == "" { - switch String(p.Proto.Type) { + switch proptools.StringDefault(p.Proto.Type, protoTypeDefault) { case "full": if ctx.useSdk() { lib = "libprotobuf-cpp-full-ndk" @@ -71,7 +77,7 @@ func protoDeps(ctx DepsContext, deps Deps, p *android.ProtoProperties, static bo } else { lib = "libprotobuf-cpp-full" } - case "lite", "": + case "lite": if ctx.useSdk() { lib = "libprotobuf-cpp-lite-ndk" static = true @@ -157,3 +163,69 @@ func protoFlags(ctx ModuleContext, flags Flags, p *android.ProtoProperties) Flag return flags } + +type protoAttributes struct { + Deps bazel.LabelListAttribute +} + +type bp2buildProtoDeps struct { + wholeStaticLib *bazel.LabelAttribute + implementationWholeStaticLib *bazel.LabelAttribute + protoDep *bazel.LabelAttribute +} + +func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) bp2buildProtoDeps { + var ret bp2buildProtoDeps + + protoInfo, ok := android.Bp2buildProtoProperties(ctx, m, protoSrcs) + if !ok { + return ret + } + + var depName string + typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault) + var rule_class string + suffix := "_cc_proto" + switch typ { + case "lite": + suffix += "_lite" + rule_class = "cc_lite_proto_library" + depName = "libprotobuf-cpp-lite" + case "full": + rule_class = "cc_proto_library" + depName = "libprotobuf-cpp-full" + default: + ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ) + } + + dep := android.BazelLabelForModuleDepSingle(ctx, depName) + ret.protoDep = &bazel.LabelAttribute{Value: &dep} + + protoLabel := bazel.Label{Label: ":" + protoInfo.Name} + var protoAttrs protoAttributes + protoAttrs.Deps.SetValue(bazel.LabelList{Includes: []bazel.Label{protoLabel}}) + + name := m.Name() + suffix + + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: rule_class, + Bzl_load_location: "//build/bazel/rules:cc_proto.bzl", + }, + android.CommonAttributes{Name: name}, + &protoAttrs) + + var privateHdrs bool + if lib, ok := m.linker.(*libraryDecorator); ok { + privateHdrs = !proptools.Bool(lib.Properties.Proto.Export_proto_headers) + } + + labelAttr := &bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + name}} + if privateHdrs { + ret.implementationWholeStaticLib = labelAttr + } else { + ret.wholeStaticLib = labelAttr + } + + return ret +} diff --git a/cc/sanitize.go b/cc/sanitize.go index 93d4b4c54..d7b1adee5 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -35,7 +35,6 @@ var ( asanCflags = []string{ "-fno-omit-frame-pointer", - "-fno-experimental-new-pass-manager", } asanLdflags = []string{"-Wl,-u,__asan_preinit"} @@ -666,9 +665,6 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-coverage=stack-depth") flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-coverage=stack-depth") - // TODO(b/133876586): Experimental PM breaks sanitizer coverage. - flags.Local.CFlags = append(flags.Local.CFlags, "-fno-experimental-new-pass-manager") - // Disable fortify for fuzzing builds. Generally, we'll be building with // UBSan or ASan here and the fortify checks pollute the stack traces. flags.Local.CFlags = append(flags.Local.CFlags, "-U_FORTIFY_SOURCE") diff --git a/cc/tidy.go b/cc/tidy.go index 53ff1564b..78a791faf 100644 --- a/cc/tidy.go +++ b/cc/tidy.go @@ -15,6 +15,7 @@ package cc import ( + "path/filepath" "regexp" "strings" @@ -183,3 +184,154 @@ func (tidy *tidyFeature) flags(ctx ModuleContext, flags Flags) Flags { } return flags } + +func init() { + android.RegisterSingletonType("tidy_phony_targets", TidyPhonySingleton) +} + +// This TidyPhonySingleton generates both tidy-* and obj-* phony targets for C/C++ files. +func TidyPhonySingleton() android.Singleton { + return &tidyPhonySingleton{} +} + +type tidyPhonySingleton struct{} + +// Given a final module, add its tidy/obj phony targets to tidy/objModulesInDirGroup. +func collectTidyObjModuleTargets(ctx android.SingletonContext, module android.Module, + tidyModulesInDirGroup, objModulesInDirGroup map[string]map[string]android.Paths) { + allObjFileGroups := make(map[string]android.Paths) // variant group name => obj file Paths + allTidyFileGroups := make(map[string]android.Paths) // variant group name => tidy file Paths + subsetObjFileGroups := make(map[string]android.Paths) // subset group name => obj file Paths + subsetTidyFileGroups := make(map[string]android.Paths) // subset group name => tidy file Paths + + // (1) Collect all obj/tidy files into OS-specific groups. + ctx.VisitAllModuleVariants(module, func(variant android.Module) { + if ctx.Config().KatiEnabled() && android.ShouldSkipAndroidMkProcessing(variant) { + return + } + if m, ok := variant.(*Module); ok { + osName := variant.Target().Os.Name + addToOSGroup(osName, m.objFiles, allObjFileGroups, subsetObjFileGroups) + addToOSGroup(osName, m.tidyFiles, allTidyFileGroups, subsetTidyFileGroups) + } + }) + + // (2) Add an all-OS group, with "" or "subset" name, to include all os-specific phony targets. + addAllOSGroup(ctx, module, allObjFileGroups, "", "obj") + addAllOSGroup(ctx, module, allTidyFileGroups, "", "tidy") + addAllOSGroup(ctx, module, subsetObjFileGroups, "subset", "obj") + addAllOSGroup(ctx, module, subsetTidyFileGroups, "subset", "tidy") + + tidyTargetGroups := make(map[string]android.Path) + objTargetGroups := make(map[string]android.Path) + genObjTidyPhonyTargets(ctx, module, "obj", allObjFileGroups, objTargetGroups) + genObjTidyPhonyTargets(ctx, module, "obj", subsetObjFileGroups, objTargetGroups) + genObjTidyPhonyTargets(ctx, module, "tidy", allTidyFileGroups, tidyTargetGroups) + genObjTidyPhonyTargets(ctx, module, "tidy", subsetTidyFileGroups, tidyTargetGroups) + + moduleDir := ctx.ModuleDir(module) + appendToModulesInDirGroup(tidyTargetGroups, moduleDir, tidyModulesInDirGroup) + appendToModulesInDirGroup(objTargetGroups, moduleDir, objModulesInDirGroup) +} + +func (m *tidyPhonySingleton) GenerateBuildActions(ctx android.SingletonContext) { + // For tidy-* directory phony targets, there are different variant groups. + // tidyModulesInDirGroup[G][D] is for group G, directory D, with Paths + // of all phony targets to be included into direct dependents of tidy-D_G. + tidyModulesInDirGroup := make(map[string]map[string]android.Paths) + // Also for obj-* directory phony targets. + objModulesInDirGroup := make(map[string]map[string]android.Paths) + + // Collect tidy/obj targets from the 'final' modules. + ctx.VisitAllModules(func(module android.Module) { + if module == ctx.FinalModule(module) { + collectTidyObjModuleTargets(ctx, module, tidyModulesInDirGroup, objModulesInDirGroup) + } + }) + + suffix := "" + if ctx.Config().KatiEnabled() { + suffix = "-soong" + } + generateObjTidyPhonyTargets(ctx, suffix, "obj", objModulesInDirGroup) + generateObjTidyPhonyTargets(ctx, suffix, "tidy", tidyModulesInDirGroup) +} + +// The name for an obj/tidy module variant group phony target is Name_group-obj/tidy, +func objTidyModuleGroupName(module android.Module, group string, suffix string) string { + if group == "" { + return module.Name() + "-" + suffix + } + return module.Name() + "_" + group + "-" + suffix +} + +// Generate obj-* or tidy-* phony targets. +func generateObjTidyPhonyTargets(ctx android.SingletonContext, suffix string, prefix string, objTidyModulesInDirGroup map[string]map[string]android.Paths) { + // For each variant group, create a <prefix>-<directory>_group target that + // depends on all subdirectories and modules in the directory. + for group, modulesInDir := range objTidyModulesInDirGroup { + groupSuffix := "" + if group != "" { + groupSuffix = "_" + group + } + mmTarget := func(dir string) string { + return prefix + "-" + strings.Replace(filepath.Clean(dir), "/", "-", -1) + groupSuffix + } + dirs, topDirs := android.AddAncestors(ctx, modulesInDir, mmTarget) + // Create a <prefix>-soong_group target that depends on all <prefix>-dir_group of top level dirs. + var topDirPaths android.Paths + for _, dir := range topDirs { + topDirPaths = append(topDirPaths, android.PathForPhony(ctx, mmTarget(dir))) + } + ctx.Phony(prefix+suffix+groupSuffix, topDirPaths...) + // Create a <prefix>-dir_group target that depends on all targets in modulesInDir[dir] + for _, dir := range dirs { + if dir != "." && dir != "" { + ctx.Phony(mmTarget(dir), modulesInDir[dir]...) + } + } + } +} + +// Append (obj|tidy)TargetGroups[group] into (obj|tidy)ModulesInDirGroups[group][moduleDir]. +func appendToModulesInDirGroup(targetGroups map[string]android.Path, moduleDir string, modulesInDirGroup map[string]map[string]android.Paths) { + for group, phonyPath := range targetGroups { + if _, found := modulesInDirGroup[group]; !found { + modulesInDirGroup[group] = make(map[string]android.Paths) + } + modulesInDirGroup[group][moduleDir] = append(modulesInDirGroup[group][moduleDir], phonyPath) + } +} + +// Add given files to the OS group and subset group. +func addToOSGroup(osName string, files android.Paths, allGroups, subsetGroups map[string]android.Paths) { + if len(files) > 0 { + subsetName := osName + "_subset" + allGroups[osName] = append(allGroups[osName], files...) + // Now include only the first variant in the subsetGroups. + // If clang and clang-tidy get faster, we might include more variants. + if _, found := subsetGroups[subsetName]; !found { + subsetGroups[subsetName] = files + } + } +} + +// Add an all-OS group, with groupName, to include all os-specific phony targets. +func addAllOSGroup(ctx android.SingletonContext, module android.Module, phonyTargetGroups map[string]android.Paths, groupName string, objTidyName string) { + if len(phonyTargetGroups) > 0 { + var targets android.Paths + for group, _ := range phonyTargetGroups { + targets = append(targets, android.PathForPhony(ctx, objTidyModuleGroupName(module, group, objTidyName))) + } + phonyTargetGroups[groupName] = targets + } +} + +// Create one phony targets for each group and add them to the targetGroups. +func genObjTidyPhonyTargets(ctx android.SingletonContext, module android.Module, objTidyName string, fileGroups map[string]android.Paths, targetGroups map[string]android.Path) { + for group, files := range fileGroups { + groupName := objTidyModuleGroupName(module, group, objTidyName) + ctx.Phony(groupName, files...) + targetGroups[group] = android.PathForPhony(ctx, groupName) + } +} |