GN: Add standalone build rules for Windows
This cl adds initial build rules that allow building
standalone on Windows using clang-cl (is_clang=true)
or MSVC (is_clang=false). Some other small CLs are
still required but this is a bigger step.
Pending items:
- Look into depot_tools builtin-toolchain for Googlers.
- Right now this works only with Build Tools for Visual Studio
but doesn't work if the user has the full visual studio.
Bug: 174454879
Change-Id: I391a924f6cb721c03588c3bf5900f1c796bbc32c
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index 9527694..6da256e 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -14,69 +14,123 @@
import("//gn/perfetto_check_build_deps.gni")
import("//gn/standalone/android.gni")
+import("//gn/standalone/libc++/libc++.gni")
import("//gn/standalone/sanitizers/sanitizers.gni")
+import("//gn/standalone/toolchain/msvc.gni")
import("//gn/standalone/wasm.gni")
# These warnings have been introduced with the newest version of clang (only in
# the hermetic build) and are enabled just with -Werror.
hermetic_clang_suppressions = [ "-Wno-c99-designator" ]
+# We deal with three toolchains here:
+# 1. Clang, used in most cases.
+# 2. GCC, used in some Linux cases.
+# 3. MSVC, used in some Windows cases.
+# Clang vs gcc is typically not a problem: both support roughly the same
+# switches. -Wno-unknown-warning-option fixes the mismatching ones.
+# The situation on Windows is a bit trickier: clang-cl.exe really pretends to be
+# cl.exe (MSVC), so we should use MSVC-style switches (e.g. /W2). However,
+# clang-cl.exe still supports some -Wclang-style-switches for flags that don't
+# have a corresponding version in MSVC.
+#
+# In the rules below, the conditionals should be interpreted as follows:
+# is_win -> can be either clang-cl.exe or cl.exe (MSVC). Only MSVC-style
+# switches (the common denominator) should be used.
+# is_clang -> could be clang-on-linux, clang-on-mac or clang-cl.exe.
+
config("extra_warnings") {
- cflags = [
- "-Wall",
- "-Wextra",
- "-Wpedantic",
- ]
+ if (is_win) {
+ cflags = [
+ "/W2",
+ "/wd4244", # conversion from 'float' to 'int', possible loss of data
+ "/wd4267", # conversion from 'size_t' to 'int', possible loss of data
+ ]
+ if (is_clang) {
+ cflags += [
+ "-Wno-float-equal",
+ "-Wno-unused-macros",
+ "-Wno-old-style-cast",
+ ]
+ }
+ } else {
+ # Clang or Gcc. On linux, Android and Mac.
+ cflags = [
+ "-Wall",
+ "-Wextra",
+ "-Wpedantic",
+ ]
+ }
# Disable variadic macro warning as we make extensive use of them in trace
# processor and client API.
if (is_clang) {
- cflags += [ "-Wno-gnu-zero-variadic-macro-arguments" ]
- }
-
- # Disable Weverything on fuzzers to avoid breakages when new versions of clang
- # are rolled into OSS-fuzz.
- if (is_clang && !is_fuzzer) {
+ if (!is_fuzzer) {
+ # Disable Weverything on fuzzers to avoid breakages when new versions of
+ # clang are rolled into OSS-fuzz.
+ cflags += [ "-Weverything" ]
+ }
cflags += [
- "-Weverything",
"-Wno-c++98-compat-pedantic",
"-Wno-c++98-compat",
"-Wno-disabled-macro-expansion",
+ "-Wno-documentation-unknown-command",
"-Wno-gnu-include-next",
"-Wno-gnu-statement-expression",
+ "-Wno-gnu-zero-variadic-macro-arguments",
"-Wno-padded",
+ "-Wno-poison-system-directories",
"-Wno-reserved-id-macro",
"-Wno-unknown-sanitizers",
"-Wno-unknown-warning-option",
- "-Wno-poison-system-directories",
]
- }
-
- if (!is_clang) {
- # Use return std::move(...) for compatibility with old compilers.
+ } else if (!is_clang && !is_win) {
+ # Use return std::move(...) for compatibility with old GCC compilers.
cflags += [ "-Wno-redundant-move" ]
}
}
config("no_exceptions") {
- cflags_cc = [ "-fno-exceptions" ]
+ # Exceptions are disabled by default on Windows (Use /EHsc to enable them).
+ if (!is_win) {
+ cflags_cc = [ "-fno-exceptions" ]
+ }
}
config("no_rtti") {
- cflags_cc = [ "-fno-rtti" ]
+ if (is_win) {
+ cflags_cc = [ "/GR-" ]
+ } else {
+ cflags_cc = [ "-fno-rtti" ]
+ }
}
config("c++11") {
- cflags_cc = [ "-std=c++11" ]
+ # C++11 is the default on Windows.
+ if (!is_win) {
+ cflags_cc = [ "-std=c++11" ]
+ }
}
# This is needed to compile libunwindstack.
config("c++17") {
- cflags_cc = [ "-std=c++17" ]
+ if (is_win) {
+ cflags_cc = [ "/std:c++17" ]
+ } else {
+ cflags_cc = [ "-std=c++17" ]
+ }
}
config("visibility_hidden") {
- cflags = [ "-fvisibility=hidden" ]
+ if (!is_win) {
+ cflags = [ "-fvisibility=hidden" ]
+ }
+}
+
+config("win32_lean_and_mean") {
+ if (is_win) {
+ defines = [ "WIN32_LEAN_AND_MEAN" ]
+ }
}
config("default") {
@@ -85,6 +139,7 @@
cflags_c = []
cflags_cc = []
defines = []
+ include_dirs = []
ldflags = []
libs = []
@@ -92,24 +147,50 @@
ldflags += [ "-Wl,--build-id" ]
}
- cflags += [
- "-fstrict-aliasing",
- "-fstack-protector-strong",
- "-fPIC",
- "-g",
- "-Wformat",
- ]
+ if (is_clang || !is_win) { # Clang or GCC, but not MSVC.
+ cflags += [
+ "-fstrict-aliasing",
+ "-Wformat",
+ ]
+ }
+ if (is_win) {
+ cflags += [
+ "/bigobj", # Some of our files are bigger than the regular limits.
+ "/Gy", # Enable function-level linking.
+ ]
+ defines += [
+ "_CRT_NONSTDC_NO_WARNINGS",
+ "_CRT_SECURE_NO_DEPRECATE",
+ "_CRT_SECURE_NO_WARNINGS", # Disables warnings on some POSIX-compat API.
+ "_SCL_SECURE_NO_DEPRECATE",
+ "NOMINMAX",
+ ]
+ if (!use_custom_libcxx) {
+ defines += [ "_HAS_EXCEPTIONS=0" ] # Disables exceptions in MSVC STL.
+ }
+ } else { # !is_win
+ cflags += [
+ "-g",
+ "-fPIC",
+ "-fstack-protector-strong",
+ ]
+ }
+
+ # Treat warnings as errors, but give up on fuzzer builds.
if (!is_fuzzer) {
- cflags += [ "-Werror" ]
+ if (is_win) {
+ cflags += [ "/WX" ]
+ } else {
+ cflags += [ "-Werror" ]
+ }
}
if (is_clang) {
- cflags += [
- # Color compiler output, see https://github.com/ninja-build/ninja/wiki/FAQ
- "-fcolor-diagnostics",
- "-fdiagnostics-show-template-tree",
- ]
+ cflags += [ "-fcolor-diagnostics" ]
+ if (!is_win) {
+ cflags += [ "-fdiagnostics-show-template-tree" ]
+ }
}
if (is_hermetic_clang && is_linux && !is_wasm) {
@@ -123,6 +204,9 @@
ldflags += [ "-flto=full" ]
}
+ # We support only x64 builds on Windows.
+ assert(!is_win || current_cpu == "x64")
+
if (current_cpu == "arm") {
cflags += [
"-march=armv7-a",
@@ -151,8 +235,24 @@
]
}
+ if (is_win && !is_clang) {
+ # When using MSVC we need to manually pass the include dirs. clang-cl.exe
+ # doesn't need them because it's smart enough to figure out the right path
+ # by querying the registry on its own.
+ include_dirs = win_msvc_inc_dirs # Defined in msvc.gni.
+ }
+
if (is_debug) {
- libs += [ "dl" ]
+ if (is_win) {
+ cflags += [ "/Z7" ]
+ if (is_clang) {
+ # Required to see symbols in windbg when building with clang-cl.exe.
+ cflags += [ "-gcodeview-ghash" ]
+ ldflags = [ "/DEBUG:GHASH" ]
+ }
+ } else {
+ libs += [ "dl" ]
+ }
}
if (is_android) {
@@ -207,27 +307,49 @@
}
config("debug_symbols") {
- cflags = [ "-O0" ]
+ cflags = []
+ if (is_win) {
+ cflags = [ "/Od" ]
+ } else {
+ cflags = [ "-O0" ]
+ }
if (is_android || is_linux) {
cflags += [ "-funwind-tables" ]
}
}
config("release") {
- cflags = [
- "-fdata-sections",
- "-ffunction-sections",
- ]
- if (is_android) {
- cflags += [ "-O2" ]
+ # Compiler flags for release builds.
+ if (is_win) {
+ cflags = [
+ "/O2",
+ "/Zc:inline",
+ ]
+ } else if (is_android) {
+ cflags = [ "-O2" ]
} else if (is_fuzzer) {
- cflags += [ "-O1" ]
+ cflags = [ "-O1" ]
} else {
- cflags += [ "-O3" ]
+ cflags = [ "-O3" ]
}
- if (is_mac) {
+ if (!is_win) {
+ cflags += [
+ "-fdata-sections",
+ "-ffunction-sections",
+ ]
+ }
+
+ # Linker flags for release builds.
+ if (is_win) {
+ ldflags = [
+ "/OPT:REF",
+ "/OPT:ICF",
+ "/INCREMENTAL:NO",
+ "/FIXED:NO",
+ ]
+ } else if (is_mac) {
ldflags = [ "-dead_strip" ]
- } else {
+ } else if (!is_win) {
ldflags = [
"-Wl,--gc-sections",
"-Wl,--icf=all",