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 config 16 17import ( 18 "strings" 19 20 "android/soong/android" 21) 22 23var ( 24 linuxCflags = []string{ 25 "-Wa,--noexecstack", 26 27 "-fPIC", 28 29 "-fno-omit-frame-pointer", 30 31 "-U_FORTIFY_SOURCE", 32 "-D_FORTIFY_SOURCE=3", 33 "-fstack-protector", 34 35 "--gcc-toolchain=${LinuxGccRoot}", 36 "-fstack-protector-strong", 37 } 38 39 linuxGlibcCflags = []string{ 40 "--sysroot ${LinuxGccRoot}/sysroot", 41 } 42 43 linuxMuslCflags = []string{ 44 "-DANDROID_HOST_MUSL", 45 "-nostdlibinc", 46 "--sysroot /dev/null", 47 } 48 49 linuxLdflags = []string{ 50 "-Wl,-z,noexecstack", 51 "-Wl,-z,relro", 52 "-Wl,-z,now", 53 "-Wl,--no-undefined-version", 54 55 "--gcc-toolchain=${LinuxGccRoot}", 56 } 57 58 linuxLldflags = append(linuxLdflags, 59 "-Wl,--compress-debug-sections=zstd", 60 ) 61 62 linuxGlibcLdflags = []string{ 63 "--sysroot ${LinuxGccRoot}/sysroot", 64 } 65 66 linuxMuslLdflags = []string{ 67 "-nostdlib", 68 "--sysroot /dev/null", 69 } 70 71 // Extended cflags 72 linuxX86Cflags = []string{ 73 "-msse3", 74 "-m32", 75 "-march=prescott", 76 "-D_FILE_OFFSET_BITS=64", 77 "-D_LARGEFILE_SOURCE=1", 78 } 79 80 linuxX8664Cflags = []string{ 81 "-m64", 82 } 83 84 linuxX86Ldflags = []string{ 85 "-m32", 86 "-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32", 87 "-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32", 88 "-L${LinuxGccRoot}/${LinuxGccTriple}/lib32", 89 } 90 91 linuxX8664Ldflags = []string{ 92 "-m64", 93 "-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}", 94 "-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}", 95 "-L${LinuxGccRoot}/${LinuxGccTriple}/lib64", 96 } 97 98 linuxAvailableLibraries = addPrefix([]string{ 99 "c", 100 "dl", 101 "gcc", 102 "gcc_s", 103 "m", 104 "ncurses", 105 "pthread", 106 "resolv", 107 "rt", 108 "util", 109 }, "-l") 110 111 muslCrtBeginStaticBinary, muslCrtEndStaticBinary = []string{"libc_musl_crtbegin_static"}, []string{"libc_musl_crtend"} 112 muslCrtBeginSharedBinary, muslCrtEndSharedBinary = []string{"libc_musl_crtbegin_dynamic"}, []string{"libc_musl_crtend"} 113 muslCrtBeginSharedLibrary, muslCrtEndSharedLibrary = []string{"libc_musl_crtbegin_so"}, []string{"libc_musl_crtend_so"} 114 115 MuslDefaultSharedLibraries = []string{"libc_musl"} 116) 117 118const ( 119 linuxGccVersion = "4.8.3" 120 linuxGlibcVersion = "2.17" 121) 122 123func init() { 124 pctx.StaticVariable("LinuxGccVersion", linuxGccVersion) 125 pctx.StaticVariable("LinuxGlibcVersion", linuxGlibcVersion) 126 127 // Most places use the full GCC version. A few only use up to the first two numbers. 128 if p := strings.Split(linuxGccVersion, "."); len(p) > 2 { 129 pctx.StaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], ".")) 130 } else { 131 pctx.StaticVariable("ShortLinuxGccVersion", linuxGccVersion) 132 } 133 134 pctx.SourcePathVariable("LinuxGccRoot", 135 "prebuilts/gcc/linux-x86/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}") 136 137 pctx.StaticVariable("LinuxGccTriple", "x86_64-linux") 138 139 pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " ")) 140 pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " ")) 141 pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLldflags, " ")) 142 pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " ")) 143 pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " ")) 144 pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " ")) 145 pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " ")) 146 pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " ")) 147 pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " ")) 148 149 pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " ")) 150 pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " ")) 151 pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " ")) 152 pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " ")) 153 pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " ")) 154 pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " ")) 155 // Yasm flags 156 pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86") 157 pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64") 158} 159 160type toolchainLinux struct { 161 toolchainBase 162 cFlags, ldFlags string 163} 164 165type toolchainLinuxX86 struct { 166 toolchain32Bit 167 toolchainLinux 168} 169 170type toolchainLinuxX8664 struct { 171 toolchain64Bit 172 toolchainLinux 173} 174 175func (t *toolchainLinuxX86) Name() string { 176 return "x86" 177} 178 179func (t *toolchainLinuxX8664) Name() string { 180 return "x86_64" 181} 182 183func (t *toolchainLinux) IncludeFlags() string { 184 return "" 185} 186 187func (t *toolchainLinuxX86) Cflags() string { 188 return "${config.LinuxCflags} ${config.LinuxX86Cflags}" 189} 190 191func (t *toolchainLinuxX86) Cppflags() string { 192 return "" 193} 194 195func (t *toolchainLinuxX8664) Cflags() string { 196 return "${config.LinuxCflags} ${config.LinuxX8664Cflags}" 197} 198 199func (t *toolchainLinuxX8664) Cppflags() string { 200 return "" 201} 202 203func (t *toolchainLinuxX86) Ldflags() string { 204 return "${config.LinuxLdflags} ${config.LinuxX86Ldflags}" 205} 206 207func (t *toolchainLinuxX86) Lldflags() string { 208 return "${config.LinuxLldflags} ${config.LinuxX86Lldflags}" 209} 210 211func (t *toolchainLinuxX8664) Ldflags() string { 212 return "${config.LinuxLdflags} ${config.LinuxX8664Ldflags}" 213} 214 215func (t *toolchainLinuxX8664) Lldflags() string { 216 return "${config.LinuxLldflags} ${config.LinuxX8664Lldflags}" 217} 218 219func (t *toolchainLinuxX86) YasmFlags() string { 220 return "${config.LinuxX86YasmFlags}" 221} 222 223func (t *toolchainLinuxX8664) YasmFlags() string { 224 return "${config.LinuxX8664YasmFlags}" 225} 226 227func (toolchainLinuxX86) LibclangRuntimeLibraryArch() string { 228 return "i386" 229} 230 231func (toolchainLinuxX8664) LibclangRuntimeLibraryArch() string { 232 return "x86_64" 233} 234 235func (t *toolchainLinux) AvailableLibraries() []string { 236 return linuxAvailableLibraries 237} 238 239func (toolchainLinux) ShlibSuffix() string { 240 return ".so" 241} 242 243func (toolchainLinux) ExecutableSuffix() string { 244 return "" 245} 246 247// glibc specialization of the linux toolchain 248 249type toolchainGlibc struct { 250 toolchainNoCrt 251} 252 253func (toolchainGlibc) Glibc() bool { return true } 254 255func (toolchainGlibc) Cflags() string { 256 return "${config.LinuxGlibcCflags}" 257} 258 259func (toolchainGlibc) Ldflags() string { 260 return "${config.LinuxGlibcLdflags}" 261} 262 263func (toolchainGlibc) Lldflags() string { 264 return "${config.LinuxGlibcLldflags}" 265} 266 267type toolchainLinuxGlibcX86 struct { 268 toolchainLinuxX86 269 toolchainGlibc 270} 271 272type toolchainLinuxGlibcX8664 struct { 273 toolchainLinuxX8664 274 toolchainGlibc 275} 276 277func (t *toolchainLinuxGlibcX86) ClangTriple() string { 278 return "i686-linux-gnu" 279} 280 281func (t *toolchainLinuxGlibcX86) Cflags() string { 282 return t.toolchainLinuxX86.Cflags() + " " + t.toolchainGlibc.Cflags() 283} 284 285func (t *toolchainLinuxGlibcX86) Ldflags() string { 286 return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainGlibc.Ldflags() 287} 288 289func (t *toolchainLinuxGlibcX86) Lldflags() string { 290 return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainGlibc.Lldflags() 291} 292 293func (t *toolchainLinuxGlibcX8664) ClangTriple() string { 294 return "x86_64-linux-gnu" 295} 296 297func (t *toolchainLinuxGlibcX8664) Cflags() string { 298 return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainGlibc.Cflags() 299} 300 301func (t *toolchainLinuxGlibcX8664) Ldflags() string { 302 return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainGlibc.Ldflags() 303} 304 305func (t *toolchainLinuxGlibcX8664) Lldflags() string { 306 return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainGlibc.Lldflags() 307} 308 309var toolchainLinuxGlibcX86Singleton Toolchain = &toolchainLinuxGlibcX86{} 310var toolchainLinuxGlibcX8664Singleton Toolchain = &toolchainLinuxGlibcX8664{} 311 312func linuxGlibcX86ToolchainFactory(arch android.Arch) Toolchain { 313 return toolchainLinuxGlibcX86Singleton 314} 315 316func linuxGlibcX8664ToolchainFactory(arch android.Arch) Toolchain { 317 return toolchainLinuxGlibcX8664Singleton 318} 319 320// musl specialization of the linux toolchain 321 322type toolchainMusl struct { 323} 324 325func (toolchainMusl) Musl() bool { return true } 326 327func (toolchainMusl) CrtBeginStaticBinary() []string { return muslCrtBeginStaticBinary } 328func (toolchainMusl) CrtBeginSharedBinary() []string { return muslCrtBeginSharedBinary } 329func (toolchainMusl) CrtBeginSharedLibrary() []string { return muslCrtBeginSharedLibrary } 330func (toolchainMusl) CrtEndStaticBinary() []string { return muslCrtEndStaticBinary } 331func (toolchainMusl) CrtEndSharedBinary() []string { return muslCrtEndSharedBinary } 332func (toolchainMusl) CrtEndSharedLibrary() []string { return muslCrtEndSharedLibrary } 333func (toolchainMusl) CrtPadSegmentSharedLibrary() []string { return nil } 334 335func (toolchainMusl) DefaultSharedLibraries() []string { return MuslDefaultSharedLibraries } 336 337func (toolchainMusl) Cflags() string { 338 return "${config.LinuxMuslCflags}" 339} 340 341func (toolchainMusl) Ldflags() string { 342 return "${config.LinuxMuslLdflags}" 343} 344 345func (toolchainMusl) Lldflags() string { 346 return "${config.LinuxMuslLldflags}" 347} 348 349type toolchainLinuxMuslX86 struct { 350 toolchainLinuxX86 351 toolchainMusl 352} 353 354type toolchainLinuxMuslX8664 struct { 355 toolchainLinuxX8664 356 toolchainMusl 357} 358 359func (t *toolchainLinuxMuslX86) ClangTriple() string { 360 return "i686-linux-musl" 361} 362 363func (t *toolchainLinuxMuslX86) Cflags() string { 364 return t.toolchainLinuxX86.Cflags() + " " + t.toolchainMusl.Cflags() 365} 366 367func (t *toolchainLinuxMuslX86) Ldflags() string { 368 return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainMusl.Ldflags() 369} 370 371func (t *toolchainLinuxMuslX86) Lldflags() string { 372 return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainMusl.Lldflags() 373} 374 375func (t *toolchainLinuxMuslX8664) ClangTriple() string { 376 return "x86_64-linux-musl" 377} 378 379func (t *toolchainLinuxMuslX8664) Cflags() string { 380 return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainMusl.Cflags() 381} 382 383func (t *toolchainLinuxMuslX8664) Ldflags() string { 384 return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainMusl.Ldflags() 385} 386 387func (t *toolchainLinuxMuslX8664) Lldflags() string { 388 return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainMusl.Lldflags() 389} 390 391var toolchainLinuxMuslX86Singleton Toolchain = &toolchainLinuxMuslX86{} 392var toolchainLinuxMuslX8664Singleton Toolchain = &toolchainLinuxMuslX8664{} 393 394func linuxMuslX86ToolchainFactory(arch android.Arch) Toolchain { 395 return toolchainLinuxMuslX86Singleton 396} 397 398func linuxMuslX8664ToolchainFactory(arch android.Arch) Toolchain { 399 return toolchainLinuxMuslX8664Singleton 400} 401 402func init() { 403 registerToolchainFactory(android.Linux, android.X86, linuxGlibcX86ToolchainFactory) 404 registerToolchainFactory(android.Linux, android.X86_64, linuxGlibcX8664ToolchainFactory) 405 registerToolchainFactory(android.LinuxMusl, android.X86, linuxMuslX86ToolchainFactory) 406 registerToolchainFactory(android.LinuxMusl, android.X86_64, linuxMuslX8664ToolchainFactory) 407} 408