1# Copyright (c) 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5# This template defines a GCC toolchain. 6# 7# It requires the following variables specifying the executables to run: 8# - cc 9# - cxx 10# - ar 11# - ld 12# and the following which is used in the toolchain_args 13# - toolchain_cpu_arch (What "cpu_arch" should be set to when invoking a 14# build using this toolchain.) 15# - toolchain_os (What "os" should be set to when invoking a build using this 16# toolchain.) 17# 18# Optional parameters: 19# - libs_section_prefix 20# - libs_section_postfix 21# The contents of these strings, if specified, will be placed around 22# the libs section of the linker line. It allows one to inject libraries 23# at the beginning and end for all targets in a toolchain. 24template("gcc_toolchain") { 25 toolchain(target_name) { 26 assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value") 27 assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value") 28 assert(defined(invoker.ar), "gcc_toolchain() must specify a \"ar\" value") 29 assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value") 30 assert(defined(invoker.toolchain_cpu_arch), 31 "gcc_toolchain() must specify a \"toolchain_cpu_arch\"") 32 assert(defined(invoker.toolchain_os), 33 "gcc_toolchain() must specify a \"toolchain_os\"") 34 35 # We can't do string interpolation ($ in strings) on things with dots in 36 # them. To allow us to use $cc below, for example, we create copies of 37 # these values in our scope. 38 cc = invoker.cc 39 cxx = invoker.cxx 40 ar = invoker.ar 41 ld = invoker.ld 42 43 # Bring these into our scope for string interpolation with default values. 44 if (defined(invoker.libs_section_prefix)) { 45 libs_section_prefix = invoker.libs_section_prefix 46 } else { 47 libs_section_prefix = "" 48 } 49 50 if (defined(invoker.libs_section_postfix)) { 51 libs_section_postfix = invoker.libs_section_postfix 52 } else { 53 libs_section_postfix = "" 54 } 55 56 # Make these apply to all tools below. 57 lib_prefix = "-l" 58 lib_dir_prefix="-L" 59 60 tool("cc") { 61 # cflags_pch_c 62 command = "$cc -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_c -c \$in -o \$out" 63 description = "CC \$out" 64 depfile = "\$out.d" 65 deps = "gcc" 66 } 67 tool("cxx") { 68 # cflags_pch_cc 69 command = "$cxx -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_cc -c \$in -o \$out" 70 description = "CXX \$out" 71 depfile = "\$out.d" 72 deps = "gcc" 73 } 74 tool("alink") { 75 command = "rm -f \$out && $ar rcs \$out @\$rspfile" 76 description = "AR \$out" 77 rspfile = "\$out.rsp" 78 rspfile_content = "\$in" 79 } 80 tool("solink") { 81 command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ]; then $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname @\$rspfile && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive $libs_section_prefix \$libs $libs_section_postfix && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi" 82 description = "SOLINK \$lib" 83 rspfile = "\$out.rsp" 84 rspfile_content = "-Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs" 85 #pool = "link_pool" 86 restat = "1" 87 } 88 tool("link") { 89 command = "$ld \$ldflags -o \$out -Wl,--start-group @\$rspfile \$solibs -Wl,--end-group $libs_section_prefix \$libs $libs_section_postfix" 90 description = "LINK \$out" 91 rspfile = "\$out.rsp" 92 rspfile_content = "\$in" 93 #pool = "link_pool" 94 } 95 tool("stamp") { 96 command = "\${postbuilds}touch \$out" 97 description = "STAMP \$out" 98 } 99 tool("copy") { 100 command = "ln -f \$in \$out 2>/dev/null || (rm -rf \$out && cp -af \$in \$out)" 101 description = "COPY \$in \$out" 102 } 103 104 # When invoking this toolchain not as the default one, these args will be 105 # passed to the build. They are ignored when this is the default toolchain. 106 toolchain_args() { 107 cpu_arch = invoker.toolchain_cpu_arch 108 os = invoker.toolchain_os 109 } 110 } 111} 112