bug 1266368 - move rust.m4 to configure. r=glandium
authorTed Mielczarek <ted@mielczarek.org>
Mon, 16 May 2016 15:27:37 -0400
changeset 345116 4b555450a4d80e208e33342620d27294ee900d59
parent 345115 9b1fcf3bae37b9b9da2338fc0f97a91a7f990e3a
child 345117 b4f0bf4b78c75ee40220e140df43b9ab29c19ec5
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1266368
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1266368 - move rust.m4 to configure. r=glandium MozReview-Commit-ID: 9ol2nMYM0a0
aclocal.m4
build/moz.configure/old.configure
build/moz.configure/rust.configure
build/moz.configure/toolchain.configure
config/rules.mk
js/src/aclocal.m4
js/src/old-configure.in
old-configure.in
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -27,17 +27,16 @@ builtin(include, build/autoconf/zlib.m4)
 builtin(include, build/autoconf/linux.m4)dnl
 builtin(include, build/autoconf/winsdk.m4)dnl
 builtin(include, build/autoconf/icu.m4)dnl
 builtin(include, build/autoconf/ffi.m4)dnl
 builtin(include, build/autoconf/clang-plugin.m4)dnl
 builtin(include, build/autoconf/alloc.m4)dnl
 builtin(include, build/autoconf/ios.m4)dnl
 builtin(include, build/autoconf/jemalloc.m4)dnl
-builtin(include, build/autoconf/rust.m4)dnl
 
 MOZ_PROG_CHECKMSYS()
 
 # Read the user's .mozconfig script.  We can't do this in
 # configure.in: autoconf puts the argument parsing code above anything
 # expanded from configure.in, and we need to get the configure options
 # from .mozconfig in place before that argument parsing code.
 MOZ_READ_MOZCONFIG(.)
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -223,17 +223,16 @@ def old_configure_options(*options):
     '--enable-pref-extensions',
     '--enable-printing',
     '--enable-pulseaudio',
     '--enable-raw',
     '--enable-readline',
     '--enable-reflow-perf',
     '--enable-release',
     '--enable-require-all-d3dc-versions',
-    '--enable-rust',
     '--enable-safe-browsing',
     '--enable-sandbox',
     '--enable-signmar',
     '--enable-simulator',
     '--enable-skia',
     '--enable-skia-gpu',
     '--enable-small-chunk-size',
     '--enable-startup-notification',
