blob: e920f0314b79ac9b436f55631c290aecfa8968b6 [file] [log] [blame]
# Copyright 2025 Google LLC.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# These rules invoke Python scripts to build Tint and Dawn using CMake. We use
# CMake instead of the GN rules because Dawn/Tint's GN rules require Chromium's
# toolchain, which we, Skia, do not want to have a dependency on.
# The result is a single static library that can be linked into Skia.
import("//third_party/dawn/args.gni")
if (is_win) {
# On Windows, the normal cc/cxx variables are just "clang" and "clang++"
# which are not found in the path. CMake needs the full path.
if (is_clang) {
assert(clang_win != "",
"clang_win must be set when is_clang is true on Windows")
_cc = "$clang_win/bin/clang-cl.exe"
_cxx = "$clang_win/bin/clang-cl.exe"
} else {
_cc = "$win_vc/Tools/MSVC/$win_toolchain_version/bin/HostX64/$target_cpu/cl.exe"
_cxx = "$win_vc/Tools/MSVC/$win_toolchain_version/bin/HostX64/$target_cpu/cl.exe"
}
_dawn_lib_name = "dawn_combined.lib"
_tint_lib_name = "tint_combined.lib"
} else {
_cc = cc
_cxx = cxx
_dawn_lib_name = "libdawn_combined.a"
_tint_lib_name = "libtint_combined.a"
}
config("tint_api_config") {
include_dirs = [
"../externals/dawn",
"../externals/dawn/include",
]
defines = [
"TINT_BUILD_WGSL_READER=1",
"TINT_BUILD_WGSL_WRITER=1",
]
# The build script produces a static library for tint in the root output directory.
lib_dirs = [ root_out_dir ]
if (is_win) {
libs = [ "tint_combined.lib" ]
} else {
libs = [ "tint_combined" ]
}
}
# This version of tint is used by skslc, which is used to compile our sksl tests.
# Thus, we do *not* want to pass in the sanitizer args to this target. When
# we build the dawn target below, that will build a new version of tint which
# does use the passed in sanitizer flags.
action("tint_cmake") {
script = "build_tint.py"
sources = [
"build_tint.py",
"cmake_utils.py",
]
# The script will place the final library in this location.
outputs = [ "$root_out_dir/${_tint_lib_name}" ]
# The script also generates a depfile that lists all of Tint's sources. This
# allows Ninja to know when to re-run the build script.
depfile = "$target_gen_dir/${_tint_lib_name}.d"
if (get_label_info(current_toolchain, "name") == host_toolchain) {
_tint_build_dir = "cmake_tint_host"
} else {
_tint_build_dir = "cmake_tint"
}
args = [
"--cc=" + _cc,
"--cxx=" + _cxx,
"--output_path=" + rebase_path(outputs[0], root_build_dir),
"--depfile_path=" + rebase_path(depfile, root_build_dir),
"--target_os=" + host_os,
"--target_cpu=" + host_cpu,
"--build_dir=" + _tint_build_dir,
]
if (is_clang) {
args += [ "--is_clang" ]
}
if (is_debug && !is_win) {
# Skia's GN toolchain for Windows doesn't set build_type to be Debug
# and if Dawn does, that is a mismatch of _ITERATOR_DEBUG_LEVEL
args += [
"--build_type=Debug",
# For performance, set O1 optimization.
"--cxx_flags=-O1",
]
} else {
args += [ "--build_type=Release" ]
}
if (is_win) {
args += [
"--win_sdk=" + win_sdk,
"--win_sdk_version=" + win_sdk_version,
"--win_vc=" + win_vc,
"--win_toolchain_version=" + win_toolchain_version,
]
}
# While we don't need to build tint with our sanitizers, we do need to adjust our target version
# of tint to be built with libc++ if we have set the rest of Skia to be using that.
if (get_label_info(current_toolchain, "name") != host_toolchain) {
if (is_linux && sanitize != "") {
args += [
"--cxx_flags=-stdlib=libc++",
"--ld_flags=-stdlib=libc++",
]
}
if (sanitize == "ASAN") {
# See Skia's GN config("no_rtti")
args += [ "--enable_rtti" ]
}
}
}
group("tint") {
deps = [ ":tint_cmake" ]
public_configs = [ ":tint_api_config" ]
}
config("dawn_api_config") {
include_dirs = [
"../externals/dawn",
"../externals/dawn/include",
"$target_gen_dir/include",
]
lib_dirs = [ root_out_dir ]
if (is_win) {
ldflags = [ "/WHOLEARCHIVE:dawn_combined.lib" ]
libs = [
"dawn_combined.lib",
"onecore.lib",
"user32.lib",
"delayimp.lib",
"dxguid.lib",
"libcpmt.lib",
]
} else {
libs = [ "dawn_combined" ]
}
# https://dawn.googlesource.com/dawn/+/647c352f57aa8a4c2666258455158a36c0c385af/src/dawn/native/BUILD.gn#645
if (is_mac || is_ios) {
frameworks = [
"Foundation.framework",
"IOSurface.framework",
"IOKit.framework",
"Metal.framework",
"QuartzCore.framework",
"Cocoa.framework",
]
}
}
sanitizer_args = []
if (sanitize != "") {
assert(is_clang, "Need to update GN rules to handle non-Clang Sanitizer")
sanitizers = ""
if (sanitize == "ASAN") {
sanitizers = "undefined,address,float-divide-by-zero"
if (is_android) {
sanitizers = "address"
}
if (!is_win) {
# See Skia's GN config("no_rtti")
sanitizer_args += [ "--enable_rtti" ]
}
} else if (sanitize == "TSAN") {
sanitizers = "thread"
} else {
assert(false, "Unsupported sanitizer option")
}
_suppressions = rebase_path("../../tools/xsan.supp")
cxx_flags = [
"-fsanitize=$sanitizers",
"-fno-sanitize-recover=$sanitizers",
"-fsanitize-blacklist=$_suppressions",
"-fno-omit-frame-pointer",
]
ld_flags = [ "-fsanitize=$sanitizers" ]
if (is_linux) {
cxx_flags += [ "-stdlib=libc++" ]
ld_flags += [ "-stdlib=libc++" ]
}
foreach(flag, cxx_flags) {
sanitizer_args += [ "--cxx_flags=" + flag ]
}
foreach(flag, ld_flags) {
sanitizer_args += [ "--ld_flags=" + flag ]
}
}
action("dawn_cmake") {
script = "build_dawn.py"
sources = [
"build_dawn.py",
"cmake_utils.py",
]
outputs = [ "$root_out_dir/${_dawn_lib_name}" ]
depfile = "$target_gen_dir/${_dawn_lib_name}.d"
args = [
"--cc=" + _cc,
"--cxx=" + _cxx,
"--output_path=" + rebase_path(outputs[0], root_build_dir),
"--depfile_path=" + rebase_path(depfile, root_build_dir),
"--gen_dir=" + rebase_path(target_gen_dir, root_build_dir),
"--target_os=" + target_os,
"--target_cpu=" + target_cpu,
"--build_dir=cmake_dawn",
]
if (is_clang) {
args += [ "--is_clang" ]
}
if (is_debug && !is_win) {
args += [
"--build_type=Debug",
# For performance, set O1 optimization.
"--cxx_flags=-O1",
]
} else {
args += [ "--build_type=Release" ]
}
if (is_win) {
args += [
"--win_sdk=" + win_sdk,
"--win_sdk_version=" + win_sdk_version,
"--win_vc=" + win_vc,
"--win_toolchain_version=" + win_toolchain_version,
]
}
if (is_android) {
args += [
"--android_ndk_path=" + ndk,
"--android_platform=android-" + ndk_api,
]
}
if (dawn_enable_d3d11) {
args += [ "--dawn_enable_d3d11=true" ]
} else {
args += [ "--dawn_enable_d3d11=false" ]
}
if (dawn_enable_d3d12) {
args += [ "--dawn_enable_d3d12=true" ]
} else {
args += [ "--dawn_enable_d3d12=false" ]
}
if (dawn_enable_opengles) {
args += [ "--dawn_enable_opengles=true" ]
} else {
args += [ "--dawn_enable_opengles=false" ]
}
if (dawn_enable_metal) {
args += [ "--dawn_enable_metal=true" ]
} else {
args += [ "--dawn_enable_metal=false" ]
}
if (dawn_enable_vulkan) {
args += [ "--dawn_enable_vulkan=true" ]
} else {
args += [ "--dawn_enable_vulkan=false" ]
}
args += sanitizer_args
}
group("dawn") {
public_deps = [ ":dawn_cmake" ]
public_configs = [ ":dawn_api_config" ]
}