Home | History | Annotate | Download | only in gn
      1 # Copyright 2016 Google Inc.
      2 #
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 declare_args() {
      7   ar = "ar"
      8   cc = "cc"
      9   cxx = "c++"
     10 
     11   if (is_android) {
     12     if (host_os == "win") {
     13       ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar.exe"
     14       cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang.exe"
     15       cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++.exe"
     16     } else {
     17       ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar"
     18       cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang"
     19       cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++"
     20     }
     21   }
     22 
     23   msvc = 2015
     24 
     25   extra_cflags = []
     26   extra_cflags_c = []
     27   extra_cflags_cc = []
     28   extra_ldflags = []
     29 
     30   cc_wrapper = ""
     31   malloc = ""
     32 }
     33 declare_args() {
     34   if (msvc == 2015) {
     35     windk = "C:/Program Files (x86)/Microsoft Visual Studio 14.0"
     36   } else {
     37     windk = "C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional"
     38   }
     39 }
     40 
     41 if (host_os == "win") {
     42   python = "python.bat"
     43   stamp = "cmd.exe /c echo >"
     44 } else {
     45   python = "python"
     46   stamp = "touch"
     47 }
     48 
     49 is_clang = is_android || is_ios || is_mac || (cc == "clang" && cxx == "clang++")
     50 if (!is_clang && !is_win) {
     51   is_clang = exec_script("is_clang.py",
     52                          [
     53                            cc,
     54                            cxx,
     55                          ],
     56                          "value")
     57 }
     58 
     59 if (is_ios) {
     60   if (is_tvos) {
     61     sdk = "appletvos"
     62     if (target_cpu == "x86" || target_cpu == "x64") {
     63       sdk = "appletvsimulator"
     64     }
     65   } else {
     66     sdk = "iphoneos"
     67     if (target_cpu == "x86" || target_cpu == "x64") {
     68       sdk = "iphonesimulator"
     69     }
     70   }
     71   ios_sysroot = exec_script("find_ios_sysroot.py", [ sdk ], "trim string")
     72 }
     73 
     74 config("default") {
     75   asmflags = []
     76   cflags = []
     77   cflags_c = []
     78   cflags_cc = []
     79   defines = []
     80   ldflags = []
     81   libs = []
     82 
     83   if (is_win) {
     84     cflags += [
     85       "/FS",  # Preserve previous PDB behavior.
     86       "/bigobj",  # Some of our files are bigger than the regular limits.
     87       "/WX",  # Treat warnings as errors.
     88       "/utf-8",  # Set Source and Executable character sets to UTF-8.
     89     ]
     90     defines += [
     91       "_CRT_SECURE_NO_WARNINGS",  # Disables warnings about sscanf().
     92       "_HAS_EXCEPTIONS=0",  # Disables exceptions in MSVC STL.
     93       "WIN32_LEAN_AND_MEAN",
     94       "NOMINMAX",
     95     ]
     96     include_dirs = [
     97       #2017
     98       "$windk/VC/Tools/MSVC/14.10.25017/include",
     99 
    100       #2015
    101       "$windk/VC/include",
    102 
    103       # For local builds.
    104       # 2017
    105       "$windk/../../../Windows Kits/10/Include/10.0.14393.0/shared",
    106       "$windk/../../../Windows Kits/10/Include/10.0.14393.0/ucrt",
    107       "$windk/../../../Windows Kits/10/Include/10.0.14393.0/um",
    108       "$windk/../../../Windows Kits/10/Include/10.0.14393.0/winrt",
    109 
    110       # 2015
    111       "$windk/../Windows Kits/8.1/Include/shared",
    112       "$windk/../Windows Kits/10/Include/10.0.10150.0/ucrt",
    113       "$windk/../Windows Kits/8.1/Include/um",
    114       "$windk/../Windows Kits/8.1/Include/winrt",
    115 
    116       # For builds using win_toolchain asset.
    117       "$windk/win_sdk/Include/10.0.14393.0/shared",
    118       "$windk/win_sdk/Include/10.0.14393.0/ucrt",
    119       "$windk/win_sdk/Include/10.0.14393.0/um",
    120       "$windk/win_sdk/Include/10.0.14393.0/winrt",
    121     ]
    122     lib_dirs = [
    123       # For local builds.
    124       # 2017
    125       "$windk/../../../Windows Kits/10/Lib/10.0.14393.0/ucrt/$target_cpu",
    126       "$windk/../../../Windows Kits/10/Lib/10.0.14393.0/um/$target_cpu",
    127 
    128       #2015
    129       "$windk/../Windows Kits/10/Lib/10.0.10150.0/ucrt/$target_cpu",
    130       "$windk/../Windows Kits/8.1/Lib/winv6.3/um/$target_cpu",
    131 
    132       # For builds using win_toolchain asset.
    133       "$windk/win_sdk/Lib/10.0.14393.0/ucrt/$target_cpu",
    134       "$windk/win_sdk/Lib/10.0.14393.0/um/$target_cpu",
    135     ]
    136 
    137     #2017
    138     lib_dirs += [ "$windk/VC/Tools/MSVC/14.10.25017/lib/$target_cpu" ]
    139 
    140     #2015
    141     if (target_cpu == "x86") {
    142       lib_dirs += [ "$windk/VC/lib" ]
    143     } else {
    144       lib_dirs += [ "$windk/VC/lib/amd64" ]
    145     }
    146   } else {
    147     cflags += [
    148       "-fstrict-aliasing",
    149       "-fPIC",
    150       "-Werror",
    151     ]
    152     cflags_cc += [
    153       "-std=c++11",
    154       "-fno-threadsafe-statics",
    155     ]
    156 
    157     # The main idea is to slim the exported API, but these flags also improve link time on Mac.
    158     # These would make stack traces worse on Linux, so we don't just set them willy-nilly.
    159     if (is_component_build || is_mac) {
    160       cflags += [ "-fvisibility=hidden" ]
    161       cflags_cc += [ "-fvisibility-inlines-hidden" ]
    162     }
    163   }
    164 
    165   if (current_cpu == "arm") {
    166     cflags += [
    167       "-march=armv7-a",
    168       "-mfpu=neon",
    169       "-mthumb",
    170     ]
    171   } else if (current_cpu == "mipsel") {
    172     cflags += [
    173       "-no-integrated-as",  # Clang <4.0 doesn't understand 'usw' mnemonic.
    174       "-march=mips32r2",
    175       "-mdspr2",
    176     ]
    177   } else if (current_cpu == "x86" && !is_win) {
    178     asmflags += [ "-m32" ]
    179     cflags += [
    180       "-m32",
    181       "-msse2",
    182       "-mfpmath=sse",
    183     ]
    184     ldflags += [ "-m32" ]
    185   }
    186 
    187   if (malloc != "" && !is_win) {
    188     cflags += [
    189       "-fno-builtin-malloc",
    190       "-fno-builtin-calloc",
    191       "-fno-builtin-realloc",
    192       "-fno-builtin-free",
    193     ]
    194     libs += [ malloc ]
    195   }
    196 
    197   if (is_android) {
    198     asmflags += [
    199       "--target=$ndk_target",
    200       "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin",
    201     ]
    202     cflags += [
    203       "--sysroot=$ndk/platforms/$ndk_platform",
    204       "--target=$ndk_target",
    205       "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin",
    206     ]
    207     cflags_cc += [
    208       "-isystem$ndk/sources/android/support/include",
    209       "-isystem$ndk/sources/cxx-stl/gnu-libstdc++/4.9/include",
    210       "-isystem$ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ndk_stdlib/include",
    211     ]
    212     ldflags += [
    213       "--sysroot=$ndk/platforms/$ndk_platform",
    214       "--target=$ndk_target",
    215       "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin",
    216     ]
    217     lib_dirs = [
    218       "$ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ndk_stdlib",
    219       "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/lib/gcc/$ndk_target/4.9.x",
    220     ]
    221 
    222     if (current_cpu == "mips64el") {
    223       # The r13 NDK omits /usr/lib from the MIPS64 sysroots, but Clang searches
    224       # for /usr/lib64 as $PATH_TO_USR_LIB/../lib64.  If there's no /usr/lib,
    225       # it can't find /usr/lib64.  We must point Clang at /usr/lib64 manually.
    226       lib_dirs += [ "$ndk/platforms/$ndk_platform/usr/lib64" ]
    227       ldflags += [ "-B$ndk/platforms/$ndk_platform/usr/lib64" ]
    228     }
    229 
    230     libs += [ "gnustl_static" ]
    231   }
    232 
    233   if (is_ios) {
    234     _target = target_cpu
    235     if (target_cpu == "arm") {
    236       _target = "armv7"
    237     } else if (target_cpu == "x86") {
    238       _target = "i386"
    239     } else if (target_cpu == "x64") {
    240       _target = "x86_64"
    241     }
    242     asmflags += [
    243       "-isysroot",
    244       ios_sysroot,
    245       "-arch",
    246       _target,
    247     ]
    248     cflags += [
    249       "-isysroot",
    250       ios_sysroot,
    251       "-arch",
    252       _target,
    253     ]
    254     cflags_cc += [ "-stdlib=libc++" ]
    255     ldflags += [
    256       "-isysroot",
    257       ios_sysroot,
    258       "-arch",
    259       _target,
    260       "-stdlib=libc++",
    261     ]
    262     libs += [ "objc" ]
    263   }
    264 
    265   if (is_linux) {
    266     libs += [ "pthread" ]
    267   }
    268 
    269   if (sanitize != "") {
    270     # You can either pass the sanitizers directly, e.g. "address,undefined",
    271     # or pass one of the couple common aliases used by the bots.
    272     sanitizers = sanitize
    273     if (sanitize == "ASAN") {
    274       sanitizers = "address,bool,function,integer-divide-by-zero,nonnull-attribute,null,object-size,return,returns-nonnull-attribute,shift,signed-integer-overflow,unreachable,vla-bound,vptr"
    275     } else if (sanitize == "TSAN") {
    276       sanitizers = "thread"
    277     } else if (sanitize == "MSAN") {
    278       sanitizers = "memory"
    279     }
    280 
    281     cflags += [
    282       "-fsanitize=$sanitizers",
    283       "-fno-sanitize-recover=$sanitizers",
    284       "-fsanitize-blacklist=" + rebase_path("../tools/xsan.blacklist"),
    285     ]
    286     ldflags += [ "-fsanitize=$sanitizers" ]
    287     if (sanitizers == "memory") {
    288       cflags += [ "-fsanitize-memory-track-origins" ]
    289       cflags_cc += [ "-stdlib=libc++" ]
    290       ldflags += [ "-stdlib=libc++" ]
    291     }
    292   }
    293 }
    294 
    295 config("no_exceptions") {
    296   # Exceptions are disabled by default on Windows.  (Use /EHsc to enable them.)
    297   if (!is_win) {
    298     cflags_cc = [ "-fno-exceptions" ]
    299   }
    300 }
    301 
    302 config("warnings") {
    303   cflags = []
    304   cflags_cc = []
    305   cflags_objc = []
    306   if (is_win) {
    307     cflags += [
    308       "/W3",  # Turn on lots of warnings.
    309 
    310       # Disable a bunch of warnings:
    311       "/wd4244",  # conversion from 'float' to 'int', possible loss of data
    312       "/wd4267",  # conversion from 'size_t' to 'int', possible loss of data
    313       "/wd4800",  # forcing value to bool 'true' or 'false' (performance warning)
    314 
    315       # Probably only triggers when /EHsc is enabled.
    316       "/wd4291",  # no matching operator delete found;
    317                   # memory will not be freed if initialization throws an exception
    318     ]
    319   } else {
    320     cflags += [
    321       "-Wall",
    322       "-Wextra",
    323       "-Winit-self",
    324       "-Wpointer-arith",
    325       "-Wsign-compare",
    326       "-Wvla",
    327 
    328       "-Wno-deprecated-declarations",
    329       "-Wno-maybe-uninitialized",
    330     ]
    331     cflags_cc += [ "-Wnon-virtual-dtor" ]
    332 
    333     if (is_clang) {
    334       cflags += [
    335         "-Weverything",
    336         "-Wno-unknown-warning-option",  # Let older Clangs ignore newer Clangs' warnings.
    337       ]
    338 
    339       if ((target_cpu == "x86" && is_android) ||
    340           (target_cpu == "arm" && is_ios)) {
    341         # Clang seems to think new/malloc will only be 4-byte aligned on x86 Android and 32-bit iOS.
    342         # We're pretty sure it's actually 8-byte alignment.
    343         cflags += [ "-Wno-over-aligned" ]
    344       }
    345 
    346       cflags += [
    347         "-Wno-cast-align",
    348         "-Wno-conditional-uninitialized",
    349         "-Wno-conversion",
    350         "-Wno-disabled-macro-expansion",
    351         "-Wno-documentation",
    352         "-Wno-documentation-unknown-command",
    353         "-Wno-double-promotion",
    354         "-Wno-exit-time-destructors",  # TODO: OK outside libskia
    355         "-Wno-float-conversion",
    356         "-Wno-float-equal",
    357         "-Wno-format-nonliteral",
    358         "-Wno-global-constructors",  # TODO: OK outside libskia
    359         "-Wno-gnu-zero-variadic-macro-arguments",
    360         "-Wno-missing-prototypes",
    361         "-Wno-missing-variable-declarations",
    362         "-Wno-pedantic",
    363         "-Wno-reserved-id-macro",
    364         "-Wno-shadow",
    365         "-Wno-shift-sign-overflow",
    366         "-Wno-sign-conversion",
    367         "-Wno-signed-enum-bitfield",
    368         "-Wno-switch-enum",
    369         "-Wno-undef",
    370         "-Wno-unreachable-code",
    371         "-Wno-unreachable-code-break",
    372         "-Wno-unreachable-code-return",
    373         "-Wno-unused-macros",
    374         "-Wno-unused-member-function",
    375       ]
    376       cflags_cc += [
    377         "-Wno-abstract-vbase-init",
    378         "-Wno-weak-vtables",
    379       ]
    380 
    381       # We are unlikely to want to fix these.
    382       cflags += [
    383         "-Wno-covered-switch-default",
    384         "-Wno-deprecated",
    385         "-Wno-implicit-fallthrough",
    386         "-Wno-missing-noreturn",
    387         "-Wno-old-style-cast",
    388         "-Wno-padded",
    389       ]
    390       cflags_cc += [
    391         "-Wno-c++98-compat",
    392         "-Wno-c++98-compat-pedantic",
    393         "-Wno-undefined-func-template",
    394       ]
    395       cflags_objc += [
    396         "-Wno-direct-ivar-access",
    397         "-Wno-objc-interface-ivars",
    398       ]
    399     }
    400   }
    401 }
    402 config("warnings_except_public_headers") {
    403   if (!is_win) {
    404     cflags = [ "-Wno-unused-parameter" ]
    405   }
    406 }
    407 
    408 config("extra_flags") {
    409   cflags = extra_cflags
    410   cflags_c = extra_cflags_c
    411   cflags_cc = extra_cflags_cc
    412   ldflags = extra_ldflags
    413 }
    414 
    415 config("debug_symbols") {
    416   # It's annoying to wait for full debug symbols to push over
    417   # to Android devices.  -gline-tables-only is a lot slimmer.
    418   if (is_android) {
    419     cflags = [ "-gline-tables-only" ]
    420   } else if (is_win) {
    421     cflags = [ "/Zi" ]
    422     ldflags = [ "/DEBUG" ]
    423   } else {
    424     cflags = [ "-g" ]
    425   }
    426 }
    427 
    428 config("no_rtti") {
    429   if (sanitize != "ASAN") {  # -fsanitize=vptr requires RTTI
    430     if (is_win) {
    431       cflags_cc = [ "/GR-" ]
    432     } else {
    433       cflags_cc = [ "-fno-rtti" ]
    434     }
    435   }
    436 }
    437 
    438 config("release") {
    439   if (is_win) {
    440     cflags = [
    441       "/O2",
    442       "/Zc:inline",
    443       "/GS-",
    444     ]
    445     ldflags = [
    446       "/OPT:ICF",
    447       "/OPT:REF",
    448     ]
    449   } else {
    450     cflags = [
    451       "-O3",
    452       "-fdata-sections",
    453       "-ffunction-sections",
    454     ]
    455     if (is_mac || is_ios) {
    456       ldflags = [ "-dead_strip" ]
    457     } else {
    458       ldflags = [ "-Wl,--gc-sections" ]
    459     }
    460   }
    461   defines = [ "NDEBUG" ]
    462 }
    463 
    464 config("executable") {
    465   if (is_android) {
    466     ldflags = [ "-pie" ]
    467   } else if (is_mac) {
    468     ldflags = [ "-Wl,-rpath,@loader_path/." ]
    469   } else if (is_linux) {
    470     ldflags = [
    471       "-rdynamic",
    472       "-Wl,-rpath,\$ORIGIN",
    473     ]
    474   } else if (is_win) {
    475     ldflags = [
    476       "/SUBSYSTEM:CONSOLE",  # Quiet "no subsystem specified; CONSOLE assumed".
    477       "/INCREMENTAL:NO",  # Quiet warnings about failing to incrementally link by never trying to.
    478     ]
    479   }
    480 }
    481 
    482 toolchain("msvc") {
    483   lib_dir_switch = "/LIBPATH:"
    484 
    485   if (msvc == 2015) {
    486     bin = "$windk/VC/bin/amd64"
    487     env_setup = ""
    488     if (target_cpu == "x86") {
    489       bin += "_x86"
    490       env_setup = "cmd /c $windk/win_sdk/bin/SetEnv.cmd /x86 && "
    491     }
    492   } else {
    493     bin = "$windk/VC/Tools/MSVC/14.10.25017/bin/HostX64/$target_cpu"
    494     env_setup = ""
    495     if (target_cpu == "x86") {
    496       print("Be sure to run")
    497       print("$windk/VC/Auxiliary/Build/vcvarsall.bat amd64_x86")
    498       print("to set up your environment before running ninja.")
    499     }
    500   }
    501 
    502   tool("asm") {
    503     command = "$env_setup$bin/ml64.exe /nologo /c /Fo {{output}} {{source}}"
    504     outputs = [
    505       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
    506     ]
    507     description = "assemble {{source}}"
    508   }
    509 
    510   tool("cc") {
    511     rspfile = "{{output}}.rsp"
    512     precompiled_header_type = "msvc"
    513     pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
    514 
    515     # Label names may have spaces so pdbname must be quoted.
    516     command = "$env_setup$bin/cl.exe /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
    517     depsformat = "msvc"
    518     outputs = [
    519       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
    520     ]
    521     rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
    522     description = "compile {{source}}"
    523   }
    524 
    525   tool("cxx") {
    526     rspfile = "{{output}}.rsp"
    527     precompiled_header_type = "msvc"
    528     pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
    529 
    530     # Label names may have spaces so pdbname must be quoted.
    531     command = "$env_setup$bin/cl.exe /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
    532     depsformat = "msvc"
    533     outputs = [
    534       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
    535     ]
    536     rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
    537     description = "compile {{source}}"
    538   }
    539 
    540   tool("alink") {
    541     rspfile = "{{output}}.rsp"
    542 
    543     command = "$env_setup$bin/lib.exe /nologo /ignore:4221 {{arflags}} /OUT:{{output}} @$rspfile"
    544     outputs = [
    545       # Ignore {{output_extension}} and always use .lib, there's no reason to
    546       # allow targets to override this extension on Windows.
    547       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
    548     ]
    549     default_output_extension = ".lib"
    550     default_output_dir = "{{target_out_dir}}"
    551 
    552     # inputs_newline works around a fixed per-line buffer size in the linker.
    553     rspfile_content = "{{inputs_newline}}"
    554     description = "link {{output}}"
    555   }
    556 
    557   tool("solink") {
    558     dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
    559     libname = "${dllname}.lib"
    560     pdbname = "${dllname}.pdb"
    561     rspfile = "${dllname}.rsp"
    562 
    563     command = "$env_setup$bin/link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile"
    564     outputs = [
    565       dllname,
    566       libname,
    567       pdbname,
    568     ]
    569     default_output_extension = ".dll"
    570     default_output_dir = "{{root_out_dir}}"
    571 
    572     link_output = libname
    573     depend_output = libname
    574     runtime_outputs = [
    575       dllname,
    576       pdbname,
    577     ]
    578 
    579     # I don't quite understand this.  Aping Chrome's toolchain/win/BUILD.gn.
    580     restat = true
    581 
    582     # inputs_newline works around a fixed per-line buffer size in the linker.
    583     rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
    584     description = "link {{output}}"
    585   }
    586 
    587   tool("link") {
    588     exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
    589     pdbname = "$exename.pdb"
    590     rspfile = "$exename.rsp"
    591 
    592     command =
    593         "$env_setup$bin/link.exe /nologo /OUT:$exename /PDB:$pdbname @$rspfile"
    594 
    595     default_output_extension = ".exe"
    596     default_output_dir = "{{root_out_dir}}"
    597     outputs = [
    598       exename,
    599     ]
    600 
    601     # inputs_newline works around a fixed per-line buffer size in the linker.
    602     rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
    603     description = "link {{output}}"
    604   }
    605 
    606   tool("stamp") {
    607     command = "$stamp {{output}}"
    608     description = "stamp {{output}}"
    609   }
    610 
    611   tool("copy") {
    612     cp_py = rebase_path("cp.py")
    613     command = "$python $cp_py {{source}} {{output}}"
    614     description = "copy {{source}} {{output}}"
    615   }
    616 }
    617 
    618 toolchain("gcc_like") {
    619   lib_switch = "-l"
    620   lib_dir_switch = "-L"
    621 
    622   tool("cc") {
    623     depfile = "{{output}}.d"
    624     command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
    625     depsformat = "gcc"
    626     outputs = [
    627       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
    628     ]
    629     description = "compile {{source}}"
    630   }
    631 
    632   tool("cxx") {
    633     depfile = "{{output}}.d"
    634     command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
    635     depsformat = "gcc"
    636     outputs = [
    637       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
    638     ]
    639     description = "compile {{source}}"
    640   }
    641 
    642   tool("objc") {
    643     depfile = "{{output}}.d"
    644     command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}"
    645     depsformat = "gcc"
    646     outputs = [
    647       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
    648     ]
    649     description = "compile {{source}}"
    650   }
    651 
    652   tool("objcxx") {
    653     depfile = "{{output}}.d"
    654     command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objc}} -c {{source}} -o {{output}}"
    655     depsformat = "gcc"
    656     outputs = [
    657       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
    658     ]
    659     description = "compile {{source}}"
    660   }
    661 
    662   tool("asm") {
    663     depfile = "{{output}}.d"
    664     command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
    665     depsformat = "gcc"
    666     outputs = [
    667       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
    668     ]
    669     description = "compile {{source}}"
    670   }
    671 
    672   tool("alink") {
    673     rspfile = "{{output}}.rsp"
    674     rspfile_content = "{{inputs}}"
    675     ar_py = rebase_path("ar.py")
    676     command = "$python $ar_py $ar {{output}} $rspfile"
    677     outputs = [
    678       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
    679     ]
    680     default_output_extension = ".a"
    681     output_prefix = "lib"
    682     description = "link {{output}}"
    683   }
    684 
    685   tool("solink") {
    686     soname = "{{target_output_name}}{{output_extension}}"
    687 
    688     rpath = "-Wl,-soname,$soname"
    689     if (is_mac) {
    690       rpath = "-Wl,-install_name,@rpath/$soname"
    691     }
    692 
    693     command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
    694     outputs = [
    695       "{{root_out_dir}}/$soname",
    696     ]
    697     output_prefix = "lib"
    698     default_output_extension = ".so"
    699     description = "link {{output}}"
    700   }
    701 
    702   tool("link") {
    703     command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
    704     outputs = [
    705       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
    706     ]
    707     description = "link {{output}}"
    708   }
    709 
    710   tool("stamp") {
    711     command = "$stamp {{output}}"
    712     description = "stamp {{output}}"
    713   }
    714 
    715   tool("copy") {
    716     cp_py = rebase_path("cp.py")
    717     command = "$python $cp_py {{source}} {{output}}"
    718     description = "copy {{source}} {{output}}"
    719   }
    720 }
    721