BUILD.gn revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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# TODO(brettw) Use "gcc_toolchain.gni" like the Linux toolchains. This requires 6# some enhancements since the commands on Mac are slightly different than on 7# Linux. 8 9import("../goma.gni") 10 11# Should only be running on Mac. 12assert(is_mac || is_ios) 13 14import("//build/toolchain/clang.gni") 15import("//build/toolchain/goma.gni") 16 17if (is_clang) { 18 cc = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang", 19 root_build_dir) 20 cxx = rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang++", 21 root_build_dir) 22} else { 23 cc = "gcc" 24 cxx = "g++" 25} 26ld = cxx 27 28# This will copy the gyp-mac-tool to the build directory. We pass in the source 29# file of the win tool. 30gyp_mac_tool_source = 31 rebase_path("//tools/gyp/pylib/gyp/mac_tool.py", root_build_dir) 32exec_script("setup_toolchain.py", [ gyp_mac_tool_source ]) 33 34# Shared toolchain definition. Invocations should set toolchain_os to set the 35# build args in this definition. 36template("mac_clang_toolchain") { 37 toolchain(target_name) { 38 assert(defined(invoker.cc), 39 "mac_clang_toolchain() must specify a \"cc\" value") 40 assert(defined(invoker.cxx), 41 "mac_clang_toolchain() must specify a \"cxx\" value") 42 assert(defined(invoker.ld), 43 "mac_clang_toolchain() must specify a \"ld\" value") 44 assert(defined(invoker.toolchain_os), 45 "mac_clang_toolchain() must specify a \"toolchain_os\"") 46 47 # We can't do string interpolation ($ in strings) on things with dots in 48 # them. To allow us to use $cc below, for example, we create copies of 49 # these values in our scope. 50 cc = invoker.cc 51 cxx = invoker.cxx 52 ld = invoker.ld 53 54 # Make these apply to all tools below. 55 lib_switch = "-l" 56 lib_dir_switch = "-L" 57 58 tool("cc") { 59 depfile = "{{output}}.d" 60 command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" 61 depsformat = "gcc" 62 description = "CC {{output}}" 63 outputs = [ 64 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 65 ] 66 } 67 68 tool("cxx") { 69 depfile = "{{output}}.d" 70 command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" 71 depsformat = "gcc" 72 description = "CXX {{output}}" 73 outputs = [ 74 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 75 ] 76 } 77 78 tool("asm") { 79 # For GCC we can just use the C compiler to compile assembly. 80 depfile = "{{output}}.d" 81 command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" 82 depsformat = "gcc" 83 description = "ASM {{output}}" 84 outputs = [ 85 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 86 ] 87 } 88 89 tool("objc") { 90 depfile = "{{output}}.d" 91 command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} {{cflags_objc}} -c {{source}} -o {{output}}" 92 depsformat = "gcc" 93 description = "OBJC {{output}}" 94 outputs = [ 95 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 96 ] 97 } 98 99 tool("objcxx") { 100 depfile = "{{output}}.d" 101 command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}" 102 depsformat = "gcc" 103 description = "OBJCXX {{output}}" 104 outputs = [ 105 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", 106 ] 107 } 108 109 tool("alink") { 110 command = "rm -f {{output}} && ./gyp-mac-tool filter-libtool libtool -static -o {{output}} {{inputs}}" 111 description = "LIBTOOL-STATIC {{output}}" 112 outputs = [ 113 "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" 114 ] 115 default_output_extension = ".a" 116 output_prefix = "lib" 117 } 118 119 tool("solink") { 120 dylib = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" # eg "./libfoo.dylib" 121 rspfile = dylib + ".rsp" 122 123 # These variables are not build into GN but are helpers that implement 124 # (1) linking to produce a .so, (2) extracting the symbols from that file 125 # to a temporary file, (3) if the temporary file has differences from the 126 # existing .TOC file, overwrite it, oterwise, don't change it. 127 # 128 # As a special case, if the library reexports symbols from other dynamic 129 # libraries, we always update the .TOC and skip the temporary file and 130 # diffing steps, since that library always needs to be re-linked. 131 tocname = dylib + ".TOC" 132 temporary_tocname = dylib + ".tmp" 133 134 does_reexport_command = "[ ! -e $dylib -o ! -e $tocname ] || otool -l $dylib | grep -q LC_REEXPORT_DYLIB" 135 link_command = "$ld -shared {{ldflags}} -o $dylib -Wl,-filelist,$rspfile {{solibs}} {{libs}}" 136 replace_command = "if ! cmp -s $temporary_tocname $tocname; then mv $temporary_tocname $tocname" 137 extract_toc_command = "{ otool -l $dylib | grep LC_ID_DYLIB -A 5; nm -gP $dylib | cut -f1-2 -d' ' | grep -v U\$\$; true; }" 138 139 command = "if $does_reexport_command ; then $link_command && $extract_toc_command > $tocname; else $link_command && $extract_toc_command > $temporary_tocname && $replace_command ; fi; fi" 140 141 rspfile_content = "{{inputs_newline}}" 142 143 description = "SOLINK {{output}}" 144 145 # Use this for {{output_extension}} expansions unless a target manually 146 # overrides it (in which case {{output_extension}} will be what the target 147 # specifies). 148 default_output_extension = ".dylib" 149 150 output_prefix = "lib" 151 152 # Since the above commands only updates the .TOC file when it changes, ask 153 # Ninja to check if the timestamp actually changed to know if downstream 154 # dependencies should be recompiled. 155 restat = true 156 157 # Tell GN about the output files. It will link to the dylib but use the 158 # tocname for dependency management. 159 outputs = [ 160 dylib, 161 tocname, 162 ] 163 link_output = dylib 164 depend_output = tocname 165 } 166 167 tool("link") { 168 outfile = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" 169 rspfile = "$outfile.rsp" 170 command = "$ld {{ldflags}} -o $outfile -Wl,-filelist,$rspfile {{solibs}} {{libs}}" 171 description = "LINK $outfile" 172 rspfile_content = "{{inputs_newline}}" 173 outputs = [ outfile ] 174 } 175 176 tool("stamp") { 177 command = "touch {{output}}" 178 description = "STAMP {{output}}" 179 } 180 181 tool("copy") { 182 command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})" 183 description = "COPY {{source}} {{output}}" 184 } 185 186 toolchain_args() { 187 os = invoker.toolchain_os 188 } 189 } 190} 191 192# Toolchain representing the target build (either mac or iOS). 193mac_clang_toolchain("clang") { 194 toolchain_os = os 195} 196 197# This toolchain provides a way for iOS target compiles to reference targets 198# compiled for the host system. It just overrides the OS back to "mac". 199mac_clang_toolchain("host_clang") { 200 toolchain_os = "mac" 201} 202