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