Bug 1353541 Fix rustc in MinGW build draft
authorTom Ritter <tom@mozilla.com>
Wed, 26 Apr 2017 12:08:59 -0500
changeset 568851 d7057fddd7efd1d0692ec5bbb9154ef98ab4889a
parent 568807 a477e80f03b61be9961bc61770a2b55cce139b91
child 626044 813e1271d71ecb8c68f860f30062e5a5c6092327
push id55999
push userbmo:tom@mozilla.com
push dateWed, 26 Apr 2017 17:09:41 +0000
bugs1353541
milestone55.0a1
Bug 1353541 Fix rustc in MinGW build rustc generates .lib files for its libraries when compiling for Windows (even using MinGW on Linux). But MinGW expects .a files. So we add in rust-specific prefix and suffixes so MinGW builds can find the libs that rustc generates. (And the RUST_LIB- variables default to the same vales as the LIB_ variables otherwise.) MozReview-Commit-ID: ClsA0YuJaxh
build/moz.configure/rust.configure
config/expandlibs_config.py
config/makefiles/debugmake.mk
js/src/old-configure.in
old-configure.in
python/mozbuild/mozbuild/backend/configenvironment.py
python/mozbuild/mozbuild/frontend/data.py
python/mozbuild/mozbuild/test/backend/common.py
python/mozbuild/mozbuild/test/common.py
--- a/build/moz.configure/rust.configure
+++ b/build/moz.configure/rust.configure
@@ -102,39 +102,42 @@ set_config('MOZ_RUST', rust_compiler)
 @template
 def rust_triple_alias(host_or_target):
     """Template defining the alias used for rustc's --target flag.
     `host_or_target` is either `host` or `target` (the @depends functions
     from init.configure).
     """
     assert host_or_target in (host, target)
 
-    @depends(rustc, host_or_target, when=rust_compiler)
+    @depends(rustc, host_or_target, building_with_gcc, when=rust_compiler)
     @imports('os')
     @imports('subprocess')
     @imports(_from='mozbuild.configure.util', _import='LineIO')
     @imports(_from='mozbuild.shellutil', _import='quote')
     @imports(_from='tempfile', _import='mkstemp')
     @imports(_from='textwrap', _import='dedent')
-    def rust_target(rustc, host_or_target):
+    def rust_target(rustc, host_or_target, building_with_gcc):
         # Rust's --target options are similar to, but not exactly the same
         # as, the autoconf-derived targets we use.  An example would be that
         # Rust uses distinct target triples for targetting the GNU C++ ABI
         # and the MSVC C++ ABI on Win32, whereas autoconf has a single
         # triple and relies on the user to ensure that everything is
         # compiled for the appropriate ABI.  We need to perform appropriate
         # munging to get the correct option to rustc.
         #
         # The canonical list of targets supported can be derived from:
         #
         # https://github.com/rust-lang/rust/blob/master/src/librustc_back/target/mod.rs
 
         # Avoid having to write out os+kernel for all the platforms where
         # they don't differ.
         os_or_kernel = host_or_target.kernel if host_or_target.kernel == 'Linux' and host_or_target.os != 'Android' else host_or_target.os
