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