blob: fa10b7bef4e004d75dedf93bd7b0b46ef203cd7e [file] [log] [blame]
diff --git a/config/BUILD.gn b/config/BUILD.gn
index ed94a16a0..3e4a62d24 100644
--- a/config/BUILD.gn
+++ b/config/BUILD.gn
@@ -122,13 +122,13 @@ config("debug") {
defines += [ "DYNAMIC_ANNOTATIONS_PREFIX=NACL_" ]
}
- if (is_win) {
+ if (is_win && !is_mingw) {
if (!enable_iterator_debugging && !use_custom_libcxx) {
# Iterator debugging is enabled by default by the compiler on debug
# builds, and we have to tell it to turn it off.
defines += [ "_HAS_ITERATOR_DEBUGGING=0" ]
}
- } else if ((is_linux || is_chromeos) && current_cpu == "x64" &&
+ } else if ((is_linux || is_chromeos || is_mingw) && current_cpu == "x64" &&
enable_iterator_debugging) {
# Enable libstdc++ debugging facilities to help catch problems early, see
# http://crbug.com/65151 .
@@ -163,7 +163,7 @@ config("release") {
# This config defines the default libraries applied to all targets.
config("default_libs") {
- if (is_win) {
+ if (is_win && !is_mingw) {
# TODO(brettw) this list of defaults should probably be smaller, and
# instead the targets that use the less common ones (e.g. wininet or
# winspool) should include those explicitly.
@@ -289,8 +289,13 @@ group("shared_library_deps") {
# Windows linker setup for EXEs and DLLs.
if (is_win) {
- _windows_linker_configs = [
- "//build/config/win:sdk_link",
+ _windows_linker_configs = []
+ if(!is_mingw){
+ _windows_linker_configs += [
+ "//build/config/win:sdk_link",
+ ]
+ }
+ _windows_linker_configs += [
"//build/config/win:common_linker_setup",
]
}
diff --git a/config/BUILDCONFIG.gn b/config/BUILDCONFIG.gn
index 0ef73ab2b..527203c6d 100644
--- a/config/BUILDCONFIG.gn
+++ b/config/BUILDCONFIG.gn
@@ -130,8 +130,12 @@ declare_args() {
# separate flags.
is_official_build = false
+ # Set to true when compiling with the MinGW GCC compiler on the MSYS2 environment.
+ is_mingw = getenv("MSYSTEM") != "" && getenv("MSYSTEM") != "MSYS"
+
# Set to true when compiling with the Clang compiler.
is_clang = current_os != "linux" ||
+ !(getenv("MSYSTEM") != "" && getenv("MSYSTEM") != "MSYS") ||
(current_cpu != "s390x" && current_cpu != "s390" &&
current_cpu != "ppc64" && current_cpu != "ppc" &&
current_cpu != "mips" && current_cpu != "mips64" &&
@@ -201,11 +205,15 @@ if (host_toolchain == "") {
if (target_cpu == "x86" || target_cpu == "x64") {
if (is_clang) {
host_toolchain = "//build/toolchain/win:win_clang_$target_cpu"
+ } else if (is_mingw) {
+ host_toolchain = "//build/toolchain/win:mingw_$target_cpu"
} else {
host_toolchain = "//build/toolchain/win:$target_cpu"
}
} else if (is_clang) {
host_toolchain = "//build/toolchain/win:win_clang_$host_cpu"
+ } else if (is_mingw) {
+ host_toolchain = "//build/toolchain/win:mingw_$host_cpu"
} else {
host_toolchain = "//build/toolchain/win:$host_cpu"
}
@@ -242,6 +250,8 @@ if (target_os == "android") {
# Beware, win cross builds have some caveats, see docs/win_cross.md
if (is_clang) {
_default_toolchain = "//build/toolchain/win:win_clang_$target_cpu"
+ } else if (is_mingw) {
+ _default_toolchain = "//build/toolchain/win:mingw_$target_cpu"
} else {
_default_toolchain = "//build/toolchain/win:$target_cpu"
}
diff --git a/config/compiler/BUILD.gn b/config/compiler/BUILD.gn
index 0c8743726..c60704e6d 100644
--- a/config/compiler/BUILD.gn
+++ b/config/compiler/BUILD.gn
@@ -299,8 +299,8 @@ config("compiler") {
}
# In general, Windows is totally different, but all the other builds share
- # some common compiler and linker configuration.
- if (!is_win) {
+ # some common GCC configuration.
+ if (!is_win || is_mingw) {
# Common POSIX compiler flags setup.
# --------------------------------
cflags += [ "-fno-strict-aliasing" ] # See http://crbug.com/32204
@@ -314,7 +314,7 @@ config("compiler") {
} else {
cflags += [ "-fstack-protector" ]
}
- } else if ((is_posix && !is_chromeos_ash && !is_nacl) || is_fuchsia) {
+ } else if ((is_posix && !is_chromeos && !is_nacl) || is_fuchsia || is_mingw) {
# TODO(phajdan.jr): Use -fstack-protector-strong when our gcc supports it.
# See also https://crbug.com/533294
cflags += [ "--param=ssp-buffer-size=4" ]
@@ -325,6 +325,12 @@ config("compiler") {
} else if (current_os != "aix") {
# Not available on aix.
cflags += [ "-fstack-protector" ]
+ if(is_mingw) {
+ # In MingW's GCC -fstack-protector
+ # needs to be passed to the linker as well
+ # for it to link against the ssp library
+ ldflags += [ "-fstack-protector" ]
+ }
}
}
@@ -354,7 +360,7 @@ config("compiler") {
# Non-Mac Posix and Fuchsia compiler flags setup.
# -----------------------------------
- if ((is_posix && !is_apple) || is_fuchsia) {
+ if ((is_posix && !is_apple) || is_fuchsia || is_mingw) {
if (enable_profiling) {
if (!is_debug) {
cflags += [ "-g" ]
@@ -503,7 +509,7 @@ config("compiler") {
# TODO(thakis): Make the driver pass --color-diagnostics to the linker
# if -fcolor-diagnostics is passed to it, and pass -fcolor-diagnostics
# in ldflags instead.
- if (is_win) {
+ if (is_win && !is_mingw) {
# On Windows, we call the linker directly, instead of calling it through
# the driver.
ldflags += [ "--color-diagnostics" ]
@@ -538,7 +544,7 @@ config("compiler") {
# C11/C++11 compiler flags setup.
# ---------------------------
- if (is_linux || is_chromeos || is_android || (is_nacl && is_clang) ||
+ if (is_linux || is_mingw || is_chromeos || is_android || (is_nacl && is_clang) ||
current_os == "aix") {
if (target_os == "android") {
cxx11_override = use_cxx11_on_android
@@ -642,7 +648,7 @@ config("compiler") {
# should be able to better manage binary size increases on its own.
import_instr_limit = 5
- if (is_win) {
+ if (is_win && !is_mingw) {
ldflags += [
"/opt:lldltojobs=all",
"-mllvm:-import-instr-limit=$import_instr_limit",
@@ -689,7 +695,7 @@ config("compiler") {
# Tracked by llvm bug: https://bugs.llvm.org/show_bug.cgi?id=48245
if (!is_android || current_cpu == "arm64") {
cflags += [ "-fwhole-program-vtables" ]
- if (!is_win) {
+ if (!is_win || is_mingw) {
ldflags += [ "-fwhole-program-vtables" ]
}
}
@@ -707,7 +713,7 @@ config("compiler") {
if (compiler_timing) {
if (is_clang && !is_nacl) {
cflags += [ "-ftime-trace" ]
- } else if (is_win) {
+ } else if (is_win && !is_mingw) {
cflags += [
# "Documented" here:
# http://aras-p.info/blog/2017/10/23/Best-unknown-MSVC-flag-d2cgsummary/
@@ -758,7 +764,7 @@ config("compiler") {
# Assign any flags set for the C compiler to asmflags so that they are sent
# to the assembler. The Windows assembler takes different types of flags
# so only do so for posix platforms.
- if (is_posix || is_fuchsia) {
+ if (is_posix || is_fuchsia || is_mingw) {
asmflags += cflags
asmflags += cflags_c
}
@@ -812,7 +818,7 @@ config("compiler_cpu_abi") {
ldflags = []
defines = []
- if ((is_posix && !is_apple) || is_fuchsia) {
+ if ((is_posix && !is_apple) || is_fuchsia || is_mingw) {
# CPU architecture. We may or may not be doing a cross compile now, so for
# simplicity we always explicitly set the architecture.
if (current_cpu == "x64") {
@@ -1166,7 +1172,7 @@ config("compiler_deterministic") {
# Eliminate build metadata (__DATE__, __TIME__ and __TIMESTAMP__) for
# deterministic build. See https://crbug.com/314403
if (!is_official_build) {
- if (is_win && !is_clang) {
+ if (is_win && !is_clang && !is_mingw) {
cflags += [
"/wd4117", # Trying to define or undefine a predefined macro.
"/D__DATE__=",
@@ -1327,7 +1333,7 @@ config("default_warnings") {
cflags_cc = []
ldflags = []
- if (is_win) {
+ if (is_win && !is_mingw) {
if (treat_warnings_as_errors) {
cflags += [ "/WX" ]
}
@@ -1537,15 +1543,32 @@ config("default_warnings") {
# files.
cflags += [ "-Wno-packed-not-aligned" ]
}
+
+ if (is_mingw) {
+ cflags += [
+ "-Wno-attributes", # "__decspec(dllimport) inline"
+ "-Wno-format", # PRIu64 llu support on MinGW
+ "-Wno-unused-but-set-variable",
+ "-Wno-stringop-overflow", # False positive overflow error on gcc 10
+
+ ]
+ cflags_cc += [
+ "-Wno-subobject-linkage", # Tests having code in header files
+ ]
+ }
}
# Common Clang and GCC warning setup.
- if (!is_win || is_clang) {
+ if (!is_win || is_clang || is_mingw) {
cflags += [
# Disables.
"-Wno-missing-field-initializers", # "struct foo f = {0};"
"-Wno-unused-parameter", # Unused function parameters.
+ "-Wno-invalid-offsetof", # Use of "conditionally-supported" offsetof in c++17
]
+ if(is_clang){
+ cflags += ["-Wno-range-loop-construct"] # Use of "conditionally-supported" offsetof in c++17
+ }
}
if (is_clang) {
@@ -1630,7 +1653,7 @@ config("default_warnings") {
# part of Chromium.
config("chromium_code") {
- if (is_win) {
+ if (is_win && !is_mingw) {
cflags = [ "/W4" ] # Warning level 4.
if (is_clang) {
@@ -1723,7 +1746,7 @@ config("no_chromium_code") {
cflags_cc = []
defines = []
- if (is_win) {
+ if (is_win && !is_mingw) {
cflags += [
"/W3", # Warning level 3.
"/wd4800", # Disable warning when forcing value to bool.
@@ -1782,7 +1805,7 @@ config("noshadowing") {
# Allows turning Run-Time Type Identification on or off.
config("rtti") {
- if (is_win) {
+ if (is_win && !is_mingw) {
cflags_cc = [ "/GR" ]
} else {
cflags_cc = [ "-frtti" ]
@@ -1792,7 +1815,7 @@ config("rtti") {
config("no_rtti") {
# Some sanitizer configs may require RTTI to be left enabled globally
if (!use_rtti) {
- if (is_win) {
+ if (is_win && !is_mingw) {
cflags_cc = [ "/GR-" ]
} else {
cflags_cc = [ "-fno-rtti" ]
@@ -1845,7 +1868,7 @@ config("thin_archive") {
# Note: exceptions are disallowed in Google code.
config("exceptions") {
- if (is_win) {
+ if (is_win && !is_mingw) {
# Enables exceptions in the STL.
if (!use_custom_libcxx) {
defines = [ "_HAS_EXCEPTIONS=1" ]
@@ -1854,11 +1877,17 @@ config("exceptions") {
} else {
cflags_cc = [ "-fexceptions" ]
cflags_objcc = cflags_cc
+ if (is_mingw && exclude_unwind_tables) {
+ # With exceptions explicitly allowed,
+ # override exclude_unwind_tables or
+ # linking will fail on MinGW
+ cflags_cc += [ "-funwind-tables", "-fasynchronous-unwind-tables" ]
+ }
}
}
config("no_exceptions") {
- if (is_win) {
+ if (is_win && !is_mingw) {
# Disables exceptions in the STL.
# libc++ uses the __has_feature macro to control whether to use exceptions,
# so defining this macro is unnecessary. Defining _HAS_EXCEPTIONS to 0 also
@@ -1928,7 +1957,7 @@ config("no_shorten_64_warnings") {
if (is_clang) {
cflags = [ "-Wno-shorten-64-to-32" ]
} else {
- if (is_win) {
+ if (is_win && !is_mingw) {
# MSVC does not have an explicit warning equivalent to
# -Wshorten-64-to-32 but 4267 warns for size_t -> int
# on 64-bit builds, so is the closest.
@@ -1968,12 +1997,22 @@ config("no_incompatible_pointer_warnings") {
# Shared settings for both "optimize" and "optimize_max" configs.
# IMPORTANT: On Windows "/O1" and "/O2" must go before the common flags.
-if (is_win) {
- common_optimize_on_cflags = [
+if (is_win && !is_mingw) {
+ common_optimize_on_cflags = []
+ if(is_clang) {
+ common_optimize_on_cflags += [
"/Ob2", # Both explicit and auto inlining.
+ ]
+ } else {
+ common_optimize_on_cflags += [
+ "/Ob3", # Both explicit and auto inlining.
+ ]
+ }
+ common_optimize_on_cflags += [
"/Oy-", # Disable omitting frame pointers, must be after /O2.
"/Zc:inline", # Remove unreferenced COMDAT (faster links).
]
+
if (!is_asan) {
common_optimize_on_cflags += [
# Put data in separate COMDATs. This allows the linker
@@ -2069,7 +2108,7 @@ config("default_stack_frames") {
# Default "optimization on" config.
config("optimize") {
- if (is_win) {
+ if (is_win && !is_mingw) {
if (chrome_pgo_phase != 2) {
# Favor size over speed, /O1 must be before the common flags.
# /O1 implies /Os and /GF.
@@ -2104,7 +2143,7 @@ config("optimize") {
# Turn off optimizations.
config("no_optimize") {
- if (is_win) {
+ if (is_win && !is_mingw) {
cflags = [
"/Od", # Disable optimization.
"/Ob0", # Disable all inlining (on by default).
@@ -2156,7 +2195,7 @@ config("optimize_max") {
configs = [ "//build/config/nacl:irt_optimize" ]
} else {
ldflags = common_optimize_on_ldflags
- if (is_win) {
+ if (is_win && !is_mingw) {
# Favor speed over size, /O2 must be before the common flags.
# /O2 implies /Ot, /Oi, and /GF.
cflags = [ "/O2" ] + common_optimize_on_cflags
@@ -2188,7 +2227,7 @@ config("optimize_speed") {
configs = [ "//build/config/nacl:irt_optimize" ]
} else {
ldflags = common_optimize_on_ldflags
- if (is_win) {
+ if (is_win && !is_mingw) {
# Favor speed over size, /O2 must be before the common flags.
# /O2 implies /Ot, /Oi, and /GF.
cflags = [ "/O2" ] + common_optimize_on_cflags
@@ -2320,7 +2359,7 @@ config("win_pdbaltpath") {
# Full symbols.
config("symbols") {
- if (is_win) {
+ if (is_win && !is_mingw) {
if (is_clang) {
cflags = [ "/Z7" ] # Debug information in the .obj files.
} else {
@@ -2372,7 +2411,8 @@ config("symbols") {
# build-directory-independent output. pnacl and nacl-clang do support that
# flag, so we can use use -g1 for pnacl and nacl-clang compiles.
# gcc nacl is is_nacl && !is_clang, pnacl and nacl-clang are && is_clang.
- if (!is_nacl || is_clang) {
+ # mingw cannot handle the size of the debug symbols generated.
+ if (!is_mingw && (!is_nacl || is_clang)) {
cflags += [ "-g2" ]
}
@@ -2423,7 +2463,7 @@ config("symbols") {
# This config guarantees to hold symbol for stack trace which are shown to user
# when crash happens in unittests running on buildbot.
config("minimal_symbols") {
- if (is_win) {
+ if (is_win && !is_mingw) {
# Functions, files, and line tables only.
cflags = []
ldflags = [ "/DEBUG" ]
@@ -2482,7 +2522,7 @@ config("minimal_symbols") {
# told to not generate debug information and the linker then just puts function
# names in the final debug information.
config("no_symbols") {
- if (is_win) {
+ if (is_win && !is_mingw) {
ldflags = [ "/DEBUG" ]
# All configs using /DEBUG should include this:
@@ -2575,6 +2615,11 @@ buildflag_header("compiler_buildflags") {
config("cet_shadow_stack") {
if (enable_cet_shadow_stack && is_win) {
assert(target_cpu == "x64")
- ldflags = [ "/CETCOMPAT" ]
+ if(is_mingw){
+ ldflags = [ "-fcf-protection=full" ]
+ cflags = [ "-fcf-protection=full" ]
+ } else {
+ ldflags = [ "/CETCOMPAT" ]
+ }
}
}
diff --git a/config/linux/pkg-config.py b/config/linux/pkg-config.py
index 5adf70cc3..e28e798df 100644
--- a/config/linux/pkg-config.py
+++ b/config/linux/pkg-config.py
@@ -41,7 +41,11 @@ from optparse import OptionParser
# Additionally, you can specify the option --atleast-version. This will skip
# the normal outputting of a dictionary and instead print true or false,
# depending on the return value of pkg-config for the given package.
-
+#
+# --pkg_config_libdir=<path> allows direct override
+# of the PKG_CONFIG_LIBDIR environment library.
+#
+# --full-path-libs causes lib names to include their full path.
def SetConfigPath(options):
"""Set the PKG_CONFIG_LIBDIR environment variable.
@@ -105,11 +109,29 @@ def RewritePath(path, strip_prefix, sysroot):
return path
+flag_regex = re.compile("(-.)(.+)")
+
+def FlagReplace(matchobj):
+ if matchobj.group(1) == '-I':
+ return matchobj.group(1) + subprocess.check_output([u'cygpath',u'-w',matchobj.group(2)]).strip().decode("utf-8")
+ if matchobj.group(1) == '-L':
+ return matchobj.group(1) + subprocess.check_output([u'cygpath',u'-w',matchobj.group(2)]).strip().decode("utf-8")
+ if matchobj.group(1) == '-l':
+ return matchobj.group(1) + matchobj.group(2) + '.lib'
+ return matchobj.group(0)
+
+def ConvertGCCToMSVC(flags):
+ """Rewrites GCC flags into MSVC flags."""
+ # need a better way to determine mingw vs msvc build
+ if 'win32' not in sys.platform or "GCC" in sys.version:
+ return flags
+ return [ flag_regex.sub(FlagReplace,flag) for flag in flags]
+
def main():
# If this is run on non-Linux platforms, just return nothing and indicate
# success. This allows us to "kind of emulate" a Linux build from other
# platforms.
- if "linux" not in sys.platform:
+ if "linux" not in sys.platform and 'win32' not in sys.platform:
print("[[],[],[],[],[]]")
return 0
@@ -122,12 +144,15 @@ def main():
parser.add_option('-a', action='store', dest='arch', type='string')
parser.add_option('--system_libdir', action='store', dest='system_libdir',
type='string', default='lib')
+ parser.add_option('--pkg_config_libdir', action='store', dest='pkg_config_libdir',
+ type='string')
parser.add_option('--atleast-version', action='store',
dest='atleast_version', type='string')
parser.add_option('--libdir', action='store_true', dest='libdir')
parser.add_option('--dridriverdir', action='store_true', dest='dridriverdir')
parser.add_option('--version-as-components', action='store_true',
dest='version_as_components')
+ parser.add_option('--full-path-libs', action='store_true', dest='full_path_libs')
(options, args) = parser.parse_args()
# Make a list of regular expressions to strip out.
@@ -144,6 +169,10 @@ def main():
else:
prefix = ''
+ # Override PKG_CONFIG_LIBDIR
+ if options.pkg_config_libdir:
+ os.environ['PKG_CONFIG_LIBDIR'] = options.pkg_config_libdir
+
if options.atleast_version:
# When asking for the return value, just run pkg-config and print the return
# value, no need to do other work.
@@ -203,7 +232,7 @@ def main():
# For now just split on spaces to get the args out. This will break if
# pkgconfig returns quoted things with spaces in them, but that doesn't seem
# to happen in practice.
- all_flags = flag_string.strip().split(' ')
+ all_flags = ConvertGCCToMSVC(flag_string.strip().split(' '))
sysroot = options.sysroot
@@ -220,7 +249,10 @@ def main():
continue;
if flag[:2] == '-l':
- libs.append(RewritePath(flag[2:], prefix, sysroot))
+ library = RewritePath(flag[2:], prefix, sysroot)
+ # Skip math library on MSVC
+ if library != 'm.lib':
+ libs.append(library)
elif flag[:2] == '-L':
lib_dirs.append(RewritePath(flag[2:], prefix, sysroot))
elif flag[:2] == '-I':
@@ -237,6 +269,14 @@ def main():
else:
cflags.append(flag)
+ if options.full_path_libs:
+ full_path_libs = []
+ for lib_dir in lib_dirs:
+ for lib in libs:
+ if os.path.isfile(lib_dir+"/"+lib):
+ full_path_libs.append(lib_dir+"/"+lib)
+ libs = full_path_libs
+
# Output a GN array, the first one is the cflags, the second are the libs. The
# JSON formatter prints GN compatible lists when everything is a list of
# strings.
diff --git a/config/linux/pkg_config.gni b/config/linux/pkg_config.gni
index 428e44ac0..a0d2175ee 100644
--- a/config/linux/pkg_config.gni
+++ b/config/linux/pkg_config.gni
@@ -45,6 +45,9 @@ declare_args() {
# in similar fashion by setting the `system_libdir` variable in the build's
# args.gn file to 'lib' or 'lib64' as appropriate for the target architecture.
system_libdir = "lib"
+
+ # Allow directly overriding the PKG_CONFIG_LIBDIR enviroment variable
+ pkg_config_libdir = ""
}
pkg_config_script = "//build/config/linux/pkg-config.py"
@@ -87,6 +90,17 @@ if (host_pkg_config != "") {
host_pkg_config_args = pkg_config_args
}
+if (pkg_config_libdir != "") {
+ pkg_config_args += [
+ "--pkg_config_libdir",
+ pkg_config_libdir,
+ ]
+ host_pkg_config_args += [
+ "--pkg_config_libdir",
+ pkg_config_libdir,
+ ]
+}
+
template("pkg_config") {
assert(defined(invoker.packages),
"Variable |packages| must be defined to be a list in pkg_config.")
diff --git a/config/win/BUILD.gn b/config/win/BUILD.gn
index 813c72c05..b3a2051c1 100644
--- a/config/win/BUILD.gn
+++ b/config/win/BUILD.gn
@@ -46,7 +46,7 @@ declare_args() {
# is applied to all targets. It is here to separate out the logic that is
# Windows-only.
config("compiler") {
- if (current_cpu == "x86") {
+ if (current_cpu == "x86" && !is_mingw) {
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
@@ -57,27 +57,36 @@ config("compiler") {
]
}
- 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_mingw) {
+ 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.
+ ]
+ } else {
+ cflags = [
+ "-Wa,-mbig-obj",
+ "-fno-keep-inline-dllexport"
+ ]
+ }
if (is_clang) {
cflags += [ "/Zc:twoPhase" ]
}
- # 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" ]
+ if(!is_mingw) {
+ # 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-",
- ]
+ 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.
@@ -150,7 +159,7 @@ config("compiler") {
ldflags += [ "/lldignoreenv" ]
}
- if (!is_debug && !is_component_build) {
+ if (!is_debug && !is_component_build && !is_mingw) {
# Enable standard linker optimizations like GC (/OPT:REF) and ICF in static
# release builds.
# Release builds always want these optimizations, so enable them explicitly.
@@ -175,17 +184,19 @@ config("compiler") {
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",
- ]
+ if(!is_mingw){
+ # 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
@@ -294,29 +305,31 @@ config("sdk_link") {
ldflags = [ "/MACHINE:ARM64" ]
}
- vcvars_toolchain_data = exec_script("../../toolchain/win/setup_toolchain.py",
- [
- visual_studio_path,
- windows_sdk_path,
- visual_studio_runtime_dirs,
- current_os,
- current_cpu,
- "none",
- ],
- "scope")
-
- vc_lib_path = vcvars_toolchain_data.vc_lib_path
- if (defined(vcvars_toolchain_data.vc_lib_atlmfc_path)) {
- vc_lib_atlmfc_path = vcvars_toolchain_data.vc_lib_atlmfc_path
- }
- vc_lib_um_path = vcvars_toolchain_data.vc_lib_um_path
+ if(!is_mingw){
+ vcvars_toolchain_data = exec_script("../../toolchain/win/setup_toolchain.py",
+ [
+ visual_studio_path,
+ windows_sdk_path,
+ visual_studio_runtime_dirs,
+ current_os,
+ current_cpu,
+ "none",
+ ],
+ "scope")
+
+ vc_lib_path = vcvars_toolchain_data.vc_lib_path
+ if (defined(vcvars_toolchain_data.vc_lib_atlmfc_path)) {
+ vc_lib_atlmfc_path = vcvars_toolchain_data.vc_lib_atlmfc_path
+ }
+ vc_lib_um_path = vcvars_toolchain_data.vc_lib_um_path
- lib_dirs = [
- "$vc_lib_um_path",
- "$vc_lib_path",
- ]
- if (defined(vc_lib_atlmfc_path)) {
- lib_dirs += [ "$vc_lib_atlmfc_path" ]
+ lib_dirs = [
+ "$vc_lib_um_path",
+ "$vc_lib_path",
+ ]
+ if (defined(vc_lib_atlmfc_path)) {
+ lib_dirs += [ "$vc_lib_atlmfc_path" ]
+ }
}
}
@@ -324,19 +337,27 @@ config("sdk_link") {
# 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",
+ if(is_mingw) {
+ # Enable DEP and ASLR
+ ldflags = [
+ "-Wl,-dynamicbase",
+ "-Wl,-nxcompat",
+ ]
+ } else {
+ ldflags = [
+ "/FIXED:NO",
+ "/ignore:4199",
+ "/ignore:4221",
+ "/NXCOMPAT",
+ "/DYNAMICBASE",
]
+
+ if (win_linker_timing) {
+ ldflags += [
+ "/time",
+ "/verbose:incr",
+ ]
+ }
}
}
@@ -373,7 +394,7 @@ config("cfi_linker") {
# 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) {
+ if (!is_debug && !is_asan && !is_mingw) {
# Turn on CFG bitmap generation and CFG load config.
ldflags = [ "/guard:cf" ]
}
@@ -464,20 +485,22 @@ config("delayloads_not_for_child_dll") {
# 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.
+ if(!is_mingw){
+ 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 {
- # Desktop Windows: static CRT.
- configs = [ ":static_crt" ]
+ 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" ]
+ }
}
}
}
@@ -518,42 +541,54 @@ config("static_crt") {
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"
+ subsystem_version_suffix = "5.02"
} else if (current_cpu == "arm64") {
# Windows ARM64 requires Windows 10.
- subsystem_version_suffix = ",10.0"
+ subsystem_version_suffix = "10.0"
} else {
# 5.01 = Windows XP.
- subsystem_version_suffix = ",5.01"
+ subsystem_version_suffix = "5.01"
}
config("console") {
- ldflags = [ "/SUBSYSTEM:CONSOLE$subsystem_version_suffix" ]
+ if(is_mingw){
+ cflags = [ "-mconsole" ]
+ ldflags = [ "-Wl,--subsystem,console:$subsystem_version_suffix" ]
+ } else {
+ ldflags = [ "/SUBSYSTEM:CONSOLE,$subsystem_version_suffix" ]
+ }
}
config("windowed") {
- ldflags = [ "/SUBSYSTEM:WINDOWS$subsystem_version_suffix" ]
+ if(is_mingw){
+ cflags = [ "-mwindows" ]
+ ldflags = [ "-Wl,--subsystem,windows:$subsystem_version_suffix" ]
+ } else {
+ 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" ]
+ if(!is_mingw){
+ # 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" ]
}
- } else {
- ldflags = [ "/INCREMENTAL:NO" ]
}
}
@@ -565,6 +600,9 @@ config("unicode") {
"_UNICODE",
"UNICODE",
]
+ if(is_mingw) {
+ cflags = [ "-municode" ]
+ }
}
# Lean and mean ----------------------------------------------------------------
@@ -585,3 +623,21 @@ config("lean_and_mean") {
config("nominmax") {
defines = [ "NOMINMAX" ]
}
+
+# Let unit tests see all "for_testing" dll symbols.
+config("export_all_symbols") {
+ if(is_win && is_mingw){
+ ldflags = [ "-Wl,--export-all-symbols" ]
+ }
+}
+
+# Workaround a Mingw ld bug where large debug symbol data
+# causes the produced executable to be corrupted
+# https://stackoverflow.com/questions/22261539/ld-exe-crashing-in-mingw
+# this affects mksnapshot and v8 component.
+
+config("strip_all_symbols_at_link_time") {
+ if(is_win && is_mingw){
+ ldflags = [ "-Wl,--strip-all" ]
+ }
+}
diff --git a/config/win/manifest.gni b/config/win/manifest.gni
index e2115083f..c6bdef8fb 100644
--- a/config/win/manifest.gni
+++ b/config/win/manifest.gni
@@ -85,12 +85,14 @@ if (is_win) {
foreach(i, rebase_path(invoker.sources, root_build_dir)) {
manifests += [ "/manifestinput:" + i ]
}
- ldflags = [
- "/manifest:embed",
+ if(!is_mingw){
+ ldflags = [
+ "/manifest:embed",
- # We handle UAC by adding explicit .manifest files instead.
- "/manifestuac:no",
- ] + manifests
+ # We handle UAC by adding explicit .manifest files instead.
+ "/manifestuac:no",
+ ] + manifests
+ }
}
# This source set only exists to add a dep on the invoker's deps and to
diff --git a/config/x64.gni b/config/x64.gni
index 9e86979cb..ca8f47501 100644
--- a/config/x64.gni
+++ b/config/x64.gni
@@ -16,7 +16,7 @@ if (current_cpu == "x64") {
x64_arch = ""
}
- if ((is_posix && !is_apple) || is_fuchsia) {
+ if ((is_posix && !is_apple) || is_fuchsia || is_mingw) {
if (x64_arch == "") {
x64_arch = "x86-64"
}
diff --git a/toolchain/gcc_solink_wrapper.py b/toolchain/gcc_solink_wrapper.py
index 39aef4d1e..7e83b058a 100644
--- a/toolchain/gcc_solink_wrapper.py
+++ b/toolchain/gcc_solink_wrapper.py
@@ -18,10 +18,11 @@ import sys
import wrapper_utils
-
def CollectSONAME(args):
"""Replaces: readelf -d $sofile | grep SONAME"""
toc = ''
+ if ("GCC" in sys.version and sys.platform=='win32'): # Mingw's readelf doesn't work on PE files
+ return 0, toc
readelf = subprocess.Popen(wrapper_utils.CommandToRun(
[args.readelf, '-d', args.sofile]),
stdout=subprocess.PIPE,
@@ -36,6 +37,10 @@ def CollectSONAME(args):
def CollectDynSym(args):
"""Replaces: nm --format=posix -g -D -p $sofile | cut -f1-2 -d' '"""
toc = ''
+
+ if ("GCC" in sys.version and sys.platform=='win32'): # Mingw's nm doesn't work on PE/COFF files
+ return 0, toc
+
nm = subprocess.Popen(wrapper_utils.CommandToRun(
[args.nm, '--format=posix', '-g', '-D', '-p', args.sofile]),
stdout=subprocess.PIPE,
@@ -94,6 +99,9 @@ def main():
help='The strip binary to run',
metavar='PATH')
parser.add_argument('--dwp', help='The dwp binary to run', metavar='PATH')
+ parser.add_argument('--objcopy',
+ help='The objcopy binary to run',
+ metavar='PATH')
parser.add_argument('--sofile',
required=True,
help='Shared object file produced by linking command',
@@ -183,8 +191,18 @@ def main():
# Finally, strip the linked shared object file (if desired).
if args.strip:
+ if args.objcopy:
+ result = subprocess.call(wrapper_utils.CommandToRun(
+ [args.objcopy, '--only-keep-debug', args.sofile, args.output + '.debug']))
+ if result != 0:
+ return result
result = subprocess.call(wrapper_utils.CommandToRun(
[args.strip, '-o', args.output, args.sofile]))
+ if result != 0:
+ return result
+ if args.objcopy:
+ result = subprocess.call(wrapper_utils.CommandToRun(
+ [args.objcopy, '--add-gnu-debuglink', args.output + '.debug',args.output]))
if dwp_proc:
dwp_result = dwp_proc.wait()
@@ -193,6 +211,5 @@ def main():
return result
-
if __name__ == "__main__":
sys.exit(main())
diff --git a/toolchain/gcc_toolchain.gni b/toolchain/gcc_toolchain.gni
index 9418f5cea..4484c2e76 100644
--- a/toolchain/gcc_toolchain.gni
+++ b/toolchain/gcc_toolchain.gni
@@ -59,6 +59,7 @@ if (enable_resource_allowlist_generation) {
# - cc
# - cxx
# - ld
+# - rc (mingw only)
#
# Optional parameters that control the tools:
#
@@ -111,7 +112,9 @@ template("gcc_toolchain") {
assert(defined(invoker.cc), "gcc_toolchain() must specify a \"cc\" value")
assert(defined(invoker.cxx), "gcc_toolchain() must specify a \"cxx\" value")
assert(defined(invoker.ld), "gcc_toolchain() must specify a \"ld\" value")
-
+ if(is_mingw){
+ assert(defined(invoker.rc), "gcc_toolchain() must specify a \"rc\" value")
+ }
# This define changes when the toolchain changes, forcing a rebuild.
# Nothing should ever use this define.
if (defined(invoker.rebuild_define)) {
@@ -269,15 +272,19 @@ template("gcc_toolchain") {
asm = asm_prefix + invoker.cc
ar = invoker.ar
ld = "$goma_ld${invoker.ld}"
- if (defined(invoker.readelf)) {
- readelf = invoker.readelf
- } else {
- readelf = "readelf"
- }
- if (defined(invoker.nm)) {
- nm = invoker.nm
+ if(!is_mingw){
+ if (defined(invoker.readelf)) {
+ readelf = invoker.readelf
+ } else {
+ readelf = "readelf"
+ }
+ if (defined(invoker.nm)) {
+ nm = invoker.nm
+ } else {
+ nm = "nm"
+ }
} else {
- nm = "nm"
+ rc = invoker.rc
}
if (defined(invoker.dwp)) {
dwp_switch = " --dwp=\"${invoker.dwp}\""
@@ -285,6 +292,7 @@ template("gcc_toolchain") {
dwp_switch = ""
}
+
if (defined(invoker.shlib_extension)) {
default_shlib_extension = invoker.shlib_extension
} else {
@@ -362,6 +370,16 @@ template("gcc_toolchain") {
outputs = [ "$object_subdir/{{source_name_part}}.o" ]
}
+ if(is_mingw){
+ tool("rc") {
+ depfile = "{{output}}.d"
+ command = "$rc -i {{source}} -o {{output}}"
+ depsformat = "gcc"
+ description = "RC {{output}}"
+ outputs = [ "$object_subdir/{{source_name_part}}.o" ]
+ }
+ }
+
tool("asm") {
# For GCC we can just use the C compiler to compile assembly.
depfile = "{{output}}.d"
@@ -422,8 +440,6 @@ template("gcc_toolchain") {
# .TOC file, overwrite it, otherwise, don't change it.
tocfile = sofile + ".TOC"
- link_command = "$ld -shared -Wl,-soname=\"$soname\" {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" @\"$rspfile\""
-
# Generate a map file to be used for binary size analysis.
# Map file adds ~10% to the link time on a z620.
# With target_os="android", libchrome.so.map.gz is ~20MB.
@@ -433,13 +449,30 @@ template("gcc_toolchain") {
map_switch = " --map-file \"$map_file\""
}
- assert(defined(readelf), "to solink you must have a readelf")
- assert(defined(nm), "to solink you must have an nm")
strip_switch = ""
if (defined(invoker.strip)) {
strip_switch = "--strip=${invoker.strip} "
}
+ mingw_flags = ""
+ if(is_mingw){
+ # Have MinGW linker generate a .def file and a .a import library
+ mingw_flags = " -Wl,--dll -Wl,--output-def=\"$sofile\".def -Wl,--out-implib=\"$sofile\".a "
+ readelf = ""
+ if (defined(invoker.readelf)) {
+ readelf = "${invoker.readelf} "
+ }
+ nm = ""
+ if (defined(invoker.nm)) {
+ readelf = "${invoker.nm} "
+ }
+ } else {
+ assert(defined(readelf), "to solink you must have a readelf")
+ assert(defined(nm), "to solink you must have an nm")
+ }
+
+ link_command = "$ld -shared -Wl,-soname=\"$soname\" ${mingw_flags} {{ldflags}}${extra_ldflags} -o \"$unstripped_sofile\" @\"$rspfile\""
+
# This needs a Python script to avoid using a complex shell command
# requiring sh control structures, pipelines, and POSIX utilities.
# The host might not have a POSIX shell and utilities (e.g. Windows).
diff --git a/toolchain/win/BUILD.gn b/toolchain/win/BUILD.gn
index a8137526d..d512605e2 100644
--- a/toolchain/win/BUILD.gn
+++ b/toolchain/win/BUILD.gn
@@ -10,6 +10,7 @@ import("//build/toolchain/cc_wrapper.gni")
import("//build/toolchain/goma.gni")
import("//build/toolchain/rbe.gni")
import("//build/toolchain/toolchain.gni")
+import("//build/toolchain/gcc_toolchain.gni")
# Should only be running on Windows.
assert(is_win)
@@ -51,13 +52,15 @@ if (current_toolchain == default_toolchain) {
} else {
configuration_name = "Release"
}
- exec_script("../../vs_toolchain.py",
- [
- "copy_dlls",
- rebase_path(root_build_dir),
- configuration_name,
- target_cpu,
- ])
+ if(!is_mingw){
+ exec_script("../../vs_toolchain.py",
+ [
+ "copy_dlls",
+ rebase_path(root_build_dir),
+ configuration_name,
+ target_cpu,
+ ])
+ }
}
if (host_os == "win") {
@@ -532,3 +535,29 @@ if (target_os == "winuwp") {
}
}
}
+
+template("mingw_toolchain") {
+ gcc_toolchain("mingw_" + target_name) {
+ forward_variables_from(invoker, "*")
+ cc = "gcc"
+ cxx = "g++"
+ ar = "ar"
+ ld = cxx
+ if(is_mingw){
+ rc = "windres"
+ }
+ strip = "strip"
+ executable_extension = ".exe"
+ toolchain_args = {
+ current_cpu = target_name
+ current_os = "win"
+ is_clang = false
+ }
+ }
+}
+
+mingw_toolchain("x64") {
+}
+
+mingw_toolchain("x86") {
+}
diff --git a/util/lastchange.py b/util/lastchange.py
index 874870ad5..a4fc0be8d 100644
--- a/util/lastchange.py
+++ b/util/lastchange.py
@@ -191,7 +191,10 @@ def GetGitTopDirectory(source_dir):
Returns:
The output of "git rev-parse --show-toplevel" as a string
"""
- return _RunGitCommand(source_dir, ['rev-parse', '--show-toplevel'])
+ directory = _RunGitCommand(source_dir, ['rev-parse', '--show-toplevel'])
+ if "GCC" in sys.version and sys.platform=='win32':
+ return subprocess.check_output(["cygpath", "-w", directory]).strip(b"\n").decode()
+ return directory
def WriteIfChanged(file_name, contents):
diff --git a/win/BUILD.gn b/win/BUILD.gn
index d449f5925..558e04229 100644
--- a/win/BUILD.gn
+++ b/win/BUILD.gn
@@ -16,7 +16,7 @@ windows_manifest("default_exe_manifest") {
]
}
-if (is_win) {
+if (is_win && !is_mingw) {
assert(host_os != "mac" || target_cpu != "x86",
"Windows cross-builds from Mac must be 64-bit.")
@@ -92,7 +92,7 @@ if (is_win) {
group("runtime_libs") {
data = []
- if (is_component_build) {
+ if (is_component_build && !is_mingw) {
# Copy the VS runtime DLLs into the isolate so that they don't have to be
# preinstalled on the target machine. The debug runtimes have a "d" at
# the end.