+        # If we are targetting Windows but the compiler is gcc, we need to
+        # use a different rustc target
+        os_or_kernel = 'WINNT-MINGW' if building_with_gcc and host_or_target.kernel == 'WINNT' else os_or_kernel
         rustc_target = {
             # DragonFly
             ('x86_64', 'DragonFly'): 'x86_64-unknown-dragonfly',
             # FreeBSD
             ('aarch64', 'FreeBSD'): 'aarch64-unknown-freebsd',
             ('x86', 'FreeBSD'): 'i686-unknown-freebsd',
             ('x86_64', 'FreeBSD'): 'x86_64-unknown-freebsd',
             # NetBSD
@@ -158,20 +161,20 @@ def rust_triple_alias(host_or_target):
             ('arm', 'iOS'): 'armv7s-apple-ios',
             ('x86', 'iOS'): 'i386-apple-ios',
             ('x86_64', 'iOS'): 'x86_64-apple-ios',
             # Android
             ('aarch64', 'Android'): 'aarch64-linux-android',
             ('arm', 'Android'): 'armv7-linux-androideabi',
             ('x86', 'Android'): 'i686-linux-android',
             # Windows
-            # XXX better detection of CXX needed here, to figure out whether
-            # we need i686-pc-windows-gnu instead, since mingw32 builds work.
             ('x86', 'WINNT'): 'i686-pc-windows-msvc',
             ('x86_64', 'WINNT'): 'x86_64-pc-windows-msvc',
+            ('x86', 'WINNT-MINGW'): 'i686-pc-windows-gnu',
+            ('x86_64', 'WINNT-MINGW'): 'x86_64-pc-windows-gnu',
         }.get((host_or_target.cpu, os_or_kernel), None)
 
         if rustc_target is None:
             die("Don't know how to translate {} for rustc".format(host_or_target.alias))
 
         # Check to see whether our rustc has a reasonably functional stdlib
         # for our chosen target.
         target_arg = '--target=' + rustc_target
--- a/config/expandlibs_config.py
+++ b/config/expandlibs_config.py
@@ -12,16 +12,18 @@ def normalize_suffix(suffix):
         value = '.' + value
     return value
 
 # Variables from the build system
 AR = substs['AR']
 AR_EXTRACT = substs['AR_EXTRACT'].replace('$(AR)', AR)
 DLL_PREFIX = substs['DLL_PREFIX']
 LIB_PREFIX = substs['LIB_PREFIX']
+RUST_LIB_PREFIX = substs['RUST_LIB_PREFIX']
 OBJ_SUFFIX = normalize_suffix(substs['OBJ_SUFFIX'])
 LIB_SUFFIX = normalize_suffix(substs['LIB_SUFFIX'])
+RUST_LIB_SUFFIX = normalize_suffix(substs['RUST_LIB_SUFFIX'])
 DLL_SUFFIX = normalize_suffix(substs['DLL_SUFFIX'])
 IMPORT_LIB_SUFFIX = normalize_suffix(substs['IMPORT_LIB_SUFFIX'])
 LIBS_DESC_SUFFIX = normalize_suffix(substs['LIBS_DESC_SUFFIX'])
 EXPAND_LIBS_LIST_STYLE = substs['EXPAND_LIBS_LIST_STYLE']
 EXPAND_LIBS_ORDER_STYLE = substs['EXPAND_LIBS_ORDER_STYLE']
 LD_PRINT_ICF_SECTIONS = substs['LD_PRINT_ICF_SECTIONS']
--- a/config/makefiles/debugmake.mk
+++ b/config/makefiles/debugmake.mk
@@ -89,16 +89,17 @@ showbuild:
 		OS_LIBS \
 		EXTRA_LIBS \
 		BIN_FLAGS \
 		INCLUDES \
 		DEFINES \
 		ACDEFINES \
 		BIN_SUFFIX \
 		LIB_SUFFIX \
