bug 1266368 - move rust.m4 to configure. r=glandium
authorTed Mielczarek <ted@mielczarek.org>
Mon, 16 May 2016 15:27:37 -0400
changeset 303020 4b555450a4d80e208e33342620d27294ee900d59
parent 303019 9b1fcf3bae37b9b9da2338fc0f97a91a7f990e3a
child 303021 b4f0bf4b78c75ee40220e140df43b9ab29c19ec5
push id19811
push usercbook@mozilla.com
push dateWed, 29 Jun 2016 14:22:11 +0000
treeherderfx-team@eeb6862f960c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium
bugs1266368
milestone50.0a1
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=