github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/cc/binary.go (about) 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 15 package cc 16 17 import ( 18 "android/soong/android" 19 ) 20 21 type BinaryLinkerProperties struct { 22 // compile executable with -static 23 Static_executable *bool `android:"arch_variant"` 24 25 // set the name of the output 26 Stem *string `android:"arch_variant"` 27 28 // append to the name of the output 29 Suffix *string `android:"arch_variant"` 30 31 // if set, add an extra objcopy --prefix-symbols= step 32 Prefix_symbols *string 33 34 // local file name to pass to the linker as --version_script 35 Version_script *string `android:"arch_variant"` 36 37 // if set, install a symlink to the preferred architecture 38 Symlink_preferred_arch *bool 39 40 // install symlinks to the binary. Symlink names will have the suffix and the binary 41 // extension (if any) appended 42 Symlinks []string `android:"arch_variant"` 43 44 // do not pass -pie 45 No_pie *bool `android:"arch_variant"` 46 47 DynamicLinker string `blueprint:"mutated"` 48 49 // Names of modules to be overridden. Listed modules can only be other binaries 50 // (in Make or Soong). 51 // This does not completely prevent installation of the overridden binaries, but if both 52 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed 53 // from PRODUCT_PACKAGES. 54 Overrides []string 55 } 56 57 func init() { 58 android.RegisterModuleType("cc_binary", binaryFactory) 59 android.RegisterModuleType("cc_binary_host", binaryHostFactory) 60 } 61 62 // Module factory for binaries 63 func binaryFactory() android.Module { 64 module, _ := NewBinary(android.HostAndDeviceSupported) 65 return module.Init() 66 } 67 68 // Module factory for host binaries 69 func binaryHostFactory() android.Module { 70 module, _ := NewBinary(android.HostSupported) 71 return module.Init() 72 } 73 74 // 75 // Executables 76 // 77 78 type binaryDecorator struct { 79 *baseLinker 80 *baseInstaller 81 stripper 82 83 Properties BinaryLinkerProperties 84 85 toolPath android.OptionalPath 86 87 // Names of symlinks to be installed for use in LOCAL_MODULE_SYMLINKS 88 symlinks []string 89 90 // Output archive of gcno coverage information 91 coverageOutputFile android.OptionalPath 92 } 93 94 var _ linker = (*binaryDecorator)(nil) 95 96 func (binary *binaryDecorator) linkerProps() []interface{} { 97 return append(binary.baseLinker.linkerProps(), 98 &binary.Properties, 99 &binary.stripper.StripProperties) 100 101 } 102 103 func (binary *binaryDecorator) getStem(ctx BaseModuleContext) string { 104 stem := ctx.baseModuleName() 105 if String(binary.Properties.Stem) != "" { 106 stem = String(binary.Properties.Stem) 107 } 108 109 return stem + String(binary.Properties.Suffix) 110 } 111 112 func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { 113 deps = binary.baseLinker.linkerDeps(ctx, deps) 114 if ctx.toolchain().Bionic() { 115 if !Bool(binary.baseLinker.Properties.Nocrt) { 116 if !ctx.useSdk() { 117 if binary.static() { 118 deps.CrtBegin = "crtbegin_static" 119 } else { 120 deps.CrtBegin = "crtbegin_dynamic" 121 } 122 deps.CrtEnd = "crtend_android" 123 } else { 124 // TODO(danalbert): Add generation of crt objects. 125 // For `sdk_version: "current"`, we don't actually have a 126 // freshly generated set of CRT objects. Use the last stable 127 // version. 128 version := ctx.sdkVersion() 129 if version == "current" { 130 version = getCurrentNdkPrebuiltVersion(ctx) 131 } 132 133 if binary.static() { 134 deps.CrtBegin = "ndk_crtbegin_static." + version 135 } else { 136 if binary.static() { 137 deps.CrtBegin = "ndk_crtbegin_static." + version 138 } else { 139 deps.CrtBegin = "ndk_crtbegin_dynamic." + version 140 } 141 deps.CrtEnd = "ndk_crtend_android." + version 142 } 143 } 144 } 145 146 if binary.static() { 147 if ctx.selectedStl() == "libc++_static" { 148 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl") 149 } 150 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with 151 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs, 152 // move them to the beginning of deps.LateStaticLibs 153 var groupLibs []string 154 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs, 155 []string{"libc", "libc_nomalloc", "libcompiler_rt"}) 156 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...) 157 } 158 159 if ctx.Os() == android.LinuxBionic && !binary.static() { 160 deps.LinkerScript = "host_bionic_linker_script" 161 } 162 } 163 164 if !binary.static() && inList("libc", deps.StaticLibs) { 165 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" + 166 "from static libs or set static_executable: true") 167 } 168 169 android.ExtractSourceDeps(ctx, binary.Properties.Version_script) 170 171 return deps 172 } 173 174 func (binary *binaryDecorator) isDependencyRoot() bool { 175 return true 176 } 177 178 func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { 179 module := newModule(hod, android.MultilibFirst) 180 binary := &binaryDecorator{ 181 baseLinker: NewBaseLinker(), 182 baseInstaller: NewBaseInstaller("bin", "", InstallInSystem), 183 } 184 module.compiler = NewBaseCompiler() 185 module.linker = binary 186 module.installer = binary 187 return module, binary 188 } 189 190 func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) { 191 binary.baseLinker.linkerInit(ctx) 192 193 if !ctx.toolchain().Bionic() { 194 if ctx.Os() == android.Linux { 195 if binary.Properties.Static_executable == nil && ctx.Config().HostStaticBinaries() { 196 binary.Properties.Static_executable = BoolPtr(true) 197 } 198 } else { 199 // Static executables are not supported on Darwin or Windows 200 binary.Properties.Static_executable = nil 201 } 202 } 203 } 204 205 func (binary *binaryDecorator) static() bool { 206 return Bool(binary.Properties.Static_executable) 207 } 208 209 func (binary *binaryDecorator) staticBinary() bool { 210 return binary.static() 211 } 212 213 func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 214 flags = binary.baseLinker.linkerFlags(ctx, flags) 215 216 if ctx.Host() && !binary.static() { 217 if !ctx.Config().IsEnvTrue("DISABLE_HOST_PIE") { 218 flags.LdFlags = append(flags.LdFlags, "-pie") 219 if ctx.Windows() { 220 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup") 221 } 222 } 223 } 224 225 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because 226 // all code is position independent, and then those warnings get promoted to 227 // errors. 228 if !ctx.Windows() { 229 flags.CFlags = append(flags.CFlags, "-fPIE") 230 } 231 232 if ctx.toolchain().Bionic() { 233 if binary.static() { 234 // Clang driver needs -static to create static executable. 235 // However, bionic/linker uses -shared to overwrite. 236 // Linker for x86 targets does not allow coexistance of -static and -shared, 237 // so we add -static only if -shared is not used. 238 if !inList("-shared", flags.LdFlags) { 239 flags.LdFlags = append(flags.LdFlags, "-static") 240 } 241 242 flags.LdFlags = append(flags.LdFlags, 243 "-nostdlib", 244 "-Bstatic", 245 "-Wl,--gc-sections", 246 ) 247 } else { 248 if flags.DynamicLinker == "" { 249 if binary.Properties.DynamicLinker != "" { 250 flags.DynamicLinker = binary.Properties.DynamicLinker 251 } else { 252 switch ctx.Os() { 253 case android.Android: 254 flags.DynamicLinker = "/system/bin/linker" 255 case android.LinuxBionic: 256 flags.DynamicLinker = "" 257 default: 258 ctx.ModuleErrorf("unknown dynamic linker") 259 } 260 if flags.Toolchain.Is64Bit() { 261 flags.DynamicLinker += "64" 262 } 263 } 264 } 265 266 flags.LdFlags = append(flags.LdFlags, 267 "-pie", 268 "-nostdlib", 269 "-Bdynamic", 270 "-Wl,--gc-sections", 271 "-Wl,-z,nocopyreloc", 272 ) 273 274 } 275 } else { 276 if binary.static() { 277 flags.LdFlags = append(flags.LdFlags, "-static") 278 } 279 if ctx.Darwin() { 280 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names") 281 } 282 } 283 284 return flags 285 } 286 287 func (binary *binaryDecorator) link(ctx ModuleContext, 288 flags Flags, deps PathDeps, objs Objects) android.Path { 289 290 versionScript := ctx.ExpandOptionalSource(binary.Properties.Version_script, "version_script") 291 fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix() 292 outputFile := android.PathForModuleOut(ctx, fileName) 293 ret := outputFile 294 295 var linkerDeps android.Paths 296 297 sharedLibs := deps.SharedLibs 298 sharedLibs = append(sharedLibs, deps.LateSharedLibs...) 299 300 if versionScript.Valid() { 301 if ctx.Darwin() { 302 ctx.PropertyErrorf("version_script", "Not supported on Darwin") 303 } else { 304 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String()) 305 linkerDeps = append(linkerDeps, versionScript.Path()) 306 } 307 } 308 309 if deps.LinkerScript.Valid() { 310 flags.LdFlags = append(flags.LdFlags, "-Wl,-T,"+deps.LinkerScript.String()) 311 linkerDeps = append(linkerDeps, deps.LinkerScript.Path()) 312 } 313 314 if flags.DynamicLinker != "" { 315 flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker) 316 } 317 318 builderFlags := flagsToBuilderFlags(flags) 319 320 if binary.stripper.needsStrip(ctx) { 321 strippedOutputFile := outputFile 322 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) 323 binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags) 324 } 325 326 if String(binary.Properties.Prefix_symbols) != "" { 327 afterPrefixSymbols := outputFile 328 outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName) 329 TransformBinaryPrefixSymbols(ctx, String(binary.Properties.Prefix_symbols), outputFile, 330 flagsToBuilderFlags(flags), afterPrefixSymbols) 331 } 332 333 if Bool(binary.baseLinker.Properties.Use_version_lib) && ctx.Host() { 334 versionedOutputFile := outputFile 335 outputFile = android.PathForModuleOut(ctx, "unversioned", fileName) 336 binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile) 337 } 338 339 linkerDeps = append(linkerDeps, deps.SharedLibsDeps...) 340 linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) 341 linkerDeps = append(linkerDeps, objs.tidyFiles...) 342 linkerDeps = append(linkerDeps, flags.LdFlagsDeps...) 343 344 TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs, 345 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true, 346 builderFlags, outputFile) 347 348 objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...) 349 objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...) 350 binary.coverageOutputFile = TransformCoverageFilesToLib(ctx, objs, builderFlags, binary.getStem(ctx)) 351 352 return ret 353 } 354 355 func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) { 356 binary.baseInstaller.install(ctx, file) 357 for _, symlink := range binary.Properties.Symlinks { 358 binary.symlinks = append(binary.symlinks, 359 symlink+String(binary.Properties.Suffix)+ctx.toolchain().ExecutableSuffix()) 360 } 361 362 if Bool(binary.Properties.Symlink_preferred_arch) { 363 if String(binary.Properties.Stem) == "" && String(binary.Properties.Suffix) == "" { 364 ctx.PropertyErrorf("symlink_preferred_arch", "must also specify stem or suffix") 365 } 366 if ctx.TargetPrimary() { 367 binary.symlinks = append(binary.symlinks, ctx.baseModuleName()) 368 } 369 } 370 371 for _, symlink := range binary.symlinks { 372 ctx.InstallSymlink(binary.baseInstaller.installDir(ctx), symlink, binary.baseInstaller.path) 373 } 374 375 if ctx.Os().Class == android.Host { 376 binary.toolPath = android.OptionalPathForPath(binary.baseInstaller.path) 377 } 378 } 379 380 func (binary *binaryDecorator) hostToolPath() android.OptionalPath { 381 return binary.toolPath 382 }