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 "strings" 20 21 "android/soong/android" 22 23 "github.com/google/blueprint/proptools" 24) 25 26// 27// Objects (for crt*.o) 28// 29 30func init() { 31 android.RegisterModuleType("cc_object", ObjectFactory) 32 android.RegisterSdkMemberType(ccObjectSdkMemberType) 33 34} 35 36var ccObjectSdkMemberType = &librarySdkMemberType{ 37 SdkMemberTypeBase: android.SdkMemberTypeBase{ 38 PropertyName: "native_objects", 39 SupportsSdk: true, 40 }, 41 prebuiltModuleType: "cc_prebuilt_object", 42} 43 44type objectLinker struct { 45 *baseLinker 46 Properties ObjectLinkerProperties 47 48 // Location of the object in the sysroot. Empty if the object is not 49 // included in the NDK. 50 ndkSysrootPath android.Path 51} 52 53type ObjectLinkerProperties struct { 54 // list of static library modules that should only provide headers for this module. 55 Static_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"` 56 57 // list of shared library modules should only provide headers for this module. 58 Shared_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"` 59 60 // list of modules that should only provide headers for this module. 61 Header_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"` 62 63 // list of default libraries that will provide headers for this module. If unset, generally 64 // defaults to libc, libm, and libdl. Set to [] to prevent using headers from the defaults. 65 System_shared_libs []string `android:"arch_variant"` 66 67 // names of other cc_object modules to link into this module using partial linking 68 Objs []string `android:"arch_variant"` 69 70 // if set, add an extra objcopy --prefix-symbols= step 71 Prefix_symbols *string 72 73 // if set, the path to a linker script to pass to ld -r when combining multiple object files. 74 Linker_script *string `android:"path,arch_variant"` 75 76 // Indicates that this module is a CRT object. CRT objects will be split 77 // into a variant per-API level between min_sdk_version and current. 78 Crt *bool 79 80 // Indicates that this module should not be included in the NDK sysroot. 81 // Only applies to CRT objects. Defaults to false. 82 Exclude_from_ndk_sysroot *bool 83} 84 85func newObject(hod android.HostOrDeviceSupported) *Module { 86 module := newBaseModule(hod, android.MultilibBoth) 87 module.sanitize = &sanitize{} 88 module.stl = &stl{} 89 return module 90} 91 92// cc_object runs the compiler without running the linker. It is rarely 93// necessary, but sometimes used to generate .s files from .c files to use as 94// input to a cc_genrule module. 95func ObjectFactory() android.Module { 96 module := newObject(android.HostAndDeviceSupported) 97 module.linker = &objectLinker{ 98 baseLinker: NewBaseLinker(module.sanitize), 99 } 100 module.compiler = NewBaseCompiler() 101 102 // Clang's address-significance tables are incompatible with ld -r. 103 module.compiler.appendCflags([]string{"-fno-addrsig"}) 104 105 module.sdkMemberTypes = []android.SdkMemberType{ccObjectSdkMemberType} 106 107 return module.Init() 108} 109 110func (object *objectLinker) appendLdflags(flags []string) { 111 panic(fmt.Errorf("appendLdflags on objectLinker not supported")) 112} 113 114func (object *objectLinker) linkerProps() []interface{} { 115 return []interface{}{&object.Properties} 116} 117 118func (*objectLinker) linkerInit(ctx BaseModuleContext) {} 119 120func (object *objectLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { 121 deps.HeaderLibs = append(deps.HeaderLibs, object.Properties.Header_libs.GetOrDefault(ctx, nil)...) 122 deps.SharedLibs = append(deps.SharedLibs, object.Properties.Shared_libs.GetOrDefault(ctx, nil)...) 123 deps.StaticLibs = append(deps.StaticLibs, object.Properties.Static_libs.GetOrDefault(ctx, nil)...) 124 deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...) 125 126 deps.SystemSharedLibs = object.Properties.System_shared_libs 127 if deps.SystemSharedLibs == nil { 128 // Provide a default set of shared libraries if system_shared_libs is unspecified. 129 // Note: If an empty list [] is specified, it implies that the module declines the 130 // default shared libraries. 131 deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...) 132 } 133 deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...) 134 return deps 135} 136 137func (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { 138 flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainLdflags()) 139 140 if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() { 141 flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-T,"+lds.String()) 142 flags.LdFlagsDeps = append(flags.LdFlagsDeps, lds.Path()) 143 } 144 return flags 145} 146 147func (object *objectLinker) link(ctx ModuleContext, 148 flags Flags, deps PathDeps, objs Objects) android.Path { 149 150 objs = objs.Append(deps.Objs) 151 152 var output android.WritablePath 153 builderFlags := flagsToBuilderFlags(flags) 154 outputName := ctx.ModuleName() 155 if !strings.HasSuffix(outputName, objectExtension) { 156 outputName += objectExtension 157 } 158 159 // isForPlatform is terribly named and actually means isNotApex. 160 if Bool(object.Properties.Crt) && 161 !Bool(object.Properties.Exclude_from_ndk_sysroot) && ctx.useSdk() && 162 ctx.isSdkVariant() && ctx.isForPlatform() { 163 164 output = getVersionedLibraryInstallPath(ctx, 165 nativeApiLevelOrPanic(ctx, ctx.sdkVersion())).Join(ctx, outputName) 166 object.ndkSysrootPath = output 167 } else { 168 output = android.PathForModuleOut(ctx, outputName) 169 } 170 171 outputFile := output 172 173 if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" { 174 if String(object.Properties.Prefix_symbols) != "" { 175 transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), objs.objFiles[0], 176 builderFlags, output) 177 } else { 178 ctx.Build(pctx, android.BuildParams{ 179 Rule: android.Cp, 180 Input: objs.objFiles[0], 181 Output: output, 182 }) 183 } 184 } else { 185 outputAddrSig := android.PathForModuleOut(ctx, "addrsig", outputName) 186 187 if String(object.Properties.Prefix_symbols) != "" { 188 input := android.PathForModuleOut(ctx, "unprefixed", outputName) 189 transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input, 190 builderFlags, output) 191 output = input 192 } 193 194 transformObjsToObj(ctx, objs.objFiles, builderFlags, outputAddrSig, flags.LdFlagsDeps) 195 196 // ld -r reorders symbols and invalidates the .llvm_addrsig section, which then causes warnings 197 // if the resulting object is used with ld --icf=safe. Strip the .llvm_addrsig section to 198 // prevent the warnings. 199 transformObjectNoAddrSig(ctx, outputAddrSig, output) 200 } 201 202 ctx.CheckbuildFile(outputFile) 203 return outputFile 204} 205 206func (object *objectLinker) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps { 207 eval := module.ConfigurableEvaluator(ctx) 208 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, object.Properties.Shared_libs.GetOrDefault(eval, nil)...) 209 210 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 211 // either input list doesn't come out as nil. 212 if specifiedDeps.systemSharedLibs == nil { 213 specifiedDeps.systemSharedLibs = object.Properties.System_shared_libs 214 } else { 215 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, object.Properties.System_shared_libs...) 216 } 217 218 return specifiedDeps 219} 220 221func (object *objectLinker) unstrippedOutputFilePath() android.Path { 222 return nil 223} 224 225func (object *objectLinker) strippedAllOutputFilePath() android.Path { 226 return nil 227} 228 229func (object *objectLinker) nativeCoverage() bool { 230 return true 231} 232 233func (object *objectLinker) coverageOutputFilePath() android.OptionalPath { 234 return android.OptionalPath{} 235} 236 237func (object *objectLinker) object() bool { 238 return true 239} 240 241func (object *objectLinker) isCrt() bool { 242 return Bool(object.Properties.Crt) 243} 244 245func (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { 246 object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) 247 moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"} 248} 249