Home | History | Annotate | Download | only in toolchain
      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.
     24 template("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