new file mode 100644
--- /dev/null
+++ b/build/moz.configure/rust.configure
@@ -0,0 +1,146 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+option('--enable-rust', help='Include Rust language sources')
+
+@depends('--enable-rust')
+def rust_compiler_names(value):
+    if value:
+        return ['rustc']
+
+rustc = check_prog('RUSTC', rust_compiler_names, allow_missing=True)
+
+@depends_if(rustc)
+@checking('rustc version')
+@imports('subprocess')
+def rustc_version(rustc):
+    try:
+        # TODO: We should run `rustc --version -v` and parse that output instead.
+        version = Version(subprocess.check_output(
+            [rustc, '--version']
+        ).splitlines()[0].split()[1])
+        return version
+    except subprocess.CalledProcessError as e:
+        die('Failed to get rustc version: %s', e.message)
+
+@depends('--enable-rust', rustc, rustc_version)
+@imports(_from='textwrap', _import='dedent')
+def rust_compiler(value, rustc, rustc_version):
+    if value:
+        if not rustc:
+            die(dedent('''\
+            Rust compiler not found.
+            To compile rust language sources, you must have 'rustc' in your path.
+            See http://www.rust-lang.org/ for more information.
+            '''))
+        if rustc_version < '1.5':
+            die(dedent('''\
+            Rust compiler {} is too old.
+            To compile Rust language sources please install at least
+            version 1.5 of the 'rustc' toolchain and make sure it is
+            first in your path.
+            You can verify this by typing 'rustc --version'.
+            '''.format(rustc_version)))
+        return True
+
+set_config('MOZ_RUST', rust_compiler)
+
+@depends(rust_compiler, rustc, target, cross_compiling)
+@imports('os')
+@imports('subprocess')
+@imports(_from='mozbuild.configure.util', _import='LineIO')
+@imports(_from='mozbuild.shellutil', _import='quote')
+@imports(_from='tempfile', _import='mkstemp')
+def rust_target(rust_compiler, rustc, target, cross_compiling):
+    if rust_compiler:
+        # 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/tree/master/mk/cfg
+
+        # Avoid having to write out os+kernel for all the platforms where
+        # they don't differ.
+        os_or_kernel = target.kernel if target.kernel == 'Linux' and target.os != 'Android' else target.os
+        rustc_target = {
+            # DragonFly
+            ('x86_64', 'Dragonfly'): 'x86_64-unknown-dragonfly',
+            # FreeBSD, GNU/kFreeBSD
+            ('x86', 'FreeBSD'): 'i686-unknown-freebsd',
+            ('x86_64', 'FreeBSD'): 'x86_64-unknown-freebsd',
+            # NetBSD
+            ('x86_64', 'NetBSD'): 'x86_64-unknown-netbsd',
+            # OpenBSD
+            ('x86_64', 'OpenBSD'): 'x86_64-unknown-openbsd',
+            # Linux
+            ('x86', 'Linux'): 'i686-unknown-linux-gnu',
+            # Linux
+            ('x86_64', 'Linux'): 'x86_64-unknown-linux-gnu',
+            # OS X and iOS
+            ('x86', 'OSX'): 'i686-apple-darwin',
+            ('x86', 'iOS'): 'i386-apple-ios',
+            ('x86_64', 'OSX'): 'x86_64-apple-darwin',
+            # Android
+            ('x86', 'Android'): 'i686-linux-android',
+            ('arm', 'Android'): 'arm-linux-androideabi',
+            # 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',
+        }.get((target.cpu, os_or_kernel), None)
+
+        if rustc_target is None:
+            if cross_compiling:
+                die("Don't know how to translate {} for rustc".format(target.alias))
+            # Fall back to implicit (native) target when not cross-compiling
+            return None
+
+        # Check to see whether our rustc has a reasonably functional stdlib
+        # for our chosen target.
+        target_arg = '--target=' + rustc_target
+        in_fd, in_path = mkstemp(prefix='conftest', suffix='.rs')
+        out_fd, out_path = mkstemp(prefix='conftest', suffix='.rlib')
+        os.close(out_fd)
+        try:
+            source = 'pub extern fn hello() { println!("Hello world"); }'
+            log.debug('Creating `%s` with content:', in_path)
+            with LineIO(lambda l: log.debug('| %s', l)) as out:
+                out.write(source)
+
+            os.write(in_fd, source)
+            os.close(in_fd)
+
+            cmd = [
+                rustc,
+                '--crate-type', 'staticlib',
+                target_arg,
+                '-o', out_path,
+                in_path,
+            ]
+            def failed():
+                die('Cannot compile for {} with {}'.format(target.alias, rustc))
+            check_cmd_output(*cmd, onerror=failed)
+            if not os.path.exists(out_path) or os.path.getsize(out_path) == 0:
+                failed()
+        finally:
+            os.remove(in_path)
+            os.remove(out_path)
+        # This target is usable.
+        return target_arg
+
+set_config('RUST_TARGET', rust_target)
+
+# Until we remove all the other Rust checks in old-configure.
+add_old_configure_assignment('MOZ_RUST', rust_compiler)
+add_old_configure_assignment('RUSTC', rustc)
+add_old_configure_assignment('RUST_TARGET', rust_target)
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -635,8 +635,10 @@ def debug_flags(env_debug_flags, enable_
     if len(enable_debug_flags):
         return enable_debug_flags[0]
     if env_debug_flags:
         return env_debug_flags[0]
     return default_debug_flags
 
 set_config('MOZ_DEBUG_FLAGS', debug_flags)
 add_old_configure_assignment('MOZ_DEBUG_FLAGS', debug_flags)
+
+include('rust.configure')
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -914,21 +914,21 @@ ifdef ASFILES
 	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
 endif
 
 ifdef MOZ_RUST
 # Assume any system libraries rustc links against are already
 # in the target's LIBS.
 $(RSOBJS):
 	$(REPORT_BUILD)
-	$(RUSTC) $(RUSTFLAGS) --crate-type rlib --emit dep-info=$(MDDEPDIR)/$(call mk_libname,$<).pp,link=$(call mk_libname,$<) $(_VPATH_SRCS)
+	$(RUSTC) $(RUST_TARGET) $(RUSTFLAGS) --crate-type rlib --emit dep-info=$(MDDEPDIR)/$(call mk_libname,$<).pp,link=$(call mk_libname,$<) $(_VPATH_SRCS)
 
 $(RS_STATICLIB_CRATE_OBJ):
 	$(REPORT_BUILD)
-	$(RUSTC) $(RUSTFLAGS) --crate-type staticlib $(RLIB_EXTERN_CRATE_OPTIONS) --emit dep-info=$(MDDEPDIR)/$(call mk_global_crate_libname,$(RS_STATICLIB_CRATE_SRC)).pp,link=$@ $(RS_STATICLIB_CRATE_SRC)
+	$(RUSTC) $(RUST_TARGET) $(RUSTFLAGS) --crate-type staticlib $(RLIB_EXTERN_CRATE_OPTIONS) --emit dep-info=$(MDDEPDIR)/$(call mk_global_crate_libname,$(RS_STATICLIB_CRATE_SRC)).pp,link=$@ $(RS_STATICLIB_CRATE_SRC)
 endif
 
 $(SOBJS):
 	$(REPORT_BUILD)
 	$(AS) -o $@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) -c $<
 
 $(CPPOBJS):
 	$(REPORT_BUILD_VERBOSE)
