# Copyright 2016 Google Inc. # # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. declare_args() { ar = "ar" cc = "cc" cxx = "c++" if (is_android) { ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar" cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang" cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++" } windk = "" extra_cflags = "" extra_cflags_c = "" extra_cflags_cc = "" extra_ldflags = "" cc_wrapper = "" } is_clang = exec_script("is_clang.py", [ cc, cxx, ], "value") config("default") { asmflags = [] cflags = [] cflags_c = [] cflags_cc = [] defines = [] ldflags = [] if (is_win) { cflags += [ "/FS", # Preserve previous PDB behavior. "/bigobj", # Some of our files are bigger than the regular limits. ] cflags_c += [ "/TC" ] cflags_cc += [ "/TP" ] defines += [ "_HAS_EXCEPTIONS=0", "WIN32_LEAN_AND_MEAN", "NOMINMAX", ] } else { cflags += [ "-O1", "-fstrict-aliasing", "-fPIC", "-fvisibility=hidden", "-Werror", "-Wall", "-Wextra", "-Winit-self", "-Wpointer-arith", "-Wsign-compare", "-Wvla", "-Wno-deprecated-declarations", "-Wno-unused-parameter", ] cflags_cc += [ "-std=c++11", "-fno-exceptions", "-fno-threadsafe-statics", "-fvisibility-inlines-hidden", "-Wnon-virtual-dtor", ] if (is_clang) { cflags += [ "-Weverything", "-Wno-unknown-warning-option", # Let older Clangs ignore newer Clangs' warnings. ] if (is_android && target_cpu == "x86") { # Clang seems to think new/malloc will only be 4-byte aligned on x86 Android. # We're pretty sure it's actually 8-byte alignment. cflags += [ "-Wno-over-aligned" ] } cflags += [ "-Wno-cast-align", "-Wno-conditional-uninitialized", "-Wno-conversion", "-Wno-disabled-macro-expansion", "-Wno-documentation", "-Wno-documentation-unknown-command", "-Wno-double-promotion", "-Wno-exit-time-destructors", # TODO: OK outside libskia "-Wno-float-conversion", "-Wno-float-equal", "-Wno-format-nonliteral", "-Wno-global-constructors", # TODO: OK outside libskia "-Wno-gnu-zero-variadic-macro-arguments", "-Wno-missing-prototypes", "-Wno-missing-variable-declarations", "-Wno-pedantic", "-Wno-reserved-id-macro", "-Wno-shadow", "-Wno-shift-sign-overflow", "-Wno-sign-conversion", "-Wno-switch-enum", "-Wno-undef", "-Wno-unreachable-code", "-Wno-unreachable-code-break", "-Wno-unreachable-code-return", "-Wno-unused-macros", "-Wno-unused-member-function", ] cflags_cc += [ "-Wno-abstract-vbase-init", "-Wno-range-loop-analysis", "-Wno-weak-vtables", ] # We are unlikely to want to fix these. cflags += [ "-Wno-covered-switch-default", "-Wno-deprecated", "-Wno-implicit-fallthrough", "-Wno-missing-noreturn", "-Wno-old-style-cast", "-Wno-padded", ] cflags_cc += [ "-Wno-c++98-compat", "-Wno-c++98-compat-pedantic", "-Wno-undefined-func-template", ] } } if (current_cpu == "arm") { cflags += [ "-march=armv7-a", "-mfpu=neon", "-mthumb", ] } else if (current_cpu == "mipsel") { cflags += [ "-march=mips32r2", "-mdspr2", ] } else if (current_cpu == "x86") { asmflags += [ "-m32" ] cflags += [ "-m32", "-msse2", "-mfpmath=sse", ] ldflags += [ "-m32" ] } if (is_android) { asmflags += [ "--target=$ndk_target", "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin", ] cflags += [ "--sysroot=$ndk/platforms/$ndk_platform", "--target=$ndk_target", "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin", ] cflags_cc += [ "-isystem$ndk/sources/android/support/include", "-isystem$ndk/sources/cxx-stl/llvm-libc++/libcxx/include", ] ldflags += [ "--sysroot=$ndk/platforms/$ndk_platform", "--target=$ndk_target", "-B$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin", "-pie", ] lib_dirs = [ "$ndk/sources/cxx-stl/llvm-libc++/libs/$ndk_stdlib", "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/lib/gcc/$ndk_target/4.9.x", ] libs = [ # Order matters here! Keep these three in exactly this order. "c++_static", "c++abi", "android_support", ] if (target_cpu == "arm") { libs += [ "unwind" ] } } if (is_linux) { libs = [ "pthread" ] } if (sanitize != "") { # You can either pass the sanitizers directly, e.g. "address,undefined", # or pass one of the couple common aliases used by the bots. sanitizers = sanitize if (sanitize == "ASAN") { 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" } else if (sanitize == "TSAN") { sanitizers = "thread" } else if (sanitize == "MSAN") { sanitizers = "memory" } cflags += [ "-fsanitize=$sanitizers", "-fno-sanitize-recover=$sanitizers", "-fsanitize-blacklist=" + rebase_path("../tools/xsan.blacklist"), ] ldflags += [ "-fsanitize=$sanitizers" ] if (sanitizers == "memory") { cflags += [ "-fsanitize-memory-track-origins" ] cflags_cc += [ "-stdlib=libc++" ] ldflags += [ "-stdlib=libc++" ] } } } config("debug_symbols") { # It's annoying to wait for full debug symbols to push over # to Android devices. -gline-tables-only is a lot slimmer. if (is_android) { cflags = [ "-gline-tables-only" ] } else if (!is_win) { cflags = [ "-g" ] } } config("no_rtti") { if (sanitize != "ASAN") { # -fsanitize=vptr requires RTTI if (!is_win) { cflags_cc = [ "-fno-rtti" ] } } } config("release") { if (!is_win) { cflags = [ "-O3" ] } defines = [ "NDEBUG" ] } config("executable") { if (is_mac) { ldflags = [ "-Wl,-rpath,@loader_path/." ] } else if (is_linux) { ldflags = [ "-rdynamic", "-Wl,-rpath,\$ORIGIN", ] } } toolchain("msvc") { vc = "$windk\VC\bin\amd64\cl.exe" vlink = "$windk\VC\bin\amd64\link.exe" vlib = "$windk\VC\bin\amd64\lib.exe" # TODO: add a python function that generates the includes using /win_sdk/bin/SetEnv..json windk_include_dirs = "/I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\um /I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\shared /I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\winrt /I$windk\win_sdk\bin\..\..\win_sdk\Include\10.0.10586.0\ucrt /I$windk\win_sdk\bin\..\..\VC\include /I$windk\win_sdk\bin\..\..\VC\atlmfc\include " tool("cc") { rspfile = "{{output}}.rsp" precompiled_header_type = "msvc" pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" # Label names may have spaces in them so the pdbname must be quoted. The # source and output don't need to be quoted because GN knows they're a # full file name and will quote automatically when necessary. command = "$vc /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" depsformat = "msvc" description = "CC {{output}}" outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj", # "$object_subdir/{{source_name_part}}.obj", ] rspfile_content = "$windk_include_dirs {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}" } tool("cxx") { rspfile = "{{output}}.rsp" precompiled_header_type = "msvc" pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" # Label names may have spaces in them so the pdbname must be quoted. The # source and output don't need to be quoted because GN knows they're a # full file name and will quote automatically when necessary. command = "$vc /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" depsformat = "msvc" description = "C++ {{output}}" outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj", ] rspfile_content = "$windk_include_dirs {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}" } tool("alink") { rspfile = "{{output}}.rsp" # gyp_win_tool_path = rebase_path("../third_party/externals/gyp/pylib/gyp/win_tool.py") command = "$vlib /nologo {{arflags}} /OUT:{{output}} @$rspfile" description = "LIB {{output}}" outputs = [ # Ignore {{output_extension}} and always use .lib, there's no reason to # allow targets to override this extension on Windows. "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", ] default_output_extension = ".lib" default_output_dir = "{{target_out_dir}}" # The use of inputs_newline is to work around a fixed per-line buffer # size in the linker. rspfile_content = "{{inputs_newline}}" } tool("link") { exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" pdbname = "$exename.pdb" rspfile = "$exename.rsp" # gyp_win_tool_path = rebase_path("../third_party/externals/gyp/pylib/gyp/win_tool.py") command = "$vlink /nologo /OUT:$exename /PDB:$pdbname @$rspfile" default_output_extension = ".exe" default_output_dir = "{{root_out_dir}}" description = "LINK {{output}}" outputs = [ #"{{root_out_dir}}/{{target_output_name}}{{output_extension}}", exename, ] #if (symbol_level != 0) { # outputs += [ pdbname ] #} #runtime_outputs = outputs # The use of inputs_newline is to work around a fixed per-line buffer # size in the linker. rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" } tool("stamp") { win_stamp_path = rebase_path("win_stamp.py") command = "python $win_stamp_path {{output}}" } } toolchain("gcc_like") { lib_switch = "-l" lib_dir_switch = "-L" tool("cc") { depfile = "{{output}}.d" command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} $extra_cflags $extra_cflags_c -c {{source}} -o {{output}}" depsformat = "gcc" outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", ] description = "$cc_wrapper $cc ... $extra_cflags $extra_cflags_c -o {{output}}" } tool("cxx") { depfile = "{{output}}.d" command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} $extra_cflags $extra_cflags_cc -c {{source}} -o {{output}}" depsformat = "gcc" outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", ] description = "$cc_wrapper $cxx ... $extra_cflags $extra_cflags_cc -o {{output}}" } tool("asm") { depfile = "{{output}}.d" command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}" depsformat = "gcc" outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", ] description = "$cc_wrapper $cc ... -o {{output}}" } tool("alink") { command = "rm -f {{output}} && $ar rcs {{output}} {{inputs}}" outputs = [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", ] default_output_extension = ".a" output_prefix = "lib" description = "$ar {{output}} ..." } tool("solink") { soname = "{{target_output_name}}{{output_extension}}" rpath = "-Wl,-soname,$soname" if (is_mac) { rpath = "-Wl,-install_name,@rpath/$soname" } command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath $extra_ldflags -o {{output}}" outputs = [ "{{root_out_dir}}/$soname", ] output_prefix = "lib" default_output_extension = ".so" description = "$cc_wrapper $cxx -shared ... $extra_ldflags -o {{output}}" } tool("link") { command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} $extra_ldflags -o {{output}}" outputs = [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}", ] description = "$cc_wrapper $cxx ... $extra_ldflags -o {{output}}" } tool("stamp") { command = "touch {{output}}" } tool("copy") { command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})" } }