mirror of
https://github.com/Alex313031/thorium.git
synced 2025-01-10 03:47:44 -03:00
Delete build directory
This commit is contained in:
parent
47c2ac544f
commit
e9949692a1
6 changed files with 0 additions and 4307 deletions
|
@ -1,148 +0,0 @@
|
|||
# Copyright 2022 The Chromium Authors and Alex313031. 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/config/v8_target_cpu.gni")
|
||||
|
||||
# These are primarily relevant in current_cpu == "arm" contexts, where
|
||||
# ARM code is being compiled. But they can also be relevant in the
|
||||
# other contexts when the code will change its behavior based on the
|
||||
# cpu it wants to generate code for.
|
||||
if (current_cpu == "arm" || v8_current_cpu == "arm") {
|
||||
declare_args() {
|
||||
# Version of the ARM processor when compiling on ARM. Ignored on non-ARM
|
||||
# platforms.
|
||||
arm_version = 8
|
||||
|
||||
# The ARM architecture. This will be a string like "armv6" or "armv7-a".
|
||||
# An empty string means to use the default for the arm_version.
|
||||
arm_arch = "armv8.5-a"
|
||||
|
||||
# The ARM floating point hardware. This will be a string like "neon" or
|
||||
# "vfpv3". An empty string means to use the default for the arm_version.
|
||||
arm_fpu = ""
|
||||
|
||||
# The ARM variant-specific tuning mode. This will be a string like "armv6"
|
||||
# or "cortex-a15". An empty string means to use the default for the
|
||||
# arm_version.
|
||||
arm_tune = "armv8.5-a"
|
||||
|
||||
# Whether to use the neon FPU instruction set or not.
|
||||
arm_use_neon = "true"
|
||||
|
||||
# Whether to enable optional NEON code paths.
|
||||
arm_optionally_use_neon = true
|
||||
|
||||
# Thumb is a reduced instruction set available on some ARM processors that
|
||||
# has increased code density.
|
||||
arm_use_thumb = true
|
||||
}
|
||||
|
||||
if (current_os == "android" || target_os == "android") {
|
||||
arm_float_abi = "softfp"
|
||||
} else {
|
||||
declare_args() {
|
||||
# The ARM floating point mode. This is either the string "hard", "soft",
|
||||
# or "softfp". An empty string means to use the default one for the
|
||||
# arm_version.
|
||||
arm_float_abi = ""
|
||||
}
|
||||
}
|
||||
assert(arm_float_abi == "" || arm_float_abi == "hard" ||
|
||||
arm_float_abi == "soft" || arm_float_abi == "softfp")
|
||||
|
||||
if (arm_use_neon == "") {
|
||||
if (current_os == "linux" && target_cpu != v8_target_cpu) {
|
||||
# Don't use neon on V8 simulator builds as a default.
|
||||
arm_use_neon = false
|
||||
} else {
|
||||
arm_use_neon = true
|
||||
}
|
||||
}
|
||||
|
||||
if (arm_version == 6) {
|
||||
if (arm_arch == "") {
|
||||
# v8 can still with version 6 but only with the armv6k extension.
|
||||
arm_arch = "armv6k"
|
||||
}
|
||||
if (arm_tune != "") {
|
||||
arm_tune = ""
|
||||
}
|
||||
if (arm_float_abi == "") {
|
||||
arm_float_abi = "softfp"
|
||||
}
|
||||
if (arm_fpu == "") {
|
||||
arm_fpu = "vfp"
|
||||
}
|
||||
arm_use_thumb = false
|
||||
arm_use_neon = false
|
||||
} else if (arm_version == 7) {
|
||||
if (arm_arch == "") {
|
||||
arm_arch = "armv7-a"
|
||||
}
|
||||
if (arm_tune == "") {
|
||||
arm_tune = "generic-armv7-a"
|
||||
}
|
||||
|
||||
if (arm_float_abi == "") {
|
||||
if (current_os == "linux" && target_cpu != v8_target_cpu) {
|
||||
# Default to the same as Android for V8 simulator builds.
|
||||
arm_float_abi = "softfp"
|
||||
} else {
|
||||
arm_float_abi = "hard"
|
||||
}
|
||||
}
|
||||
|
||||
if (arm_fpu == "") {
|
||||
if (arm_use_neon) {
|
||||
arm_fpu = "neon"
|
||||
} else {
|
||||
arm_fpu = "vfpv3-d16"
|
||||
}
|
||||
}
|
||||
} else if (arm_version == 8) {
|
||||
if (arm_arch == "") {
|
||||
arm_arch = "armv8-a"
|
||||
}
|
||||
if (arm_tune == "") {
|
||||
arm_tune = "generic-armv8-a"
|
||||
}
|
||||
|
||||
if (arm_float_abi == "") {
|
||||
arm_float_abi = "hard"
|
||||
}
|
||||
|
||||
if (arm_fpu == "") {
|
||||
if (arm_use_neon) {
|
||||
arm_fpu = "neon"
|
||||
} else {
|
||||
arm_fpu = "vfpv3-d16"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (current_cpu == "arm64" || v8_current_cpu == "arm64") {
|
||||
# arm64 supports only "hard".
|
||||
arm_float_abi = "hard"
|
||||
arm_use_neon = true
|
||||
declare_args() {
|
||||
# Enables the new Armv8 branch protection features. Valid strings are:
|
||||
# - "pac": Enables Pointer Authentication Code (PAC, featured in Armv8.3)
|
||||
# - "standard": Enables both PAC and Branch Target Identification (Armv8.5).
|
||||
# - "none": No branch protection.
|
||||
arm_control_flow_integrity = "standard"
|
||||
|
||||
# TODO(cavalcantii): enable the feature for the following OSes next.
|
||||
if (is_mac || is_chromeos || is_fuchsia || is_win ||
|
||||
target_cpu != "arm64") {
|
||||
# target_cpu != "arm64" covers some cases (e.g. the ChromeOS x64 MSAN
|
||||
# build) where the target platform is x64, but V8 is configured to use
|
||||
# the arm64 simulator. Pointer authentication doesn't work properly
|
||||
# in this mode (yet).
|
||||
arm_control_flow_integrity = "none"
|
||||
}
|
||||
}
|
||||
assert(arm_control_flow_integrity == "none" ||
|
||||
arm_control_flow_integrity == "standard" ||
|
||||
arm_control_flow_integrity == "pac",
|
||||
"Invalid branch protection option")
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,157 +0,0 @@
|
|||
# Copyright (c) 2022 The Chromium Authors and Alex313031. 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/config/apple/symbols.gni")
|
||||
import("//build/config/c++/c++.gni")
|
||||
import("//build/config/mac/mac_sdk.gni")
|
||||
import("//build/config/sysroot.gni")
|
||||
import("//build/toolchain/goma.gni")
|
||||
import("//build/toolchain/rbe.gni")
|
||||
|
||||
# This is included by reference in the //build/config/compiler config that
|
||||
# is applied to all targets. It is here to separate out the logic.
|
||||
config("compiler") {
|
||||
# These flags are shared between the C compiler and linker.
|
||||
common_mac_flags = []
|
||||
|
||||
# CPU architecture.
|
||||
if (current_cpu == "x64") {
|
||||
clang_arch = "x86_64"
|
||||
} else if (current_cpu == "x86") {
|
||||
clang_arch = "i386"
|
||||
} else if (current_cpu == "arm64") {
|
||||
clang_arch = current_cpu
|
||||
} else {
|
||||
assert(false, "unknown current_cpu $current_cpu")
|
||||
}
|
||||
if (host_os == "mac") {
|
||||
common_mac_flags += [
|
||||
"-arch",
|
||||
clang_arch,
|
||||
]
|
||||
} else {
|
||||
common_mac_flags += [ "--target=$clang_arch-apple-macos" ]
|
||||
}
|
||||
|
||||
# This is here so that all files get recompiled after an Xcode update.
|
||||
# (defines are passed via the command line, and build system rebuild things
|
||||
# when their commandline changes). Nothing should ever read this define.
|
||||
defines = [ "CR_XCODE_VERSION=$xcode_version" ]
|
||||
|
||||
asmflags = [ "-O3", ] + common_mac_flags
|
||||
cflags = [ "-O3", ] + common_mac_flags
|
||||
|
||||
# Without this, the constructors and destructors of a C++ object inside
|
||||
# an Objective C struct won't be called, which is very bad.
|
||||
cflags_objcc = [ "-fobjc-call-cxx-cdtors" ]
|
||||
|
||||
ldflags = [ "-Wl,-O3", ] + common_mac_flags
|
||||
|
||||
if (target_cpu == "x64") {
|
||||
cflags += [ "-maes", "-mavx", "-mavx2", "-ffp-contract=fast", "-mf16c", "-mfma", "-Wno-unused-command-line-argument", ]
|
||||
}
|
||||
|
||||
if (current_cpu == "x64") {
|
||||
cflags += [ "-maes", "-mavx", "-mavx2", "-ffp-contract=fast", "-mf16c", "-mfma", "-Wno-unused-command-line-argument", ]
|
||||
}
|
||||
|
||||
if (save_unstripped_output) {
|
||||
ldflags += [ "-Wcrl,unstripped," + rebase_path(root_out_dir) ]
|
||||
}
|
||||
|
||||
if (export_libcxxabi_from_executables) {
|
||||
ldflags += [ "-Wl,-undefined,dynamic_lookup" ]
|
||||
}
|
||||
}
|
||||
|
||||
# This is included by reference in the //build/config/compiler:runtime_library
|
||||
# config that is applied to all targets. It is here to separate out the logic
|
||||
# that is Mac-only. Please see that target for advice on what should go in
|
||||
# :runtime_library vs. :compiler.
|
||||
config("runtime_library") {
|
||||
common_flags = [
|
||||
"-isysroot",
|
||||
rebase_path(sysroot, root_build_dir),
|
||||
"-mmacos-version-min=$mac_deployment_target",
|
||||
]
|
||||
|
||||
asmflags = common_flags
|
||||
cflags = common_flags
|
||||
ldflags = common_flags
|
||||
|
||||
# Prevent Mac OS X AssertMacros.h (included by system header) from defining
|
||||
# macros that collide with common names, like 'check', 'require', and
|
||||
# 'verify'.
|
||||
# http://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/AssertMacros.h
|
||||
defines = [ "__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0" ]
|
||||
}
|
||||
|
||||
# On Mac, this is used for everything except static libraries.
|
||||
config("mac_dynamic_flags") {
|
||||
ldflags = [ "-Wl,-ObjC", "-Wl,-O3", ] # Always load Objective-C categories and classes.
|
||||
|
||||
if (is_component_build) {
|
||||
ldflags += [
|
||||
# Path for loading shared libraries for unbundled binaries.
|
||||
"-Wl,-rpath,@loader_path/.",
|
||||
|
||||
# Path for loading shared libraries for bundled binaries. Get back from
|
||||
# Binary.app/Contents/MacOS.
|
||||
"-Wl,-rpath,@loader_path/../../..",
|
||||
]
|
||||
|
||||
# Path for loading shared libraries for unbundled binaries for
|
||||
# the host toolchain (see https://crbug.com/1315433). Only used
|
||||
# for when building for iOS.
|
||||
if (target_os == "ios" && current_toolchain == host_toolchain) {
|
||||
ldflags += [
|
||||
"-Wl,-rpath,@loader_path/" +
|
||||
rebase_path(get_label_info(":mac_dynamic_flags", "root_out_dir"),
|
||||
root_build_dir),
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# The ldflags referenced below are handled by
|
||||
# //build/toolchain/apple/linker_driver.py.
|
||||
# Remove this config if a target wishes to change the arguments passed to the
|
||||
# strip command during linking. This config by default strips all symbols
|
||||
# from a binary, but some targets may wish to specify an exports file to
|
||||
# preserve specific symbols.
|
||||
config("strip_all") {
|
||||
if (enable_stripping) {
|
||||
ldflags = [ "-Wcrl,strip,-x,-S", "-Wl,-O3", ]
|
||||
}
|
||||
}
|
||||
|
||||
# When building with Goma, all inputs must be relative to the build directory.
|
||||
# If using the system Xcode, which typically resides outside the build root, a
|
||||
# symlink to the SDK is created in the build directory, and the path to that
|
||||
# link is stored in $mac_sdk_path. If an action references a file in the SDK as
|
||||
# an input, GN will complain that no target generates the file because it is
|
||||
# below the $root_build_dir. The below action lists as outputs the files in the
|
||||
# SDK that are referenced as inputs to actions, so that GN thinks a target has
|
||||
# generated them. The list is centralized here, as multiple targets need to
|
||||
# reference the same files, and an output can only be generated once.
|
||||
#
|
||||
# The symbolic link for $mac_sdk_path is set up by
|
||||
# //build/config/apple/sdk_info.py in //build/config/mac/mac_sdk.gni.
|
||||
if (use_system_xcode && (use_goma || use_remoteexec) && target_os == "mac" &&
|
||||
current_toolchain == default_toolchain) {
|
||||
action("sdk_inputs") {
|
||||
script = "//build/noop.py"
|
||||
outputs = [
|
||||
"$mac_sdk_path/usr/include/mach/exc.defs",
|
||||
"$mac_sdk_path/usr/include/mach/mach_exc.defs",
|
||||
"$mac_sdk_path/usr/include/mach/notify.defs",
|
||||
]
|
||||
}
|
||||
} else {
|
||||
group("sdk_inputs") {
|
||||
if (current_toolchain != default_toolchain) {
|
||||
public_deps = [ ":sdk_inputs($default_toolchain)" ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,614 +0,0 @@
|
|||
# Copyright (c) 2022 The Chromium Authors and Alex313031. 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/config/c++/c++.gni")
|
||||
import("//build/config/chrome_build.gni")
|
||||
import("//build/config/clang/clang.gni")
|
||||
import("//build/config/compiler/compiler.gni")
|
||||
import("//build/config/sanitizers/sanitizers.gni")
|
||||
import("//build/config/win/control_flow_guard.gni")
|
||||
import("//build/config/win/visual_studio_version.gni")
|
||||
import("//build/timestamp.gni")
|
||||
import("//build/toolchain/goma.gni")
|
||||
import("//build/toolchain/toolchain.gni")
|
||||
|
||||
assert(is_win)
|
||||
|
||||
declare_args() {
|
||||
# Turn this on to have the linker output extra timing information.
|
||||
win_linker_timing = false
|
||||
|
||||
# possible values for target_winuwp_version:
|
||||
# "10" - Windows UWP 10
|
||||
# "8.1" - Windows RT 8.1
|
||||
# "8.0" - Windows RT 8.0
|
||||
target_winuwp_version = "10"
|
||||
|
||||
# possible values:
|
||||
# "app" - Windows Store Applications
|
||||
# "phone" - Windows Phone Applications
|
||||
# "system" - Windows Drivers and Tools
|
||||
# "server" - Windows Server Applications
|
||||
# "desktop" - Windows Desktop Applications
|
||||
target_winuwp_family = "app"
|
||||
|
||||
# Set this to use clang-style diagnostics format instead of MSVC-style, which
|
||||
# is useful in e.g. Emacs compilation mode.
|
||||
# E.g.:
|
||||
# Without this, clang emits a diagnostic message like this:
|
||||
# foo/bar.cc(12,34): error: something went wrong
|
||||
# and with this switch, clang emits it like this:
|
||||
# foo/bar.cc:12:34: error: something went wrong
|
||||
use_clang_diagnostics_format = false
|
||||
|
||||
# Indicates whether to use /pdbpagesize:8192 to allow PDBs larger than 4 GiB.
|
||||
# This requires updated debugging and profiling tools which are not widely
|
||||
# distributed yet which is why it is currently opt-in.
|
||||
use_large_pdbs = false
|
||||
}
|
||||
|
||||
# This is included by reference in the //build/config/compiler config that
|
||||
# is applied to all targets. It is here to separate out the logic that is
|
||||
# Windows-only.
|
||||
config("compiler") {
|
||||
if (current_cpu == "x86") {
|
||||
asmflags = [
|
||||
# When /safeseh is specified, the linker will only produce an image if it
|
||||
# can also produce a table of the image's safe exception handlers. This
|
||||
# table specifies for the operating system which exception handlers are
|
||||
# valid for the image. Note that /SAFESEH isn't accepted on the command
|
||||
# line, only /safeseh. This is only accepted by ml.exe, not ml64.exe.
|
||||
"/safeseh",
|
||||
]
|
||||
}
|
||||
|
||||
cflags = [
|
||||
"/Gy", # Enable function-level linking.
|
||||
"/FS", # Preserve previous PDB behavior.
|
||||
"/bigobj", # Some of our files are bigger than the regular limits.
|
||||
"/utf-8", # Assume UTF-8 by default to avoid code page dependencies.
|
||||
]
|
||||
|
||||
if (is_clang) {
|
||||
cflags += [
|
||||
"/Zc:twoPhase",
|
||||
|
||||
# Consistently use backslash as the path separator when expanding the
|
||||
# __FILE__ macro when targeting Windows regardless of the build
|
||||
# environment.
|
||||
"-ffile-reproducible",
|
||||
]
|
||||
}
|
||||
|
||||
# Force C/C++ mode for the given GN detected file type. This is necessary
|
||||
# for precompiled headers where the same source file is compiled in both
|
||||
# modes.
|
||||
cflags_c = [ "/TC" ]
|
||||
cflags_cc = [ "/TP" ]
|
||||
|
||||
cflags += [
|
||||
# Work around crbug.com/526851, bug in VS 2015 RTM compiler.
|
||||
"/Zc:sizedDealloc-",
|
||||
]
|
||||
|
||||
if (is_clang) {
|
||||
# Required to make the 19041 SDK compatible with clang-cl.
|
||||
# See https://crbug.com/1089996 issue #2 for details.
|
||||
cflags += [ "/D__WRL_ENABLE_FUNCTION_STATICS__" ]
|
||||
|
||||
# Tell clang which version of MSVC to emulate.
|
||||
cflags += [ "-fmsc-version=1916" ]
|
||||
|
||||
if (is_component_build) {
|
||||
cflags += [
|
||||
# Do not export inline member functions. This makes component builds
|
||||
# faster. This is similar to -fvisibility-inlines-hidden.
|
||||
"/Zc:dllexportInlines-",
|
||||
]
|
||||
}
|
||||
|
||||
if (current_cpu == "x86") {
|
||||
if (host_cpu == "x86" || host_cpu == "x64") {
|
||||
cflags += [ "-m32" ]
|
||||
} else {
|
||||
cflags += [ "--target=i386-windows", "/O3", "/clang:-O3", "-Xclang", "-O3", "-Wno-unused-command-line-argument", ]
|
||||
}
|
||||
} else if (current_cpu == "x64") {
|
||||
if (host_cpu == "x86" || host_cpu == "x64") {
|
||||
cflags += [ "-m64" ]
|
||||
} else {
|
||||
cflags += [ "--target=x86_64-windows" ]
|
||||
}
|
||||
} else if (current_cpu == "arm64") {
|
||||
cflags += [ "--target=arm64-windows", "/O3", "/clang:-O3", "-Xclang", "-O3", "-Wno-unused-command-line-argument", ]
|
||||
} else {
|
||||
assert(false, "unknown current_cpu " + current_cpu)
|
||||
}
|
||||
|
||||
# Chrome currently requires SSE3. Clang supports targeting any Intel
|
||||
# microarchitecture. MSVC only supports a subset of architectures, and the
|
||||
# next step after SSE2 will be AVX.
|
||||
# "/fp:fast", enables FMA.
|
||||
if (current_cpu == "x86" || current_cpu == "x64") {
|
||||
cflags += [
|
||||
"/O3",
|
||||
"-mavx",
|
||||
"-maes",
|
||||
"/clang:-O3",
|
||||
"/clang:-mavx",
|
||||
"/clang:-maes",
|
||||
"-Xclang", "-O3",
|
||||
"-Wno-unused-command-line-argument",
|
||||
]
|
||||
}
|
||||
|
||||
if (exec_script("//build/win/use_ansi_codes.py", [], "trim string") ==
|
||||
"True") {
|
||||
cflags += [
|
||||
# cmd.exe doesn't understand ANSI escape codes by default,
|
||||
# so only enable them if something emulating them is around.
|
||||
"-fansi-escape-codes",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_clang_diagnostics_format) {
|
||||
cflags += [ "/clang:-fdiagnostics-format=clang" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Disabled with cc_wrapper because of https://github.com/mozilla/sccache/issues/264
|
||||
if (use_lld && !use_thin_lto && (is_clang || !use_goma) && cc_wrapper == "") {
|
||||
# /Brepro lets the compiler not write the mtime field in the .obj output.
|
||||
# link.exe /incremental relies on this field to work correctly, but lld
|
||||
# never looks at this timestamp, so it's safe to pass this flag with
|
||||
# lld and get more deterministic compiler output in return.
|
||||
# In LTO builds, the compiler doesn't write .obj files containing mtimes,
|
||||
# so /Brepro is ignored there.
|
||||
cflags += [ "/Brepro" ]
|
||||
}
|
||||
|
||||
ldflags = []
|
||||
|
||||
if (use_lld) {
|
||||
# lld defaults to writing the current time in the pe/coff header.
|
||||
# For build reproducibility, pass an explicit timestamp. See
|
||||
# build/compute_build_timestamp.py for how the timestamp is chosen.
|
||||
# (link.exe also writes the current time, but it doesn't have a flag to
|
||||
# override that behavior.)
|
||||
ldflags += [ "/TIMESTAMP:" + build_timestamp ]
|
||||
|
||||
# Don't look for libpaths in %LIB%, similar to /X in cflags above.
|
||||
ldflags += [ "/lldignoreenv" ]
|
||||
ldflags += [ "/opt:lldlto=3", ]
|
||||
}
|
||||
|
||||
if (use_large_pdbs) {
|
||||
# This allows PDBs up to 8 GiB in size. This requires lld-link.exe or
|
||||
# link.exe from VS 2022 or later.
|
||||
ldflags += [ "/pdbpagesize:8192" ]
|
||||
}
|
||||
|
||||
if (!is_debug && !is_component_build) {
|
||||
# Enable standard linker optimizations like GC (/OPT:REF) and ICF in static
|
||||
# release builds.
|
||||
# Release builds always want these optimizations, so enable them explicitly.
|
||||
ldflags += [
|
||||
"/OPT:REF",
|
||||
"/OPT:ICF",
|
||||
"/INCREMENTAL:NO",
|
||||
"/FIXED:NO",
|
||||
"/OPT:lldlto=3",
|
||||
"-mllvm:-march=sandybridge",
|
||||
]
|
||||
|
||||
if (use_lld) {
|
||||
# String tail merging leads to smaller binaries, but they don't compress
|
||||
# as well, leading to increased mini_installer size (crbug.com/838449).
|
||||
ldflags += [ "/OPT:NOLLDTAILMERGE" ]
|
||||
}
|
||||
|
||||
# TODO(siggi): Is this of any use anymore?
|
||||
# /PROFILE ensures that the PDB file contains FIXUP information (growing the
|
||||
# PDB file by about 5%) but does not otherwise alter the output binary. It
|
||||
# is enabled opportunistically for builds where it is not prohibited (not
|
||||
# supported when incrementally linking, or using /debug:fastlink).
|
||||
ldflags += [ "/PROFILE" ]
|
||||
}
|
||||
|
||||
# arflags apply only to static_libraries. The normal linker configs are only
|
||||
# set for executable and shared library targets so arflags must be set
|
||||
# elsewhere. Since this is relatively contained, we just apply them in this
|
||||
# more general config and they will only have an effect on static libraries.
|
||||
arflags = [
|
||||
# "No public symbols found; archive member will be inaccessible." This
|
||||
# means that one or more object files in the library can never be
|
||||
# pulled in to targets that link to this library. It's just a warning that
|
||||
# the source file is a no-op.
|
||||
"/ignore:4221",
|
||||
]
|
||||
}
|
||||
|
||||
# This is included by reference in the //build/config/compiler:runtime_library
|
||||
# config that is applied to all targets. It is here to separate out the logic
|
||||
# that is Windows-only. Please see that target for advice on what should go in
|
||||
# :runtime_library vs. :compiler.
|
||||
config("runtime_library") {
|
||||
cflags = []
|
||||
cflags_cc = []
|
||||
|
||||
# Defines that set up the CRT.
|
||||
defines = [
|
||||
"__STD_C",
|
||||
"_CRT_RAND_S",
|
||||
"_CRT_SECURE_NO_DEPRECATE",
|
||||
"_SCL_SECURE_NO_DEPRECATE",
|
||||
]
|
||||
|
||||
# Defines that set up the Windows SDK.
|
||||
defines += [
|
||||
"_ATL_NO_OPENGL",
|
||||
"_WINDOWS",
|
||||
"CERT_CHAIN_PARA_HAS_EXTRA_FIELDS",
|
||||
"PSAPI_VERSION=2",
|
||||
"WIN32",
|
||||
"_SECURE_ATL",
|
||||
]
|
||||
|
||||
if (current_os == "winuwp") {
|
||||
# When targeting Windows Runtime, certain compiler/linker flags are
|
||||
# necessary.
|
||||
defines += [
|
||||
"WINUWP",
|
||||
"__WRL_NO_DEFAULT_LIB__",
|
||||
]
|
||||
if (target_winuwp_family == "app") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_PC_APP" ]
|
||||
} else if (target_winuwp_family == "phone") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" ]
|
||||
} else if (target_winuwp_family == "system") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_SYSTEM" ]
|
||||
} else if (target_winuwp_family == "server") {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_SERVER" ]
|
||||
} else {
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP" ]
|
||||
}
|
||||
cflags_cc += [ "/EHsc" ]
|
||||
|
||||
# This warning is given because the linker cannot tell the difference
|
||||
# between consuming WinRT APIs versus authoring WinRT within static
|
||||
# libraries as such this warning is always given by the linker. Since
|
||||
# consuming WinRT APIs within a library is legitimate but authoring
|
||||
# WinRT APis is not allowed, this warning is disabled to ignore the
|
||||
# legitimate consumption of WinRT APIs within static library builds.
|
||||
arflags = [ "/IGNORE:4264" ]
|
||||
|
||||
if (target_winuwp_version == "10") {
|
||||
defines += [ "WIN10=_WIN32_WINNT_WIN10" ]
|
||||
} else if (target_winuwp_version == "8.1") {
|
||||
defines += [ "WIN8_1=_WIN32_WINNT_WINBLUE" ]
|
||||
} else if (target_winuwp_version == "8.0") {
|
||||
defines += [ "WIN8=_WIN32_WINNT_WIN8" ]
|
||||
}
|
||||
} else {
|
||||
# When not targeting Windows Runtime, make sure the WINAPI family is set
|
||||
# to desktop.
|
||||
defines += [ "WINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Chromium supports running on Windows 7, but if these constants are set to
|
||||
# Windows 7, then newer APIs aren't made available by the Windows SDK.
|
||||
# So we set this to Windows 10 and then are careful to check at runtime
|
||||
# to only call newer APIs when they're available.
|
||||
# Some third-party libraries assume that these defines set what version of
|
||||
# Windows is available at runtime. Targets using these libraries need to
|
||||
# manually override this config for their compiles.
|
||||
config("winver") {
|
||||
defines = [
|
||||
"NTDDI_VERSION=NTDDI_WIN10_FE",
|
||||
|
||||
# We can't say `=_WIN32_WINNT_WIN10` here because some files do
|
||||
# `#if WINVER < 0x0600` without including windows.h before,
|
||||
# and then _WIN32_WINNT_WIN10 isn't yet known to be 0x0A00.
|
||||
"_WIN32_WINNT=0x0A00",
|
||||
"WINVER=0x0A00",
|
||||
]
|
||||
}
|
||||
|
||||
# Linker flags for Windows SDK setup, this is applied only to EXEs and DLLs.
|
||||
config("sdk_link") {
|
||||
if (current_cpu == "x86") {
|
||||
ldflags = [
|
||||
"/SAFESEH", # Not compatible with x64 so use only for x86.
|
||||
"/largeaddressaware",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# This default linker setup is provided separately from the SDK setup so
|
||||
# targets who want different library configurations can remove this and specify
|
||||
# their own.
|
||||
config("common_linker_setup") {
|
||||
ldflags = [
|
||||
"/FIXED:NO",
|
||||
"/ignore:4199",
|
||||
"/ignore:4221",
|
||||
"/NXCOMPAT",
|
||||
"/DYNAMICBASE",
|
||||
]
|
||||
|
||||
if (win_linker_timing) {
|
||||
ldflags += [
|
||||
"/time",
|
||||
"/verbose:incr",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
config("default_cfg_compiler") {
|
||||
# Emit table of address-taken functions for Control-Flow Guard (CFG).
|
||||
# This is needed to allow functions to be called by code that is built
|
||||
# with CFG enabled, such as system libraries.
|
||||
# The CFG guards are only emitted if |win_enable_cfg_guards| is enabled.
|
||||
if (is_clang) {
|
||||
if (win_enable_cfg_guards) {
|
||||
cflags = [ "/guard:cf" ]
|
||||
} else {
|
||||
cflags = [ "/guard:cf,nochecks" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# To disable CFG guards for a target, remove the "default_cfg_compiler"
|
||||
# config, and add "disable_guards_cfg_compiler" config.
|
||||
config("disable_guards_cfg_compiler") {
|
||||
# Emit table of address-taken functions for Control-Flow Guard (CFG).
|
||||
# This is needed to allow functions to be called by code that is built
|
||||
# with CFG enabled, such as system libraries.
|
||||
if (is_clang) {
|
||||
cflags = [ "/guard:cf,nochecks" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("cfi_linker") {
|
||||
# Control Flow Guard (CFG)
|
||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/mt637065.aspx
|
||||
# /DYNAMICBASE (ASLR) is turned off in debug builds, therefore CFG cannot be
|
||||
# turned on either.
|
||||
# ASan and CFG leads to slow process startup. Chromium's test runner uses
|
||||
# lots of child processes, so this means things are really slow. Disable CFG
|
||||
# for now. https://crbug.com/846966
|
||||
if (!is_debug && !is_asan) {
|
||||
# Turn on CFG bitmap generation and CFG load config.
|
||||
ldflags = [ "/guard:cf" ]
|
||||
}
|
||||
}
|
||||
|
||||
# This is a superset of all the delayloads needed for chrome.exe, chrome.dll,
|
||||
# chrome_child.dll, and chrome_elf.dll. The linker will automatically ignore
|
||||
# anything which is not linked to the binary at all.
|
||||
# Most of the dlls are simply not required at startup (or at all, depending
|
||||
# on how the browser is used). The following dlls are interconnected and need to
|
||||
# be delayloaded together to ensure user32 does not load too early or at all,
|
||||
# depending on the process type: user32, gdi32, comctl32, comdlg32, cryptui,
|
||||
# d3d9, dwmapi, imm32, msi, ole32, oleacc, rstrtmgr, shell32, shlwapi, and
|
||||
# uxtheme.
|
||||
# There are some exceptions to this list which need to be declared separately.
|
||||
# Some dlls cannot be delayloaded by chrome_child.dll due to the sandbox
|
||||
# restrictions that prevent them from being loaded properly. Those dlls are
|
||||
# specified in the separate config below.
|
||||
# This config should also be used for any test binary whose goal is to run
|
||||
# tests with the full browser.
|
||||
config("delayloads") {
|
||||
ldflags = [
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll",
|
||||
"/DELAYLOAD:comctl32.dll",
|
||||
"/DELAYLOAD:comdlg32.dll",
|
||||
"/DELAYLOAD:credui.dll",
|
||||
"/DELAYLOAD:cryptui.dll",
|
||||
"/DELAYLOAD:d3d11.dll",
|
||||
"/DELAYLOAD:d3d9.dll",
|
||||
"/DELAYLOAD:dwmapi.dll",
|
||||
"/DELAYLOAD:dxgi.dll",
|
||||
"/DELAYLOAD:dxva2.dll",
|
||||
"/DELAYLOAD:esent.dll",
|
||||
"/DELAYLOAD:gdi32.dll",
|
||||
"/DELAYLOAD:hid.dll",
|
||||
"/DELAYLOAD:imagehlp.dll",
|
||||
"/DELAYLOAD:imm32.dll",
|
||||
"/DELAYLOAD:msi.dll",
|
||||
"/DELAYLOAD:netapi32.dll",
|
||||
"/DELAYLOAD:ncrypt.dll",
|
||||
"/DELAYLOAD:ole32.dll",
|
||||
"/DELAYLOAD:oleacc.dll",
|
||||
"/DELAYLOAD:propsys.dll",
|
||||
"/DELAYLOAD:psapi.dll",
|
||||
"/DELAYLOAD:rpcrt4.dll",
|
||||
"/DELAYLOAD:rstrtmgr.dll",
|
||||
"/DELAYLOAD:setupapi.dll",
|
||||
"/DELAYLOAD:shell32.dll",
|
||||
"/DELAYLOAD:shlwapi.dll",
|
||||
"/DELAYLOAD:urlmon.dll",
|
||||
"/DELAYLOAD:user32.dll",
|
||||
"/DELAYLOAD:usp10.dll",
|
||||
"/DELAYLOAD:uxtheme.dll",
|
||||
"/DELAYLOAD:wer.dll",
|
||||
"/DELAYLOAD:wevtapi.dll",
|
||||
"/DELAYLOAD:wininet.dll",
|
||||
"/DELAYLOAD:winusb.dll",
|
||||
"/DELAYLOAD:wsock32.dll",
|
||||
"/DELAYLOAD:wtsapi32.dll",
|
||||
]
|
||||
}
|
||||
|
||||
config("delayloads_not_for_child_dll") {
|
||||
ldflags = [
|
||||
"/DELAYLOAD:advapi32.dll",
|
||||
"/DELAYLOAD:crypt32.dll",
|
||||
"/DELAYLOAD:dbghelp.dll",
|
||||
"/DELAYLOAD:dhcpcsvc.dll",
|
||||
"/DELAYLOAD:dwrite.dll",
|
||||
"/DELAYLOAD:iphlpapi.dll",
|
||||
"/DELAYLOAD:oleaut32.dll",
|
||||
"/DELAYLOAD:secur32.dll",
|
||||
"/DELAYLOAD:uiautomationcore.dll",
|
||||
"/DELAYLOAD:userenv.dll",
|
||||
"/DELAYLOAD:winhttp.dll",
|
||||
"/DELAYLOAD:winmm.dll",
|
||||
"/DELAYLOAD:winspool.drv",
|
||||
"/DELAYLOAD:wintrust.dll",
|
||||
"/DELAYLOAD:ws2_32.dll",
|
||||
]
|
||||
}
|
||||
|
||||
# CRT --------------------------------------------------------------------------
|
||||
|
||||
# Configures how the runtime library (CRT) is going to be used.
|
||||
# See https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx for a reference of
|
||||
# what each value does.
|
||||
config("default_crt") {
|
||||
if (is_component_build) {
|
||||
# Component mode: dynamic CRT. Since the library is shared, it requires
|
||||
# exceptions or will give errors about things not matching, so keep
|
||||
# exceptions on.
|
||||
configs = [ ":dynamic_crt" ]
|
||||
} else {
|
||||
if (current_os == "winuwp") {
|
||||
# https://blogs.msdn.microsoft.com/vcblog/2014/06/10/the-great-c-runtime-crt-refactoring/
|
||||
# contains a details explanation of what is happening with the Windows
|
||||
# CRT in Visual Studio releases related to Windows store applications.
|
||||
configs = [ ":dynamic_crt" ]
|
||||
} else {
|
||||
# Desktop Windows: static CRT.
|
||||
configs = [ ":static_crt" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Use this to force use of the release CRT when building perf-critical build
|
||||
# tools that need to be fully optimized even in debug builds, for those times
|
||||
# when the debug CRT is part of the bottleneck. This also avoids *implicitly*
|
||||
# defining _DEBUG.
|
||||
config("release_crt") {
|
||||
if (is_component_build) {
|
||||
cflags = [ "/MD" ]
|
||||
|
||||
if (use_custom_libcxx) {
|
||||
# On Windows, including libcpmt[d]/msvcprt[d] explicitly links the C++
|
||||
# standard library, which libc++ needs for exception_ptr internals.
|
||||
ldflags = [ "/DEFAULTLIB:msvcprt.lib" ]
|
||||
}
|
||||
} else {
|
||||
cflags = [ "/MT" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:libcpmt.lib" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config("dynamic_crt") {
|
||||
if (is_debug) {
|
||||
# This pulls in the DLL debug CRT and defines _DEBUG
|
||||
cflags = [ "/MDd" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:msvcprtd.lib" ]
|
||||
}
|
||||
} else {
|
||||
cflags = [ "/MD" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:msvcprt.lib" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config("static_crt") {
|
||||
if (is_debug) {
|
||||
# This pulls in the static debug CRT and defines _DEBUG
|
||||
cflags = [ "/MTd" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:libcpmtd.lib" ]
|
||||
}
|
||||
} else {
|
||||
cflags = [ "/MT" ]
|
||||
if (use_custom_libcxx) {
|
||||
ldflags = [ "/DEFAULTLIB:libcpmt.lib" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Subsystem --------------------------------------------------------------------
|
||||
|
||||
# This is appended to the subsystem to specify a minimum version.
|
||||
if (current_cpu == "x64") {
|
||||
# The number after the comma is the minimum required OS version.
|
||||
# 5.02 = Windows Server 2003.
|
||||
subsystem_version_suffix = ",5.02"
|
||||
} else if (current_cpu == "arm64") {
|
||||
# Windows ARM64 requires Windows 10.
|
||||
subsystem_version_suffix = ",10.0"
|
||||
} else {
|
||||
# 5.01 = Windows XP.
|
||||
subsystem_version_suffix = ",5.01"
|
||||
}
|
||||
|
||||
config("console") {
|
||||
ldflags = [ "/SUBSYSTEM:CONSOLE$subsystem_version_suffix" ]
|
||||
}
|
||||
config("windowed") {
|
||||
ldflags = [ "/SUBSYSTEM:WINDOWS$subsystem_version_suffix" ]
|
||||
}
|
||||
|
||||
# Incremental linking ----------------------------------------------------------
|
||||
|
||||
# Applies incremental linking or not depending on the current configuration.
|
||||
config("default_incremental_linking") {
|
||||
# Enable incremental linking for debug builds and all component builds - any
|
||||
# builds where performance is not job one.
|
||||
# TODO(thakis): Always turn this on with lld, no reason not to.
|
||||
if (is_debug || is_component_build) {
|
||||
ldflags = [ "/INCREMENTAL" ]
|
||||
if (use_lld) {
|
||||
# lld doesn't use ilk files and doesn't really have an incremental link
|
||||
# mode; the only effect of the flag is that the .lib file timestamp isn't
|
||||
# updated if the .lib doesn't change.
|
||||
# TODO(thakis): Why pass /OPT:NOREF for lld, but not otherwise?
|
||||
# TODO(thakis): /INCREMENTAL is on by default in link.exe, but not in
|
||||
# lld.
|
||||
ldflags += [ "/OPT:NOREF" ]
|
||||
}
|
||||
} else {
|
||||
ldflags = [ "/INCREMENTAL:NO" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Character set ----------------------------------------------------------------
|
||||
|
||||
# Not including this config means "ansi" (8-bit system codepage).
|
||||
config("unicode") {
|
||||
defines = [
|
||||
"_UNICODE",
|
||||
"UNICODE",
|
||||
]
|
||||
}
|
||||
|
||||
# Lean and mean ----------------------------------------------------------------
|
||||
|
||||
# Some third party code might not compile with WIN32_LEAN_AND_MEAN so we have
|
||||
# to have a separate config for it. Remove this config from your target to
|
||||
# get the "bloaty and accommodating" version of windows.h.
|
||||
config("lean_and_mean") {
|
||||
defines = [ "WIN32_LEAN_AND_MEAN" ]
|
||||
}
|
||||
|
||||
# Nominmax --------------------------------------------------------------------
|
||||
|
||||
# Some third party code defines NOMINMAX before including windows.h, which
|
||||
# then causes warnings when it's been previously defined on the command line.
|
||||
# For such targets, this config can be removed.
|
||||
|
||||
config("nominmax") {
|
||||
defines = [ "NOMINMAX" ]
|
||||
}
|
|
@ -1,585 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2022 The Chromium Authors and Alex313031 and gz83. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import pipes
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from gn_helpers import ToGNString
|
||||
|
||||
# VS 2019 16.61 with 10.0.20348.0 SDK, 10.0.19041 version of Debuggers
|
||||
# with ARM64 libraries and UWP support.
|
||||
# See go/chromium-msvc-toolchain for instructions about how to update the
|
||||
# toolchain.
|
||||
#
|
||||
# When updating the toolchain, consider the following areas impacted by the
|
||||
# toolchain version:
|
||||
#
|
||||
# * //base/win/windows_version.cc NTDDI preprocessor check
|
||||
# Triggers a compiler error if the available SDK is older than the minimum.
|
||||
# * //build/config/win/BUILD.gn NTDDI_VERSION value
|
||||
# Affects the availability of APIs in the toolchain headers.
|
||||
# * //docs/windows_build_instructions.md mentions of VS or Windows SDK.
|
||||
# Keeps the document consistent with the toolchain version.
|
||||
TOOLCHAIN_HASH = '1023ce2e82'
|
||||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
json_data_file = os.path.join(script_dir, 'win_toolchain.json')
|
||||
|
||||
# VS versions are listed in descending order of priority (highest first).
|
||||
# The first version is assumed by this script to be the one that is packaged,
|
||||
# which makes a difference for the arm64 runtime.
|
||||
MSVS_VERSIONS = collections.OrderedDict([
|
||||
('2022', '17.0'), # Default and packaged version of Visual Studio.
|
||||
('2019', '16.0'),
|
||||
('2017', '15.0'),
|
||||
])
|
||||
|
||||
# List of preferred VC toolset version based on MSVS
|
||||
# Order is not relevant for this dictionary.
|
||||
MSVC_TOOLSET_VERSION = {
|
||||
'2022': 'VC143',
|
||||
'2019': 'VC142',
|
||||
'2017': 'VC141',
|
||||
}
|
||||
|
||||
def _HostIsWindows():
|
||||
"""Returns True if running on a Windows host (including under cygwin)."""
|
||||
return sys.platform in ('win32', 'cygwin')
|
||||
|
||||
def SetEnvironmentAndGetRuntimeDllDirs():
|
||||
"""Sets up os.environ to use the depot_tools VS toolchain with gyp, and
|
||||
returns the location of the VC runtime DLLs so they can be copied into
|
||||
the output directory after gyp generation.
|
||||
|
||||
Return value is [x64path, x86path, 'Arm64Unused'] or None. arm64path is
|
||||
generated separately because there are multiple folders for the arm64 VC
|
||||
runtime.
|
||||
"""
|
||||
vs_runtime_dll_dirs = None
|
||||
depot_tools_win_toolchain = \
|
||||
bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
|
||||
# When running on a non-Windows host, only do this if the SDK has explicitly
|
||||
# been downloaded before (in which case json_data_file will exist).
|
||||
if ((_HostIsWindows() or os.path.exists(json_data_file))
|
||||
and depot_tools_win_toolchain):
|
||||
if ShouldUpdateToolchain():
|
||||
if len(sys.argv) > 1 and sys.argv[1] == 'update':
|
||||
update_result = Update()
|
||||
else:
|
||||
update_result = Update(no_download=True)
|
||||
if update_result != 0:
|
||||
raise Exception('Failed to update, error code %d.' % update_result)
|
||||
with open(json_data_file, 'r') as tempf:
|
||||
toolchain_data = json.load(tempf)
|
||||
|
||||
toolchain = toolchain_data['path']
|
||||
version = toolchain_data['version']
|
||||
win_sdk = toolchain_data.get('win_sdk')
|
||||
wdk = toolchain_data['wdk']
|
||||
# TODO(scottmg): The order unfortunately matters in these. They should be
|
||||
# split into separate keys for x64/x86/arm64. (See CopyDlls call below).
|
||||
# http://crbug.com/345992
|
||||
vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
|
||||
# The number of runtime_dirs in the toolchain_data was two (x64/x86) but
|
||||
# changed to three (x64/x86/arm64) and this code needs to handle both
|
||||
# possibilities, which can change independently from this code.
|
||||
if len(vs_runtime_dll_dirs) == 2:
|
||||
vs_runtime_dll_dirs.append('Arm64Unused')
|
||||
|
||||
os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
|
||||
|
||||
os.environ['WINDOWSSDKDIR'] = win_sdk
|
||||
os.environ['WDK_DIR'] = wdk
|
||||
# Include the VS runtime in the PATH in case it's not machine-installed.
|
||||
runtime_path = os.path.pathsep.join(vs_runtime_dll_dirs)
|
||||
os.environ['PATH'] = runtime_path + os.path.pathsep + os.environ['PATH']
|
||||
elif sys.platform == 'win32' and not depot_tools_win_toolchain:
|
||||
if not 'GYP_MSVS_OVERRIDE_PATH' in os.environ:
|
||||
os.environ['GYP_MSVS_OVERRIDE_PATH'] = DetectVisualStudioPath()
|
||||
|
||||
# When using an installed toolchain these files aren't needed in the output
|
||||
# directory in order to run binaries locally, but they are needed in order
|
||||
# to create isolates or the mini_installer. Copying them to the output
|
||||
# directory ensures that they are available when needed.
|
||||
bitness = platform.architecture()[0]
|
||||
# When running 64-bit python the x64 DLLs will be in System32
|
||||
# ARM64 binaries will not be available in the system directories because we
|
||||
# don't build on ARM64 machines.
|
||||
x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
|
||||
x64_path = os.path.join(os.path.expandvars('%windir%'), x64_path)
|
||||
vs_runtime_dll_dirs = [x64_path,
|
||||
os.path.join(os.path.expandvars('%windir%'),
|
||||
'SysWOW64'),
|
||||
'Arm64Unused']
|
||||
|
||||
return vs_runtime_dll_dirs
|
||||
|
||||
|
||||
def _RegistryGetValueUsingWinReg(key, value):
|
||||
"""Use the _winreg module to obtain the value of a registry key.
|
||||
|
||||
Args:
|
||||
key: The registry key.
|
||||
value: The particular registry value to read.
|
||||
Return:
|
||||
contents of the registry key's value, or None on failure. Throws
|
||||
ImportError if _winreg is unavailable.
|
||||
"""
|
||||
import _winreg
|
||||
try:
|
||||
root, subkey = key.split('\\', 1)
|
||||
assert root == 'HKLM' # Only need HKLM for now.
|
||||
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey:
|
||||
return _winreg.QueryValueEx(hkey, value)[0]
|
||||
except WindowsError:
|
||||
return None
|
||||
|
||||
|
||||
def _RegistryGetValue(key, value):
|
||||
try:
|
||||
return _RegistryGetValueUsingWinReg(key, value)
|
||||
except ImportError:
|
||||
raise Exception('The python library _winreg not found.')
|
||||
|
||||
|
||||
def GetVisualStudioVersion():
|
||||
"""Return best available version of Visual Studio.
|
||||
"""
|
||||
supported_versions = list(MSVS_VERSIONS.keys())
|
||||
|
||||
# VS installed in depot_tools for Googlers
|
||||
if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))):
|
||||
return supported_versions[0]
|
||||
|
||||
# VS installed in system for external developers
|
||||
supported_versions_str = ', '.join('{} ({})'.format(v,k)
|
||||
for k,v in MSVS_VERSIONS.items())
|
||||
available_versions = []
|
||||
for version in supported_versions:
|
||||
# Checking vs%s_install environment variables.
|
||||
# For example, vs2019_install could have the value
|
||||
# "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community".
|
||||
# Only vs2017_install, vs2019_install and vs2022_install are supported.
|
||||
path = os.environ.get('vs%s_install' % version)
|
||||
if path and os.path.exists(path):
|
||||
available_versions.append(version)
|
||||
break
|
||||
# Detecting VS under possible paths.
|
||||
if version >= '2022':
|
||||
program_files_path_variable = '%ProgramFiles%'
|
||||
else:
|
||||
program_files_path_variable = '%ProgramFiles(x86)%'
|
||||
path = os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s' % version)
|
||||
if path and any(
|
||||
os.path.exists(os.path.join(path, edition))
|
||||
for edition in ('Enterprise', 'Professional', 'Community', 'Preview',
|
||||
'BuildTools')):
|
||||
available_versions.append(version)
|
||||
break
|
||||
|
||||
if not available_versions:
|
||||
raise Exception('No supported Visual Studio can be found.'
|
||||
' Supported versions are: %s.' % supported_versions_str)
|
||||
return available_versions[0]
|
||||
|
||||
|
||||
def DetectVisualStudioPath():
|
||||
"""Return path to the installed Visual Studio.
|
||||
"""
|
||||
|
||||
# Note that this code is used from
|
||||
# build/toolchain/win/setup_toolchain.py as well.
|
||||
version_as_year = GetVisualStudioVersion()
|
||||
|
||||
# The VC++ >=2017 install location needs to be located using COM instead of
|
||||
# the registry. For details see:
|
||||
# https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/
|
||||
# For now we use a hardcoded default with an environment variable override.
|
||||
if version_as_year >= '2022':
|
||||
program_files_path_variable = '%ProgramFiles%'
|
||||
else:
|
||||
program_files_path_variable = '%ProgramFiles(x86)%'
|
||||
for path in (os.environ.get('vs%s_install' % version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Enterprise' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Professional' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Community' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/Preview' %
|
||||
version_as_year),
|
||||
os.path.expandvars(program_files_path_variable +
|
||||
'/Microsoft Visual Studio/%s/BuildTools' %
|
||||
version_as_year)):
|
||||
if path and os.path.exists(path):
|
||||
return path
|
||||
|
||||
raise Exception('Visual Studio Version %s not found.' % version_as_year)
|
||||
|
||||
|
||||
def _CopyRuntimeImpl(target, source, verbose=True):
|
||||
"""Copy |source| to |target| if it doesn't already exist or if it needs to be
|
||||
updated (comparing last modified time as an approximate float match as for
|
||||
some reason the values tend to differ by ~1e-07 despite being copies of the
|
||||
same file... https://crbug.com/603603).
|
||||
"""
|
||||
if (os.path.isdir(os.path.dirname(target)) and
|
||||
(not os.path.isfile(target) or
|
||||
abs(os.stat(target).st_mtime - os.stat(source).st_mtime) >= 0.01)):
|
||||
if verbose:
|
||||
print('Copying %s to %s...' % (source, target))
|
||||
if os.path.exists(target):
|
||||
# Make the file writable so that we can delete it now, and keep it
|
||||
# readable.
|
||||
os.chmod(target, stat.S_IWRITE | stat.S_IREAD)
|
||||
os.unlink(target)
|
||||
shutil.copy2(source, target)
|
||||
# Make the file writable so that we can overwrite or delete it later,
|
||||
# keep it readable.
|
||||
os.chmod(target, stat.S_IWRITE | stat.S_IREAD)
|
||||
|
||||
def _SortByHighestVersionNumberFirst(list_of_str_versions):
|
||||
"""This sorts |list_of_str_versions| according to version number rules
|
||||
so that version "1.12" is higher than version "1.9". Does not work
|
||||
with non-numeric versions like 1.4.a8 which will be higher than
|
||||
1.4.a12. It does handle the versions being embedded in file paths.
|
||||
"""
|
||||
def to_int_if_int(x):
|
||||
try:
|
||||
return int(x)
|
||||
except ValueError:
|
||||
return x
|
||||
|
||||
def to_number_sequence(x):
|
||||
part_sequence = re.split(r'[\\/\.]', x)
|
||||
return [to_int_if_int(x) for x in part_sequence]
|
||||
|
||||
list_of_str_versions.sort(key=to_number_sequence, reverse=True)
|
||||
|
||||
|
||||
def _CopyUCRTRuntime(target_dir, source_dir, target_cpu, suffix):
|
||||
"""Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't
|
||||
exist, but the target directory does exist."""
|
||||
if target_cpu == 'arm64':
|
||||
# Windows ARM64 VCRuntime is located at {toolchain_root}/VC/Redist/MSVC/
|
||||
# {x.y.z}/[debug_nonredist/]arm64/Microsoft.VC14x.CRT/.
|
||||
# Select VC toolset directory based on Visual Studio version
|
||||
vc_redist_root = FindVCRedistRoot()
|
||||
if suffix.startswith('.'):
|
||||
vc_toolset_dir = 'Microsoft.{}.CRT' \
|
||||
.format(MSVC_TOOLSET_VERSION[GetVisualStudioVersion()])
|
||||
source_dir = os.path.join(vc_redist_root,
|
||||
'arm64', vc_toolset_dir)
|
||||
else:
|
||||
vc_toolset_dir = 'Microsoft.{}.DebugCRT' \
|
||||
.format(MSVC_TOOLSET_VERSION[GetVisualStudioVersion()])
|
||||
source_dir = os.path.join(vc_redist_root, 'debug_nonredist',
|
||||
'arm64', vc_toolset_dir)
|
||||
file_parts = ('msvcp140', 'vccorlib140', 'vcruntime140')
|
||||
if target_cpu == 'x64' and GetVisualStudioVersion() != '2017':
|
||||
file_parts = file_parts + ('vcruntime140_1', )
|
||||
for file_part in file_parts:
|
||||
dll = file_part + suffix
|
||||
target = os.path.join(target_dir, dll)
|
||||
source = os.path.join(source_dir, dll)
|
||||
_CopyRuntimeImpl(target, source)
|
||||
# Copy the UCRT files from the Windows SDK. This location includes the
|
||||
# api-ms-win-crt-*.dll files that are not found in the Windows directory.
|
||||
# These files are needed for component builds. If WINDOWSSDKDIR is not set
|
||||
# use the default SDK path. This will be the case when
|
||||
# DEPOT_TOOLS_WIN_TOOLCHAIN=0 and vcvarsall.bat has not been run.
|
||||
win_sdk_dir = os.path.normpath(
|
||||
os.environ.get('WINDOWSSDKDIR',
|
||||
os.path.expandvars('%ProgramFiles(x86)%'
|
||||
'\\Windows Kits\\10')))
|
||||
# ARM64 doesn't have a redist for the ucrt DLLs because they are always
|
||||
# present in the OS.
|
||||
if target_cpu != 'arm64':
|
||||
# Starting with the 10.0.17763 SDK the ucrt files are in a version-named
|
||||
# directory - this handles both cases.
|
||||
redist_dir = os.path.join(win_sdk_dir, 'Redist')
|
||||
version_dirs = glob.glob(os.path.join(redist_dir, '10.*'))
|
||||
if len(version_dirs) > 0:
|
||||
_SortByHighestVersionNumberFirst(version_dirs)
|
||||
redist_dir = version_dirs[0]
|
||||
ucrt_dll_dirs = os.path.join(redist_dir, 'ucrt', 'DLLs', target_cpu)
|
||||
ucrt_files = glob.glob(os.path.join(ucrt_dll_dirs, 'api-ms-win-*.dll'))
|
||||
assert len(ucrt_files) > 0
|
||||
for ucrt_src_file in ucrt_files:
|
||||
file_part = os.path.basename(ucrt_src_file)
|
||||
ucrt_dst_file = os.path.join(target_dir, file_part)
|
||||
_CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False)
|
||||
# We must copy ucrtbase.dll for x64/x86, and ucrtbased.dll for all CPU types.
|
||||
if target_cpu != 'arm64' or not suffix.startswith('.'):
|
||||
if not suffix.startswith('.'):
|
||||
# ucrtbased.dll is located at {win_sdk_dir}/bin/{a.b.c.d}/{target_cpu}/
|
||||
# ucrt/.
|
||||
sdk_bin_root = os.path.join(win_sdk_dir, 'bin')
|
||||
sdk_bin_sub_dirs = glob.glob(os.path.join(sdk_bin_root, '10.*'))
|
||||
# Select the most recent SDK if there are multiple versions installed.
|
||||
_SortByHighestVersionNumberFirst(sdk_bin_sub_dirs)
|
||||
for directory in sdk_bin_sub_dirs:
|
||||
sdk_redist_root_version = os.path.join(sdk_bin_root, directory)
|
||||
if not os.path.isdir(sdk_redist_root_version):
|
||||
continue
|
||||
source_dir = os.path.join(sdk_redist_root_version, target_cpu, 'ucrt')
|
||||
break
|
||||
_CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
|
||||
os.path.join(source_dir, 'ucrtbase' + suffix))
|
||||
|
||||
|
||||
def FindVCComponentRoot(component):
|
||||
"""Find the most recent Tools or Redist or other directory in an MSVC install.
|
||||
Typical results are {toolchain_root}/VC/{component}/MSVC/{x.y.z}. The {x.y.z}
|
||||
version number part changes frequently so the highest version number found is
|
||||
used.
|
||||
"""
|
||||
|
||||
SetEnvironmentAndGetRuntimeDllDirs()
|
||||
assert ('GYP_MSVS_OVERRIDE_PATH' in os.environ)
|
||||
vc_component_msvc_root = os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
|
||||
'VC', component, 'MSVC')
|
||||
vc_component_msvc_contents = glob.glob(
|
||||
os.path.join(vc_component_msvc_root, '14.*'))
|
||||
# Select the most recent toolchain if there are several.
|
||||
_SortByHighestVersionNumberFirst(vc_component_msvc_contents)
|
||||
for directory in vc_component_msvc_contents:
|
||||
if os.path.isdir(directory):
|
||||
return directory
|
||||
raise Exception('Unable to find the VC %s directory.' % component)
|
||||
|
||||
|
||||
def FindVCRedistRoot():
|
||||
"""In >=VS2017, Redist binaries are located in
|
||||
{toolchain_root}/VC/Redist/MSVC/{x.y.z}/{target_cpu}/.
|
||||
|
||||
This returns the '{toolchain_root}/VC/Redist/MSVC/{x.y.z}/' path.
|
||||
"""
|
||||
return FindVCComponentRoot('Redist')
|
||||
|
||||
|
||||
def _CopyRuntime(target_dir, source_dir, target_cpu, debug):
|
||||
"""Copy the VS runtime DLLs, only if the target doesn't exist, but the target
|
||||
directory does exist. Handles VS 2015, 2017 and 2019."""
|
||||
suffix = 'd.dll' if debug else '.dll'
|
||||
# VS 2015, 2017 and 2019 use the same CRT DLLs.
|
||||
_CopyUCRTRuntime(target_dir, source_dir, target_cpu, suffix)
|
||||
|
||||
|
||||
def CopyDlls(target_dir, configuration, target_cpu):
|
||||
"""Copy the VS runtime DLLs into the requested directory as needed.
|
||||
|
||||
configuration is one of 'Debug' or 'Release'.
|
||||
target_cpu is one of 'x86', 'x64' or 'arm64'.
|
||||
|
||||
The debug configuration gets both the debug and release DLLs; the
|
||||
release config only the latter.
|
||||
"""
|
||||
vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
|
||||
if not vs_runtime_dll_dirs:
|
||||
return
|
||||
|
||||
x64_runtime, x86_runtime, arm64_runtime = vs_runtime_dll_dirs
|
||||
if target_cpu == 'x64':
|
||||
runtime_dir = x64_runtime
|
||||
elif target_cpu == 'x86':
|
||||
runtime_dir = x86_runtime
|
||||
elif target_cpu == 'arm64':
|
||||
runtime_dir = arm64_runtime
|
||||
else:
|
||||
raise Exception('Unknown target_cpu: ' + target_cpu)
|
||||
_CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
|
||||
if configuration == 'Debug':
|
||||
_CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
|
||||
_CopyDebugger(target_dir, target_cpu)
|
||||
|
||||
|
||||
def _CopyDebugger(target_dir, target_cpu):
|
||||
"""Copy dbghelp.dll and dbgcore.dll into the requested directory as needed.
|
||||
|
||||
target_cpu is one of 'x86', 'x64' or 'arm64'.
|
||||
|
||||
dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file
|
||||
from the SDK directory avoids using the system copy of dbghelp.dll which then
|
||||
ensures compatibility with recent debug information formats, such as VS
|
||||
2017 /debug:fastlink PDBs.
|
||||
|
||||
dbgcore.dll is needed when using some functions from dbghelp.dll (like
|
||||
MinidumpWriteDump).
|
||||
"""
|
||||
win_sdk_dir = SetEnvironmentAndGetSDKDir()
|
||||
if not win_sdk_dir:
|
||||
return
|
||||
|
||||
# List of debug files that should be copied, the first element of the tuple is
|
||||
# the name of the file and the second indicates if it's optional.
|
||||
debug_files = [('dbghelp.dll', False), ('dbgcore.dll', True)]
|
||||
# The UCRT is not a redistributable component on arm64.
|
||||
if target_cpu != 'arm64':
|
||||
debug_files.extend([('api-ms-win-downlevel-kernel32-l2-1-0.dll', False),
|
||||
('api-ms-win-eventing-provider-l1-1-0.dll', False)])
|
||||
for debug_file, is_optional in debug_files:
|
||||
full_path = os.path.join(win_sdk_dir, 'Debuggers', target_cpu, debug_file)
|
||||
if not os.path.exists(full_path):
|
||||
if is_optional:
|
||||
continue
|
||||
else:
|
||||
raise Exception('%s not found in "%s"\r\nYou must install '
|
||||
'Windows 10 SDK version 10.0.20348.0 including the '
|
||||
'"Debugging Tools for Windows" feature.' %
|
||||
(debug_file, full_path))
|
||||
target_path = os.path.join(target_dir, debug_file)
|
||||
_CopyRuntimeImpl(target_path, full_path)
|
||||
|
||||
|
||||
def _GetDesiredVsToolchainHashes():
|
||||
"""Load a list of SHA1s corresponding to the toolchains that we want installed
|
||||
to build with."""
|
||||
# Third parties that do not have access to the canonical toolchain can map
|
||||
# canonical toolchain version to their own toolchain versions.
|
||||
toolchain_hash_mapping_key = 'GYP_MSVS_HASH_%s' % TOOLCHAIN_HASH
|
||||
return [os.environ.get(toolchain_hash_mapping_key, TOOLCHAIN_HASH)]
|
||||
|
||||
|
||||
def ShouldUpdateToolchain():
|
||||
"""Check if the toolchain should be upgraded."""
|
||||
if not os.path.exists(json_data_file):
|
||||
return True
|
||||
with open(json_data_file, 'r') as tempf:
|
||||
toolchain_data = json.load(tempf)
|
||||
version = toolchain_data['version']
|
||||
env_version = GetVisualStudioVersion()
|
||||
# If there's a mismatch between the version set in the environment and the one
|
||||
# in the json file then the toolchain should be updated.
|
||||
return version != env_version
|
||||
|
||||
|
||||
def Update(force=False, no_download=False):
|
||||
"""Requests an update of the toolchain to the specific hashes we have at
|
||||
this revision. The update outputs a .json of the various configuration
|
||||
information required to pass to gyp which we use in |GetToolchainDir()|.
|
||||
If no_download is true then the toolchain will be configured if present but
|
||||
will not be downloaded.
|
||||
"""
|
||||
if force != False and force != '--force':
|
||||
print('Unknown parameter "%s"' % force, file=sys.stderr)
|
||||
return 1
|
||||
if force == '--force' or os.path.exists(json_data_file):
|
||||
force = True
|
||||
|
||||
depot_tools_win_toolchain = \
|
||||
bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
|
||||
if (_HostIsWindows() or force) and depot_tools_win_toolchain:
|
||||
import find_depot_tools
|
||||
depot_tools_path = find_depot_tools.add_depot_tools_to_path()
|
||||
|
||||
# On Linux, the file system is usually case-sensitive while the Windows
|
||||
# SDK only works on case-insensitive file systems. If it doesn't already
|
||||
# exist, set up a ciopfs fuse mount to put the SDK in a case-insensitive
|
||||
# part of the file system.
|
||||
toolchain_dir = os.path.join(depot_tools_path, 'win_toolchain', 'vs_files')
|
||||
# For testing this block, unmount existing mounts with
|
||||
# fusermount -u third_party/depot_tools/win_toolchain/vs_files
|
||||
if sys.platform.startswith('linux') and not os.path.ismount(toolchain_dir):
|
||||
import distutils.spawn
|
||||
ciopfs = distutils.spawn.find_executable('ciopfs')
|
||||
if not ciopfs:
|
||||
# ciopfs not found in PATH; try the one downloaded from the DEPS hook.
|
||||
ciopfs = os.path.join(script_dir, 'ciopfs')
|
||||
if not os.path.isdir(toolchain_dir):
|
||||
os.mkdir(toolchain_dir)
|
||||
if not os.path.isdir(toolchain_dir + '.ciopfs'):
|
||||
os.mkdir(toolchain_dir + '.ciopfs')
|
||||
# Without use_ino, clang's #pragma once and Wnonportable-include-path
|
||||
# both don't work right, see https://llvm.org/PR34931
|
||||
# use_ino doesn't slow down builds, so it seems there's no drawback to
|
||||
# just using it always.
|
||||
subprocess.check_call([
|
||||
ciopfs, '-o', 'use_ino', toolchain_dir + '.ciopfs', toolchain_dir])
|
||||
|
||||
get_toolchain_args = [
|
||||
sys.executable,
|
||||
os.path.join(depot_tools_path,
|
||||
'win_toolchain',
|
||||
'get_toolchain_if_necessary.py'),
|
||||
'--output-json', json_data_file,
|
||||
] + _GetDesiredVsToolchainHashes()
|
||||
if force:
|
||||
get_toolchain_args.append('--force')
|
||||
if no_download:
|
||||
get_toolchain_args.append('--no-download')
|
||||
subprocess.check_call(get_toolchain_args)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def NormalizePath(path):
|
||||
while path.endswith('\\'):
|
||||
path = path[:-1]
|
||||
return path
|
||||
|
||||
|
||||
def SetEnvironmentAndGetSDKDir():
|
||||
"""Gets location information about the current sdk (must have been
|
||||
previously updated by 'update'). This is used for the GN build."""
|
||||
SetEnvironmentAndGetRuntimeDllDirs()
|
||||
|
||||
# If WINDOWSSDKDIR is not set, search the default SDK path and set it.
|
||||
if not 'WINDOWSSDKDIR' in os.environ:
|
||||
default_sdk_path = os.path.expandvars('%ProgramFiles(x86)%'
|
||||
'\\Windows Kits\\10')
|
||||
if os.path.isdir(default_sdk_path):
|
||||
os.environ['WINDOWSSDKDIR'] = default_sdk_path
|
||||
|
||||
return NormalizePath(os.environ['WINDOWSSDKDIR'])
|
||||
|
||||
|
||||
def GetToolchainDir():
|
||||
"""Gets location information about the current toolchain (must have been
|
||||
previously updated by 'update'). This is used for the GN build."""
|
||||
runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
|
||||
win_sdk_dir = SetEnvironmentAndGetSDKDir()
|
||||
|
||||
print('''vs_path = %s
|
||||
sdk_path = %s
|
||||
vs_version = %s
|
||||
wdk_dir = %s
|
||||
runtime_dirs = %s
|
||||
''' % (ToGNString(NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH'])),
|
||||
ToGNString(win_sdk_dir), ToGNString(GetVisualStudioVersion()),
|
||||
ToGNString(NormalizePath(os.environ.get('WDK_DIR', ''))),
|
||||
ToGNString(os.path.pathsep.join(runtime_dll_dirs or ['None']))))
|
||||
|
||||
|
||||
def main():
|
||||
commands = {
|
||||
'update': Update,
|
||||
'get_toolchain_dir': GetToolchainDir,
|
||||
'copy_dlls': CopyDlls,
|
||||
}
|
||||
if len(sys.argv) < 2 or sys.argv[1] not in commands:
|
||||
print('Expected one of: %s' % ', '.join(commands), file=sys.stderr)
|
||||
return 1
|
||||
return commands[sys.argv[1]](*sys.argv[2:])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -1,98 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2022 The Chromium Authors, Alex313031, and gz83. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import glob
|
||||
import optparse
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sys.path.insert(
|
||||
0,
|
||||
os.path.join(os.path.dirname(__file__), '..', '..', 'third_party',
|
||||
'pefile_py3'))
|
||||
import pefile
|
||||
|
||||
def reorder_imports(input_dir, output_dir, architecture):
|
||||
"""Swap chrome_elf.dll to be the first import of chrome.exe.
|
||||
Also copy over any related files that might be needed
|
||||
(pdbs, manifests etc.).
|
||||
"""
|
||||
# TODO(thakis): See if there is a reliable way to write the
|
||||
# correct executable in the first place, so that this script
|
||||
# only needs to verify that and not write a whole new exe.
|
||||
|
||||
input_image = os.path.join(input_dir, 'thorium.exe')
|
||||
output_image = os.path.join(output_dir, 'thorium.exe')
|
||||
|
||||
# pefile mmap()s the whole executable, and then parses parts of
|
||||
# it into python data structures for ease of processing.
|
||||
# To write the file again, only the mmap'd data is written back,
|
||||
# so modifying the parsed python objects generally has no effect.
|
||||
# However, parsed raw data ends up in pe.Structure instances,
|
||||
# and these all get serialized back when the file gets written.
|
||||
# So things that are in a Structure must have their data set
|
||||
# through the Structure, while other data must bet set through
|
||||
# the set_bytes_*() methods.
|
||||
pe = pefile.PE(input_image, fast_load=True)
|
||||
if architecture == 'x64' or architecture == 'arm64':
|
||||
assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS
|
||||
else:
|
||||
assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE
|
||||
|
||||
pe.parse_data_directories(directories=[
|
||||
pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_IMPORT']])
|
||||
|
||||
found_elf = False
|
||||
for i, peimport in enumerate(pe.DIRECTORY_ENTRY_IMPORT):
|
||||
if peimport.dll.lower() == b'chrome_elf.dll':
|
||||
assert not found_elf, 'only one chrome_elf.dll import expected'
|
||||
found_elf = True
|
||||
if i > 0:
|
||||
swap = pe.DIRECTORY_ENTRY_IMPORT[0]
|
||||
|
||||
# Morally we want to swap peimport.struct and swap.struct here,
|
||||
# but the pe module doesn't expose a public method on Structure
|
||||
# to get all data of a Structure without explicitly listing all
|
||||
# field names.
|
||||
# NB: OriginalFirstThunk and Characteristics are an union both at
|
||||
# offset 0, handling just one of them is enough.
|
||||
peimport.struct.OriginalFirstThunk, swap.struct.OriginalFirstThunk = \
|
||||
swap.struct.OriginalFirstThunk, peimport.struct.OriginalFirstThunk
|
||||
peimport.struct.TimeDateStamp, swap.struct.TimeDateStamp = \
|
||||
swap.struct.TimeDateStamp, peimport.struct.TimeDateStamp
|
||||
peimport.struct.ForwarderChain, swap.struct.ForwarderChain = \
|
||||
swap.struct.ForwarderChain, peimport.struct.ForwarderChain
|
||||
peimport.struct.Name, swap.struct.Name = \
|
||||
swap.struct.Name, peimport.struct.Name
|
||||
peimport.struct.FirstThunk, swap.struct.FirstThunk = \
|
||||
swap.struct.FirstThunk, peimport.struct.FirstThunk
|
||||
assert found_elf, 'chrome_elf.dll import not found'
|
||||
|
||||
pe.write(filename=output_image)
|
||||
|
||||
for fname in glob.iglob(os.path.join(input_dir, 'thorium.exe.*')):
|
||||
shutil.copy(fname, os.path.join(output_dir, os.path.basename(fname)))
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv):
|
||||
usage = 'reorder_imports.py -i <input_dir> -o <output_dir> -a <target_arch>'
|
||||
parser = optparse.OptionParser(usage=usage)
|
||||
parser.add_option('-i', '--input', help='reorder thorium.exe in DIR',
|
||||
metavar='DIR')
|
||||
parser.add_option('-o', '--output', help='write new thorium.exe to DIR',
|
||||
metavar='DIR')
|
||||
parser.add_option('-a', '--arch', help='architecture of build (optional)',
|
||||
default='ia32')
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
if not opts.input or not opts.output:
|
||||
parser.error('Please provide and input and output directory')
|
||||
return reorder_imports(opts.input, opts.output, opts.arch)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1:]))
|
Loading…
Reference in a new issue