Bug 1177599 - always pass --target to rustc; r=mshal
authorNathan Froyd <froydnj@mozilla.com>
Mon, 25 Jan 2016 16:25:59 -0500
changeset 319139 627dd0b985234a11ef62b1f76063e97276f3931b
parent 319138 e997a56353e81a3340751fcce2378173f9401bb7
child 319140 9f24d3935ab97cc64152999a635cd89bc51c5f6a
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmshal
bugs1177599
milestone47.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 1177599 - always pass --target to rustc; r=mshal rustc, unlike our typical C++ compilers, can target multiple platforms with ease through its use of the --target flag. To support cross-compiling, we just need to pass the appropriate --target option. rustc uses specific names for its accepted --target option, however, and they are slightly different from the values we get out of autoconf. So in addition to checking whether rustc can accept --target for our chosen platform, we also need to munge autoconf's idea of the target into something rustc understands.
build/autoconf/rust.m4
configure.in
--- a/build/autoconf/rust.m4
+++ b/build/autoconf/rust.m4
@@ -27,10 +27,92 @@ AC_DEFUN([MOZ_RUST_SUPPORT], [
     "$_RUSTC_MAJOR_VERSION" -lt 1 -o \
     \( "$_RUSTC_MAJOR_VERSION" -eq 1 -a "$_RUSTC_MINOR_VERSION" -lt 5 \); then
     AC_MSG_ERROR([Rust compiler ${RUSTC_VERSION} 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'.])
   fi
+
+  if test -n "$RUSTC" -a -n "$MOZ_RUST"; then
+    # 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
+    rust_target=
+    case "$target" in
+      # Linux
+      i*86*linux-gnu)
+          rust_target=i686-unknown-linux-gnu
+          ;;
+      x86_64*linux-gnu)
+          rust_target=x86_64-unknown-linux-gnu
+          ;;
+
+      # OS X and iOS
+      i*86-apple-darwin*)
+          rust_target=i686-apple-darwin
+          ;;
+      i*86-apple-ios*)
+          rust_target=i386-apple-ios
+          ;;
+      x86_64-apple-darwin*)
+          rust_target=x86_64-apple-darwin
+          ;;
+
+      # Android
+      i*86*linux-android)
+          rust_target=i686-linux-android
+          ;;
+      arm*linux-android*)
+          rust_target=arm-linux-androideabi
+          ;;
+
+      # Windows
+      i*86-pc-mingw32)
+          # XXX better detection of CXX needed here, to figure out whether
+          # we need i686-pc-windows-gnu instead, since mingw32 builds work.
+          rust_target=i686-pc-windows-msvc
+          ;;
+      x86_64-pc-mingw32)
+          # XXX and here as well
+          rust_target=x86_64-pc-windows-msvc
+          ;;
+      *)
+          AC_ERROR([don't know how to translate $target for rustc])
+    esac
+
+    # Check to see whether we need to pass --target to RUSTC.  This can
+    # happen when building Firefox on Windows: js's configure will receive
+    # a RUSTC from the toplevel configure that already has --target added to
+    # it.
+    rustc_target_arg=
+    case "$RUSTC" in
+      *--target=${rust_target}*)
+        ;;
+      *)
+        rustc_target_arg=--target=${rust_target}
+        ;;
+    esac
+
+    # Check to see whether our rustc has a reasonably functional stdlib
+    # for our chosen target.
+    echo 'pub extern fn hello() { println!("Hello world"); }' > conftest.rs
+    if AC_TRY_COMMAND(${RUSTC} --crate-type staticlib ${rustc_target_arg} -o conftest.rlib conftest.rs > /dev/null) && test -s conftest.rlib; then
+      RUSTC="${RUSTC} ${rustc_target_arg}"
+    else
+      AC_ERROR([cannot compile for ${rust_target} with ${RUSTC}])
+    fi
+    rm -f conftest.rs conftest.rlib
+  fi
+
+  # TODO: separate HOST_RUSTC and RUSTC variables
+
   AC_SUBST(MOZ_RUST)
 ])
--- a/configure.in
+++ b/configure.in
@@ -1632,17 +1632,16 @@ fi # COMPILE_ENVIRONMENT
 
 dnl ========================================================
 dnl Special rust checks
 dnl ========================================================
 
 if test -n "$MACOSX_DEPLOYMENT_TARGET" -a -n "$MOZ_RUST"; then
   AC_MSG_CHECKING([if we're targeting 32-bit])
   if test -z "$HAVE_64BIT_BUILD"; then
-    RUSTC="$RUSTC --target=i686-apple-darwin"
     AC_MSG_RESULT([using $RUSTC])
   else
     AC_MSG_RESULT([no])
   fi
   AC_MSG_CHECKING([rustc compatibility with MacOS X])
   # Stock rustc doesn't support MacOS X 10.6 or earlier.
   # https://github.com/rust-lang/rust/issues/25342
   _MACOSX_TARGET_MINOR=`echo "$MACOSX_DEPLOYMENT_TARGET" | cut -d. -f2`