+		RUST_LIB_SUFFIX \
 		DLL_SUFFIX \
 		IMPORT_LIB_SUFFIX \
 		INSTALL \
 		VPATH \
 	)
 
 showhost:
 	$(call print_vars,\
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -403,19 +403,21 @@ dnl ====================================
 dnl set the defaults first
 dnl ========================================================
 AS_BIN=$AS
 AR_EXTRACT='$(AR) x'
 AS='$(CC)'
 AS_DASH_C_FLAG='-c'
 DLL_PREFIX=lib
 LIB_PREFIX=lib
+RUST_LIB_PREFIX=lib
 DLL_SUFFIX=.so
 OBJ_SUFFIX=o
 LIB_SUFFIX=a
+RUST_LIB_SUFFIX=a
 IMPORT_LIB_SUFFIX=
 DIRENT_INO=d_ino
 MOZ_USER_DIR=".mozilla"
 
 MOZ_FIX_LINK_PATHS="-Wl,-rpath-link,${DIST}/bin -Wl,-rpath-link,${prefix}/lib"
 
 dnl Configure platform-specific CPU architecture compiler options.
 dnl ==============================================================
@@ -668,18 +670,20 @@ case "$target" in
         AR='lib'
         AR_FLAGS='-NOLOGO -OUT:$@'
         AR_EXTRACT=
         RANLIB='echo not_ranlib'
         STRIP='echo not_strip'
         PKG_SKIP_STRIP=1
         OBJ_SUFFIX=obj
         LIB_SUFFIX=lib
+        RUST_LIB_SUFFIX=lib
         DLL_PREFIX=
         LIB_PREFIX=
+        RUST_LIB_PREFIX=
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         WIN32_SUBSYSTEM_VERSION=6.01
         WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
         WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         _USE_CPP_INCLUDE_FLAG=1
@@ -2090,20 +2094,22 @@ AC_SUBST(TARGET_XPCOM_ABI)
 
 AC_SUBST(WRAP_LDFLAGS)
 AC_SUBST(MKSHLIB)
 AC_SUBST(MKCSHLIB)
 AC_SUBST(DSO_CFLAGS)
 AC_SUBST(DSO_PIC_CFLAGS)
 AC_SUBST(DSO_LDOPTS)
 AC_SUBST(LIB_PREFIX)
+AC_SUBST(RUST_LIB_PREFIX)
 AC_SUBST(DLL_PREFIX)
 AC_SUBST(DLL_SUFFIX)
 AC_DEFINE_UNQUOTED(MOZ_DLL_SUFFIX, "$DLL_SUFFIX")
 AC_SUBST(LIB_SUFFIX)
+AC_SUBST(RUST_LIB_SUFFIX)
 AC_SUBST(OBJ_SUFFIX)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(IMPORT_LIB_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(MOZ_LINKER)
 AC_SUBST(WIN32_CONSOLE_EXE_LDFLAGS)
 AC_SUBST(WIN32_GUI_EXE_LDFLAGS)
--- a/old-configure.in
+++ b/old-configure.in
@@ -501,19 +501,21 @@ dnl ====================================
 dnl set the defaults first
 dnl ========================================================
 AS_BIN=$AS
 AR_EXTRACT='$(AR) x'
 AS='$(CC)'
 AS_DASH_C_FLAG='-c'
 DLL_PREFIX=lib
 LIB_PREFIX=lib
+RUST_LIB_PREFIX=lib
 DLL_SUFFIX=.so
 OBJ_SUFFIX=o
 LIB_SUFFIX=a
+RUST_LIB_SUFFIX=a
 IMPORT_LIB_SUFFIX=
 DIRENT_INO=d_ino
 MOZ_USER_DIR=".mozilla"
 
 MOZ_FIX_LINK_PATHS="-Wl,-rpath-link,${DIST}/bin -Wl,-rpath-link,${prefix}/lib"
 
 MOZ_FS_LAYOUT=unix
 
@@ -921,16 +923,18 @@ case "$target" in
         NSPR_LDFLAGS="$NSPR_LDFLAGS -static-libgcc"
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32 -luserenv -lsecur32"
         MOZ_FIX_LINK_PATHS=
         DLL_PREFIX=
         IMPORT_LIB_SUFFIX=a
+        RUST_LIB_PREFIX=
+        RUST_LIB_SUFFIX=lib
 
         WIN32_CONSOLE_EXE_LDFLAGS=-mconsole
         WIN32_GUI_EXE_LDFLAGS=-mwindows
 
         # GCC/binutils can't link to a function if we try to include dllexport function
         # in the same library as dllimport caller. To work around it, we build NSPR
         # and NSS with -mnop-fun-dllimport flag. The drawback of this solution is that
         # function thunks need to be generated for cross-DLL calls.
@@ -943,18 +947,20 @@ case "$target" in
         AR='lib'
         AR_FLAGS='-NOLOGO -OUT:$@'
         AR_EXTRACT=
         RANLIB='echo not_ranlib'
         STRIP='echo not_strip'
         PKG_SKIP_STRIP=1
         OBJ_SUFFIX=obj
         LIB_SUFFIX=lib
+        RUST_LIB_SUFFIX=lib
         DLL_PREFIX=
         LIB_PREFIX=
+        RUST_LIB_PREFIX=
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LINK) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         WIN32_SUBSYSTEM_VERSION=6.01
         WIN32_CONSOLE_EXE_LDFLAGS=-SUBSYSTEM:CONSOLE,$WIN32_SUBSYSTEM_VERSION
         WIN32_GUI_EXE_LDFLAGS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS,$WIN32_SUBSYSTEM_VERSION
         _USE_CPP_INCLUDE_FLAG=1
@@ -5317,20 +5323,22 @@ AC_SUBST(GCC_USE_GNU_LD)
 
 AC_SUBST(WRAP_LDFLAGS)
 AC_SUBST(MKSHLIB)
 AC_SUBST(MKCSHLIB)
 AC_SUBST(DSO_CFLAGS)
 AC_SUBST(DSO_PIC_CFLAGS)
 AC_SUBST(DSO_LDOPTS)
 AC_SUBST(LIB_PREFIX)
+AC_SUBST(RUST_LIB_PREFIX)
 AC_SUBST(DLL_PREFIX)
 AC_SUBST(DLL_SUFFIX)
 AC_DEFINE_UNQUOTED(MOZ_DLL_SUFFIX, "$DLL_SUFFIX")
 AC_SUBST(LIB_SUFFIX)
+AC_SUBST(RUST_LIB_SUFFIX)
 AC_SUBST(OBJ_SUFFIX)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(IMPORT_LIB_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(NS_ENABLE_TSF)
 AC_SUBST(WIN32_CONSOLE_EXE_LDFLAGS)
 AC_SUBST(WIN32_GUI_EXE_LDFLAGS)
--- a/python/mozbuild/mozbuild/backend/configenvironment.py
+++ b/python/mozbuild/mozbuild/backend/configenvironment.py
@@ -120,18 +120,21 @@ class ConfigEnvironment(object):
         self.source = source
         self.defines = ReadOnlyDict(defines or {})
         self.non_global_defines = non_global_defines or []
         self.substs = dict(substs or {})
         self.topsrcdir = mozpath.abspath(topsrcdir)
         self.topobjdir = mozpath.abspath(topobjdir)
         self.mozconfig = mozpath.abspath(mozconfig) if mozconfig else None
         self.lib_prefix = self.substs.get('LIB_PREFIX', '')
+        self.rust_lib_prefix = self.substs.get('RUST_LIB_PREFIX', '')
         if 'LIB_SUFFIX' in self.substs:
             self.lib_suffix = '.%s' % self.substs['LIB_SUFFIX']
+        if 'RUST_LIB_SUFFIX' in self.substs:
+            self.rust_lib_suffix = '.%s' % self.substs['RUST_LIB_SUFFIX']
         self.dll_prefix = self.substs.get('DLL_PREFIX', '')
         self.dll_suffix = self.substs.get('DLL_SUFFIX', '')
         if self.substs.get('IMPORT_LIB_SUFFIX'):
             self.import_prefix = self.lib_prefix
             self.import_suffix = '.%s' % self.substs['IMPORT_LIB_SUFFIX']
         else:
             self.import_prefix = self.dll_prefix
             self.import_suffix = self.dll_suffix
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -534,19 +534,19 @@ class RustLibrary(StaticLibrary):
         StaticLibrary.__init__(self, context, basename, **args)
         self.cargo_file = cargo_file
         self.crate_type = crate_type
         # We need to adjust our naming here because cargo replaces '-' in
         # package names defined in Cargo.toml with underscores in actual
         # filenames. But we need to keep the basename consistent because
         # many other things in the build system depend on that.
         assert self.crate_type == 'staticlib'
-        self.lib_name = '%s%s%s' % (context.config.lib_prefix,
+        self.lib_name = '%s%s%s' % (context.config.rust_lib_prefix,
                                      basename.replace('-', '_'),
-                                     context.config.lib_suffix)
+                                     context.config.rust_lib_suffix)
         self.dependencies = dependencies
         build_dir = mozpath.join(target_dir,
                                  cargo_output_directory(context, self.TARGET_SUBST_VAR))
         self.import_name = mozpath.join(build_dir, self.lib_name)
         self.deps_path = mozpath.join(build_dir, 'deps')
         self.features = features
         self.target_dir = target_dir
 
--- a/python/mozbuild/mozbuild/test/backend/common.py
+++ b/python/mozbuild/mozbuild/test/backend/common.py
@@ -43,60 +43,70 @@ CONFIGS = defaultdict(lambda: {
             'MOZ_WIDGET_TOOLKIT': 'android',
         },
     },
     'binary-components': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'LIB_PREFIX': 'lib',
+            'RUST_LIB_PREFIX': 'lib',
             'LIB_SUFFIX': 'a',
+            'RUST_LIB_SUFFIX': 'a',
             'COMPILE_ENVIRONMENT': '1',
         },
     },
     'rust-library': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'COMPILE_ENVIRONMENT': '1',
             'RUST_TARGET': 'x86_64-unknown-linux-gnu',
             'LIB_PREFIX': 'lib',
