dart-sdk/build/config/BUILDCONFIG.gn
Jonas Termansen a19d3f3375 [infra] Support testing with RBE on Windows.
Place the windows toolchain in the build root so it can be sent to RBE.

Use relative paths in debug symbols when building with Windows clang,
which is needed for remotely building with RBE.

Set the executable bit when invoking clang-cl remotely as it has not
been set on Windows RBE clients.

Stop including .rst files during build commands as @options-from-file
is not supported by rewrapper at this time.

Forward RBE_cfg into the msvc build environment and rewrite the
INCLUDE, LIB, and LIBPATH environment variables to use relative paths
instead of absolute paths.

Don't download reclient on windows-arm64 where there is no cipd
package and the windows-arm64 python lies and says it's x64 because
they actually packaged a x64 python.

Tune the Windows -j performance to match the historic bot performance
as most casual Windows machines won't handle -j 1000 well.

Bug: b/296994239
Change-Id: I2bd1b4478fca796f0a326c062a5f478f16c2c6ef
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/343440
Reviewed-by: William Hesse <whesse@google.com>
Commit-Queue: Jonas Termansen <sortie@google.com>
2024-02-29 10:33:09 +00:00

559 lines
18 KiB
Plaintext

# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# =============================================================================
# PLATFORM SELECTION
# =============================================================================
#
# There are two main things to set: "os" and "cpu". The "toolchain" is the name
# of the GN thing that encodes combinations of these things.
#
# Users typically only set the variables "target_os" and "target_cpu" in "gn
# args", the rest are set up by our build and internal to GN.
#
# There are three different types of each of these things: The "host"
# represents the computer doing the compile and never changes. The "target"
# represents the main thing we're trying to build. The "current" represents
# which configuration is currently being defined, which can be either the
# host, the target, or something completely different (like nacl). GN will
# run the same build file multiple times for the different required
# configuration in the same build.
#
# This gives the following variables:
# - host_os, host_cpu, host_toolchain
# - target_os, target_cpu, default_toolchain
# - current_os, current_cpu, current_toolchain.
#
# Note the default_toolchain isn't symmetrical (you would expect
# target_toolchain). This is because the "default" toolchain is a GN built-in
# concept, and "target" is something our build sets up that's symmetrical with
# its GYP counterpart. Potentially the built-in default_toolchain variable
# could be renamed in the future.
#
# When writing build files, to do something only for the host:
# if (current_toolchain == host_toolchain) { ...
if (target_os == "") {
target_os = host_os
}
assert(host_cpu != "")
assert(target_cpu != "")
if (current_cpu == "") {
current_cpu = target_cpu
}
if (current_os == "") {
current_os = target_os
}
# =============================================================================
# BUILD FLAGS
# =============================================================================
#
# This block lists input arguments to the build, along with their default
# values.
#
# If a value is specified on the command line, it will overwrite the defaults
# given in a declare_args block, otherwise the default will be used.
#
# YOU SHOULD ALMOST NEVER NEED TO ADD FLAGS TO THIS FILE. GN allows any file in
# the build to declare build flags. If you need a flag for a single component,
# you can just declare it in the corresponding BUILD.gn file. If you need a
# flag in multiple components, there are a few options:
#
# - If your feature is a single target, say //components/foo, and the targets
# depending on foo need to have some define set if foo is enabled: (1) Write
# a declare_args block in foo's BUILD.gn file listing your enable_foo build
# flag. (2) Write a config in that file listing the define, and list that
# config in foo's public_configs. This will propagate that define to all the
# targets depending on foo. (3) When foo is not enabled, just make it expand
# to an empty group (or whatever's appropriate for the "off" state of your
# feature.
#
# - If a semi-random set of targets need to know about a define: (1) In the
# lowest level of the build that knows about this feature, add a declare_args
# block in the build file for your enable flag. (2) Write a config that adds
# a define conditionally based on that build flags. (3) Manually add that
# config to the "configs" applying to the targets that need the define.
#
# - If a semi-random set of targets need to know about the build flag (to do
# file inclusion or exclusion, more than just defines): (1) Write a .gni file
# in the lowest-level directory that knows about the feature. (2) Put the
# declare_args block with your build flag in that .gni file. (3) Import that
# .gni file from the BUILD.gn files that need the flag.
#
# Other advice:
#
# - Use boolean values when possible. If you need a default value that expands
# to some complex thing in the default case (like the location of the
# compiler which would be computed by a script), use a default value of -1 or
# the empty string. Outside of the declare_args block, conditionally expand
# the default value as necessary.
#
# - Use a name like "use_foo" or "is_foo" (whatever is more appropriate for
# your feature) rather than just "foo".
#
# - Write good comments directly above the declaration with no blank line.
# These comments will appear as documentation in "gn args --list".
#
# - Don't call exec_script inside declare_args. This will execute the script
# even if the value is overridden, which is wasteful. See first bullet.
# There is no component build for the Dart VM, but build files in some
# dependencies check this.
is_component_build = false
declare_args() {
# Debug build.
is_debug = true
# Release build.
is_release = false
# Product build.
is_product = false
# Set to true when compiling with the Clang compiler. Typically this is used
# to configure warnings.
is_clang = current_os == "mac" || current_os == "linux"
# Compile for Address Sanitizer to find memory bugs.
is_asan = false
# Compile for Leak Sanitizer to find leaks.
is_lsan = false
# Compile for Memory Sanitizer to find uninitialized reads.
is_msan = false
# Compile for Thread Sanitizer to find threading bugs.
is_tsan = false
# Compile for Undefined Behavior Sanitizer to find reliance on undefined behavior.
is_ubsan = false
# Compile for execution in user-mode QEMU.
is_qemu = false
# protobuf-gn fails to build if this argument isn't defined. This should never
# be set to true, becuase we never build within the Fuchsia tree.
is_fuchsia_tree = false
}
# =============================================================================
# OS DEFINITIONS
# =============================================================================
#
# We set these various is_FOO booleans for convenience in writing OS-based
# conditions.
#
# - is_android, is_chromeos, is_ios, and is_win should be obvious.
# - is_mac is set only for desktop Mac. It is not set on iOS.
# - is_posix is true for mac and any Unix-like system (basically everything
# except Windows).
# - is_linux is true for desktop Linux and ChromeOS, but not Android (which is
# generally too different despite being based on the Linux kernel).
#
# Do not add more is_* variants here for random lesser-used Unix systems like
# aix or one of the BSDs. If you need to check these, just check the
# current_os value directly.
if (current_os == "win") {
is_android = false
is_chromeos = false
is_fuchsia = false
is_ios = false
is_linux = false
is_mac = false
is_nacl = false
is_posix = false
is_win = true
} else if (current_os == "mac") {
is_android = false
is_chromeos = false
is_fuchsia = false
is_ios = false
is_linux = false
is_mac = true
is_nacl = false
is_posix = true
is_win = false
} else if (current_os == "android") {
is_android = true
is_chromeos = false
is_fuchsia = false
is_ios = false
is_linux = false
is_mac = false
is_nacl = false
is_posix = true
is_win = false
} else if (current_os == "linux") {
is_android = false
is_chromeos = false
is_fuchsia = false
is_ios = false
is_linux = true
is_mac = false
is_nacl = false
is_posix = true
is_win = false
} else if (current_os == "fuchsia") {
is_android = false
is_chromeos = false
is_fuchsia = true
is_ios = false
is_linux = false
is_mac = false
is_nacl = false
is_posix = true
is_win = false
}
# =============================================================================
# BUILD OPTIONS
# =============================================================================
use_flutter_cxx = is_clang && (is_msan || is_tsan)
# =============================================================================
# TARGET DEFAULTS
# =============================================================================
#
# Set up the default configuration for every build target of the given type.
# The values configured here will be automatically set on the scope of the
# corresponding target. Target definitions can add or remove to the settings
# here as needed.
# Holds all configs used for making native executables and libraries, to avoid
# duplication in each target below.
_native_compiler_configs = [
"//build/config/compiler:compiler",
"//build/config/compiler:cxx_version_default",
"//build/config/compiler:clang_stackrealign",
"//build/config/compiler:compiler_arm_fpu",
"//build/config/compiler:compiler_arm_thumb",
"//build/config/compiler:chromium_code",
"//build/config/compiler:default_include_dirs",
"//build/config/compiler:no_rtti",
"//build/config/compiler:runtime_library",
]
if (use_flutter_cxx) {
_native_compiler_configs += [
"//third_party/libcxxabi:libcxxabi_config",
"//third_party/libcxx:libcxx_config",
]
}
if (is_win) {
_native_compiler_configs += [
"//build/config/win:lean_and_mean",
"//build/config/win:nominmax",
"//build/config/win:sdk",
"//build/config/win:unicode",
"//build/config/win:winver",
]
if (is_clang) {
_native_compiler_configs += [
"//build/config/win:relative_paths",
]
}
}
if (is_posix) {
_native_compiler_configs += [
"//build/config/gcc:relative_paths",
"//build/config/gcc:symbol_visibility_hidden",
]
}
if (is_fuchsia) {
_native_compiler_configs += [
"//build/config/fuchsia:compiler",
"//build/config/fuchsia:runtime_library",
]
}
if (is_linux) {
_native_compiler_configs += [ "//build/config/linux:sdk" ]
} else if (is_mac) {
_native_compiler_configs += [ "//build/config/mac:sdk" ]
} else if (is_android) {
_native_compiler_configs += [ "//build/config/android:sdk" ]
}
if (is_clang) {
_native_compiler_configs += [ "//build/config/clang:extra_warnings" ]
}
# Optimizations and debug checking.
if (is_debug) {
_native_compiler_configs += [ "//build/config:debug" ]
_default_optimization_config = "//build/config/compiler:no_optimize"
} else if (is_release) {
_native_compiler_configs += [ "//build/config:release" ]
_default_optimization_config = "//build/config/compiler:optimize"
} else {
assert(is_product)
_native_compiler_configs += [ "//build/config:product" ]
_default_optimization_config = "//build/config/compiler:optimize"
}
_native_compiler_configs += [ _default_optimization_config ]
# zlib's BUILD.gn expects to have this config among default configs.
_native_compiler_configs += [ "//build/config/compiler:default_optimization" ]
# Symbol setup.
_default_symbols_config = "//build/config/compiler:symbols"
_native_compiler_configs += [ _default_symbols_config ]
# Windows linker setup for EXEs and DLLs.
if (is_win) {
_windows_linker_configs = [
"//build/config/win:default_incremental_linking",
"//build/config/win:sdk_link",
"//build/config/win:common_linker_setup",
# Default to console-mode apps. Most of our targets are tests and such
# that shouldn't use the windows subsystem.
"//build/config/win:console",
]
}
# Executable defaults.
_executable_configs = _native_compiler_configs
if (is_win) {
_executable_configs += _windows_linker_configs
} else if (is_mac) {
_executable_configs += [
"//build/config/mac:mac_dynamic_flags",
"//build/config/mac:mac_executable_flags",
]
} else if (is_linux) {
_executable_configs += [
"//build/config/gcc:executable_ldconfig",
"//build/config/linux:executable_config",
]
} else if (is_android) {
_executable_configs += [
"//build/config/gcc:executable_ldconfig",
"//build/config/android:executable_config",
]
}
set_defaults("executable") {
configs = _executable_configs
}
# Static library defaults.
set_defaults("static_library") {
configs = _native_compiler_configs
}
# Shared library defaults (also for components in component mode).
_shared_library_configs =
_native_compiler_configs + [ "//build/config:shared_library_config" ]
if (is_win) {
_shared_library_configs += _windows_linker_configs
} else if (is_mac) {
_shared_library_configs += [ "//build/config/mac:mac_dynamic_flags" ]
}
set_defaults("shared_library") {
configs = _shared_library_configs
}
# Source set defaults (also for components in non-component mode).
set_defaults("source_set") {
configs = _native_compiler_configs
}
set_defaults("component") {
configs = _native_compiler_configs
}
# ==============================================================================
# TOOLCHAIN SETUP
# ==============================================================================
#
# Here we set the default toolchain, as well as the variable host_toolchain
# 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) {
if (is_clang) {
host_toolchain = "//build/toolchain/win:clang_$host_cpu"
set_default_toolchain("//build/toolchain/win:clang_$current_cpu")
} else {
host_toolchain = "//build/toolchain/win:$host_cpu"
set_default_toolchain("//build/toolchain/win:$current_cpu")
}
} else if (is_android) {
if (host_os == "linux") {
if (host_cpu == "x86" || host_cpu == "x64") {
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
} else {
host_toolchain = "//build/toolchain/linux:$host_cpu"
}
} else if (host_os == "mac") {
host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
} else {
assert(false, "Unknown host for android cross compile")
}
if (is_clang) {
set_default_toolchain("//build/toolchain/android:clang_$current_cpu")
} else {
set_default_toolchain("//build/toolchain/android:$current_cpu")
}
} else if (is_linux) {
if (is_clang) {
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
set_default_toolchain("//build/toolchain/linux:clang_$current_cpu")
} else {
host_toolchain = "//build/toolchain/linux:$host_cpu"
set_default_toolchain("//build/toolchain/linux:$current_cpu")
}
} else if (is_mac) {
host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
set_default_toolchain("//build/toolchain/mac:clang_$current_cpu")
} else if (is_fuchsia) {
assert(host_cpu == "x64")
if (host_os == "linux") {
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
set_default_toolchain("//build/toolchain/fuchsia")
} else if (host_os == "mac") {
host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
set_default_toolchain("//build/toolchain/fuchsia")
} else {
assert(false, "Unknown host for fuchsia cross compile")
}
}
# Sets default dependencies for executable and shared_library targets.
#
# Variables
# no_default_deps: If true, no standard dependencies will be added.
foreach(_target_type,
[
"executable",
"loadable_module",
"shared_library",
]) {
template(_target_type) {
target(_target_type, target_name) {
forward_variables_from(invoker, "*", [ "no_default_deps" ])
if (!defined(deps)) {
deps = []
}
if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) {
if (use_flutter_cxx) {
deps += [ "//third_party/libcxx" ]
}
if (is_fuchsia) {
deps += [
"//build/config/fuchsia:runtime_library_group",
"//build/fuchsia/config/clang:c++-runtime-deps",
]
}
}
}
}
}
# ==============================================================================
# COMPONENT SETUP
# ==============================================================================
# Don't try to do component builds for the standalone Dart VM.
assert(!is_component_build)
component_mode = "source_set"
template("component") {
source_set(target_name) {
# See above.
configs = [] # Prevent list overwriting warning.
configs = invoker.configs
if (defined(invoker.all_dependent_configs)) {
all_dependent_configs = invoker.all_dependent_configs
}
if (defined(invoker.allow_circular_includes_from)) {
allow_circular_includes_from = invoker.allow_circular_includes_from
}
if (defined(invoker.cflags)) {
cflags = invoker.cflags
}
if (defined(invoker.cflags_c)) {
cflags_c = invoker.cflags_c
}
if (defined(invoker.cflags_cc)) {
cflags_cc = invoker.cflags_cc
}
if (defined(invoker.cflags_objc)) {
cflags_objc = invoker.cflags_objc
}
if (defined(invoker.cflags_objcc)) {
cflags_objcc = invoker.cflags_objcc
}
if (defined(invoker.check_includes)) {
check_includes = invoker.check_includes
}
if (defined(invoker.data)) {
data = invoker.data
}
if (defined(invoker.data_deps)) {
data_deps = invoker.data_deps
}
if (defined(invoker.datadeps)) {
datadeps = invoker.datadeps
}
if (defined(invoker.defines)) {
defines = invoker.defines
}
if (defined(invoker.deps)) {
deps = invoker.deps
}
if (defined(invoker.direct_dependent_configs)) {
direct_dependent_configs = invoker.direct_dependent_configs
}
if (defined(invoker.forward_dependent_configs_from)) {
forward_dependent_configs_from = invoker.forward_dependent_configs_from
}
if (defined(invoker.include_dirs)) {
include_dirs = invoker.include_dirs
}
if (defined(invoker.ldflags)) {
ldflags = invoker.ldflags
}
if (defined(invoker.lib_dirs)) {
lib_dirs = invoker.lib_dirs
}
if (defined(invoker.libs)) {
libs = invoker.libs
}
if (defined(invoker.output_extension)) {
output_extension = invoker.output_extension
}
if (defined(invoker.output_name)) {
output_name = invoker.output_name
}
if (defined(invoker.public)) {
public = invoker.public
}
if (defined(invoker.public_configs)) {
public_configs = invoker.public_configs
}
if (defined(invoker.public_deps)) {
public_deps = invoker.public_deps
}
if (defined(invoker.sources)) {
sources = invoker.sources
}
if (defined(invoker.testonly)) {
testonly = invoker.testonly
}
if (defined(invoker.visibility)) {
visibility = invoker.visibility
}
}
}