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