diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 584a9159c4..afc827bdab 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -568,8 +568,14 @@ set_defaults("test") { # which will identify the toolchain corresponding to the local system when # doing cross-compiles. When not cross-compiling, this will be the same as the # default toolchain. - -if (is_win) { +import("//build/toolchain/custom/custom.gni") + +if (custom_toolchain != "") { + assert(custom_sysroot != "") + assert(custom_target_triple != "") + host_toolchain = "//build/toolchain/linux:clang_$host_cpu" + set_default_toolchain("//build/toolchain/custom") +} else if (is_win) { # On windows we use the same toolchain for host and target by default. host_toolchain = "//build/toolchain/win:$current_cpu" set_default_toolchain("$host_toolchain") diff --git a/build/toolchain/custom/BUILD.gn b/build/toolchain/custom/BUILD.gn new file mode 100644 index 0000000000..8189b78072 --- /dev/null +++ b/build/toolchain/custom/BUILD.gn @@ -0,0 +1,152 @@ +# Copyright 2017 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/toolchain/custom/custom.gni") + +toolchain("custom") { + toolchain_bin = "${custom_toolchain}/bin" + + # We can't do string interpolation ($ in strings) on things with dots in + # them. To allow us to use $cc below, for example, we create copies of + # these values in our scope. + cc = "${toolchain_bin}/clang" + cxx = "${toolchain_bin}/clang++" + ar = "${toolchain_bin}/${custom_target_triple}-ar" + ld = "${toolchain_bin}/clang++" + readelf = "${toolchain_bin}/${custom_target_triple}-readelf" + nm = "${toolchain_bin}/${custom_target_triple}-nm" + + target_triple_flags = "--target=${custom_target_triple}" + sysroot_flags = "--sysroot ${custom_sysroot}" + + custom_lib_flags = "-L${custom_toolchain}/lib" + + # These library switches can apply to all tools below. + lib_switch = "-l" + lib_dir_switch = "-L" + + tool("cc") { + depfile = "{{output}}.d" + command = "$cc -MMD -MF $depfile $target_triple_flags $sysroot_flags {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" + depsformat = "gcc" + description = "CC {{output}}" + outputs = [ + "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", + ] + } + + tool("cxx") { + depfile = "{{output}}.d" + command = "$cxx -MMD -MF $depfile $target_triple_flags $sysroot_flags {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" + depsformat = "gcc" + description = "CXX {{output}}" + outputs = [ + "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", + ] + } + + tool("asm") { + depfile = "{{output}}.d" + command = "$cc -MMD -MF $depfile $target_triple_flags $sysroot_flags {{defines}} {{include_dirs}} {{asmflags}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" + depsformat = "gcc" + description = "ASM {{output}}" + outputs = [ + "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o", + ] + } + + tool("alink") { + rspfile = "{{output}}.rsp" + command = "rm -f {{output}} && $ar rcs {{output}} @$rspfile" + description = "AR {{output}}" + rspfile_content = "{{inputs}}" + outputs = [ + "{{target_out_dir}}/{{target_output_name}}{{output_extension}}", + ] + default_output_extension = ".a" + output_prefix = "lib" + } + + tool("solink") { + soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so". + sofile = "{{root_out_dir}}/$soname" # Possibly including toolchain dir. + rspfile = sofile + ".rsp" + + # These variables are not built into GN but are helpers that implement + # (1) linking to produce a .so, (2) extracting the symbols from that file + # to a temporary file, (3) if the temporary file has differences from the + # existing .TOC file, overwrite it, otherwise, don't change it. + tocfile = sofile + ".TOC" + temporary_tocname = sofile + ".tmp" + link_command = "$ld $target_triple_flags $sysroot_flags -shared {{ldflags}} -o $sofile $custom_lib_flags -Wl,--build-id -Wl,-soname=$soname @$rspfile" + toc_command = "{ $readelf -d $sofile | grep SONAME ; $nm -gD -f p $sofile | cut -f1-2 -d' '; } > $temporary_tocname" + replace_command = "if ! cmp -s $temporary_tocname $tocfile; then mv $temporary_tocname $tocfile; fi" + + command = "$link_command && $toc_command && $replace_command" + rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}" + + description = "SOLINK $sofile" + + # Use this for {{output_extension}} expansions unless a target manually + # overrides it (in which case {{output_extension}} will be what the target + # specifies). + default_output_extension = ".so" + + output_prefix = "lib" + + # Since the above commands only updates the .TOC file when it changes, ask + # Ninja to check if the timestamp actually changed to know if downstream + # dependencies should be recompiled. + restat = true + + # Tell GN about the output files. It will link to the sofile but use the + # tocfile for dependency management. + outputs = [ + sofile, + tocfile, + ] + + link_output = sofile + depend_output = tocfile + } + + tool("link") { + exename = "{{target_output_name}}{{output_extension}}" + outfile = "{{root_out_dir}}/$exename" + rspfile = "$outfile.rsp" + unstripped_outfile = outfile + command = "$ld $target_triple_flags $sysroot_flags {{ldflags}} -o $unstripped_outfile $custom_lib_flags -Wl,--build-id -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}" + description = "LINK $outfile" + rspfile_content = "{{inputs}}" + outputs = [ + outfile, + ] + if (outfile != unstripped_outfile) { + outputs += [ unstripped_outfile ] + } + } + + tool("stamp") { + command = "touch {{output}}" + description = "STAMP {{output}}" + } + + tool("copy") { + command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})" + description = "COPY {{source}} {{output}}" + } + + # When invoking this toolchain not as the default one, these args will be + # passed to the build. They are ignored when this is the default toolchain. + toolchain_args = { + current_cpu = target_cpu + current_os = target_os + + # These values need to be passed through unchanged. + target_os = target_os + target_cpu = target_cpu + + is_clang = true + } +} diff --git a/build/toolchain/custom/custom.gni b/build/toolchain/custom/custom.gni new file mode 100644 index 0000000000..6d7bc6c5ef --- /dev/null +++ b/build/toolchain/custom/custom.gni @@ -0,0 +1,17 @@ +# Copyright 2018 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + # Path to a custom toolchain containing the compilers, linkers and associated + # tools to build native executables. + custom_toolchain = "" + + # Path to the sysroot containing the system libraries and associated headers + # on the target. Binaries generated on the host will be able to link against + # these libraries. + custom_sysroot = "" + + # The target triple. For example: arm-linux-gnueabihf. + custom_target_triple = "" +} diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn index 27d7bbd973..2ac6755585 100644 --- a/third_party/libpng/BUILD.gn +++ b/third_party/libpng/BUILD.gn @@ -30,8 +30,7 @@ source_set("libpng") { ] if ((is_ios && !use_ios_simulator) || - (is_android && (current_cpu == "arm" || current_cpu == "arm64")) || - (is_linux && (current_cpu == "arm64"))) { + ((is_android || is_linux) && (current_cpu == "arm" || current_cpu == "arm64"))) { if (is_android) { import("//build/config/android/config.gni")