+            'RUST_LIB_PREFIX': 'lib',
             'LIB_SUFFIX': 'a',
+            'RUST_LIB_SUFFIX': 'a',
         },
     },
     'host-rust-library': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'COMPILE_ENVIRONMENT': '1',
             'RUST_HOST_TARGET': 'x86_64-unknown-linux-gnu',
             'RUST_TARGET': 'armv7-linux-androideabi',
             'LIB_PREFIX': 'lib',
+            'RUST_LIB_PREFIX': 'lib',
             'LIB_SUFFIX': 'a',
+            'RUST_LIB_SUFFIX': 'a',
         },
     },
     'host-rust-library-features': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'COMPILE_ENVIRONMENT': '1',
             'RUST_HOST_TARGET': 'x86_64-unknown-linux-gnu',
             'RUST_TARGET': 'armv7-linux-androideabi',
             'LIB_PREFIX': 'lib',
+            'RUST_LIB_PREFIX': 'lib',
             'LIB_SUFFIX': 'a',
+            'RUST_LIB_SUFFIX': 'a',
         },
     },
     'rust-library-features': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'COMPILE_ENVIRONMENT': '1',
             'RUST_TARGET': 'x86_64-unknown-linux-gnu',
             'LIB_PREFIX': 'lib',
+            'RUST_LIB_PREFIX': 'lib',
             'LIB_SUFFIX': 'a',
+            'RUST_LIB_SUFFIX': 'a',
         },
     },
     'rust-programs': {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'COMPILE_ENVIRONMENT': '1',
             'RUST_TARGET': 'i686-pc-windows-msvc',
--- a/python/mozbuild/mozbuild/test/common.py
+++ b/python/mozbuild/mozbuild/test/common.py
@@ -37,14 +37,16 @@ class MockConfig(object):
 
         self.substs_unicode = ReadOnlyDict({k.decode('utf-8'): v.decode('utf-8',
             'replace') for k, v in self.substs.items()})
 
         self.defines = self.substs
 
         self.external_source_dir = None
         self.lib_prefix = 'lib'
+        self.rust_lib_prefix = 'lib'
         self.lib_suffix = '.a'
+        self.rust_lib_suffix = '.a'
         self.import_prefix = 'lib'
         self.import_suffix = '.so'
         self.dll_prefix = 'lib'
         self.dll_suffix = '.so'
         self.error_is_fatal = error_is_fatal