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