1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package cc 16 17import ( 18 "fmt" 19 20 "android/soong/android" 21 "android/soong/bazel" 22) 23 24// 25// Objects (for crt*.o) 26// 27 28func init() { 29 android.RegisterModuleType("cc_object", ObjectFactory) 30 android.RegisterSdkMemberType(ccObjectSdkMemberType) 31 32} 33 34var ccObjectSdkMemberType = &librarySdkMemberType{ 35 SdkMemberTypeBase: android.SdkMemberTypeBase{ 36 PropertyName: "native_objects", 37 SupportsSdk: true, 38 }, 39 prebuiltModuleType: "cc_prebuilt_object", 40 linkTypes: nil, 41} 42 43type objectLinker struct { 44 *baseLinker 45 Properties ObjectLinkerProperties 46} 47 48type objectBazelHandler struct { 49 android.BazelHandler 50 51 module *Module 52} 53 54func (handler *objectBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool { 55 bazelCtx := ctx.Config().BazelContext 56 objPaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx)) 57 if ok { 58 if len(objPaths) != 1 { 59 ctx.ModuleErrorf("expected exactly one object file for '%s', but got %s", label, objPaths) 60 return false 61 } 62 63 handler.module.outputFile = android.OptionalPathForPath(android.PathForBazelOut(ctx, objPaths[0])) 64 } 65 return ok 66} 67 68type ObjectLinkerProperties struct { 69 // list of static library modules that should only provide headers for this module. 70 Static_libs []string `android:"arch_variant,variant_prepend"` 71 72 // list of shared library modules should only provide headers for this module. 73 Shared_libs []string `android:"arch_variant"` 74 75 // list of modules that should only provide headers for this module. 76 Header_libs []string `android:"arch_variant,variant_prepend"` 77 78 // list of default libraries that will provide headers for this module. If unset, generally 79 // defaults to libc, libm, and libdl. Set to [] to prevent using headers from the defaults. 80 System_shared_libs []string `android:"arch_variant"` 81 82 // names of other cc_object modules to link into this module using partial linking 83 Objs []string `android:"arch_variant"` 84 85 // if set, add an extra objcopy --prefix-symbols= step 86 Prefix_symbols *string 87 88 // if set, the path to a linker script to pass to ld -r when combining multiple object files. 89 Linker_script *string `android:"path,arch_variant"` 90 91 // Indicates that this module is a CRT object. CRT objects will be split 92 // into a variant per-API level between min_sdk_version and current. 93 Crt *bool 94} 95 96func newObject(hod android.HostOrDeviceSupported) *Module { 97 module := newBaseModule(hod, android.MultilibBoth) 98 module.sanitize = &sanitize{} 99 module.stl = &stl{} 100 return module 101} 102 103// cc_object runs the compiler without running the linker. It is rarely 104// necessary, but sometimes used to generate .s files from .c files to use as 105// input to a cc_genrule module. 106func ObjectFactory() android.Module { 107 module := newObject(android.HostAndDeviceSupported) 108 module.linker = &objectLinker{ 109 baseLinker: NewBaseLinker(module.sanitize), 110 } 111 module.compiler = NewBaseCompiler() 112 module.bazelHandler = &objectBazelHandler{module: module} 113 114 // Clang's address-significance tables are incompatible with ld -r. 115 module.compiler.appendCflags([]string{"-fno-addrsig"}) 116 117 module.sdkMemberTypes = []android.SdkMemberType{ccObjectSdkMemberType} 118 119 module.bazelable = true 120 return module.Init() 121} 122 123// For bp2build conversion. 124type bazelObjectAttributes struct { 125 Srcs bazel.LabelListAttribute 126 Srcs_as bazel.LabelListAttribute 127 Hdrs bazel.LabelListAttribute 128 Deps bazel.LabelListAttribute 129 System_dynamic_deps bazel.LabelListAttribute 130 Copts bazel.StringListAttribute 131 Asflags bazel.StringListAttribute 132 Local_includes bazel.StringListAttribute 133 Absolute_includes bazel.StringListAttribute 134 Stl *string 135 Linker_script bazel.LabelAttribute 136 sdkAttributes 137} 138 139// objectBp2Build is the bp2build converter from cc_object modules to the 140// Bazel equivalent target, plus any necessary include deps for the cc_object. 141func objectBp2Build(ctx android.TopDownMutatorContext, m *Module) { 142 if m.compiler == nil { 143 // a cc_object must have access to the compiler decorator for its props. 144 ctx.ModuleErrorf("compiler must not be nil for a cc_object module") 145 } 146 147 // Set arch-specific configurable attributes 148 baseAttributes := bp2BuildParseBaseProps(ctx, m) 149 compilerAttrs := baseAttributes.compilerAttributes 150 var deps bazel.LabelListAttribute 151 systemDynamicDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true} 152 153 var linkerScript bazel.LabelAttribute 154 155 for axis, configToProps := range m.GetArchVariantProperties(ctx, &ObjectLinkerProperties{}) { 156 for config, props := range configToProps { 157 if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok { 158 if objectLinkerProps.Linker_script != nil { 159 label := android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script) 160 linkerScript.SetSelectValue(axis, config, label) 161 } 162 deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs)) 163 systemSharedLibs := objectLinkerProps.System_shared_libs 164 if len(systemSharedLibs) > 0 { 165 systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs) 166 } 167 systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs)) 168 } 169 } 170 } 171 deps.ResolveExcludes() 172 173 // Don't split cc_object srcs across languages. Doing so would add complexity, 174 // and this isn't typically done for cc_object. 175 srcs := compilerAttrs.srcs 176 srcs.Append(compilerAttrs.cSrcs) 177 178 asFlags := compilerAttrs.asFlags 179 if compilerAttrs.asSrcs.IsEmpty() { 180 // Skip asflags for BUILD file simplicity if there are no assembly sources. 181 asFlags = bazel.MakeStringListAttribute(nil) 182 } 183 184 attrs := &bazelObjectAttributes{ 185 Srcs: srcs, 186 Srcs_as: compilerAttrs.asSrcs, 187 Deps: deps, 188 System_dynamic_deps: systemDynamicDeps, 189 Copts: compilerAttrs.copts, 190 Asflags: asFlags, 191 Local_includes: compilerAttrs.localIncludes, 192 Absolute_includes: compilerAttrs.absoluteIncludes, 193 Stl: compilerAttrs.stl, 194 Linker_script: linkerScript, 195 sdkAttributes: bp2BuildParseSdkAttributes(m), 196 } 197 198 props := bazel.BazelTargetModuleProperties{ 199 Rule_class: "cc_object", 200 Bzl_load_location: "//build/bazel/rules/cc:cc_object.bzl", 201 } 202 203 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) 204} 205 206func (object *objectLinker) appendLdflags(flags []string) { 207 panic(fmt.Errorf("appendLdflags on objectLinker not supported")) 208} 209 210func (object *objectLinker) linkerProps() []interface{} { 211 return []interface{}{&object.Properties} 212} 213 214func (*objectLinker) linkerInit(ctx BaseModuleContext) {} 215 216func (object *objectLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { 217 deps.HeaderLibs = append(deps.HeaderLibs, object.Properties.Header_libs...) 218 deps.SharedLibs = append(deps.SharedLibs, object.Properties.Shared_libs...) 219 deps.StaticLibs = append(deps.StaticLibs, object.Properties.Static_libs...) 220 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...) 221 222 deps.SystemSharedLibs = object.Properties.System_shared_libs 223 if deps.SystemSharedLibs == nil { 224 // Provide a default set of shared libraries if system_shared_libs is unspecified. 225 // Note: If an empty list [] is specified, it implies that the module declines the 226 // default shared libraries. 227 deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...) 228 } 229 deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...) 230 return deps 231} 232 233func (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { 234 flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainLdflags()) 235 236 if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() { 237 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-T,"+lds.String()) 238 flags.LdFlagsDeps = append(flags.LdFlagsDeps, lds.Path()) 239 } 240 return flags 241} 242 243func (object *objectLinker) link(ctx ModuleContext, 244 flags Flags, deps PathDeps, objs Objects) android.Path { 245 246 objs = objs.Append(deps.Objs) 247 248 var outputFile android.Path 249 builderFlags := flagsToBuilderFlags(flags) 250 251 if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" { 252 outputFile = objs.objFiles[0] 253 254 if String(object.Properties.Prefix_symbols) != "" { 255 output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension) 256 transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), outputFile, 257 builderFlags, output) 258 outputFile = output 259 } 260 } else { 261 output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension) 262 outputFile = output 263 264 if String(object.Properties.Prefix_symbols) != "" { 265 input := android.PathForModuleOut(ctx, "unprefixed", ctx.ModuleName()+objectExtension) 266 transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input, 267 builderFlags, output) 268 output = input 269 } 270 271 transformObjsToObj(ctx, objs.objFiles, builderFlags, output, flags.LdFlagsDeps) 272 } 273 274 ctx.CheckbuildFile(outputFile) 275 return outputFile 276} 277 278func (object *objectLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { 279 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, object.Properties.Shared_libs...) 280 281 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 282 // either input list doesn't come out as nil. 283 if specifiedDeps.systemSharedLibs == nil { 284 specifiedDeps.systemSharedLibs = object.Properties.System_shared_libs 285 } else { 286 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, object.Properties.System_shared_libs...) 287 } 288 289 return specifiedDeps 290} 291 292func (object *objectLinker) unstrippedOutputFilePath() android.Path { 293 return nil 294} 295 296func (object *objectLinker) nativeCoverage() bool { 297 return true 298} 299 300func (object *objectLinker) coverageOutputFilePath() android.OptionalPath { 301 return android.OptionalPath{} 302} 303 304func (object *objectLinker) object() bool { 305 return true 306} 307 308func (object *objectLinker) isCrt() bool { 309 return Bool(object.Properties.Crt) 310} 311