--- a/js/src/aclocal.m4
+++ b/js/src/aclocal.m4
@@ -26,17 +26,16 @@ builtin(include, ../../build/autoconf/zl
 builtin(include, ../../build/autoconf/linux.m4)dnl
 builtin(include, ../../build/autoconf/winsdk.m4)dnl
 builtin(include, ../../build/autoconf/icu.m4)dnl
 builtin(include, ../../build/autoconf/ffi.m4)dnl
 builtin(include, ../../build/autoconf/clang-plugin.m4)dnl
 builtin(include, ../../build/autoconf/alloc.m4)dnl
 builtin(include, ../../build/autoconf/jemalloc.m4)dnl
 builtin(include, ../../build/autoconf/ios.m4)dnl
-builtin(include, ../../build/autoconf/rust.m4)dnl
 
 define([__MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
 define([AC_INIT_PREPARE],
 [if test -z "$srcdir"; then
   srcdir=`dirname "[$]0"`
 fi
 srcdir="$srcdir/../.."
 __MOZ_AC_INIT_PREPARE($1)
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -139,17 +139,16 @@ else
         HOST_AR_FLAGS='$(AR_FLAGS)'
     fi
 fi
 
 MOZ_TOOL_VARIABLES
 
 AC_PROG_CPP
 AC_PROG_CXXCPP
-MOZ_RUST_SUPPORT
 
 dnl Special win32 checks
 dnl ========================================================
 
 # Target the Windows 8.1 SDK by default
 WINSDK_TARGETVER=603
 WINVER=502
 
--- a/old-configure.in
+++ b/old-configure.in
@@ -255,18 +255,16 @@ else
 fi
 
 if test -n "$MOZ_WINCONSOLE"; then
     AC_DEFINE(MOZ_WINCONSOLE)
 fi
 
 MOZ_TOOL_VARIABLES
 
-MOZ_RUST_SUPPORT
-
 AC_PROG_CPP
 AC_PROG_CXXCPP
 
 dnl ========================================================
 dnl Special win32 checks
 dnl ========================================================
 
 # Target the Windows 8.1 SDK by default
@@ -1031,17 +1029,17 @@ if test -n "$MACOSX_DEPLOYMENT_TARGET" -
   _MACOSX_TARGET_MINOR=`echo "$MACOSX_DEPLOYMENT_TARGET" | cut -d. -f2`
   if test "$_MACOSX_TARGET_MINOR" -lt 7; then
     dnl Test C linkage against rust code to see if the rust
     dnl toolchain output is compatible.
     cat > conftest.rs <<EOF
       [#[no_mangle]]
       pub extern fn rusty_answer() -> u8 { 42 }
 EOF
-    ac_try="$RUSTC --crate-type staticlib -o conftest.a conftest.rs >/dev/null"
+    ac_try="$RUSTC $RUST_TARGET --crate-type staticlib -o conftest.a conftest.rs >/dev/null"
     AC_TRY_EVAL(ac_try)
     save_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS conftest.a -lpthread -lm"
     AC_TRY_LINK_FUNC([rusty_answer], [
       AC_MSG_RESULT([$MACOSX_DEPLOYMENT_TARGET is ok with this rustc])
     ], [
       AC_MSG_RESULT([cannot link for $MACOSX_DEPLOYMENT_TARGET])
       MOZ_RUST=