All of lore.kernel.org
 help / color / mirror / Atom feed
* Merge meta-rust to oe-core
@ 2021-02-24  3:01 Randy MacLeod
  2021-02-24  3:01 ` [PATCH 1/8] Add libgit2, libssh2 from meta-oe for rust Randy MacLeod
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:01 UTC (permalink / raw)
  To: openembedded-core

Clean-up the merge of meta-rust to oe-core by squashing most of the 
meta-rust history so we are left with:

  35da4b252f rust: add a language demo image to test reproducibility
  088374371b cargo/rust/rustfmt: exclude from world
  7df10d2a22 meta-rust: merge commits
  4187796cd6 rust: mv README.md to recipes-devtools/rust/README-rust.md
  03b9c60ef4 meta-rust: move code to oe-core from meta-rust layer
  2c62874204 libgit2: pull in updates from meta-oe
  24cb3db88c libssh2: pull in additional commits from meta-oe
  e9a0a3bad2 Add libgit2, libssh2 from meta-oe for rust

The full diffstat is below. (1)

I didn't really notice the scripts shown below since they are mostly harmless.
I'll review them and remove them in v2 if they don't make sense for oe-core.

----------
BUILDALL-QEMU LOG FOR rust-hello-world
START TIME: 2021-02-23_16:39:26
HOSTNAME: ala-lpggp3
HOST OS: Ubuntu 18.04.3 LTS
HOST KERNEL: 5.4.0-62-generic
===============
BUILD RESULTS:
[glibc]
PASS: qemuarmv5
PASS: qemumips
PASS: qemux86-64
PASS: qemuarm64
PASS: qemumips64
PASS: qemuarm
PASS: qemuppc
PASS: qemuriscv64
PASS: qemux86
[musl]
PASS: qemuarmv5
PASS: qemumips
PASS: qemux86-64
PASS: qemuarm64
PASS: qemumips64
PASS: qemuarm
FAIL: qemuppc
FAIL: qemuriscv64
PASS: qemux86
===============
PASSED: 16
FAILED: 2
----------

Khem is aware of the musl/riscv64 issue and hopes to have a fix for
the next release of rustc. I haven't looked into the musl/ppc problem yet.
World build is clean.

The SDK changes aren't included since they haven't been merged to meta-rust.
The SDK works for older releases but there is a problem with libcrypto and glibc-2.33:
   ldd sysroots/x86_64-oesdk-linux/usr/bin/../lib/libcrypto.so.1.1
sysroots/x86_64-oesdk-linux/usr/bin/../lib/libcrypto.so.1.1: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by sysroots/x86_64-oesdk-linux/usr/bin/../lib/libcrypto.so.1.1)

I have a reproducible build test somewhere but it's not tested recently
so I'll send that later.

I'll create a rust version of meta/lib/oeqa/selftest/cases/gotoolchain.py
but for the local rust-hello-world recipe so it should be simpler.

../Randy


1)

 meta/classes/cargo.bbclass                                              |   77 +
 meta/classes/cargo_common.bbclass                                       |  121 ++
 meta/classes/crate-fetch.bbclass                                        |   13 
 meta/classes/rust-bin.bbclass                                           |  149 ++
 meta/classes/rust-common.bbclass                                        |  167 +++
 meta/classes/rust.bbclass                                               |   45 
 meta/conf/distro/include/rust_security_flags.inc                        |    7 
 meta/conf/distro/include/rust_versions.inc                              |   13 
 meta/conf/layer.conf                                                    |    2 
 meta/lib/crate.py                                                       |  149 ++
 meta/recipes-devtools/cargo/cargo-1.47.0/0001-Disable-http2.patch       |   31 
 meta/recipes-devtools/cargo/cargo-1.49.0/0001-Disable-http2.patch       |   31 
 meta/recipes-devtools/cargo/cargo.inc                                   |   52 
 meta/recipes-devtools/cargo/cargo_1.47.0.bb                             |    3 
 meta/recipes-devtools/cargo/cargo_1.49.0.bb                             |    3 
 meta/recipes-devtools/images/core-image-languages.bb                    |   12 
 meta/recipes-devtools/rust/README-rust.md                               |   69 +
 meta/recipes-devtools/rust/libstd-rs.inc                                |   40 
 meta/recipes-devtools/rust/libstd-rs_1.47.0.bb                          |    5 
 meta/recipes-devtools/rust/libstd-rs_1.49.0.bb                          |    5 
 meta/recipes-devtools/rust/rust-cross.inc                               |   71 +
 meta/recipes-devtools/rust/rust-cross_1.47.0.bb                         |    2 
 meta/recipes-devtools/rust/rust-cross_1.49.0.bb                         |    2 
 meta/recipes-devtools/rust/rust-llvm.inc                                |   64 +
 s-devtools/rust/rust-llvm/0002-llvm-allow-env-override-of-exe-path.patch|   32 
 meta/recipes-devtools/rust/rust-llvm_1.47.0.bb                          |    2 
 meta/recipes-devtools/rust/rust-llvm_1.49.0.bb                          |    2 
 meta/recipes-devtools/rust/rust-snapshot-1.47.0.inc                     |   13 
 meta/recipes-devtools/rust/rust-snapshot-1.49.0.inc                     |   13 
 meta/recipes-devtools/rust/rust-snapshot.inc                            |    9 
 meta/recipes-devtools/rust/rust-source-1.47.0.inc                       |    3 
 meta/recipes-devtools/rust/rust-source-1.49.0.inc                       |    3 
 meta/recipes-devtools/rust/rust-source.inc                              |    3 
 meta/recipes-devtools/rust/rust-target.inc                              |   10 
 meta/recipes-devtools/rust/rust.inc                                     |  524 ++++++++++
 ust/rust/0001-rustc_target-Fix-dash-vs-underscore-mismatches-in-op.patch|   75 +
 meta/recipes-devtools/rust/rust_1.47.0.bb                               |    9 
 meta/recipes-devtools/rust/rust_1.49.0.bb                               |   15 
 /recipes-example/rust-hello-world/rust-hello-world/0001-enable-LTO.patch|   23 
 meta/recipes-example/rust-hello-world/rust-hello-world_git.bb           |   17 
 meta/recipes-example/rustfmt/rustfmt_1.4.2.bb                           |  171 +++
 meta/recipes-support/libgit2/libgit2_1.1.0.bb                           |   22 
 h2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch|   46 
 bssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch|   30 
 meta/recipes-support/libssh2/files/CVE-2019-17498.patch                 |  131 ++
 meta/recipes-support/libssh2/files/run-ptest                            |    8 
 meta/recipes-support/libssh2/libssh2_1.9.0.bb                           |   53 +
 scripts/build.sh                                                        |   19 
 scripts/cleanup-env.sh                                                  |   14 
 scripts/containerize.sh                                                 |   54 +
 scripts/fetch.sh                                                        |  103 +
 scripts/publish-build-cache.sh                                          |   13 
 scripts/setup-env.sh                                                    |   12 
 53 files changed, 2562 insertions(+)



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/8] Add libgit2, libssh2 from meta-oe for rust
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
@ 2021-02-24  3:01 ` Randy MacLeod
  2021-02-24  3:01 ` [PATCH 2/8] libssh2: pull in additional commits from meta-oe Randy MacLeod
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:01 UTC (permalink / raw)
  To: openembedded-core

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
---
 .../recipes-support/libgit2/libgit2_0.27.8.bb | 25 +++++++++++++++++
 meta/recipes-support/libssh2/libssh2_1.8.2.bb | 27 +++++++++++++++++++
 2 files changed, 52 insertions(+)
 create mode 100644 meta/recipes-support/libgit2/libgit2_0.27.8.bb
 create mode 100644 meta/recipes-support/libssh2/libssh2_1.8.2.bb

diff --git a/meta/recipes-support/libgit2/libgit2_0.27.8.bb b/meta/recipes-support/libgit2/libgit2_0.27.8.bb
new file mode 100644
index 0000000000..a43408908c
--- /dev/null
+++ b/meta/recipes-support/libgit2/libgit2_0.27.8.bb
@@ -0,0 +1,25 @@
+SUMMARY = "the Git linkable library"
+HOMEPAGE = "http://libgit2.github.com/"
+LICENSE = "GPL-2.0-with-GCC-exception & MIT"
+LIC_FILES_CHKSUM = "file://COPYING;md5=3f2cd5d3cccd71d62066ba619614592b"
+
+DEPENDS = "curl openssl zlib libssh2 libgcrypt"
+
+SRC_URI = "git://github.com/libgit2/libgit2.git;branch=maint/v0.27"
+#v0.27.8
+SRCREV = "2882803ca2b2cdedd069746422155a23fdd002b2"
+
+S = "${WORKDIR}/git"
+
+inherit cmake
+
+EXTRA_OECMAKE = "\
+    -DTHREADSAFE=ON \
+    -DBUILD_CLAR=OFF \
+    -DSHA1_TYPE="builtin" \
+    -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+    -DBUILD_EXAMPLES=OFF \
+    -DLIB_INSTALL_DIR=${libdir} \
+"
+
+BBCLASSEXTEND = "native"
diff --git a/meta/recipes-support/libssh2/libssh2_1.8.2.bb b/meta/recipes-support/libssh2/libssh2_1.8.2.bb
new file mode 100644
index 0000000000..fe853cde4f
--- /dev/null
+++ b/meta/recipes-support/libssh2/libssh2_1.8.2.bb
@@ -0,0 +1,27 @@
+SUMMARY = "A client-side C library implementing the SSH2 protocol"
+HOMEPAGE = "http://www.libssh2.org/"
+SECTION = "libs"
+
+DEPENDS = "zlib"
+
+LICENSE = "BSD"
+LIC_FILES_CHKSUM = "file://COPYING;md5=c5cf34fc0acb44b082ef50ef5e4354ca"
+
+SRC_URI = "http://www.libssh2.org/download/${BP}.tar.gz"
+
+SRC_URI[md5sum] = "616efd99af3d9ef731a26bed6cee9593"
+SRC_URI[sha256sum] = "088307d9f6b6c4b8c13f34602e8ff65d21c2dc4d55284dfe15d502c4ee190d67"
+
+inherit autotools pkgconfig
+
+EXTRA_OECONF += "\
+                 --with-libz \
+                 --with-libz-prefix=${STAGING_LIBDIR} \
+                "
+
+# only one of openssl and gcrypt could be set
+PACKAGECONFIG ??= "openssl"
+PACKAGECONFIG[openssl] = "--with-openssl --with-libssl-prefix=${STAGING_LIBDIR},--without-openssl,openssl"
+PACKAGECONFIG[gcrypt] = "--with-libgcrypt --with-libgcrypt-prefix=${STAGING_EXECPREFIXDIR},--without-libgcrypt,libgcrypt"
+
+BBCLASSEXTEND = "native"
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/8] libssh2: pull in additional commits from meta-oe
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
  2021-02-24  3:01 ` [PATCH 1/8] Add libgit2, libssh2 from meta-oe for rust Randy MacLeod
@ 2021-02-24  3:01 ` Randy MacLeod
  2021-02-24  3:01 ` [PATCH 3/8] libgit2: pull in updates " Randy MacLeod
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:01 UTC (permalink / raw)
  To: openembedded-core

b24ef04ae libssh2: Fix build with autoconf 2.70+
d7aa71734 libssh2: enhance ptest
b3e9b51c9 libssh2: fix ptest
f5df715e2 libssh2: enable ptest
c1d1697c5 libssh2: add nativesdk support
3a6cbf246 libssh2: Security Advisory - libssh2 - CVE-2019-17498
40ea4c939 libssh2: upgrade 1.8.2 -> 1.9.0
5a7e65cbf libssh2: Clarify BSD license variant

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
---
 ...nviroment-to-decide-if-a-test-is-bui.patch |  46 ++++++
 ...ditionally-undefine-backend-m4-macro.patch |  30 ++++
 .../libssh2/files/CVE-2019-17498.patch        | 131 ++++++++++++++++++
 meta/recipes-support/libssh2/files/run-ptest  |   8 ++
 meta/recipes-support/libssh2/libssh2_1.8.2.bb |  27 ----
 meta/recipes-support/libssh2/libssh2_1.9.0.bb |  53 +++++++
 6 files changed, 268 insertions(+), 27 deletions(-)
 create mode 100644 meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch
 create mode 100644 meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch
 create mode 100644 meta/recipes-support/libssh2/files/CVE-2019-17498.patch
 create mode 100644 meta/recipes-support/libssh2/files/run-ptest
 delete mode 100644 meta/recipes-support/libssh2/libssh2_1.8.2.bb
 create mode 100644 meta/recipes-support/libssh2/libssh2_1.9.0.bb

diff --git a/meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch b/meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch
new file mode 100644
index 0000000000..5ff9bf8462
--- /dev/null
+++ b/meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch
@@ -0,0 +1,46 @@
+From f9e3e2ee7b18ba5bb8efe083171f3e701eb0a663 Mon Sep 17 00:00:00 2001
+From: Your Name <you@example.com>
+Date: Mon, 28 Dec 2020 02:08:03 +0000
+Subject: [PATCH] Don't let host enviroment to decide if a test is build
+
+test ssh2.sh need sshd, for cross compile, we need it on target, so
+don't use SSHD on host to decide weither to build a test
+
+Upstream-Status: Inappropriate[oe specific]
+
+Signed-off-by: Changqing Li <changqing.li@windriver.com>
+---
+ tests/Makefile.am | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index dc0922f..6cbc35d 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -1,16 +1,12 @@
+ AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
+ LDADD = ../src/libssh2.la
+ 
+-if SSHD
+ noinst_PROGRAMS = ssh2
+ ssh2_SOURCES = ssh2.c
+-endif
+ 
+ ctests = simple$(EXEEXT)
+ TESTS = $(ctests) mansyntax.sh
+-if SSHD
+ TESTS += ssh2.sh
+-endif
+ check_PROGRAMS = $(ctests)
+ 
+ TESTS_ENVIRONMENT = SSHD=$(SSHD) EXEEXT=$(EXEEXT)
+@@ -38,4 +34,4 @@ if OPENSSL
+ # EXTRA_DIST += test_public_key_auth_succeeds_with_correct_encrypted_ed25519_key.c
+ # EXTRA_DIST += test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c
+ EXTRA_DIST += test_public_key_auth_succeeds_with_correct_rsa_openssh_key.c
+-endif
+\ No newline at end of file
++endif
+-- 
+2.20.1
+
diff --git a/meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch b/meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch
new file mode 100644
index 0000000000..1128c7ea0c
--- /dev/null
+++ b/meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch
@@ -0,0 +1,30 @@
+From efe7101786193eaddb749c0583af6b54aec6f289 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Tue, 2 Feb 2021 18:45:16 -0800
+Subject: [PATCH] configure: Conditionally undefine backend m4 macro
+
+Unlike the M4 builtin, this macro fails if macro is not defined
+therefore recover the behavior of the builtin.
+
+Upstream-Status: Pending
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index fe5054a..758f8c2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -127,7 +127,7 @@ fi
+ m4_set_foreach([crypto_backends], [backend],
+   [AM_CONDITIONAL(m4_toupper(backend), test "$found_crypto" = "backend")]
+ )
+-m4_undefine([backend])
++m4_ifdef([backend], [m4_undefine([backend])])
+ 
+ 
+ # libz
+-- 
+2.30.0
+
diff --git a/meta/recipes-support/libssh2/files/CVE-2019-17498.patch b/meta/recipes-support/libssh2/files/CVE-2019-17498.patch
new file mode 100644
index 0000000000..001080072b
--- /dev/null
+++ b/meta/recipes-support/libssh2/files/CVE-2019-17498.patch
@@ -0,0 +1,131 @@
+From dedcbd106f8e52d5586b0205bc7677e4c9868f9c Mon Sep 17 00:00:00 2001
+From: Will Cosgrove <will@panic.com>
+Date: Fri, 30 Aug 2019 09:57:38 -0700
+Subject: [PATCH] packet.c: improve message parsing (#402)
+
+* packet.c: improve parsing of packets
+
+file: packet.c
+
+notes:
+Use _libssh2_get_string API in SSH_MSG_DEBUG/SSH_MSG_DISCONNECT. Additional uint32 bounds check in SSH_MSG_GLOBAL_REQUEST.
+
+Upstream-Status: Backport
+CVE: CVE-2019-17498
+Signed-off-by: Li Zhou <li.zhou@windriver.com>
+---
+ src/packet.c | 68 ++++++++++++++++++++++------------------------------
+ 1 file changed, 29 insertions(+), 39 deletions(-)
+
+diff --git a/src/packet.c b/src/packet.c
+index 38ab629..2e01bfc 100644
+--- a/src/packet.c
++++ b/src/packet.c
+@@ -419,8 +419,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
+                     size_t datalen, int macstate)
+ {
+     int rc = 0;
+-    char *message = NULL;
+-    char *language = NULL;
++    unsigned char *message = NULL;
++    unsigned char *language = NULL;
+     size_t message_len = 0;
+     size_t language_len = 0;
+     LIBSSH2_CHANNEL *channelp = NULL;
+@@ -472,33 +472,23 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
+ 
+         case SSH_MSG_DISCONNECT:
+             if(datalen >= 5) {
+-                size_t reason = _libssh2_ntohu32(data + 1);
++                uint32_t reason = 0;
++                struct string_buf buf;
++                buf.data = (unsigned char *)data;
++                buf.dataptr = buf.data;
++                buf.len = datalen;
++                buf.dataptr++; /* advance past type */
+ 
+-                if(datalen >= 9) {
+-                    message_len = _libssh2_ntohu32(data + 5);
++                _libssh2_get_u32(&buf, &reason);
++                _libssh2_get_string(&buf, &message, &message_len);
++                _libssh2_get_string(&buf, &language, &language_len);
+ 
+-                    if(message_len < datalen-13) {
+-                        /* 9 = packet_type(1) + reason(4) + message_len(4) */
+-                        message = (char *) data + 9;
+-
+-                        language_len =
+-                            _libssh2_ntohu32(data + 9 + message_len);
+-                        language = (char *) data + 9 + message_len + 4;
+-
+-                        if(language_len > (datalen-13-message_len)) {
+-                            /* bad input, clear info */
+-                            language = message = NULL;
+-                            language_len = message_len = 0;
+-                        }
+-                    }
+-                    else
+-                        /* bad size, clear it */
+-                        message_len = 0;
+-                }
+                 if(session->ssh_msg_disconnect) {
+-                    LIBSSH2_DISCONNECT(session, reason, message,
+-                                       message_len, language, language_len);
++                    LIBSSH2_DISCONNECT(session, reason, (const char *)message,
++                                       message_len, (const char *)language,
++                                       language_len);
+                 }
++
+                 _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
+                                "Disconnect(%d): %s(%s)", reason,
+                                message, language);
+@@ -539,24 +529,24 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
+                 int always_display = data[1];
+ 
+                 if(datalen >= 6) {
+-                    message_len = _libssh2_ntohu32(data + 2);
+-
+-                    if(message_len <= (datalen - 10)) {
+-                        /* 6 = packet_type(1) + display(1) + message_len(4) */
+-                        message = (char *) data + 6;
+-                        language_len = _libssh2_ntohu32(data + 6 +
+-                                                        message_len);
+-
+-                        if(language_len <= (datalen - 10 - message_len))
+-                            language = (char *) data + 10 + message_len;
+-                    }
++                    struct string_buf buf;
++                    buf.data = (unsigned char *)data;
++                    buf.dataptr = buf.data;
++                    buf.len = datalen;
++                    buf.dataptr += 2; /* advance past type & always display */
++
++                    _libssh2_get_string(&buf, &message, &message_len);
++                    _libssh2_get_string(&buf, &language, &language_len);
+                 }
+ 
+                 if(session->ssh_msg_debug) {
+-                    LIBSSH2_DEBUG(session, always_display, message,
+-                                  message_len, language, language_len);
++                    LIBSSH2_DEBUG(session, always_display,
++                                  (const char *)message,
++                                  message_len, (const char *)language,
++                                  language_len);
+                 }
+             }
++
+             /*
+              * _libssh2_debug will actually truncate this for us so
+              * that it's not an inordinate about of data
+@@ -579,7 +569,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
+                 uint32_t len = 0;
+                 unsigned char want_reply = 0;
+                 len = _libssh2_ntohu32(data + 1);
+-                if(datalen >= (6 + len)) {
++                if((len <= (UINT_MAX - 6)) && (datalen >= (6 + len))) {
+                     want_reply = data[5 + len];
+                     _libssh2_debug(session,
+                                    LIBSSH2_TRACE_CONN,
+-- 
+2.17.1
+
diff --git a/meta/recipes-support/libssh2/files/run-ptest b/meta/recipes-support/libssh2/files/run-ptest
new file mode 100644
index 0000000000..5fd7ec65f6
--- /dev/null
+++ b/meta/recipes-support/libssh2/files/run-ptest
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+ptestdir=$(dirname "$(readlink -f "$0")")
+cd tests
+for test in simple ssh2.sh mansyntax.sh
+do
+	./../test-driver --test-name $test --log-file ../$test.log --trs-file ../$test.trs --color-tests no --enable-hard-errors yes --expect-failure no -- ./$test
+done
diff --git a/meta/recipes-support/libssh2/libssh2_1.8.2.bb b/meta/recipes-support/libssh2/libssh2_1.8.2.bb
deleted file mode 100644
index fe853cde4f..0000000000
--- a/meta/recipes-support/libssh2/libssh2_1.8.2.bb
+++ /dev/null
@@ -1,27 +0,0 @@
-SUMMARY = "A client-side C library implementing the SSH2 protocol"
-HOMEPAGE = "http://www.libssh2.org/"
-SECTION = "libs"
-
-DEPENDS = "zlib"
-
-LICENSE = "BSD"
-LIC_FILES_CHKSUM = "file://COPYING;md5=c5cf34fc0acb44b082ef50ef5e4354ca"
-
-SRC_URI = "http://www.libssh2.org/download/${BP}.tar.gz"
-
-SRC_URI[md5sum] = "616efd99af3d9ef731a26bed6cee9593"
-SRC_URI[sha256sum] = "088307d9f6b6c4b8c13f34602e8ff65d21c2dc4d55284dfe15d502c4ee190d67"
-
-inherit autotools pkgconfig
-
-EXTRA_OECONF += "\
-                 --with-libz \
-                 --with-libz-prefix=${STAGING_LIBDIR} \
-                "
-
-# only one of openssl and gcrypt could be set
-PACKAGECONFIG ??= "openssl"
-PACKAGECONFIG[openssl] = "--with-openssl --with-libssl-prefix=${STAGING_LIBDIR},--without-openssl,openssl"
-PACKAGECONFIG[gcrypt] = "--with-libgcrypt --with-libgcrypt-prefix=${STAGING_EXECPREFIXDIR},--without-libgcrypt,libgcrypt"
-
-BBCLASSEXTEND = "native"
diff --git a/meta/recipes-support/libssh2/libssh2_1.9.0.bb b/meta/recipes-support/libssh2/libssh2_1.9.0.bb
new file mode 100644
index 0000000000..0b8ccbd217
--- /dev/null
+++ b/meta/recipes-support/libssh2/libssh2_1.9.0.bb
@@ -0,0 +1,53 @@
+SUMMARY = "A client-side C library implementing the SSH2 protocol"
+HOMEPAGE = "http://www.libssh2.org/"
+SECTION = "libs"
+
+DEPENDS = "zlib"
+
+LICENSE = "BSD-3-Clause"
+LIC_FILES_CHKSUM = "file://COPYING;md5=c5cf34fc0acb44b082ef50ef5e4354ca"
+
+SRC_URI = "http://www.libssh2.org/download/${BP}.tar.gz \
+           file://CVE-2019-17498.patch \
+           file://0001-configure-Conditionally-undefine-backend-m4-macro.patch \
+           file://run-ptest \
+"
+
+SRC_URI_append_ptest = " file://0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch"
+
+SRC_URI[md5sum] = "1beefafe8963982adc84b408b2959927"
+SRC_URI[sha256sum] = "d5fb8bd563305fd1074dda90bd053fb2d29fc4bce048d182f96eaa466dfadafd"
+
+inherit autotools pkgconfig ptest
+
+EXTRA_OECONF += "\
+                 --with-libz \
+                 --with-libz-prefix=${STAGING_LIBDIR} \
+                "
+
+# only one of openssl and gcrypt could be set
+PACKAGECONFIG ??= "openssl"
+PACKAGECONFIG[openssl] = "--with-crypto=openssl --with-libssl-prefix=${STAGING_LIBDIR}, , openssl"
+PACKAGECONFIG[gcrypt] = "--with-crypto=libgcrypt --with-libgcrypt-prefix=${STAGING_EXECPREFIXDIR}, , libgcrypt"
+
+BBCLASSEXTEND = "native nativesdk"
+
+# required for ptest on documentation
+RDEPENDS_${PN}-ptest = "man-db openssh"
+RDEPENDS_${PN}-ptest_append_libc-glibc = " locale-base-en-us"
+
+do_compile_ptest() {
+	sed -i "/\$(MAKE) \$(AM_MAKEFLAGS) check-TESTS/d" tests/Makefile
+	oe_runmake check
+}
+
+do_install_ptest() {
+	install -d ${D}${PTEST_PATH}/tests
+	install -m 0755 ${S}/test-driver ${D}${PTEST_PATH}/
+	cp -rf ${B}/tests/.libs/* ${D}${PTEST_PATH}/tests/
+	cp -rf ${S}/tests/mansyntax.sh  ${D}${PTEST_PATH}/tests/
+	cp -rf ${S}/tests/ssh2.sh  ${D}${PTEST_PATH}/tests/
+	cp -rf ${S}/tests/etc ${D}${PTEST_PATH}/tests/
+	mkdir -p ${D}${PTEST_PATH}/docs
+	cp -r ${S}/docs/* ${D}${PTEST_PATH}/docs/
+}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/8] libgit2: pull in updates from meta-oe
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
  2021-02-24  3:01 ` [PATCH 1/8] Add libgit2, libssh2 from meta-oe for rust Randy MacLeod
  2021-02-24  3:01 ` [PATCH 2/8] libssh2: pull in additional commits from meta-oe Randy MacLeod
@ 2021-02-24  3:01 ` Randy MacLeod
  2021-02-24  3:01 ` [PATCH 4/8] meta-rust: move code to oe-core from meta-rust layer Randy MacLeod
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:01 UTC (permalink / raw)
  To: openembedded-core

d62613046 libgit2: update to 1.1.0
ce47a064d libgit2: upgrade 1.0.0 -> 1.0.1
7d137c5b2 libgit2: Enable pcre2 regexp backend
14894a4c4 libgit2: Update to v1.0.0
7b39ea059 libgit2: Upgrade to 0.28.4
da358cf1f libgit2: Don't pass parameters with their default values to cmake
bcd89f7cd libgit2: Upgrade 0.27.9 -> 0.28.3
87c9da253 libgit2: Upgrade 0.27.8 -> 0.27.9

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
---
 .../recipes-support/libgit2/libgit2_0.27.8.bb | 25 -------------------
 meta/recipes-support/libgit2/libgit2_1.1.0.bb | 22 ++++++++++++++++
 2 files changed, 22 insertions(+), 25 deletions(-)
 delete mode 100644 meta/recipes-support/libgit2/libgit2_0.27.8.bb
 create mode 100644 meta/recipes-support/libgit2/libgit2_1.1.0.bb

diff --git a/meta/recipes-support/libgit2/libgit2_0.27.8.bb b/meta/recipes-support/libgit2/libgit2_0.27.8.bb
deleted file mode 100644
index a43408908c..0000000000
--- a/meta/recipes-support/libgit2/libgit2_0.27.8.bb
+++ /dev/null
@@ -1,25 +0,0 @@
-SUMMARY = "the Git linkable library"
-HOMEPAGE = "http://libgit2.github.com/"
-LICENSE = "GPL-2.0-with-GCC-exception & MIT"
-LIC_FILES_CHKSUM = "file://COPYING;md5=3f2cd5d3cccd71d62066ba619614592b"
-
-DEPENDS = "curl openssl zlib libssh2 libgcrypt"
-
-SRC_URI = "git://github.com/libgit2/libgit2.git;branch=maint/v0.27"
-#v0.27.8
-SRCREV = "2882803ca2b2cdedd069746422155a23fdd002b2"
-
-S = "${WORKDIR}/git"
-
-inherit cmake
-
-EXTRA_OECMAKE = "\
-    -DTHREADSAFE=ON \
-    -DBUILD_CLAR=OFF \
-    -DSHA1_TYPE="builtin" \
-    -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-    -DBUILD_EXAMPLES=OFF \
-    -DLIB_INSTALL_DIR=${libdir} \
-"
-
-BBCLASSEXTEND = "native"
diff --git a/meta/recipes-support/libgit2/libgit2_1.1.0.bb b/meta/recipes-support/libgit2/libgit2_1.1.0.bb
new file mode 100644
index 0000000000..2bbf59ea74
--- /dev/null
+++ b/meta/recipes-support/libgit2/libgit2_1.1.0.bb
@@ -0,0 +1,22 @@
+SUMMARY = "the Git linkable library"
+HOMEPAGE = "http://libgit2.github.com/"
+LICENSE = "GPL-2.0-with-GCC-exception & MIT"
+LIC_FILES_CHKSUM = "file://COPYING;md5=5b002a195fb7ea2d8d583f07eaff3a8e"
+
+DEPENDS = "curl openssl zlib libssh2 libgcrypt libpcre2"
+
+SRC_URI = "git://github.com/libgit2/libgit2.git;branch=maint/v1.1"
+SRCREV = "7f4fa178629d559c037a1f72f79f79af9c1ef8ce"
+
+S = "${WORKDIR}/git"
+
+inherit cmake
+
+EXTRA_OECMAKE = "\
+    -DBUILD_CLAR=OFF \
+    -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+    -DLIB_INSTALL_DIR=${libdir} \
+    -DREGEX_BACKEND='pcre2' \
+"
+
+BBCLASSEXTEND = "native"
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/8] meta-rust: move code to oe-core from meta-rust layer
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
                   ` (2 preceding siblings ...)
  2021-02-24  3:01 ` [PATCH 3/8] libgit2: pull in updates " Randy MacLeod
@ 2021-02-24  3:01 ` Randy MacLeod
  2021-02-24  3:01 ` [PATCH 5/8] rust: mv README.md to recipes-devtools/rust/README-rust.md Randy MacLeod
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:01 UTC (permalink / raw)
  To: openembedded-core

Rust is becoming more widely used so move the
meta-rust layer. Taken from meta-rust at commit:
   11aed43 cargo-1.37.0: fix patch fuzz

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
---
 meta/classes/cargo.bbclass                    |  70 +++
 meta/classes/cargo_common.bbclass             |  98 ++++
 meta/classes/crate-fetch.bbclass              |  13 +
 meta/classes/rust-bin.bbclass                 | 149 +++++
 meta/classes/rust-common.bbclass              | 144 +++++
 meta/classes/rust.bbclass                     |  45 ++
 .../distro/include/rust_security_flags.inc    |   7 +
 meta/conf/layer.conf                          |   2 +
 meta/lib/crate.py                             | 149 +++++
 .../cargo-1.34.2/0001-Disable-http2.patch     |  29 +
 .../cargo-1.36.0/0001-Disable-http2.patch     |  31 ++
 .../cargo-1.37.0/0001-Disable-http2.patch     |  29 +
 meta/recipes-devtools/cargo/cargo.inc         |  43 ++
 meta/recipes-devtools/cargo/cargo_1.34.2.bb   |   8 +
 meta/recipes-devtools/cargo/cargo_1.36.0.bb   |   8 +
 meta/recipes-devtools/cargo/cargo_1.37.0.bb   |   8 +
 meta/recipes-devtools/rust/libstd-rs.inc      |  31 ++
 .../recipes-devtools/rust/libstd-rs_1.34.2.bb |   8 +
 .../recipes-devtools/rust/libstd-rs_1.36.0.bb |   8 +
 .../recipes-devtools/rust/libstd-rs_1.37.0.bb |   8 +
 meta/recipes-devtools/rust/rust-cross.inc     |  52 ++
 .../rust/rust-cross_1.34.2.bb                 |   3 +
 .../rust/rust-cross_1.36.0.bb                 |   3 +
 .../rust/rust-cross_1.37.0.bb                 |   3 +
 meta/recipes-devtools/rust/rust-llvm.inc      |  62 +++
 ...-llvm-allow-env-override-of-exe-path.patch |  32 ++
 .../recipes-devtools/rust/rust-llvm_1.34.2.bb |  16 +
 .../recipes-devtools/rust/rust-llvm_1.36.0.bb |  16 +
 .../recipes-devtools/rust/rust-llvm_1.37.0.bb |  16 +
 .../rust/rust-snapshot-1.34.2.inc             |  24 +
 .../rust/rust-snapshot-1.36.0.inc             |  24 +
 .../rust/rust-snapshot-1.37.0.inc             |  24 +
 .../rust/rust-source-1.34.2.inc               |  11 +
 .../rust/rust-source-1.36.0.inc               |  11 +
 .../rust/rust-source-1.37.0.inc               |  11 +
 meta/recipes-devtools/rust/rust.inc           | 509 ++++++++++++++++++
 meta/recipes-devtools/rust/rust_1.34.2.bb     |  12 +
 meta/recipes-devtools/rust/rust_1.36.0.bb     |  12 +
 meta/recipes-devtools/rust/rust_1.37.0.bb     |  12 +
 .../rust-hello-world/rust-hello-world_git.bb  |  13 +
 meta/recipes-example/rustfmt/rustfmt_0.8.0.bb |  67 +++
 scripts/build.sh                              |  19 +
 scripts/cleanup-env.sh                        |  14 +
 scripts/containerize.sh                       |  54 ++
 scripts/fetch.sh                              | 103 ++++
 scripts/publish-build-cache.sh                |  13 +
 scripts/setup-env.sh                          |  12 +
 47 files changed, 2036 insertions(+)
 create mode 100644 meta/classes/cargo.bbclass
 create mode 100644 meta/classes/cargo_common.bbclass
 create mode 100644 meta/classes/crate-fetch.bbclass
 create mode 100644 meta/classes/rust-bin.bbclass
 create mode 100644 meta/classes/rust-common.bbclass
 create mode 100644 meta/classes/rust.bbclass
 create mode 100644 meta/conf/distro/include/rust_security_flags.inc
 create mode 100644 meta/lib/crate.py
 create mode 100644 meta/recipes-devtools/cargo/cargo-1.34.2/0001-Disable-http2.patch
 create mode 100644 meta/recipes-devtools/cargo/cargo-1.36.0/0001-Disable-http2.patch
 create mode 100644 meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch
 create mode 100644 meta/recipes-devtools/cargo/cargo.inc
 create mode 100644 meta/recipes-devtools/cargo/cargo_1.34.2.bb
 create mode 100644 meta/recipes-devtools/cargo/cargo_1.36.0.bb
 create mode 100644 meta/recipes-devtools/cargo/cargo_1.37.0.bb
 create mode 100644 meta/recipes-devtools/rust/libstd-rs.inc
 create mode 100644 meta/recipes-devtools/rust/libstd-rs_1.34.2.bb
 create mode 100644 meta/recipes-devtools/rust/libstd-rs_1.36.0.bb
 create mode 100644 meta/recipes-devtools/rust/libstd-rs_1.37.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust-cross.inc
 create mode 100644 meta/recipes-devtools/rust/rust-cross_1.34.2.bb
 create mode 100644 meta/recipes-devtools/rust/rust-cross_1.36.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust-cross_1.37.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust-llvm.inc
 create mode 100644 meta/recipes-devtools/rust/rust-llvm/0002-llvm-allow-env-override-of-exe-path.patch
 create mode 100644 meta/recipes-devtools/rust/rust-llvm_1.34.2.bb
 create mode 100644 meta/recipes-devtools/rust/rust-llvm_1.36.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust-llvm_1.37.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc
 create mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-source-1.34.2.inc
 create mode 100644 meta/recipes-devtools/rust/rust-source-1.36.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-source-1.37.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust.inc
 create mode 100644 meta/recipes-devtools/rust/rust_1.34.2.bb
 create mode 100644 meta/recipes-devtools/rust/rust_1.36.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust_1.37.0.bb
 create mode 100644 meta/recipes-example/rust-hello-world/rust-hello-world_git.bb
 create mode 100644 meta/recipes-example/rustfmt/rustfmt_0.8.0.bb
 create mode 100755 scripts/build.sh
 create mode 100755 scripts/cleanup-env.sh
 create mode 100755 scripts/containerize.sh
 create mode 100755 scripts/fetch.sh
 create mode 100755 scripts/publish-build-cache.sh
 create mode 100755 scripts/setup-env.sh

diff --git a/meta/classes/cargo.bbclass b/meta/classes/cargo.bbclass
new file mode 100644
index 0000000000..c321e6bf70
--- /dev/null
+++ b/meta/classes/cargo.bbclass
@@ -0,0 +1,70 @@
+##
+## Purpose:
+## This class is used by any recipes that are built using
+## Cargo.
+
+inherit cargo_common
+
+# the binary we will use
+CARGO = "cargo"
+
+# We need cargo to compile for the target
+BASEDEPENDS_append = " cargo-native"
+
+# Ensure we get the right rust variant
+DEPENDS_append_class-target = " virtual/${TARGET_PREFIX}rust ${RUSTLIB_DEP}"
+DEPENDS_append_class-native = " rust-native"
+
+# Cargo only supports in-tree builds at the moment
+B = "${S}"
+
+# In case something fails in the build process, give a bit more feedback on
+# where the issue occured
+export RUST_BACKTRACE = "1"
+
+RUSTFLAGS ??= ""
+BUILD_MODE = "${@['--release', ''][d.getVar('DEBUG_BUILD') == '1']}"
+CARGO_BUILD_FLAGS = "-v --target ${HOST_SYS} ${BUILD_MODE}"
+
+# This is based on the content of CARGO_BUILD_FLAGS and generally will need to
+# change if CARGO_BUILD_FLAGS changes.
+BUILD_DIR = "${@['release', 'debug'][d.getVar('DEBUG_BUILD') == '1']}"
+CARGO_TARGET_SUBDIR="${HOST_SYS}/${BUILD_DIR}"
+oe_cargo_build () {
+	export RUSTFLAGS="${RUSTFLAGS}"
+	export RUST_TARGET_PATH="${RUST_TARGET_PATH}"
+	bbnote "cargo = $(which ${CARGO})"
+	bbnote "rustc = $(which ${RUSTC})"
+	bbnote "${CARGO} build ${CARGO_BUILD_FLAGS} $@"
+	"${CARGO}" build ${CARGO_BUILD_FLAGS} "$@"
+}
+
+cargo_do_compile () {
+	oe_cargo_fix_env
+	oe_cargo_build
+}
+
+cargo_do_install () {
+	local have_installed=false
+	for tgt in "${B}/target/${CARGO_TARGET_SUBDIR}/"*; do
+		case $tgt in
+		*.so|*.rlib)
+			install -d "${D}${rustlibdir}"
+			install -m755 "$tgt" "${D}${rustlibdir}"
+			have_installed=true
+			;;
+		*)
+			if [ -f "$tgt" ] && [ -x "$tgt" ]; then
+				install -d "${D}${bindir}"
+				install -m755 "$tgt" "${D}${bindir}"
+				have_installed=true
+			fi
+			;;
+		esac
+	done
+	if ! $have_installed; then
+		die "Did not find anything to install"
+	fi
+}
+
+EXPORT_FUNCTIONS do_compile do_install
diff --git a/meta/classes/cargo_common.bbclass b/meta/classes/cargo_common.bbclass
new file mode 100644
index 0000000000..e5f908033d
--- /dev/null
+++ b/meta/classes/cargo_common.bbclass
@@ -0,0 +1,98 @@
+##
+## Purpose:
+## This class is to support building with cargo. It
+## must be different than cargo.bbclass because Rust
+## now builds with Cargo but cannot use cargo.bbclass
+## due to dependencies and assumptions in cargo.bbclass
+## that Rust & Cargo are already installed. So this
+## is used by cargo.bbclass and Rust
+##
+
+# add crate fetch support
+inherit crate-fetch
+inherit rust-common
+
+# Where we download our registry and dependencies to
+export CARGO_HOME = "${WORKDIR}/cargo_home"
+
+# The pkg-config-rs library used by cargo build scripts disables itself when
+# cross compiling unless this is defined. We set up pkg-config appropriately
+# for cross compilation, so tell it we know better than it.
+export PKG_CONFIG_ALLOW_CROSS = "1"
+
+# Don't instruct cargo to use crates downloaded by bitbake. Some rust packages,
+# for example the rust compiler itself, come with their own vendored sources.
+# Specifying two [source.crates-io] will not work.
+CARGO_DISABLE_BITBAKE_VENDORING ?= "0"
+
+# Used by libstd-rs to point to the vendor dir included in rustc src
+CARGO_VENDORING_DIRECTORY ?= "${CARGO_HOME}/bitbake"
+
+cargo_common_do_configure () {
+	mkdir -p ${CARGO_HOME}/bitbake
+	echo "paths = [" > ${CARGO_HOME}/config
+
+	for p in ${EXTRA_OECARGO_PATHS}; do
+		printf "\"%s\"\n" "$p"
+	done | sed -e 's/$/,/' >> ${CARGO_HOME}/config
+	echo "]" >> ${CARGO_HOME}/config
+
+	# Point cargo at our local mirror of the registry
+	cat <<- EOF >> ${CARGO_HOME}/config
+	[source.bitbake]
+	directory = "${CARGO_VENDORING_DIRECTORY}"
+	EOF
+
+	if [ -z "${EXTERNALSRC}" ] && [ ${CARGO_DISABLE_BITBAKE_VENDORING} = "0" ]; then
+		cat <<- EOF >> ${CARGO_HOME}/config
+		[source.crates-io]
+		replace-with = "bitbake"
+		local-registry = "/nonexistant"
+		EOF
+	fi
+
+        # Disable multiplexing in order to keep cargo from using http2, which we
+        # can't currently enable because of dependency loops
+        cat <<- EOF >> ${CARGO_HOME}/config
+		[http]
+		multiplexing = false
+	EOF
+
+	# When a sstate-cache is used sometimes the certificates are not available
+	# at the compile time path anymore. Set it explicitly instead.
+	echo "cainfo = \"${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt\"" \
+		>> ${CARGO_HOME}/config
+
+	if [ -n "${http_proxy}" ]; then
+		echo "proxy = \"${http_proxy}\"" >> ${CARGO_HOME}/config
+	fi
+
+	echo "[target.${HOST_SYS}]" >> ${CARGO_HOME}/config
+	echo "linker = '${RUST_TARGET_CCLD}'" >> ${CARGO_HOME}/config
+	if [ "${HOST_SYS}" != "${BUILD_SYS}" ]; then
+		echo "[target.${BUILD_SYS}]" >> ${CARGO_HOME}/config
+		echo "linker = '${RUST_BUILD_CCLD}'" >> ${CARGO_HOME}/config
+	fi
+}
+
+oe_cargo_fix_env () {
+	export CC="${RUST_TARGET_CC}"
+	export CXX="${RUST_TARGET_CXX}"
+	export CFLAGS="${CFLAGS}"
+	export CXXFLAGS="${CXXFLAGS}"
+	export AR="${AR}"
+	export TARGET_CC="${RUST_TARGET_CC}"
+	export TARGET_CXX="${RUST_TARGET_CXX}"
+	export TARGET_CFLAGS="${CFLAGS}"
+	export TARGET_CXXFLAGS="${CXXFLAGS}"
+	export TARGET_AR="${AR}"
+	export HOST_CC="${RUST_BUILD_CC}"
+	export HOST_CXX="${RUST_BUILD_CXX}"
+	export HOST_CFLAGS="${BUILD_CFLAGS}"
+	export HOST_CXXFLAGS="${BUILD_CXXFLAGS}"
+	export HOST_AR="${BUILD_AR}"
+}
+
+EXTRA_OECARGO_PATHS ??= ""
+
+EXPORT_FUNCTIONS do_configure
diff --git a/meta/classes/crate-fetch.bbclass b/meta/classes/crate-fetch.bbclass
new file mode 100644
index 0000000000..c0ed434a96
--- /dev/null
+++ b/meta/classes/crate-fetch.bbclass
@@ -0,0 +1,13 @@
+#
+# crate-fetch class
+#
+# Registers 'crate' method for Bitbake fetch2.
+#
+# Adds support for following format in recipe SRC_URI:
+# crate://<packagename>/<version>
+#
+
+python () {
+        import crate
+        bb.fetch2.methods.append( crate.Crate() )
+}
diff --git a/meta/classes/rust-bin.bbclass b/meta/classes/rust-bin.bbclass
new file mode 100644
index 0000000000..a13fbafb56
--- /dev/null
+++ b/meta/classes/rust-bin.bbclass
@@ -0,0 +1,149 @@
+inherit rust
+
+RDEPENDS_${PN}_append_class-target += "${RUSTLIB_DEP}"
+
+RUSTC_ARCHFLAGS += "-C opt-level=3 -g -L ${STAGING_DIR_HOST}/${rustlibdir} -C linker=${RUST_TARGET_CCLD}"
+EXTRA_OEMAKE += 'RUSTC_ARCHFLAGS="${RUSTC_ARCHFLAGS}"'
+
+# Some libraries alias with the standard library but libstd is configured to
+# make it difficult or imposisble to use its version. Unfortunately libstd
+# must be explicitly overridden using extern.
+OVERLAP_LIBS = "\
+    libc \
+    log \
+    getopts \
+    rand \
+"
+def get_overlap_deps(d):
+    deps = d.getVar("DEPENDS").split()
+    overlap_deps = []
+    for o in d.getVar("OVERLAP_LIBS").split():
+        l = len([o for dep in deps if (o + '-rs' in dep)])
+        if l > 0:
+            overlap_deps.append(o)
+    return " ".join(overlap_deps)
+OVERLAP_DEPS = "${@get_overlap_deps(d)}"
+
+# Prevents multiple static copies of standard library modules
+# See https://github.com/rust-lang/rust/issues/19680
+RUSTC_PREFER_DYNAMIC = "-C prefer-dynamic"
+RUSTC_FLAGS += "${RUSTC_PREFER_DYNAMIC}"
+
+CRATE_NAME ?= "${@d.getVar('BPN').replace('-rs', '').replace('-', '_')}"
+BINNAME ?= "${BPN}"
+LIBNAME ?= "lib${CRATE_NAME}-rs"
+CRATE_TYPE ?= "dylib"
+BIN_SRC ?= "${S}/src/main.rs"
+LIB_SRC ?= "${S}/src/lib.rs"
+
+rustbindest ?= "${bindir}"
+rustlibdest ?= "${rustlibdir}"
+RUST_RPATH_ABS ?= "${rustlibdir}:${rustlib}"
+
+def relative_rpaths(paths, base):
+    relpaths = set()
+    for p in paths.split(':'):
+        if p == base:
+            relpaths.add('$ORIGIN')
+            continue
+        relpaths.add(os.path.join('$ORIGIN', os.path.relpath(p, base)))
+    return '-rpath=' + ':'.join(relpaths) if len(relpaths) else ''
+
+RUST_LIB_RPATH_FLAGS ?= "${@relative_rpaths(d.getVar('RUST_RPATH_ABS', True), d.getVar('rustlibdest', True))}"
+RUST_BIN_RPATH_FLAGS ?= "${@relative_rpaths(d.getVar('RUST_RPATH_ABS', True), d.getVar('rustbindest', True))}"
+
+def libfilename(d):
+    if d.getVar('CRATE_TYPE', True) == 'dylib':
+        return d.getVar('LIBNAME', True) + '.so'
+    else:
+        return d.getVar('LIBNAME', True) + '.rlib'
+
+def link_args(d, bin):
+    linkargs = []
+    if bin:
+        rpaths = d.getVar('RUST_BIN_RPATH_FLAGS', False)
+    else:
+        rpaths = d.getVar('RUST_LIB_RPATH_FLAGS', False)
+        if d.getVar('CRATE_TYPE', True) == 'dylib':
+            linkargs.append('-soname')
+            linkargs.append(libfilename(d))
+    if len(rpaths):
+        linkargs.append(rpaths)
+    if len(linkargs):
+        return ' '.join(['-Wl,' + arg for arg in linkargs])
+    else:
+        return ''
+
+get_overlap_externs () {
+    externs=
+    for dep in ${OVERLAP_DEPS}; do
+        extern=$(ls ${STAGING_DIR_HOST}/${rustlibdir}/lib$dep-rs.{so,rlib} 2>/dev/null \
+                    | awk '{print $1}');
+        if [ -n "$extern" ]; then
+            externs="$externs --extern $dep=$extern"
+        else
+            echo "$dep in depends but no such library found in ${rustlibdir}!" >&2
+            exit 1
+        fi
+    done
+    echo "$externs"
+}
+
+do_configure () {
+}
+
+oe_runrustc () {
+	export RUST_TARGET_PATH="${RUST_TARGET_PATH}"
+	bbnote ${RUSTC} ${RUSTC_ARCHFLAGS} ${RUSTC_FLAGS} "$@"
+	"${RUSTC}" ${RUSTC_ARCHFLAGS} ${RUSTC_FLAGS} "$@"
+}
+
+oe_compile_rust_lib () {
+    rm -rf ${LIBNAME}.{rlib,so}
+    local -a link_args
+    if [ -n '${@link_args(d, False)}' ]; then
+        link_args[0]='-C'
+        link_args[1]='link-args=${@link_args(d, False)}'
+    fi
+    oe_runrustc $(get_overlap_externs) \
+        "${link_args[@]}" \
+        ${LIB_SRC} \
+        -o ${@libfilename(d)} \
+        --crate-name=${CRATE_NAME} --crate-type=${CRATE_TYPE} \
+        "$@"
+}
+oe_compile_rust_lib[vardeps] += "get_overlap_externs"
+
+oe_compile_rust_bin () {
+    rm -rf ${BINNAME}
+    local -a link_args
+    if [ -n '${@link_args(d, True)}' ]; then
+        link_args[0]='-C'
+        link_args[1]='link-args=${@link_args(d, True)}'
+    fi
+    oe_runrustc $(get_overlap_externs) \
+        "${link_args[@]}" \
+        ${BIN_SRC} -o ${BINNAME} "$@"
+}
+oe_compile_rust_bin[vardeps] += "get_overlap_externs"
+
+oe_install_rust_lib () {
+    for lib in $(ls ${LIBNAME}.{so,rlib} 2>/dev/null); do
+        echo Installing $lib
+        install -D -m 755 $lib ${D}/${rustlibdest}/$lib
+    done
+}
+
+oe_install_rust_bin () {
+    echo Installing ${BINNAME}
+    install -D -m 755 ${BINNAME} ${D}/${rustbindest}/${BINNAME}
+}
+
+do_rust_bin_fixups() {
+    for f in `find ${PKGD} -name '*.so*'`; do
+        echo "Strip rust note: $f"
+        ${OBJCOPY} -R .note.rustc $f $f
+    done
+}
+PACKAGE_PREPROCESS_FUNCS += "do_rust_bin_fixups"
+
diff --git a/meta/classes/rust-common.bbclass b/meta/classes/rust-common.bbclass
new file mode 100644
index 0000000000..cbc7d3cfe6
--- /dev/null
+++ b/meta/classes/rust-common.bbclass
@@ -0,0 +1,144 @@
+# Common variables used by all Rust builds
+export rustlibdir = "${libdir}/rust"
+FILES_${PN} += "${rustlibdir}/*.so"
+FILES_${PN}-dev += "${rustlibdir}/*.rlib ${rustlibdir}/*.rmeta"
+FILES_${PN}-dbg += "${rustlibdir}/.debug"
+
+RUSTLIB = "-L ${STAGING_LIBDIR}/rust"
+RUST_DEBUG_REMAP = "--remap-path-prefix=${WORKDIR}=/usr/src/debug/${PN}/${EXTENDPE}${PV}-${PR}"
+RUSTFLAGS += "${RUSTLIB} ${RUST_DEBUG_REMAP}"
+RUSTLIB_DEP ?= "libstd-rs"
+RUST_TARGET_PATH = "${STAGING_LIBDIR_NATIVE}/rustlib"
+RUST_PANIC_STRATEGY ?= "unwind"
+
+# Native builds are not effected by TCLIBC. Without this, rust-native
+# thinks it's "target" (i.e. x86_64-linux) is a musl target.
+RUST_LIBC = "${TCLIBC}"
+RUST_LIBC_class-native = "glibc"
+
+def determine_libc(d, thing):
+    '''Determine which libc something should target'''
+
+    # BUILD is never musl, TARGET may be musl or glibc,
+    # HOST could be musl, but only if a compiler is built to be run on
+    # target in which case HOST_SYS != BUILD_SYS.
+    if thing == 'TARGET':
+        libc = d.getVar('RUST_LIBC')
+    elif thing == 'BUILD' and (d.getVar('HOST_SYS') != d.getVar('BUILD_SYS')):
+        libc = d.getVar('RUST_LIBC')
+    else:
+        libc = d.getVar('RUST_LIBC_class-native')
+
+    return libc
+
+# Responsible for taking Yocto triples and converting it to Rust triples
+def rust_base_triple(d, thing):
+    '''
+    Mangle bitbake's *_SYS into something that rust might support (see
+    rust/mk/cfg/* for a list)
+
+    Note that os is assumed to be some linux form
+    '''
+
+    arch = d.getVar('{}_ARCH'.format(thing))
+    # All the Yocto targets are Linux and are 'unknown'
+    vendor = "-unknown"
+    os = d.getVar('{}_OS'.format(thing))
+    libc = determine_libc(d, thing)
+
+    # Prefix with a dash and convert glibc -> gnu
+    if libc == "glibc":
+        libc = "-gnu"
+    elif libc == "musl":
+        libc = "-musl"
+
+    # Don't double up musl (only appears to be the case on aarch64)
+    if os == "linux-musl":
+        if libc != "-musl":
+            bb.fatal("{}_OS was '{}' but TCLIBC was not 'musl'".format(thing, os))
+        os = "linux"
+
+    # This catches ARM targets and appends the necessary hard float bits
+    if os == "linux-gnueabi" or os == "linux-musleabi":
+        libc = bb.utils.contains('TUNE_FEATURES', 'callconvention-hard', 'hf', '', d)
+    return arch + vendor + '-' + os + libc
+
+# Naming explanation
+# Yocto
+# - BUILD_SYS - Yocto triple of the build environment
+# - HOST_SYS - What we're building for in Yocto
+# - TARGET_SYS - What we're building for in Yocto
+#
+# So when building '-native' packages BUILD_SYS == HOST_SYS == TARGET_SYS
+# When building packages for the image HOST_SYS == TARGET_SYS
+# This is a gross over simplification as there are other modes but
+# currently this is all that's supported.
+#
+# Rust
+# - TARGET - the system where the binary will run
+# - HOST - the system where the binary is being built
+#
+# Rust additionally will use two additional cases:
+# - undecorated (e.g. CC) - equivalent to TARGET
+# - triple suffix (e.g. CC_x86_64_unknown_linux_gnu) - both
+#   see: https://github.com/alexcrichton/gcc-rs
+# The way that Rust's internal triples and Yocto triples are mapped together
+# its likely best to not use the triple suffix due to potential confusion.
+
+RUST_BUILD_SYS = "${@rust_base_triple(d, 'BUILD')}"
+RUST_HOST_SYS = "${@rust_base_triple(d, 'HOST')}"
+RUST_TARGET_SYS = "${@rust_base_triple(d, 'TARGET')}"
+
+# wrappers to get around the fact that Rust needs a single
+# binary but Yocto's compiler and linker commands have
+# arguments. Technically the archiver is always one command but
+# this is necessary for builds that determine the prefix and then
+# use those commands based on the prefix.
+WRAPPER_DIR = "${WORKDIR}/wrapper"
+RUST_BUILD_CC = "${WRAPPER_DIR}/build-rust-cc"
+RUST_BUILD_CXX = "${WRAPPER_DIR}/build-rust-cxx"
+RUST_BUILD_CCLD = "${WRAPPER_DIR}/build-rust-ccld"
+RUST_BUILD_AR = "${WRAPPER_DIR}/build-rust-ar"
+RUST_TARGET_CC = "${WRAPPER_DIR}/target-rust-cc"
+RUST_TARGET_CXX = "${WRAPPER_DIR}/target-rust-cxx"
+RUST_TARGET_CCLD = "${WRAPPER_DIR}/target-rust-ccld"
+RUST_TARGET_AR = "${WRAPPER_DIR}/target-rust-ar"
+
+create_wrapper () {
+	file="$1"
+	shift
+
+	cat <<- EOF > "${file}"
+	#!/bin/sh
+	$@ "\$@"
+	EOF
+	chmod +x "${file}"
+}
+
+# compiler is used by gcc-rs
+# linker is used by rustc/cargo
+# archiver is used by the build of libstd-rs
+do_rust_create_wrappers () {
+	mkdir -p "${WRAPPER_DIR}"
+
+	# Yocto Build / Rust Host C compiler
+	create_wrapper "${RUST_BUILD_CC}" "${BUILD_CC}"
+	# Yocto Build / Rust Host C++ compiler
+	create_wrapper "${RUST_BUILD_CXX}" "${BUILD_CXX}"
+	# Yocto Build / Rust Host linker
+	create_wrapper "${RUST_BUILD_CCLD}" "${BUILD_CCLD}" "${BUILD_LDFLAGS}"
+	# Yocto Build / Rust Host archiver
+	create_wrapper "${RUST_BUILD_AR}" "${BUILD_AR}"
+
+	# Yocto Target / Rust Target C compiler
+	create_wrapper "${RUST_TARGET_CC}" "${CC}"
+	# Yocto Target / Rust Target C++ compiler
+	create_wrapper "${RUST_TARGET_CXX}" "${CXX}"
+	# Yocto Target / Rust Target linker
+	create_wrapper "${RUST_TARGET_CCLD}" "${CCLD}" "${LDFLAGS}"
+	# Yocto Target / Rust Target archiver
+	create_wrapper "${RUST_TARGET_AR}" "${AR}"
+}
+
+addtask rust_create_wrappers before do_configure after do_patch
+do_rust_create_wrappers[dirs] += "${WRAPPER_DIR}"
diff --git a/meta/classes/rust.bbclass b/meta/classes/rust.bbclass
new file mode 100644
index 0000000000..ec9ad54bc6
--- /dev/null
+++ b/meta/classes/rust.bbclass
@@ -0,0 +1,45 @@
+inherit rust-common
+
+RUSTC = "rustc"
+
+RUSTC_ARCHFLAGS += "--target=${HOST_SYS} ${RUSTFLAGS}"
+
+def rust_base_dep(d):
+    # Taken from meta/classes/base.bbclass `base_dep_prepend` and modified to
+    # use rust instead of gcc
+    deps = ""
+    if not d.getVar('INHIBIT_DEFAULT_RUST_DEPS'):
+        if (d.getVar('HOST_SYS') != d.getVar('BUILD_SYS')):
+            deps += " virtual/${TARGET_PREFIX}rust ${RUSTLIB_DEP}"
+        else:
+            deps += " rust-native"
+    return deps
+
+DEPENDS_append = " ${@rust_base_dep(d)}"
+
+# BUILD_LDFLAGS
+# 	${STAGING_LIBDIR_NATIVE}
+# 	${STAGING_BASE_LIBDIR_NATIVE}
+# BUILDSDK_LDFLAGS
+# 	${STAGING_LIBDIR}
+# 	#{STAGING_DIR_HOST}
+# TARGET_LDFLAGS ?????
+#RUSTC_BUILD_LDFLAGS = "\
+#	--sysroot ${STAGING_DIR_NATIVE} \
+#	-L${STAGING_LIBDIR_NATIVE}	\
+#	-L${STAGING_BASE_LIBDIR_NATIVE}	\
+#"
+
+# XXX: for some reason bitbake sets BUILD_* & TARGET_* but uses the bare
+# variables for HOST. Alias things to make it easier for us.
+HOST_LDFLAGS  ?= "${LDFLAGS}"
+HOST_CFLAGS   ?= "${CFLAGS}"
+HOST_CXXFLAGS ?= "${CXXFLAGS}"
+HOST_CPPFLAGS ?= "${CPPFLAGS}"
+
+rustlib_suffix="${TUNE_ARCH}${TARGET_VENDOR}-${TARGET_OS}/rustlib/${HOST_SYS}/lib"
+# Native sysroot standard library path
+rustlib_src="${prefix}/lib/${rustlib_suffix}"
+# Host sysroot standard library path
+rustlib="${libdir}/${rustlib_suffix}"
+rustlib_class-native="${libdir}/rustlib/${BUILD_SYS}/lib"
diff --git a/meta/conf/distro/include/rust_security_flags.inc b/meta/conf/distro/include/rust_security_flags.inc
new file mode 100644
index 0000000000..7e6377e8c7
--- /dev/null
+++ b/meta/conf/distro/include/rust_security_flags.inc
@@ -0,0 +1,7 @@
+# Build errors with PIE options enabled
+SECURITY_CFLAGS_pn-rust-native = "${SECURITY_NO_PIE_CFLAGS}"
+SECURITY_CFLAGS_pn-rust-cross-${TARGET_ARCH} = "${SECURITY_NO_PIE_CFLAGS}"
+SECURITY_CFLAGS_pn-rust = "${SECURITY_NO_PIE_CFLAGS}"
+SECURITY_CFLAGS_pn-rust-llvm = "${SECURITY_NO_PIE_CFLAGS}"
+
+SECURITY_LDFLAGS_pn-rust-cross-arm = " -lssp_nonshared -lssp"
diff --git a/meta/conf/layer.conf b/meta/conf/layer.conf
index cda37c33b4..d834be1d02 100644
--- a/meta/conf/layer.conf
+++ b/meta/conf/layer.conf
@@ -105,3 +105,5 @@ SSTATE_EXCLUDEDEPS_SYSROOT += ".*->autoconf-archive-native"
 # Avoid empty path entries
 BITBAKEPATH := "${@os.path.dirname(bb.utils.which(d.getVar('PATH'),'bitbake'))}"
 PATH := "${@'${BITBAKEPATH}:' if '${BITBAKEPATH}' != '' else ''}${HOSTTOOLS_DIR}"
+
+require conf/distro/include/rust_security_flags.inc
diff --git a/meta/lib/crate.py b/meta/lib/crate.py
new file mode 100644
index 0000000000..d10f441875
--- /dev/null
+++ b/meta/lib/crate.py
@@ -0,0 +1,149 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+"""
+BitBake 'Fetch' implementation for crates.io
+"""
+
+# Copyright (C) 2016 Doug Goldstein
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Based on functions from the base bb module, Copyright 2003 Holger Schurig
+
+import hashlib
+import json
+import os
+import shutil
+import subprocess
+import bb
+from   bb.fetch2 import logger, subprocess_setup, UnpackError
+from   bb.fetch2.wget import Wget
+
+
+class Crate(Wget):
+
+    """Class to fetch crates via wget"""
+
+    def _cargo_bitbake_path(self, rootdir):
+        return os.path.join(rootdir, "cargo_home", "bitbake")
+
+    def supports(self, ud, d):
+        """
+        Check to see if a given url is for this fetcher
+        """
+        return ud.type in ['crate']
+
+    def recommends_checksum(self, urldata):
+        return False
+
+    def urldata_init(self, ud, d):
+        """
+        Sets up to download the respective crate from crates.io
+        """
+
+        if ud.type == 'crate':
+            self._crate_urldata_init(ud, d)
+
+        super(Crate, self).urldata_init(ud, d)
+
+    def _crate_urldata_init(self, ud, d):
+        """
+        Sets up the download for a crate
+        """
+
+        # URL syntax is: crate://NAME/VERSION
+        # break the URL apart by /
+        parts = ud.url.split('/')
+        if len(parts) < 5:
+            raise bb.fetch2.ParameterError("Invalid URL: Must be crate://HOST/NAME/VERSION", ud.url)
+
+        # last field is version
+        version = parts[len(parts) - 1]
+        # second to last field is name
+        name = parts[len(parts) - 2]
+        # host (this is to allow custom crate registries to be specified
+        host = '/'.join(parts[2:len(parts) - 2])
+
+        # if using upstream just fix it up nicely
+        if host == 'crates.io':
+            host = 'crates.io/api/v1/crates'
+
+        ud.url = "https://%s/%s/%s/download" % (host, name, version)
+        ud.parm['downloadfilename'] = "%s-%s.crate" % (name, version)
+        ud.parm['name'] = name
+
+        logger.debug(2, "Fetching %s to %s" % (ud.url, ud.parm['downloadfilename']))
+
+    def unpack(self, ud, rootdir, d):
+        """
+        Uses the crate to build the necessary paths for cargo to utilize it
+        """
+        if ud.type == 'crate':
+            return self._crate_unpack(ud, rootdir, d)
+        else:
+            super(Crate, self).unpack(ud, rootdir, d)
+
+    def _crate_unpack(self, ud, rootdir, d):
+        """
+        Unpacks a crate
+        """
+        thefile = ud.localpath
+
+        # possible metadata we need to write out
+        metadata = {}
+
+        # change to the rootdir to unpack but save the old working dir
+        save_cwd = os.getcwd()
+        os.chdir(rootdir)
+
+        pn = d.getVar('BPN')
+        if pn == ud.parm.get('name'):
+            cmd = "tar -xz --no-same-owner -f %s" % thefile
+        else:
+            cargo_bitbake = self._cargo_bitbake_path(rootdir)
+
+            cmd = "tar -xz --no-same-owner -f %s -C %s" % (thefile, cargo_bitbake)
+
+            # ensure we've got these paths made
+            bb.utils.mkdirhier(cargo_bitbake)
+
+            # generate metadata necessary
+            with open(thefile, 'rb') as f:
+                # get the SHA256 of the original tarball
+                tarhash = hashlib.sha256(f.read()).hexdigest()
+
+            metadata['files'] = {}
+            metadata['package'] = tarhash
+
+        # path it
+        path = d.getVar('PATH')
+        if path:
+            cmd = "PATH=\"%s\" %s" % (path, cmd)
+        bb.note("Unpacking %s to %s/" % (thefile, os.getcwd()))
+
+        ret = subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True)
+
+        os.chdir(save_cwd)
+
+        if ret != 0:
+            raise UnpackError("Unpack command %s failed with return value %s" % (cmd, ret), ud.url)
+
+        # if we have metadata to write out..
+        if len(metadata) > 0:
+            cratepath = os.path.splitext(os.path.basename(thefile))[0]
+            bbpath = self._cargo_bitbake_path(rootdir)
+            mdfile = '.cargo-checksum.json'
+            mdpath = os.path.join(bbpath, cratepath, mdfile)
+            with open(mdpath, "w") as f:
+                json.dump(metadata, f)
diff --git a/meta/recipes-devtools/cargo/cargo-1.34.2/0001-Disable-http2.patch b/meta/recipes-devtools/cargo/cargo-1.34.2/0001-Disable-http2.patch
new file mode 100644
index 0000000000..a44482a112
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo-1.34.2/0001-Disable-http2.patch
@@ -0,0 +1,29 @@
+From 44cf21036646e4849e9f8566db7decb7da917394 Mon Sep 17 00:00:00 2001
+From: Johan Anderholm <johan.anderholm@gmail.com>
+Date: Sun, 27 Jan 2019 10:19:00 +0100
+Subject: [PATCH] Disable http2
+
+http2 requires that curl is build with nghttp2 which in turn depends on
+many dependencies and ultimately a dependency loop in the case of
+curl-native. As long as multiplexing is disabled in cargo this should
+be fine.
+
+Upstream-Status: Inappropriate
+
+---
+ Cargo.toml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Cargo.toml b/Cargo.toml
+index 8238380861d9..ced1defea459 100644
+--- a/Cargo.toml
++++ b/Cargo.toml
+@@ -24,7 +24,7 @@ bytesize = "1.0"
+ crates-io = { path = "src/crates-io", version = "0.23" }
+ crossbeam-utils = "0.6"
+ crypto-hash = "0.3.1"
+-curl = { version = "0.4.19", features = ['http2'] }
++curl = { version = "0.4.19" }
+ curl-sys = "0.4.15"
+ env_logger = "0.6.0"
+ pretty_env_logger = { version = "0.3", optional = true }
diff --git a/meta/recipes-devtools/cargo/cargo-1.36.0/0001-Disable-http2.patch b/meta/recipes-devtools/cargo/cargo-1.36.0/0001-Disable-http2.patch
new file mode 100644
index 0000000000..9794ec05f9
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo-1.36.0/0001-Disable-http2.patch
@@ -0,0 +1,31 @@
+From 42e65192b6f7520b7a05924856e00600961f6758 Mon Sep 17 00:00:00 2001
+From: Johan Anderholm <johan.anderholm@gmail.com>
+Date: Sun, 27 Jan 2019 10:19:00 +0100
+Subject: [PATCH] Disable http2
+
+http2 requires that curl is build with nghttp2 which in turn depends on
+many dependencies and ultimately a dependency loop in the case of
+curl-native. As long as multiplexing is disabled in cargo this should
+be fine.
+
+Upstream-Status: Inappropriate
+---
+ Cargo.toml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Cargo.toml b/Cargo.toml
+index c3fcacf5..bd6ec50b 100644
+--- a/Cargo.toml
++++ b/Cargo.toml
+@@ -24,7 +24,7 @@ bytesize = "1.0"
+ crates-io = { path = "src/crates-io", version = "0.25" }
+ crossbeam-utils = "0.6"
+ crypto-hash = "0.3.1"
+-curl = { version = "0.4.21", features = ['http2'] }
++curl = { version = "0.4.21" }
+ curl-sys = "0.4.18"
+ env_logger = "0.6.0"
+ pretty_env_logger = { version = "0.3", optional = true }
+-- 
+2.11.0
+
diff --git a/meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch b/meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch
new file mode 100644
index 0000000000..c804297d48
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch
@@ -0,0 +1,29 @@
+From 0e2384133664ebeb548b782ad763c3a627c1bc66 Mon Sep 17 00:00:00 2001
+From: Johan Anderholm <johan.anderholm@gmail.com>
+Date: Sun, 27 Jan 2019 10:19:00 +0100
+Subject: [PATCH] Disable http2
+
+http2 requires that curl is build with nghttp2 which in turn depends on
+many dependencies and ultimately a dependency loop in the case of
+curl-native. As long as multiplexing is disabled in cargo this should
+be fine.
+
+Upstream-Status: Inappropriate
+
+---
+ src/tools/cargo/Cargo.toml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Cargo.toml b/Cargo.toml
+index d15aa2513..ba9c77d25 100644
+--- a/Cargo.toml
++++ b/Cargo.toml
+@@ -24,7 +24,7 @@ bytesize = "1.0"
+ crates-io = { path = "crates/crates-io", version = "0.26" }
+ crossbeam-utils = "0.6"
+ crypto-hash = "0.3.1"
+-curl = { version = "0.4.21", features = ['http2'] }
++curl = { version = "0.4.21" }
+ curl-sys = "0.4.18"
+ env_logger = "0.6.0"
+ pretty_env_logger = { version = "0.3", optional = true }
diff --git a/meta/recipes-devtools/cargo/cargo.inc b/meta/recipes-devtools/cargo/cargo.inc
new file mode 100644
index 0000000000..48012520d9
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo.inc
@@ -0,0 +1,43 @@
+SUMMARY = "Cargo, a package manager for Rust."
+HOMEPAGE = "https://crates.io"
+LICENSE = "MIT | Apache-2.0"
+SECTION = "devel"
+
+DEPENDS = "openssl zlib libgit2 curl ca-certificates libssh2"
+
+LIC_FILES_CHKSUM = " \
+    file://LICENSE-MIT;md5=b377b220f43d747efdec40d69fcaa69d \
+"
+
+SRC_URI += "file://0001-Disable-http2.patch"
+
+S = "${RUSTSRC}/src/tools/cargo"
+CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
+
+inherit cargo
+
+do_cargo_setup_snapshot () {
+	${WORKDIR}/rust-snapshot-components/${CARGO_SNAPSHOT}/install.sh --prefix="${WORKDIR}/${CARGO_SNAPSHOT}" --disable-ldconfig
+}
+
+addtask cargo_setup_snapshot after do_unpack before do_configure
+do_cargo_setup_snapshot[dirs] += "${WORKDIR}/${CARGO_SNAPSHOT}"
+
+do_compile_prepend () {
+	export RUSTC_BOOTSTRAP="1"
+}
+
+do_install () {
+	install -d "${D}${bindir}"
+	install -m 755 "${RUSTSRC}/target/${CARGO_TARGET_SUBDIR}/cargo" "${D}${bindir}"
+}
+
+# Needed for pkg-config to be used
+export LIBGIT2_SYS_USE_PKG_CONFIG = "1"
+export LIBSSH2_SYS_USE_PKG_CONFIG = "1"
+
+BBCLASSEXTEND = "native"
+
+# When building cargo-native we don't have a built cargo to use so we must use
+# the snapshot to bootstrap the build of cargo
+CARGO_class-native = "${WORKDIR}/${CARGO_SNAPSHOT}/bin/cargo"
diff --git a/meta/recipes-devtools/cargo/cargo_1.34.2.bb b/meta/recipes-devtools/cargo/cargo_1.34.2.bb
new file mode 100644
index 0000000000..d79f958c6e
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo_1.34.2.bb
@@ -0,0 +1,8 @@
+require recipes-devtools/rust/rust-source-${PV}.inc
+require recipes-devtools/rust/rust-snapshot-${PV}.inc
+require cargo.inc
+
+LIC_FILES_CHKSUM += " \
+    file://LICENSE-APACHE;md5=1836efb2eb779966696f473ee8540542 \
+    file://LICENSE-THIRD-PARTY;md5=892ea68b169e69cfe75097fc38a15b56 \
+"
diff --git a/meta/recipes-devtools/cargo/cargo_1.36.0.bb b/meta/recipes-devtools/cargo/cargo_1.36.0.bb
new file mode 100644
index 0000000000..f048779aae
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo_1.36.0.bb
@@ -0,0 +1,8 @@
+require recipes-devtools/rust/rust-source-${PV}.inc
+require recipes-devtools/rust/rust-snapshot-${PV}.inc
+require cargo.inc
+
+LIC_FILES_CHKSUM += " \
+    file://LICENSE-APACHE;md5=71b224ca933f0676e26d5c2e2271331c \
+    file://LICENSE-THIRD-PARTY;md5=f257ad009884cb88a3a87d6920e7180a \
+"
diff --git a/meta/recipes-devtools/cargo/cargo_1.37.0.bb b/meta/recipes-devtools/cargo/cargo_1.37.0.bb
new file mode 100644
index 0000000000..f048779aae
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo_1.37.0.bb
@@ -0,0 +1,8 @@
+require recipes-devtools/rust/rust-source-${PV}.inc
+require recipes-devtools/rust/rust-snapshot-${PV}.inc
+require cargo.inc
+
+LIC_FILES_CHKSUM += " \
+    file://LICENSE-APACHE;md5=71b224ca933f0676e26d5c2e2271331c \
+    file://LICENSE-THIRD-PARTY;md5=f257ad009884cb88a3a87d6920e7180a \
+"
diff --git a/meta/recipes-devtools/rust/libstd-rs.inc b/meta/recipes-devtools/rust/libstd-rs.inc
new file mode 100644
index 0000000000..5298c00706
--- /dev/null
+++ b/meta/recipes-devtools/rust/libstd-rs.inc
@@ -0,0 +1,31 @@
+SUMMARY = "Rust standard libaries"
+HOMEPAGE = "http://www.rust-lang.org"
+SECTION = "devel"
+LICENSE = "MIT | Apache-2.0"
+
+RUSTLIB_DEP = ""
+inherit cargo
+
+DEPENDS_append_libc-musl = " libunwind"
+# Needed so cargo can find libbacktrace
+RUSTFLAGS += "-L ${STAGING_LIBDIR} -C link-arg=-Wl,-soname,libstd.so"
+
+S = "${RUSTSRC}/src/libstd"
+
+CARGO_BUILD_FLAGS += "--features '${CARGO_FEATURES}'"
+
+do_compile_prepend () {
+    export CARGO_TARGET_DIR="${B}"
+    # For Rust 1.13.0 and newer
+    export RUSTC_BOOTSTRAP="1"
+}
+
+do_install () {
+    mkdir -p ${D}${rustlibdir}
+
+    # With the incremental build support added in 1.24, the libstd deps directory also includes dependency
+    # files that get installed. Those are really only needed to incrementally rebuild the libstd library
+    # itself and don't need to be installed.
+    rm -f ${B}/${TARGET_SYS}/${BUILD_DIR}/deps/*.d
+    cp ${B}/${TARGET_SYS}/${BUILD_DIR}/deps/* ${D}${rustlibdir}
+}
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.34.2.bb b/meta/recipes-devtools/rust/libstd-rs_1.34.2.bb
new file mode 100644
index 0000000000..69cb48ad07
--- /dev/null
+++ b/meta/recipes-devtools/rust/libstd-rs_1.34.2.bb
@@ -0,0 +1,8 @@
+require rust-source-${PV}.inc
+require libstd-rs.inc
+
+LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
+
+CARGO_FEATURES ?= "panic-unwind backtrace"
+
+CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.36.0.bb b/meta/recipes-devtools/rust/libstd-rs_1.36.0.bb
new file mode 100644
index 0000000000..69cb48ad07
--- /dev/null
+++ b/meta/recipes-devtools/rust/libstd-rs_1.36.0.bb
@@ -0,0 +1,8 @@
+require rust-source-${PV}.inc
+require libstd-rs.inc
+
+LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
+
+CARGO_FEATURES ?= "panic-unwind backtrace"
+
+CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.37.0.bb b/meta/recipes-devtools/rust/libstd-rs_1.37.0.bb
new file mode 100644
index 0000000000..69cb48ad07
--- /dev/null
+++ b/meta/recipes-devtools/rust/libstd-rs_1.37.0.bb
@@ -0,0 +1,8 @@
+require rust-source-${PV}.inc
+require libstd-rs.inc
+
+LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
+
+CARGO_FEATURES ?= "panic-unwind backtrace"
+
+CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
diff --git a/meta/recipes-devtools/rust/rust-cross.inc b/meta/recipes-devtools/rust/rust-cross.inc
new file mode 100644
index 0000000000..4869b85c03
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-cross.inc
@@ -0,0 +1,52 @@
+require rust.inc
+inherit cross
+
+# Otherwise we'll depend on what we provide
+INHIBIT_DEFAULT_RUST_DEPS = "1"
+
+# Unlike native (which nicely maps it's DEPENDS) cross wipes them out completely.
+# Generally, we (and cross in general) need the same things that native needs,
+# so it might make sense to take it's mapping. For now, though, we just mention
+# the bits we need explicitly.
+DEPENDS += "rust-llvm-native"
+DEPENDS += "virtual/${TARGET_PREFIX}gcc virtual/${TARGET_PREFIX}compilerlibs virtual/libc"
+DEPENDS += "rust-native"
+
+PROVIDES = "virtual/${TARGET_PREFIX}rust"
+PN = "rust-cross-${TARGET_ARCH}"
+
+# In the cross compilation case, rustc doesn't seem to get the rpath quite
+# right. It manages to include '../../lib/${TARGET_PREFIX}', but doesn't
+# include the '../../lib' (ie: relative path from cross_bindir to normal
+# libdir. As a result, we end up not being able to properly reference files in normal ${libdir}.
+# Most of the time this happens to work fine as the systems libraries are
+# subsituted, but sometimes a host system will lack a library, or the right
+# version of a library (libtinfo was how I noticed this).
+#
+# FIXME: this should really be fixed in rust itself.
+# FIXME: using hard-coded relative paths is wrong, we should ask bitbake for
+#        the relative path between 2 of it's vars.
+HOST_POST_LINK_ARGS_append = " -Wl,-rpath=../../lib"
+BUILD_POST_LINK_ARGS_append = " -Wl,-rpath=../../lib"
+
+# We need the same thing for the calls to the compiler when building the runtime crap
+TARGET_CC_ARCH_append = " --sysroot=${STAGING_DIR_TARGET}"
+
+do_rust_setup_snapshot () {
+}
+
+do_configure () {
+}
+
+do_compile () {
+}
+
+do_install () {
+	mkdir -p ${D}${prefix}/${base_libdir_native}/rustlib
+	cp ${WORKDIR}/targets/${TARGET_SYS}.json ${D}${prefix}/${base_libdir_native}/rustlib
+}
+
+rust_cross_sysroot_preprocess() {
+    sysroot_stage_dir ${D}${prefix}/${base_libdir_native}/rustlib ${SYSROOT_DESTDIR}${prefix}/${base_libdir_native}/rustlib
+}
+SYSROOT_PREPROCESS_FUNCS += "rust_cross_sysroot_preprocess"
diff --git a/meta/recipes-devtools/rust/rust-cross_1.34.2.bb b/meta/recipes-devtools/rust/rust-cross_1.34.2.bb
new file mode 100644
index 0000000000..bb92b99ccc
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-cross_1.34.2.bb
@@ -0,0 +1,3 @@
+require rust-cross.inc
+require rust-source-${PV}.inc
+
diff --git a/meta/recipes-devtools/rust/rust-cross_1.36.0.bb b/meta/recipes-devtools/rust/rust-cross_1.36.0.bb
new file mode 100644
index 0000000000..bb92b99ccc
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-cross_1.36.0.bb
@@ -0,0 +1,3 @@
+require rust-cross.inc
+require rust-source-${PV}.inc
+
diff --git a/meta/recipes-devtools/rust/rust-cross_1.37.0.bb b/meta/recipes-devtools/rust/rust-cross_1.37.0.bb
new file mode 100644
index 0000000000..bb92b99ccc
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-cross_1.37.0.bb
@@ -0,0 +1,3 @@
+require rust-cross.inc
+require rust-source-${PV}.inc
+
diff --git a/meta/recipes-devtools/rust/rust-llvm.inc b/meta/recipes-devtools/rust/rust-llvm.inc
new file mode 100644
index 0000000000..b4bef3875c
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-llvm.inc
@@ -0,0 +1,62 @@
+SUMMARY = "LLVM compiler framework (packaged with rust)"
+LICENSE = "NCSA"
+
+SRC_URI += "file://0002-llvm-allow-env-override-of-exe-path.patch"
+
+S = "${RUSTSRC}/src/llvm-project/llvm"
+
+LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=4c0bc17c954e99fd547528d938832bfa"
+
+inherit cmake pythonnative
+
+DEPENDS += "ninja-native rust-llvm-native"
+
+ARM_INSTRUCTION_SET_armv5 = "arm"
+ARM_INSTRUCTION_SET_armv4t = "arm"
+
+LLVM_RELEASE = "6.0"
+LLVM_DIR = "llvm${LLVM_RELEASE}"
+
+EXTRA_OECMAKE = " \
+    -DCMAKE_BUILD_TYPE=Release \
+    -DLLVM_TARGETS_TO_BUILD='X86;ARM;AArch64;PowerPC;Mips' \
+    -DLLVM_BUILD_DOCS=OFF \
+    -DLLVM_ENABLE_TERMINFO=OFF \
+    -DLLVM_ENABLE_ZLIB=OFF \
+    -DLLVM_ENABLE_LIBXML2=OFF \
+    -DLLVM_ENABLE_FFI=OFF \
+    -DLLVM_INSTALL_UTILS=ON \
+    -DLLVM_BUILD_EXAMPLES=OFF \
+    -DLLVM_INCLUDE_EXAMPLES=OFF \
+    -DLLVM_BUILD_TESTS=OFF \
+    -DLLVM_INCLUDE_TESTS=OFF \
+    -DLLVM_TARGET_ARCH=${TARGET_ARCH} \
+    -DCMAKE_INSTALL_PREFIX:PATH=${libdir}/llvm-rust \
+"
+EXTRA_OECMAKE_append_class-target = "\
+    -DCMAKE_CROSSCOMPILING:BOOL=ON \
+    -DLLVM_BUILD_TOOLS=OFF \
+    -DLLVM_TABLEGEN=${STAGING_LIBDIR_NATIVE}/llvm-rust/bin/llvm-tblgen \
+    -DLLVM_CONFIG_PATH=${STAGING_LIBDIR_NATIVE}/llvm-rust/bin/llvm-config \
+"
+
+# The debug symbols are huge here (>2GB) so suppress them since they
+# provide almost no value. If you really need them then override this
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+
+do_install_append_class-target() {
+    # Disable checks on the native tools, since these should came from the native recipe
+    sed -i -e 's/\(.*APPEND.*_IMPORT_CHECK_FILES_FOR_.*{_IMPORT_PREFIX}\/bin\/.*\)/#\1/' ${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake
+}
+
+PACKAGES =+ "${PN}-bugpointpasses ${PN}-llvmhello ${PN}-liblto"
+
+# Add the extra locations to avoid the complaints about unpackaged files
+FILES_${PN}-bugpointpasses = "${libdir}/llvm-rust/lib/BugpointPasses.so"
+FILES_${PN}-llvmhello = "${libdir}/llvm-rust/lib/LLVMHello.so"
+FILES_${PN}-liblto = "${libdir}/llvm-rust/lib/libLTO.so.*"
+FILES_${PN}-staticdev =+ "${libdir}/llvm-rust/*/*.a"
+FILES_${PN} += "${libdir}/libLLVM*.so.* ${libdir}/llvm-rust/lib/*.so.* ${libdir}/llvm-rust/bin"
+FILES_${PN}-dev += "${datadir}/llvm ${libdir}/llvm-rust/lib/*.so ${libdir}/llvm-rust/include ${libdir}/llvm-rust/share ${libdir}/llvm-rust/lib/cmake"
+
+BBCLASSEXTEND = "native"
diff --git a/meta/recipes-devtools/rust/rust-llvm/0002-llvm-allow-env-override-of-exe-path.patch b/meta/recipes-devtools/rust/rust-llvm/0002-llvm-allow-env-override-of-exe-path.patch
new file mode 100644
index 0000000000..65dbd6ffd6
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-llvm/0002-llvm-allow-env-override-of-exe-path.patch
@@ -0,0 +1,32 @@
+From 7111770e8290082530d920e120995bf81431b0aa Mon Sep 17 00:00:00 2001
+From: Martin Kelly <mkelly@xevo.com>
+Date: Fri, 19 May 2017 00:22:57 -0700
+Subject: [PATCH 12/18] llvm: allow env override of exe path
+
+When using a native llvm-config from inside a sysroot, we need llvm-config to
+return the libraries, include directories, etc. from inside the sysroot rather
+than from the native sysroot. Thus provide an env override for calling
+llvm-config from a target sysroot.
+
+Signed-off-by: Martin Kelly <mkelly@xevo.com>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ tools/llvm-config/llvm-config.cpp | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/tools/llvm-config/llvm-config.cpp
++++ b/tools/llvm-config/llvm-config.cpp
+@@ -226,6 +226,13 @@ Typical components:\n\
+ 
+ /// Compute the path to the main executable.
+ std::string GetExecutablePath(const char *Argv0) {
++  // Hack for Yocto: we need to override the root path when we are using
++  // llvm-config from within a target sysroot.
++  const char *Sysroot = std::getenv("YOCTO_ALTERNATE_EXE_PATH");
++  if (Sysroot != nullptr) {
++    return Sysroot;
++  }
++
+   // This just needs to be some symbol in the binary; C++ doesn't
+   // allow taking the address of ::main however.
+   void *P = (void *)(intptr_t)GetExecutablePath;
diff --git a/meta/recipes-devtools/rust/rust-llvm_1.34.2.bb b/meta/recipes-devtools/rust/rust-llvm_1.34.2.bb
new file mode 100644
index 0000000000..d41fa28477
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-llvm_1.34.2.bb
@@ -0,0 +1,16 @@
+require rust-source-${PV}.inc
+require rust-llvm.inc
+
+LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=c6b766a4e85dd28301eeed54a6684648"
+
+do_install_prepend () {
+	# the install does a sed on this without installing the file
+	# we don't need it for anything
+	mkdir -p "${D}/usr/share/llvm/cmake"
+	touch "${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake"
+}
+
+do_install_append () {
+	# we don't need any of this stuff to build Rust
+	rm -rf "${D}/usr/lib/cmake"
+}
diff --git a/meta/recipes-devtools/rust/rust-llvm_1.36.0.bb b/meta/recipes-devtools/rust/rust-llvm_1.36.0.bb
new file mode 100644
index 0000000000..d41fa28477
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-llvm_1.36.0.bb
@@ -0,0 +1,16 @@
+require rust-source-${PV}.inc
+require rust-llvm.inc
+
+LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=c6b766a4e85dd28301eeed54a6684648"
+
+do_install_prepend () {
+	# the install does a sed on this without installing the file
+	# we don't need it for anything
+	mkdir -p "${D}/usr/share/llvm/cmake"
+	touch "${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake"
+}
+
+do_install_append () {
+	# we don't need any of this stuff to build Rust
+	rm -rf "${D}/usr/lib/cmake"
+}
diff --git a/meta/recipes-devtools/rust/rust-llvm_1.37.0.bb b/meta/recipes-devtools/rust/rust-llvm_1.37.0.bb
new file mode 100644
index 0000000000..d41fa28477
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-llvm_1.37.0.bb
@@ -0,0 +1,16 @@
+require rust-source-${PV}.inc
+require rust-llvm.inc
+
+LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=c6b766a4e85dd28301eeed54a6684648"
+
+do_install_prepend () {
+	# the install does a sed on this without installing the file
+	# we don't need it for anything
+	mkdir -p "${D}/usr/share/llvm/cmake"
+	touch "${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake"
+}
+
+do_install_append () {
+	# we don't need any of this stuff to build Rust
+	rm -rf "${D}/usr/lib/cmake"
+}
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc b/meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc
new file mode 100644
index 0000000000..d0209bb864
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc
@@ -0,0 +1,24 @@
+## This is information on the rust-snapshot (binary) used to build our current release.
+## snapshot info is taken from rust/src/stage0.txt
+## TODO: find a way to add additional SRC_URIs based on the contents of an
+##       earlier SRC_URI.
+RS_VERSION = "1.33.0"
+
+RUST_STD_SNAPSHOT = "rust-std-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+RUSTC_SNAPSHOT = "rustc-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+CARGO_VERSION = "0.34.0"
+CARGO_SNAPSHOT = "cargo-${CARGO_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+
+SRC_URI += " \
+	https://static.rust-lang.org/dist/${RUST_STD_SNAPSHOT}.tar.gz;name=rust-std-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	https://static.rust-lang.org/dist/${RUSTC_SNAPSHOT}.tar.gz;name=rustc-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	https://static.rust-lang.org/dist/${CARGO_SNAPSHOT}.tar.gz;name=cargo-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	"
+
+# TODO: Add hashes for other architecture toolchains as well. Make a script?
+SRC_URI[rustc-snapshot-x86_64.md5sum] = "c1ec989c1965dce754dda1e54274a68c"
+SRC_URI[rustc-snapshot-x86_64.sha256sum] = "54a342f718b712d8a17fd7878ebd37d22a82ebc70b59c421168cd4153fd04c2b"
+SRC_URI[rust-std-snapshot-x86_64.md5sum] = "d573c5bd3a965c973734c1606968a91e"
+SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "661c2ba717ae1502f002b4c6e7aeb8941685c7ea8fe7ac26ed9ede26f615b7af"
+SRC_URI[cargo-snapshot-x86_64.md5sum] = "de0e635afa9bf495cefecea476bfce36"
+SRC_URI[cargo-snapshot-x86_64.sha256sum] = "4795ae5ca3bb8c7c83ca338676bb02b670efa1eb474e346284b629dc872bcce8"
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc b/meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc
new file mode 100644
index 0000000000..e4b6813e84
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc
@@ -0,0 +1,24 @@
+## This is information on the rust-snapshot (binary) used to build our current release.
+## snapshot info is taken from rust/src/stage0.txt
+## TODO: find a way to add additional SRC_URIs based on the contents of an
+##       earlier SRC_URI.
+RS_VERSION = "1.35.0"
+
+RUSTC_SNAPSHOT = "rustc-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+RUST_STD_SNAPSHOT = "rust-std-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+CARGO_VERSION = "0.36.0"
+CARGO_SNAPSHOT = "cargo-${CARGO_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+
+SRC_URI += " \
+	https://static.rust-lang.org/dist/${RUSTC_SNAPSHOT}.tar.xz;name=rustc-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	https://static.rust-lang.org/dist/${RUST_STD_SNAPSHOT}.tar.xz;name=rust-std-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	https://static.rust-lang.org/dist/${CARGO_SNAPSHOT}.tar.xz;name=cargo-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	"
+
+# TODO: Add hashes for other architecture toolchains as well. Make a script?
+SRC_URI[rustc-snapshot-x86_64.md5sum] = "47ea78f6b3f68e30f24b9c94e465d6bd"
+SRC_URI[rustc-snapshot-x86_64.sha256sum] = "5d6dc216ba429ddf3a1657e70f3e5e380549b546fe56de897677a11d72aa4e07"
+SRC_URI[rust-std-snapshot-x86_64.md5sum] = "348ec23ca8e47fc65079bc80e63cca5f"
+SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "ccff05d0e2d88499505b10f8e33e8b1645df057f918edc81f8acb0fcee9f90b2"
+SRC_URI[cargo-snapshot-x86_64.md5sum] = "93a375e771f3d9b3a139e612dd4730ee"
+SRC_URI[cargo-snapshot-x86_64.sha256sum] = "ab5a6ff1947463dbd2477ca5dac2012494dae821112098ae0c54add652adfdc3"
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc b/meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc
new file mode 100644
index 0000000000..8d4c1801ed
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc
@@ -0,0 +1,24 @@
+## This is information on the rust-snapshot (binary) used to build our current release.
+## snapshot info is taken from rust/src/stage0.txt
+## TODO: find a way to add additional SRC_URIs based on the contents of an
+##       earlier SRC_URI.
+RS_VERSION = "1.36.0"
+
+RUSTC_SNAPSHOT = "rustc-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+RUST_STD_SNAPSHOT = "rust-std-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+CARGO_VERSION = "0.37.0"
+CARGO_SNAPSHOT = "cargo-${CARGO_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+
+SRC_URI += " \
+	https://static.rust-lang.org/dist/${RUSTC_SNAPSHOT}.tar.xz;name=rustc-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	https://static.rust-lang.org/dist/${RUST_STD_SNAPSHOT}.tar.xz;name=rust-std-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	https://static.rust-lang.org/dist/${CARGO_SNAPSHOT}.tar.xz;name=cargo-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+	"
+
+# TODO: Add hashes for other architecture toolchains as well. Make a script?
+SRC_URI[rustc-snapshot-x86_64.md5sum] = "ec27794c94cc1df1a0a69f7244a09176"
+SRC_URI[rustc-snapshot-x86_64.sha256sum] = "fff0158da6f5af2a89936dc3e0c361077c06c2983eb310615e02f81ebbde1416"
+SRC_URI[rust-std-snapshot-x86_64.md5sum] = "b71a6fd6f44527c3bf09584e89ad8958"
+SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "ce8e12684b568a8a4f7d346a743383429849cf3f028f5712ad3d3e31590c8db3"
+SRC_URI[cargo-snapshot-x86_64.md5sum] = "8c661276a0da7a1aa48affbe33b347e6"
+SRC_URI[cargo-snapshot-x86_64.sha256sum] = "d20fa121951339d5492cf8862f8a7af59efc99d18f3c27b95ab6d4658b6a7d67"
diff --git a/meta/recipes-devtools/rust/rust-source-1.34.2.inc b/meta/recipes-devtools/rust/rust-source-1.34.2.inc
new file mode 100644
index 0000000000..5c83f6f000
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-source-1.34.2.inc
@@ -0,0 +1,11 @@
+SRC_URI += "https://static.rust-lang.org/dist/rustc-${PV}-src.tar.gz;name=rust"
+
+SRC_URI[rust.md5sum] = "7c85e6a60dda740295f7e004a1fb15e1"
+SRC_URI[rust.sha256sum] = "c69a4a85a1c464368597df8878cb9e1121aae93e215616d45ad7d23af3052f56"
+
+# later versions of rust change the directory that they unextract to
+RUSTSRC = "${WORKDIR}/rustc-${PV}-src"
+# set this as our default
+S = "${RUSTSRC}"
+
+LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
diff --git a/meta/recipes-devtools/rust/rust-source-1.36.0.inc b/meta/recipes-devtools/rust/rust-source-1.36.0.inc
new file mode 100644
index 0000000000..1a1d07c72f
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-source-1.36.0.inc
@@ -0,0 +1,11 @@
+SRC_URI += "https://static.rust-lang.org/dist/rustc-${PV}-src.tar.xz;name=rust"
+
+SRC_URI[rust.md5sum] = "78ffc0b029aaed216b45c3fe24747d46"
+SRC_URI[rust.sha256sum] = "f51645b9f787af4a5d94db17f6af39db0c55980ed24fe366cad55b57900f8f2d"
+
+# later versions of rust change the directory that they unextract to
+RUSTSRC = "${WORKDIR}/rustc-${PV}-src"
+# set this as our default
+S = "${RUSTSRC}"
+
+LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
diff --git a/meta/recipes-devtools/rust/rust-source-1.37.0.inc b/meta/recipes-devtools/rust/rust-source-1.37.0.inc
new file mode 100644
index 0000000000..0169cd3fbd
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-source-1.37.0.inc
@@ -0,0 +1,11 @@
+SRC_URI += "https://static.rust-lang.org/dist/rustc-${PV}-src.tar.xz;name=rust"
+
+SRC_URI[rust.md5sum] = "ee6300b1d7e5767115492915c4c0d8ef"
+SRC_URI[rust.sha256sum] = "10abffac50a729cf74cef6dd03193a2f4647541bd19ee9281be9e5b12ca8cdfd"
+
+# later versions of rust change the directory that they unextract to
+RUSTSRC = "${WORKDIR}/rustc-${PV}-src"
+# set this as our default
+S = "${RUSTSRC}"
+
+LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
diff --git a/meta/recipes-devtools/rust/rust.inc b/meta/recipes-devtools/rust/rust.inc
new file mode 100644
index 0000000000..abd4e0e4bc
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust.inc
@@ -0,0 +1,509 @@
+SUMMARY = "Rust compiler and runtime libaries"
+HOMEPAGE = "http://www.rust-lang.org"
+SECTION = "devel"
+LICENSE = "MIT | Apache-2.0"
+
+inherit rust
+inherit cargo_common
+
+DEPENDS += "file-native python-native"
+DEPENDS_append_class-native = " rust-llvm-native"
+
+# We generate local targets, and need to be able to locate them
+export RUST_TARGET_PATH="${WORKDIR}/targets/"
+
+export FORCE_CRATE_HASH="${BB_TASKHASH}"
+
+export YOCTO_ALTERNATE_EXE_PATH = "${STAGING_LIBDIR}/llvm-rust/bin/llvm-config"
+export YOCTO_ALTERNATE_MULTILIB_NAME = "/${BASELIB}"
+
+# We don't want to use bitbakes vendoring because the rust sources do their
+# own vendoring.
+CARGO_DISABLE_BITBAKE_VENDORING = "1"
+
+# We can't use RUST_BUILD_SYS here because that may be "musl" if
+# TCLIBC="musl". Snapshots are always -unknown-linux-gnu
+SNAPSHOT_BUILD_SYS = "${BUILD_ARCH}-unknown-linux-gnu"
+setup_cargo_environment () {
+    # The first step is to build bootstrap and some early stage tools,
+    # these are build for the same target as the snapshot, e.g.
+    # x86_64-unknown-linux-gnu.
+    # Later stages are build for the native target (i.e. target.x86_64-linux)
+    cargo_common_do_configure
+
+    printf '[target.%s]\n' "${SNAPSHOT_BUILD_SYS}" >> ${CARGO_HOME}/config
+    printf "linker = '%s'\n" "${RUST_BUILD_CCLD}" >> ${CARGO_HOME}/config
+}
+
+# Right now this is focused on arm-specific tune features.
+# We get away with this for now as one can only use x86-64 as the build host
+# (not arm).
+# Note that TUNE_FEATURES is _always_ refering to the target, so we really
+# don't want to use this for the host/build.
+def llvm_features_from_tune(d):
+    f = []
+    feat = d.getVar('TUNE_FEATURES')
+    if not feat:
+        return []
+    feat = frozenset(feat.split())
+
+    if 'vfpv4' in feat:
+        f.append("+vfp4")
+    if 'vfpv3' in feat:
+        f.append("+vfp3")
+    if 'vfpv3d16' in feat:
+        f.append("+d16")
+
+    if 'vfpv2' in feat or 'vfp' in feat:
+        f.append("+vfp2")
+
+    if 'neon' in feat:
+        f.append("+neon")
+
+    if 'aarch64' in feat:
+        f.append("+v8")
+
+    if 'mips32' in feat:
+        f.append("+mips32")
+
+    if 'mips32r2' in feat:
+        f.append("+mips32r2")
+
+    v7=frozenset(['armv7a', 'armv7r', 'armv7m', 'armv7ve'])
+    if not feat.isdisjoint(v7):
+        f.append("+v7")
+    if 'armv6' in feat:
+        f.append("+v6")
+
+    if 'dsp' in feat:
+        f.append("+dsp")
+
+    if 'thumb' in feat:
+        if d.getVar('ARM_THUMB_OPT') is "thumb":
+            if not feat.isdisjoint(v7):
+                f.append("+thumb2")
+            f.append("+thumb-mode")
+
+    if 'cortexa5' in feat:
+        f.append("+a5")
+    if 'cortexa7' in feat:
+        f.append("+a7")
+    if 'cortexa9' in feat:
+        f.append("+a9")
+    if 'cortexa15' in feat:
+        f.append("+a15")
+    if 'cortexa17' in feat:
+        f.append("+a17")
+
+    return f
+
+# TARGET_CC_ARCH changes from build/cross/target so it'll do the right thing
+# this should go away when https://github.com/rust-lang/rust/pull/31709 is
+# stable (1.9.0?)
+def llvm_features_from_cc_arch(d):
+    f = []
+    feat = d.getVar('TARGET_CC_ARCH')
+    if not feat:
+        return []
+    feat = frozenset(feat.split())
+
+    if '-mmmx' in feat:
+        f.append("+mmx")
+    if '-msse' in feat:
+        f.append("+sse")
+    if '-msse2' in feat:
+        f.append("+sse2")
+    if '-msse3' in feat:
+        f.append("+sse3")
+    if '-mssse3' in feat:
+        f.append("+ssse3")
+    if '-msse4.1' in feat:
+        f.append("+sse4.1")
+    if '-msse4.2' in feat:
+        f.append("+sse4.2")
+    if '-msse4a' in feat:
+        f.append("+sse4a")
+    if '-mavx' in feat:
+        f.append("+avx")
+    if '-mavx2' in feat:
+        f.append("+avx2")
+
+    return f
+
+def llvm_features_from_target_fpu(d):
+    # TARGET_FPU can be hard or soft. +soft-float tell llvm to use soft float
+    # ABI. There is no option for hard.
+
+    fpu = d.getVar('TARGET_FPU', True)
+    return ["+soft-float"] if fpu == "soft" else []
+
+def llvm_features(d):
+    return ','.join(llvm_features_from_tune(d) +
+                    llvm_features_from_cc_arch(d) +
+                    llvm_features_from_target_fpu(d))
+
+## arm-unknown-linux-gnueabihf
+DATA_LAYOUT[arm] = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+LLVM_TARGET[arm] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[arm] = "little"
+TARGET_POINTER_WIDTH[arm] = "32"
+TARGET_C_INT_WIDTH[arm] = "32"
+MAX_ATOMIC_WIDTH[arm] = "64"
+FEATURES[arm] = "+v6,+vfp2"
+
+## aarch64-unknown-linux-{gnu, musl}
+DATA_LAYOUT[aarch64] = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+LLVM_TARGET[aarch64] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[aarch64] = "little"
+TARGET_POINTER_WIDTH[aarch64] = "64"
+TARGET_C_INT_WIDTH[aarch64] = "32"
+MAX_ATOMIC_WIDTH[aarch64] = "128"
+
+## x86_64-unknown-linux-{gnu, musl}
+DATA_LAYOUT[x86_64] = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+LLVM_TARGET[x86_64] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[x86_64] = "little"
+TARGET_POINTER_WIDTH[x86_64] = "64"
+TARGET_C_INT_WIDTH[x86_64] = "32"
+MAX_ATOMIC_WIDTH[x86_64] = "64"
+
+## i686-unknown-linux-{gnu, musl}
+DATA_LAYOUT[i686] = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+LLVM_TARGET[i686] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[i686] = "little"
+TARGET_POINTER_WIDTH[i686] = "32"
+TARGET_C_INT_WIDTH[i686] = "32"
+MAX_ATOMIC_WIDTH[i686] = "64"
+
+## XXX: a bit of a hack so qemux86 builds, clone of i686-unknown-linux-{gnu, musl} above
+DATA_LAYOUT[i586] = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+LLVM_TARGET[i586] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[i586] = "little"
+TARGET_POINTER_WIDTH[i586] = "32"
+TARGET_C_INT_WIDTH[i586] = "32"
+MAX_ATOMIC_WIDTH[i586] = "64"
+
+## mips-unknown-linux-{gnu, musl}
+DATA_LAYOUT[mips] = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+LLVM_TARGET[mips] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[mips] = "big"
+TARGET_POINTER_WIDTH[mips] = "32"
+TARGET_C_INT_WIDTH[mips] = "32"
+MAX_ATOMIC_WIDTH[mips] = "32"
+
+## mipsel-unknown-linux-{gnu, musl}
+DATA_LAYOUT[mipsel] = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+LLVM_TARGET[mipsel] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[mipsel] = "little"
+TARGET_POINTER_WIDTH[mipsel] = "32"
+TARGET_C_INT_WIDTH[mipsel] = "32"
+MAX_ATOMIC_WIDTH[mipsel] = "32"
+
+## mips64-unknown-linux-{gnu, musl}
+DATA_LAYOUT[mips64] = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+LLVM_TARGET[mips64] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[mips64] = "big"
+TARGET_POINTER_WIDTH[mips64] = "64"
+TARGET_C_INT_WIDTH[mips64] = "64"
+MAX_ATOMIC_WIDTH[mips64] = "64"
+
+## mips64el-unknown-linux-{gnu, musl}
+DATA_LAYOUT[mips64el] = "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+LLVM_TARGET[mips64el] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[mips64el] = "little"
+TARGET_POINTER_WIDTH[mips64el] = "64"
+TARGET_C_INT_WIDTH[mips64el] = "64"
+MAX_ATOMIC_WIDTH[mips64el] = "64"
+
+## powerpc-unknown-linux-{gnu, musl}
+DATA_LAYOUT[powerpc] = "E-m:e-p:32:32-i64:64-n32"
+LLVM_TARGET[powerpc] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[powerpc] = "big"
+TARGET_POINTER_WIDTH[powerpc] = "32"
+TARGET_C_INT_WIDTH[powerpc] = "32"
+MAX_ATOMIC_WIDTH[powerpc] = "32"
+
+## riscv32-unknown-linux-{gnu, musl}
+DATA_LAYOUT[riscv32] = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
+LLVM_TARGET[riscv32] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[riscv32] = "little"
+TARGET_POINTER_WIDTH[riscv32] = "32"
+TARGET_C_INT_WIDTH[riscv32] = "32"
+MAX_ATOMIC_WIDTH[riscv32] = "32"
+
+## riscv64-unknown-linux-{gnu, musl}
+DATA_LAYOUT[riscv64] = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
+LLVM_TARGET[riscv64] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[riscv64] = "little"
+TARGET_POINTER_WIDTH[riscv64] = "64"
+TARGET_C_INT_WIDTH[riscv64] = "64"
+MAX_ATOMIC_WIDTH[riscv64] = "64"
+
+def arch_for(d, thing):
+    return d.getVar('{}_ARCH'.format(thing))
+
+def sys_for(d, thing):
+    return d.getVar('{}_SYS'.format(thing))
+
+def prefix_for(d, thing):
+    return d.getVar('{}_PREFIX'.format(thing))
+
+# Convert a normal arch (HOST_ARCH, TARGET_ARCH, BUILD_ARCH, etc) to something
+# rust's internals won't choke on.
+def arch_to_rust_target_arch(arch):
+    if arch == "i586" or arch == "i686":
+        return "x86"
+    elif arch == "mipsel":
+        return "mips"
+    elif arch == "mip64sel":
+        return "mips64"
+    else:
+        return arch
+
+# generates our target CPU value
+def llvm_cpu(d):
+    cpu = d.getVar('PACKAGE_ARCH')
+    target = d.getVar('TRANSLATED_TARGET_ARCH')
+
+    trans = {}
+    trans['corei7-64'] = "corei7"
+    trans['core2-32'] = "core2"
+    trans['x86-64'] = "x86-64"
+    trans['i686'] = "i686"
+    trans['i586'] = "i586"
+    trans['powerpc'] = "powerpc"
+    trans['mips64'] = "mips64"
+    trans['mips64el'] = "mips64"
+
+    if target in ["mips", "mipsel"]:
+        feat = frozenset(d.getVar('TUNE_FEATURES').split())
+        if "mips32r2" in feat:
+            trans['mipsel'] = "mips32r2"
+            trans['mips'] = "mips32r2"
+        elif "mips32" in feat:
+            trans['mipsel'] = "mips32"
+            trans['mips'] = "mips32"
+
+    try:
+        return trans[cpu]
+    except:
+        return trans.get(target, "generic")
+
+TARGET_LLVM_CPU="${@llvm_cpu(d)}"
+TARGET_LLVM_FEATURES = "${@llvm_features(d)}"
+
+# class-native implies TARGET=HOST, and TUNE_FEATURES only describes the real
+# (original) target.
+TARGET_LLVM_FEATURES_class-native = "${@','.join(llvm_features_from_cc_arch(d))}"
+
+def rust_gen_target(d, thing, wd):
+    import json
+    from distutils.version import LooseVersion
+    arch = arch_for(d, thing)
+    sys = sys_for(d, thing)
+    prefix = prefix_for(d, thing)
+
+    features = ""
+    cpu = "generic"
+    if thing is "TARGET":
+        features = d.getVar('TARGET_LLVM_FEATURES') or ""
+        cpu = d.getVar('TARGET_LLVM_CPU')
+    features = features or d.getVarFlag('FEATURES', arch) or ""
+    features = features.strip()
+
+    # build tspec
+    tspec = {}
+    tspec['llvm-target'] = d.getVarFlag('LLVM_TARGET', arch)
+    tspec['data-layout'] = d.getVarFlag('DATA_LAYOUT', arch)
+    tspec['max-atomic-width'] = d.getVarFlag('MAX_ATOMIC_WIDTH', arch)
+    tspec['target-pointer-width'] = d.getVarFlag('TARGET_POINTER_WIDTH', arch)
+    tspec['target-c-int-width'] = d.getVarFlag('TARGET_C_INT_WIDTH', arch)
+    tspec['target-endian'] = d.getVarFlag('TARGET_ENDIAN', arch)
+    tspec['arch'] = arch_to_rust_target_arch(arch)
+    tspec['os'] = "linux"
+    if "musl" in tspec['llvm-target']:
+        tspec['env'] = "musl"
+    else:
+        tspec['env'] = "gnu"
+    tspec['vendor'] = "unknown"
+    tspec['target-family'] = "unix"
+    tspec['linker'] = "{}{}gcc".format(d.getVar('CCACHE'), prefix)
+    tspec['ar'] = "{}ar".format(prefix)
+    tspec['cpu'] = cpu
+    if features is not "":
+        tspec['features'] = features
+    tspec['dynamic-linking'] = True
+    tspec['executables'] = True
+    tspec['linker-is-gnu'] = True
+    tspec['linker-flavor'] = "gcc"
+    tspec['has-rpath'] = True
+    tspec['has-elf-tls'] = True
+    tspec['position-independent-executables'] = True
+    tspec['panic-strategy'] = d.getVar("RUST_PANIC_STRATEGY")
+
+    # Don't use jemalloc as it doesn't work for many targets.
+    # https://github.com/rust-lang/rust/pull/37392
+    # From 1.20.0 and forward, system allocator is the default.
+    if LooseVersion(d.getVar("PV")) < LooseVersion("1.20.0"):
+        tspec['exe-allocation-crate'] = "alloc_system"
+        tspec['lib-allocation-crate'] = "alloc_system"
+
+    # write out the target spec json file
+    with open(wd + sys + '.json', 'w') as f:
+        json.dump(tspec, f, indent=4)
+
+
+python do_rust_gen_targets () {
+    wd = d.getVar('WORKDIR') + '/targets/'
+    # It is important 'TARGET' is last here so that it overrides our less
+    # informed choices for BUILD & HOST if TARGET happens to be the same as
+    # either of them.
+    for thing in ['BUILD', 'HOST', 'TARGET']:
+        bb.debug(1, "rust_gen_target for " + thing)
+        rust_gen_target(d, thing, wd)
+}
+addtask rust_gen_targets after do_patch before do_compile
+do_rust_gen_targets[dirs] += "${WORKDIR}/targets"
+
+
+do_rust_setup_snapshot () {
+    for installer in "${WORKDIR}/rust-snapshot-components/"*"/install.sh"; do
+        "${installer}" --prefix="${WORKDIR}/rust-snapshot" --disable-ldconfig
+    done
+
+    # Some versions of rust (e.g. 1.18.0) tries to find cargo in stage0/bin/cargo
+    # and fail without it there.
+    mkdir -p ${RUSTSRC}/build/${BUILD_SYS}
+    ln -sf ${WORKDIR}/rust-snapshot/ ${RUSTSRC}/build/${BUILD_SYS}/stage0
+}
+addtask rust_setup_snapshot after do_unpack before do_configure
+do_rust_setup_snapshot[dirs] += "${WORKDIR}/rust-snapshot"
+
+
+python do_configure() {
+    import json
+    from distutils.version import LooseVersion
+    try:
+        import configparser
+    except ImportError:
+        import ConfigParser as configparser
+
+    # toml is rather similar to standard ini like format except it likes values
+    # that look more JSON like. So for our purposes simply escaping all values
+    # as JSON seem to work fine.
+
+    e = lambda s: json.dumps(s)
+
+    config = configparser.RawConfigParser()
+
+    # [target.ARCH-poky-linux]
+    target_section = "target.{}".format(d.getVar('TARGET_SYS', True))
+    config.add_section(target_section)
+
+    llvm_config = d.expand("${YOCTO_ALTERNATE_EXE_PATH}")
+    config.set(target_section, "llvm-config", e(llvm_config))
+
+    config.set(target_section, "cxx", e(d.expand("${RUST_TARGET_CXX}")))
+    config.set(target_section, "cc", e(d.expand("${RUST_TARGET_CC}")))
+
+    # If we don't do this rust-native will compile it's own llvm for BUILD.
+    # [target.${BUILD_ARCH}-unknown-linux-gnu]
+    target_section = "target.{}".format(d.getVar('SNAPSHOT_BUILD_SYS', True))
+    config.add_section(target_section)
+
+    config.set(target_section, "llvm-config", e(llvm_config))
+
+    config.set(target_section, "cxx", e(d.expand("${RUST_BUILD_CXX}")))
+    config.set(target_section, "cc", e(d.expand("${RUST_BUILD_CC}")))
+
+    # [rust]
+    config.add_section("rust")
+    config.set("rust", "rpath", e(True))
+    config.set("rust", "channel", e("stable"))
+
+    if LooseVersion(d.getVar("PV")) < LooseVersion("1.32.0"):
+        config.set("rust", "use-jemalloc", e(False))
+
+    # Whether or not to optimize the compiler and standard library
+    config.set("rust", "optimize", e(True))
+
+    # [build]
+    config.add_section("build")
+    config.set("build", "submodules", e(False))
+    config.set("build", "docs", e(False))
+
+    rustc = d.expand("${WORKDIR}/rust-snapshot/bin/rustc")
+    config.set("build", "rustc", e(rustc))
+
+    cargo = d.expand("${WORKDIR}/rust-snapshot/bin/cargo")
+    config.set("build", "cargo", e(cargo))
+
+    config.set("build", "vendor", e(True))
+
+    targets = [d.getVar("TARGET_SYS", True)]
+    config.set("build", "target", e(targets))
+
+    hosts = [d.getVar("HOST_SYS", True)]
+    config.set("build", "host", e(targets))
+
+    # We can't use BUILD_SYS since that is something the rust snapshot knows
+    # nothing about when trying to build some stage0 tools (like fabricate)
+    config.set("build", "build", e(d.getVar("SNAPSHOT_BUILD_SYS", True)))
+
+    with open("config.toml", "w") as f:
+        config.write(f)
+
+    # set up ${WORKDIR}/cargo_home
+    bb.build.exec_func("setup_cargo_environment", d)
+}
+
+
+rust_runx () {
+    echo "COMPILE ${PN}" "$@"
+
+    # CFLAGS, LDFLAGS, CXXFLAGS, CPPFLAGS are used by rust's build for a
+    # wide range of targets (not just TARGET). Yocto's settings for them will
+    # be inappropriate, avoid using.
+    unset CFLAGS
+    unset LDFLAGS
+    unset CXXFLAGS
+    unset CPPFLAGS
+
+    oe_cargo_fix_env
+
+    python src/bootstrap/bootstrap.py "$@" --verbose
+}
+
+do_compile () {
+    rust_runx build
+    rust_runx dist
+}
+
+rust_do_install () {
+    # Only install compiler generated for the HOST_SYS. There will be
+    # one for SNAPSHOT_BUILD_SYS as well.
+    local installer=build/tmp/dist/rustc-${PV}-${HOST_SYS}/install.sh
+    ${installer} --destdir="${D}" --prefix="${prefix}" --disable-ldconfig
+
+    installer=build/tmp/dist/rust-std-${PV}-${HOST_SYS}/install.sh
+    ${installer} --destdir="${D}" --prefix="${prefix}" --disable-ldconfig
+
+    # Install our custom target.json files
+    local td="${D}${libdir}/rustlib/"
+    install -d "$td"
+    for tgt in "${WORKDIR}/targets/"* ; do
+        install -m 0644 "$tgt" "$td"
+    done
+
+    # cleanup after rust-installer since we don't need these bits
+    rm ${D}/${libdir}/rustlib/install.log
+    rm ${D}/${libdir}/rustlib/rust-installer-version
+    rm ${D}/${libdir}/rustlib/uninstall.sh
+    rm ${D}/${libdir}/rustlib/components
+}
+
+
+do_install () {
+    rust_do_install
+}
+# ex: sts=4 et sw=4 ts=8
diff --git a/meta/recipes-devtools/rust/rust_1.34.2.bb b/meta/recipes-devtools/rust/rust_1.34.2.bb
new file mode 100644
index 0000000000..c7f9f4fd87
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust_1.34.2.bb
@@ -0,0 +1,12 @@
+require rust.inc
+require rust-source-${PV}.inc
+require rust-snapshot-${PV}.inc
+
+DEPENDS += "rust-llvm (=${PV})"
+
+# Otherwise we'll depend on what we provide
+INHIBIT_DEFAULT_RUST_DEPS_class-native = "1"
+# We don't need to depend on gcc-native because yocto assumes it exists
+PROVIDES_class-native = "virtual/${TARGET_PREFIX}rust"
+
+BBCLASSEXTEND = "native"
diff --git a/meta/recipes-devtools/rust/rust_1.36.0.bb b/meta/recipes-devtools/rust/rust_1.36.0.bb
new file mode 100644
index 0000000000..c7f9f4fd87
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust_1.36.0.bb
@@ -0,0 +1,12 @@
+require rust.inc
+require rust-source-${PV}.inc
+require rust-snapshot-${PV}.inc
+
+DEPENDS += "rust-llvm (=${PV})"
+
+# Otherwise we'll depend on what we provide
+INHIBIT_DEFAULT_RUST_DEPS_class-native = "1"
+# We don't need to depend on gcc-native because yocto assumes it exists
+PROVIDES_class-native = "virtual/${TARGET_PREFIX}rust"
+
+BBCLASSEXTEND = "native"
diff --git a/meta/recipes-devtools/rust/rust_1.37.0.bb b/meta/recipes-devtools/rust/rust_1.37.0.bb
new file mode 100644
index 0000000000..c7f9f4fd87
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust_1.37.0.bb
@@ -0,0 +1,12 @@
+require rust.inc
+require rust-source-${PV}.inc
+require rust-snapshot-${PV}.inc
+
+DEPENDS += "rust-llvm (=${PV})"
+
+# Otherwise we'll depend on what we provide
+INHIBIT_DEFAULT_RUST_DEPS_class-native = "1"
+# We don't need to depend on gcc-native because yocto assumes it exists
+PROVIDES_class-native = "virtual/${TARGET_PREFIX}rust"
+
+BBCLASSEXTEND = "native"
diff --git a/meta/recipes-example/rust-hello-world/rust-hello-world_git.bb b/meta/recipes-example/rust-hello-world/rust-hello-world_git.bb
new file mode 100644
index 0000000000..ba8854849d
--- /dev/null
+++ b/meta/recipes-example/rust-hello-world/rust-hello-world_git.bb
@@ -0,0 +1,13 @@
+inherit cargo
+
+SRC_URI = "git://github.com/jmesmon/rust-hello-world.git;protocol=https"
+SRCREV="e0fa23f1a3cb1eb1407165bd2fc36d2f6e6ad728"
+LIC_FILES_CHKSUM="file://COPYRIGHT;md5=e6b2207ac3740d2d01141c49208c2147"
+
+SUMMARY = "Hello World by Cargo for Rust"
+HOMEPAGE = "https://github.com/jmesmon/rust-hello-world"
+LICENSE = "MIT | Apache-2.0"
+
+S = "${WORKDIR}/git"
+
+BBCLASSEXTEND = "native"
diff --git a/meta/recipes-example/rustfmt/rustfmt_0.8.0.bb b/meta/recipes-example/rustfmt/rustfmt_0.8.0.bb
new file mode 100644
index 0000000000..0c94e38e66
--- /dev/null
+++ b/meta/recipes-example/rustfmt/rustfmt_0.8.0.bb
@@ -0,0 +1,67 @@
+# Auto-Generated by cargo-bitbake 0.3.6
+#
+inherit cargo
+
+# If this is git based prefer versioned ones if they exist
+# DEFAULT_PREFERENCE = "-1"
+
+# how to get rustfmt could be as easy as but default to a git checkout:
+# SRC_URI += "crate://crates.io/rustfmt/0.8.0"
+SRC_URI += "git://github.com/rust-lang-nursery/rustfmt.git;protocol=https;branch=syntex"
+SRCREV = "4ed5a3bac71ed104e27797ee63729b0333e39d39"
+S = "${WORKDIR}/git"
+CARGO_SRC_DIR=""
+
+
+# please note if you have entries that do not begin with crate://
+# you must change them to how that package can be fetched
+SRC_URI += " \
+crate://crates.io/aho-corasick/0.6.2 \
+crate://crates.io/bitflags/0.8.0 \
+crate://crates.io/diff/0.1.10 \
+crate://crates.io/either/1.0.3 \
+crate://crates.io/env_logger/0.4.1 \
+crate://crates.io/getopts/0.2.14 \
+crate://crates.io/itertools/0.5.9 \
+crate://crates.io/kernel32-sys/0.2.2 \
+crate://crates.io/libc/0.2.21 \
+crate://crates.io/log/0.3.6 \
+crate://crates.io/memchr/1.0.1 \
+crate://crates.io/multimap/0.3.0 \
+crate://crates.io/regex-syntax/0.4.0 \
+crate://crates.io/regex/0.2.1 \
+crate://crates.io/rustc-serialize/0.3.22 \
+crate://crates.io/same-file/0.1.3 \
+crate://crates.io/strings/0.0.1 \
+crate://crates.io/syntex_errors/0.58.1 \
+crate://crates.io/syntex_pos/0.58.1 \
+crate://crates.io/syntex_syntax/0.58.1 \
+crate://crates.io/term/0.4.5 \
+crate://crates.io/thread-id/3.0.0 \
+crate://crates.io/thread_local/0.3.3 \
+crate://crates.io/toml/0.2.1 \
+crate://crates.io/unicode-segmentation/1.1.0 \
+crate://crates.io/unicode-xid/0.0.4 \
+crate://crates.io/unreachable/0.1.1 \
+crate://crates.io/utf8-ranges/1.0.0 \
+crate://crates.io/void/1.0.2 \
+crate://crates.io/walkdir/1.0.7 \
+crate://crates.io/winapi-build/0.1.1 \
+crate://crates.io/winapi/0.2.8 \
+"
+
+
+
+LIC_FILES_CHKSUM=" \
+file://LICENSE-APACHE;md5=1836efb2eb779966696f473ee8540542 \
+file://LICENSE-MIT;md5=0b29d505d9225d1f0815cbdcf602b901 \
+"
+
+SUMMARY = "Tool to find and fix Rust formatting issues"
+HOMEPAGE = "https://github.com/rust-lang-nursery/rustfmt"
+LICENSE = "Apache-2.0 | MIT"
+
+# includes this file if it exists but does not fail
+# this is useful for anything you may want to override from
+# what cargo-bitbake generates.
+include rustfmt.inc
diff --git a/scripts/build.sh b/scripts/build.sh
new file mode 100755
index 0000000000..cfff7c1ba8
--- /dev/null
+++ b/scripts/build.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# Grab the MACHINE from the environment; otherwise, set it to a sane default
+export MACHINE="${MACHINE-qemux86-64}"
+
+# What to build
+BUILD_TARGETS="\
+    rustfmt \
+    "
+
+die() {
+    echo "$*" >&2
+    exit 1
+}
+
+rm -f build/conf/bblayers.conf || die "failed to nuke bblayers.conf"
+rm -f build/conf/local.conf || die "failed to nuke local.conf"
+
+./scripts/containerize.sh bitbake ${BUILD_TARGETS} || die "failed to build"
diff --git a/scripts/cleanup-env.sh b/scripts/cleanup-env.sh
new file mode 100755
index 0000000000..d2d57295b2
--- /dev/null
+++ b/scripts/cleanup-env.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -x
+
+sudo fuser -m `pwd`/build
+
+# Only attempt to unmount if the directory is already mounted
+if mountpoint -q `pwd`/build; then
+    sudo umount `pwd`/build
+fi
+
+sudo fuser -m `pwd`/build
+
+ps -ef
+
+exit 0
diff --git a/scripts/containerize.sh b/scripts/containerize.sh
new file mode 100755
index 0000000000..9e28453a0a
--- /dev/null
+++ b/scripts/containerize.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# what container are we using to build this
+CONTAINER="cardoe/yocto:pyro"
+
+einfo() {
+	echo "$*" >&2
+}
+
+die() {
+    echo "$*" >&2
+    exit 1
+}
+
+# Save the commands for future use
+cmd=$@
+
+# If no command was specified, just drop us into a shell if we're interactive
+[ $# -eq 0 ] && tty -s && cmd="/bin/bash"
+
+# user and group we are running as to ensure files created inside
+# the container retain the same permissions
+my_uid=$(id -u)
+my_gid=$(id -g)
+
+# Are we in an interactive terminal?
+tty -s && termint=t
+
+# Fetch the latest version of the container
+einfo "*** Ensuring local container is up to date"
+docker pull ${CONTAINER} > /dev/null || die "Failed to update docker container"
+
+# Ensure we've got what we need for SSH_AUTH_SOCK
+if [[ -n ${SSH_AUTH_SOCK} ]]; then
+	SSH_AUTH_DIR=$(dirname $(readlink -f ${SSH_AUTH_SOCK}))
+	SSH_AUTH_NAME=$(basename ${SSH_AUTH_SOCK})
+fi
+
+# Kick off Docker
+einfo "*** Launching container ..."
+exec docker run \
+    --privileged \
+    -e BUILD_UID=${my_uid} \
+    -e BUILD_GID=${my_gid} \
+    -e TEMPLATECONF=meta-rust/conf \
+    -e MACHINE=${MACHINE:-qemux86-64} \
+    ${SSH_AUTH_SOCK:+-e SSH_AUTH_SOCK="/tmp/ssh-agent/${SSH_AUTH_NAME}"} \
+    -v ${HOME}/.ssh:/var/build/.ssh \
+    -v "${PWD}":/var/build:rw \
+    ${SSH_AUTH_SOCK:+-v "${SSH_AUTH_DIR}":/tmp/ssh-agent} \
+    ${EXTRA_CONTAINER_ARGS} \
+    -${termint}i --rm -- \
+    ${CONTAINER} \
+    ${cmd}
diff --git a/scripts/fetch.sh b/scripts/fetch.sh
new file mode 100755
index 0000000000..f8639a94af
--- /dev/null
+++ b/scripts/fetch.sh
@@ -0,0 +1,103 @@
+#!/bin/bash -x
+
+# default repo
+if [[ $# -lt 1 ]]; then
+    echo "No Yocto branch specified, defaulting to master"
+    echo "To change this pass a Yocto branch name as an argument to this script"
+fi
+branch=${1-master}
+
+# the repos we want to check out, must setup variables below
+# NOTE: poky must remain first
+REPOS="poky metaoe"
+
+POKY_URI="git://git.yoctoproject.org/poky.git"
+POKY_PATH="poky"
+POKY_REV="${POKY_REV-refs/remotes/origin/${branch}}"
+
+METAOE_URI="git://git.openembedded.org/meta-openembedded.git"
+METAOE_PATH="poky/meta-openembedded"
+METAOE_REV="${METAOE_REV-refs/remotes/origin/${branch}}"
+
+METARUST_URI="."
+METARUST_PATH="poky/meta-rust"
+
+die() {
+	echo "$*" >&2
+	exit 1
+}
+
+update_repo() {
+	uri=$1
+	path=$2
+	rev=$3
+
+	# check if we already have it checked out, if so we just want to update
+	if [[ -d ${path} ]]; then
+		pushd ${path} > /dev/null
+		echo "Updating '${path}'"
+		git remote set-url origin "${uri}"
+		git fetch origin || die "unable to fetch ${uri}"
+	else
+		echo "Cloning '${path}'"
+		if [ -d "${GIT_LOCAL_REF_DIR}" ]; then
+			git clone --reference ${GIT_LOCAL_REF_DIR}/`basename ${path}` \
+				${uri} ${path} || die "unable to clone ${uri}"
+		else
+			git clone ${uri} ${path} || die "unable to clone ${uri}"
+		fi
+		pushd ${path} > /dev/null
+	fi
+
+	# The reset steps are taken from Jenkins
+
+	# Reset
+	# * drop -d from clean to not nuke build/tmp
+	# * add -e to not clear out bitbake bits
+	git reset --hard || die "failed reset"
+	git clean -fx -e bitbake -e meta/lib/oe || die "failed clean"
+
+	# Call the branch what we're basing it on, otherwise use default
+	# if the revision was not a branch.
+	branch=$(basename ${rev})
+	[[ "${branch}" == "${rev}" ]] && branch="default"
+
+	# Create 'default' branch
+	git update-ref refs/heads/${branch} ${rev} || \
+		die "unable to get ${rev} of ${uri}"
+	git config branch.${branch}.remote origin || die "failed config remote"
+	git config branch.${branch}.merge ${rev} || die "failed config merge"
+	git symbolic-ref HEAD refs/heads/${branch} || die "failed symbolic-ref"
+	git reset --hard || die "failed reset"
+	popd > /dev/null
+	echo "Updated '${path}' to '${rev}'"
+}
+
+# For each repo, do the work
+for repo in ${REPOS}; do
+	# upper case the name
+	repo=$(echo ${repo} | tr '[:lower:]' '[:upper:]')
+
+	# expand variables
+	expand_uri="${repo}_URI"
+	expand_path="${repo}_PATH"
+	expand_rev="${repo}_REV"
+	repo_uri=${!expand_uri}
+	repo_path=${!expand_path}
+	repo_rev=${!expand_rev}
+
+	# check that we've got data
+	[[ -z ${repo_uri} ]] && die "No revision defined in ${expand_uri}"
+	[[ -z ${repo_path} ]] && die "No revision defined in ${expand_path}"
+	[[ -z ${repo_rev} ]] && die "No revision defined in ${expand_rev}"
+
+	# now fetch/clone/update repo
+	update_repo "${repo_uri}" "${repo_path}" "${repo_rev}"
+
+done
+
+rm -rf "${METARUST_PATH}" || die "unable to clear old ${METARUST_PATH}"
+ln -sf "../${METARUST_URI}" "${METARUST_PATH}" || \
+	die "unable to symlink ${METARUST_PATH}"
+
+exit 0
diff --git a/scripts/publish-build-cache.sh b/scripts/publish-build-cache.sh
new file mode 100755
index 0000000000..e3a0a1829a
--- /dev/null
+++ b/scripts/publish-build-cache.sh
@@ -0,0 +1,13 @@
+#!/bin/bash -x
+
+if [[ $# -lt 1 ]]; then
+    echo "No Yocto branch specified, defaulting to master"
+    echo "To change this pass a Yocto branch name as an argument to this script"
+fi
+branch=${1-master}
+
+rsync -avz -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress build/downloads yocto-cache@build-cache.asterius.io:/srv/yocto-cache/
+
+rsync -avz -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress build/sstate-cache yocto-cache@build-cache.asterius.io:/srv/yocto-cache/${branch}/
+
+exit 0
diff --git a/scripts/setup-env.sh b/scripts/setup-env.sh
new file mode 100755
index 0000000000..dbed06111b
--- /dev/null
+++ b/scripts/setup-env.sh
@@ -0,0 +1,12 @@
+#!/bin/bash -e
+
+mkdir -p build
+
+total_mem=`grep MemTotal /proc/meminfo | awk '{print $2}'`
+
+# Only have the slaves with large amounts of RAM mount the tmpfs
+if [ "$total_mem" -ge "67108864" ]; then
+    sudo mount -t tmpfs -o size=64G,mode=755,uid=${UID} tmpfs build
+fi
+
+exit 0
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/8] rust: mv README.md to recipes-devtools/rust/README-rust.md
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
                   ` (3 preceding siblings ...)
  2021-02-24  3:01 ` [PATCH 4/8] meta-rust: move code to oe-core from meta-rust layer Randy MacLeod
@ 2021-02-24  3:01 ` Randy MacLeod
  2021-02-24  3:01 ` [PATCH 6/8] meta-rust: merge commits Randy MacLeod
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:01 UTC (permalink / raw)
  To: openembedded-core

Import the meta-rust/README.md but relocate and rename it.

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
---
 meta/recipes-devtools/rust/README-rust.md | 69 +++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 meta/recipes-devtools/rust/README-rust.md

diff --git a/meta/recipes-devtools/rust/README-rust.md b/meta/recipes-devtools/rust/README-rust.md
new file mode 100644
index 0000000000..329d59ab7b
--- /dev/null
+++ b/meta/recipes-devtools/rust/README-rust.md
@@ -0,0 +1,69 @@
+## Introduction
+
+This OpenEmbedded layer provides the rust compiler, tools for building packages
+(cargo), and a few example projects.
+
+## What works:
+
+ - Building `rust-native` and `cargo-native`
+ - Building Rust based projects with Cargo for the TARGET
+   - e.g. `rustfmt` which is used by the CI system
+ - `-buildsdk` and `-crosssdk` packages
+
+## What doesn't:
+
+ - Using anything but x86_64 as the build environment
+ - rust (built for target) issue #81
+
+## What's untested:
+
+ - cargo (built for target)
+
+## Building a rust package
+
+When building a rust package in bitbake, it's usually easiest to build with
+cargo using cargo.bbclass.  If the package already has a Cargo.toml file (most
+rust packages do), then it's especially easy.  Otherwise you should probably
+get the code building in cargo first.
+
+Once your package builds in cargo, you can use
+[cargo-bitbake](https://github.com/cardoe/cargo-bitbake) to generate a bitbake
+recipe for it.  This allows bitbake to fetch all the necessary dependent
+crates, as well as a pegged version of the crates.io index, to ensure maximum
+reproducibility.
+
+NOTE: You will have to edit the generated recipe based on the comments
+contained within it
+
+## TODO
+
+## Pitfalls
+
+ - TARGET_SYS _must_ be different from BUILD_SYS. This is due to the way Rust configuration options are tracked for different targets. This is the reason we use the Yocto triples instead of the native Rust triples. See rust-lang/cargo#3349.
+
+## Dependencies
+
+On the host:
+ - Any `-sys` packages your project might need must have RDEPENDs for
+ the native library.
+
+On the target:
+ - Any `-sys` packages your project might need must have RDEPENDs for
+ the native library.
+
+## Maintainer(s) & Patch policy
+
+Open a Pull Request.
+
+The master branch supports the latest master of poky. When poky creates releases, we will create a branch with the same name as the poky release. This release branch should always work with that poky release. Note that these release branches will typically be less tested than the master branch.
+
+All new patches against rust, rust-llvm, and cargo must have referenced
+upstream issues or PRs opened or an explanation why the patch cannot be
+upstreamed. This cooresponds to the OpenEmbedded policy for other meta layers.
+
+More info can be seen on the wiki.
+
+## Copyright
+
+MIT OR Apache-2.0 - Same as rust
+
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/8] meta-rust: merge commits
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
                   ` (4 preceding siblings ...)
  2021-02-24  3:01 ` [PATCH 5/8] rust: mv README.md to recipes-devtools/rust/README-rust.md Randy MacLeod
@ 2021-02-24  3:01 ` Randy MacLeod
  2021-02-24  3:02 ` [PATCH 7/8] cargo/rust/rustfmt: exclude from world Randy MacLeod
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:01 UTC (permalink / raw)
  To: openembedded-core

Merge most of:
  git log --oneline --no-merges 5cda04c..029f1ea
with two layer.conf exceptions explained below.

920328c rust-native shouldn't depend on TARGET variables
4e96013 Factor in `CARGO_SRC_DIR` when setting `MANIFEST_PATH`.
87e8d50 Keep only the most recent two Rust versions.
53c9aab rust: Drop v8.1a tune for aarch64
7feed5d recipes-example/rust-hello-world: move to new url in meta-rust org
1b94401 readme: fix url and link issue number
26609f4 rust.inc: use 'v8.1a' feature when building for aarch64 instead of 'v8'
71538c8 rust_versions.inc: switch the default version to 1.49.0
c976184 {cargo,rust}-1.49.0: simplify as in https://github.com/meta-rust/meta-rust/pull/299
0025ceb Fix *-native cargo builds
3ab7542 rust-source, rust-snaphost: drop md5sums
b163a89 rust-source, rust-snapshot: simplify as well
0ee328a add rust 1.49.0
3e73030 rust-target.inc: add new include file to simplify all rust_*.bb
9c0a105 rust_versions.inc: add include for easy switching between versions
a31a407 cargo: move LIC_FILES_CHKSUM from cargo_*.bb to cargo.inc where LICENSE is set
1d64f90 rust: move LIC_FILES_CHKSUM from rust-source-*.inc to rust.inc where LICENSE is set
80c30c3 rust-llvm-ncsa.inc: reorder to actually set LICENSE and LIC_FILES_CHKSUM
1cb40bd Revert "rust-llvm: Use early variable assignment for the license checksum in rust-llvm.inc"
d5ab20d rust-hello-world: enable LTO in the build
b7eacc0 libstd-rs: embed bitcode for LTO
1936904 cargo: Mark the cargo-native dependency specific to target
5dda6c4 rust-llvm: Use early variable assignment for the license checksum in rust-llvm.inc
47de35e libstd-rs: Remove libunwind on riscv
e297948 rust: Add riscv32/riscv64 support
a679b6f rust: Build rust backend
a59ddd9 rust: Correct the data layout for riscv32
e5ee880 cargo_common: Make output more readable
a673320 cargo: Enable build separation
cb4f829 Use proper llvm-target for armv7
4b151fa add rust 1.47.0
8cfc3c9 clean up some common definitions across rust versions
aec6519 cargo: add missing version 1.46.0
7afffa0 rust-bin.bbclass: Do not use append and += together
2822b50 layer.conf: Add gatesgarth to LAYERSERIES_COMPAT
    skip the layer compat change but keep
    rust-llvm.inc: export YOCTO_ALTERNATE_EXE_PATH
8a44bae Disable LIBGIT2_SYS_USE_PKG_CONFIG due to incompatibility with 0.28.x
b7f9c1d Add rust 1.46.0
647b976 rust: use PARALLEL_MAKE instead of BB_NUMBER_THREADS
8d3f79f rust.inc: whitelist BB_NUMBER_THREADS in do_compile
2c7321d Bump to Rust version 1.43
b84c61e Revert "cargo: fix progress output"
dd0fc89 cargo: fix progress output
afcb58e rust.inc: cut build time in half
40a6bd8 rust.inc: run bootstrap.py in parallel
c023edd rust.inc: make max-atomic-width an integer
3b78365 rust-native shouldn't depend on TARGET variables
8ef8b39 rustfmt: Upgrade to 1.4.2
e4d25b9 layer.conf: Mark it 3.1 release compatible
    skip the layer compat change so this commit was omitted
ea97549 Avoid extra sh process from shell wrapper
4a763a2 Update 0001-Disable-http2.patch for cargo 1.41.0
5c7f51b Update to Rust 1.41.0
837b635 cargo: Refresh http2 disable patch
2668f6a Update 0001-Disable-http2.patch for Cargo shipped with Rust 1.40.0
e5c2a40 Update to Rust and Cargo 1.40.0.
72aa4ef rust: Use Python3 native for build
186ec59 rust: Improve TUNE_FEATURE parsing
71895ec Update to Rust and Cargo 1.39.0

Signed-off-by: Randy Macleod <randy.macleod@windriver.com>
---
 meta/classes/cargo.bbclass                    |  13 +-
 meta/classes/cargo_common.bbclass             |  63 +++++--
 meta/classes/rust-bin.bbclass                 |   2 +-
 meta/classes/rust-common.bbclass              |  27 ++-
 meta/conf/distro/include/rust_versions.inc    |  13 ++
 .../cargo-1.37.0/0001-Disable-http2.patch     |  29 ---
 .../0001-Disable-http2.patch                  |  22 +--
 .../0001-Disable-http2.patch                  |  24 +--
 meta/recipes-devtools/cargo/cargo.inc         |  18 +-
 meta/recipes-devtools/cargo/cargo_1.34.2.bb   |   8 -
 meta/recipes-devtools/cargo/cargo_1.36.0.bb   |   8 -
 meta/recipes-devtools/cargo/cargo_1.37.0.bb   |   8 -
 meta/recipes-devtools/cargo/cargo_1.47.0.bb   |   3 +
 meta/recipes-devtools/cargo/cargo_1.49.0.bb   |   3 +
 meta/recipes-devtools/rust/README-rust.md     |   6 +-
 meta/recipes-devtools/rust/libstd-rs.inc      |   9 +
 .../recipes-devtools/rust/libstd-rs_1.34.2.bb |   8 -
 .../recipes-devtools/rust/libstd-rs_1.36.0.bb |   8 -
 .../recipes-devtools/rust/libstd-rs_1.37.0.bb |   8 -
 .../recipes-devtools/rust/libstd-rs_1.47.0.bb |   5 +
 .../recipes-devtools/rust/libstd-rs_1.49.0.bb |   5 +
 meta/recipes-devtools/rust/rust-cross.inc     |  19 ++
 ...t-cross_1.34.2.bb => rust-cross_1.47.0.bb} |   1 -
 ...t-cross_1.36.0.bb => rust-cross_1.49.0.bb} |   1 -
 meta/recipes-devtools/rust/rust-llvm.inc      |  16 +-
 .../recipes-devtools/rust/rust-llvm_1.34.2.bb |  16 --
 .../recipes-devtools/rust/rust-llvm_1.36.0.bb |  16 --
 .../recipes-devtools/rust/rust-llvm_1.37.0.bb |  16 --
 ...st-cross_1.37.0.bb => rust-llvm_1.47.0.bb} |   3 +-
 .../recipes-devtools/rust/rust-llvm_1.49.0.bb |   2 +
 .../rust/rust-snapshot-1.34.2.inc             |  24 ---
 .../rust/rust-snapshot-1.36.0.inc             |  24 ---
 .../rust/rust-snapshot-1.37.0.inc             |  24 ---
 .../rust/rust-snapshot-1.47.0.inc             |  13 ++
 .../rust/rust-snapshot-1.49.0.inc             |  13 ++
 meta/recipes-devtools/rust/rust-snapshot.inc  |   9 +
 .../rust/rust-source-1.34.2.inc               |  11 --
 .../rust/rust-source-1.36.0.inc               |  11 --
 .../rust/rust-source-1.37.0.inc               |  11 --
 .../rust/rust-source-1.47.0.inc               |   3 +
 .../rust/rust-source-1.49.0.inc               |   3 +
 meta/recipes-devtools/rust/rust-source.inc    |   3 +
 .../rust/{rust_1.36.0.bb => rust-target.inc}  |   2 -
 meta/recipes-devtools/rust/rust.inc           | 105 ++++++-----
 ...-dash-vs-underscore-mismatches-in-op.patch |  75 ++++++++
 meta/recipes-devtools/rust/rust_1.34.2.bb     |  12 --
 meta/recipes-devtools/rust/rust_1.37.0.bb     |  12 --
 meta/recipes-devtools/rust/rust_1.47.0.bb     |   9 +
 meta/recipes-devtools/rust/rust_1.49.0.bb     |  15 ++
 .../rust-hello-world/0001-enable-LTO.patch    |  23 +++
 .../rust-hello-world/rust-hello-world_git.bb  |   8 +-
 meta/recipes-example/rustfmt/rustfmt_0.8.0.bb |  67 -------
 meta/recipes-example/rustfmt/rustfmt_1.4.2.bb | 171 ++++++++++++++++++
 53 files changed, 591 insertions(+), 437 deletions(-)
 create mode 100644 meta/conf/distro/include/rust_versions.inc
 delete mode 100644 meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch
 rename meta/recipes-devtools/cargo/{cargo-1.36.0 => cargo-1.47.0}/0001-Disable-http2.patch (53%)
 rename meta/recipes-devtools/cargo/{cargo-1.34.2 => cargo-1.49.0}/0001-Disable-http2.patch (53%)
 delete mode 100644 meta/recipes-devtools/cargo/cargo_1.34.2.bb
 delete mode 100644 meta/recipes-devtools/cargo/cargo_1.36.0.bb
 delete mode 100644 meta/recipes-devtools/cargo/cargo_1.37.0.bb
 create mode 100644 meta/recipes-devtools/cargo/cargo_1.47.0.bb
 create mode 100644 meta/recipes-devtools/cargo/cargo_1.49.0.bb
 delete mode 100644 meta/recipes-devtools/rust/libstd-rs_1.34.2.bb
 delete mode 100644 meta/recipes-devtools/rust/libstd-rs_1.36.0.bb
 delete mode 100644 meta/recipes-devtools/rust/libstd-rs_1.37.0.bb
 create mode 100644 meta/recipes-devtools/rust/libstd-rs_1.47.0.bb
 create mode 100644 meta/recipes-devtools/rust/libstd-rs_1.49.0.bb
 rename meta/recipes-devtools/rust/{rust-cross_1.34.2.bb => rust-cross_1.47.0.bb} (98%)
 rename meta/recipes-devtools/rust/{rust-cross_1.36.0.bb => rust-cross_1.49.0.bb} (98%)
 delete mode 100644 meta/recipes-devtools/rust/rust-llvm_1.34.2.bb
 delete mode 100644 meta/recipes-devtools/rust/rust-llvm_1.36.0.bb
 delete mode 100644 meta/recipes-devtools/rust/rust-llvm_1.37.0.bb
 rename meta/recipes-devtools/rust/{rust-cross_1.37.0.bb => rust-llvm_1.47.0.bb} (55%)
 create mode 100644 meta/recipes-devtools/rust/rust-llvm_1.49.0.bb
 delete mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc
 delete mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc
 delete mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.47.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-snapshot-1.49.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-snapshot.inc
 delete mode 100644 meta/recipes-devtools/rust/rust-source-1.34.2.inc
 delete mode 100644 meta/recipes-devtools/rust/rust-source-1.36.0.inc
 delete mode 100644 meta/recipes-devtools/rust/rust-source-1.37.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-source-1.47.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-source-1.49.0.inc
 create mode 100644 meta/recipes-devtools/rust/rust-source.inc
 rename meta/recipes-devtools/rust/{rust_1.36.0.bb => rust-target.inc} (82%)
 create mode 100644 meta/recipes-devtools/rust/rust/0001-rustc_target-Fix-dash-vs-underscore-mismatches-in-op.patch
 delete mode 100644 meta/recipes-devtools/rust/rust_1.34.2.bb
 delete mode 100644 meta/recipes-devtools/rust/rust_1.37.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust_1.47.0.bb
 create mode 100644 meta/recipes-devtools/rust/rust_1.49.0.bb
 create mode 100644 meta/recipes-example/rust-hello-world/rust-hello-world/0001-enable-LTO.patch
 delete mode 100644 meta/recipes-example/rustfmt/rustfmt_0.8.0.bb
 create mode 100644 meta/recipes-example/rustfmt/rustfmt_1.4.2.bb

diff --git a/meta/classes/cargo.bbclass b/meta/classes/cargo.bbclass
index c321e6bf70..c2eee101bd 100644
--- a/meta/classes/cargo.bbclass
+++ b/meta/classes/cargo.bbclass
@@ -15,16 +15,23 @@ BASEDEPENDS_append = " cargo-native"
 DEPENDS_append_class-target = " virtual/${TARGET_PREFIX}rust ${RUSTLIB_DEP}"
 DEPENDS_append_class-native = " rust-native"
 
-# Cargo only supports in-tree builds at the moment
-B = "${S}"
+# Enable build separation
+B = "${WORKDIR}/build"
 
 # In case something fails in the build process, give a bit more feedback on
 # where the issue occured
 export RUST_BACKTRACE = "1"
 
+# The directory of the Cargo.toml relative to the root directory, per default
+# assume there's a Cargo.toml directly in the root directory
+CARGO_SRC_DIR ??= ""
+
+# The actual path to the Cargo.toml
+MANIFEST_PATH ??= "${S}/${CARGO_SRC_DIR}/Cargo.toml"
+
 RUSTFLAGS ??= ""
 BUILD_MODE = "${@['--release', ''][d.getVar('DEBUG_BUILD') == '1']}"
-CARGO_BUILD_FLAGS = "-v --target ${HOST_SYS} ${BUILD_MODE}"
+CARGO_BUILD_FLAGS = "-v --target ${HOST_SYS} ${BUILD_MODE} --manifest-path=${MANIFEST_PATH}"
 
 # This is based on the content of CARGO_BUILD_FLAGS and generally will need to
 # change if CARGO_BUILD_FLAGS changes.
diff --git a/meta/classes/cargo_common.bbclass b/meta/classes/cargo_common.bbclass
index e5f908033d..5ed99b881b 100644
--- a/meta/classes/cargo_common.bbclass
+++ b/meta/classes/cargo_common.bbclass
@@ -30,48 +30,71 @@ CARGO_VENDORING_DIRECTORY ?= "${CARGO_HOME}/bitbake"
 
 cargo_common_do_configure () {
 	mkdir -p ${CARGO_HOME}/bitbake
-	echo "paths = [" > ${CARGO_HOME}/config
 
-	for p in ${EXTRA_OECARGO_PATHS}; do
-		printf "\"%s\"\n" "$p"
-	done | sed -e 's/$/,/' >> ${CARGO_HOME}/config
-	echo "]" >> ${CARGO_HOME}/config
+	cat <<- EOF > ${CARGO_HOME}/config
+	# EXTRA_OECARGO_PATHS
+	paths = [
+	$(for p in ${EXTRA_OECARGO_PATHS}; do echo \"$p\",; done)
+	]
+	EOF
 
-	# Point cargo at our local mirror of the registry
 	cat <<- EOF >> ${CARGO_HOME}/config
+
+	# Local mirror vendored by bitbake
 	[source.bitbake]
 	directory = "${CARGO_VENDORING_DIRECTORY}"
 	EOF
 
 	if [ -z "${EXTERNALSRC}" ] && [ ${CARGO_DISABLE_BITBAKE_VENDORING} = "0" ]; then
 		cat <<- EOF >> ${CARGO_HOME}/config
+
 		[source.crates-io]
 		replace-with = "bitbake"
 		local-registry = "/nonexistant"
 		EOF
 	fi
 
-        # Disable multiplexing in order to keep cargo from using http2, which we
-        # can't currently enable because of dependency loops
-        cat <<- EOF >> ${CARGO_HOME}/config
-		[http]
-		multiplexing = false
-	EOF
+	cat <<- EOF >> ${CARGO_HOME}/config
 
-	# When a sstate-cache is used sometimes the certificates are not available
-	# at the compile time path anymore. Set it explicitly instead.
-	echo "cainfo = \"${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt\"" \
-		>> ${CARGO_HOME}/config
+	[http]
+	# Multiplexing can't be enabled because http2 can't be enabled
+	# in curl-native without dependency loops
+	multiplexing = false
+
+	# Ignore the hard coded and incorrect path to certificates
+	cainfo = "${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt"
+
+	EOF
 
 	if [ -n "${http_proxy}" ]; then
 		echo "proxy = \"${http_proxy}\"" >> ${CARGO_HOME}/config
 	fi
 
-	echo "[target.${HOST_SYS}]" >> ${CARGO_HOME}/config
-	echo "linker = '${RUST_TARGET_CCLD}'" >> ${CARGO_HOME}/config
+	cat <<- EOF >> ${CARGO_HOME}/config
+
+	# HOST_SYS
+	[target.${HOST_SYS}]
+	linker = "${RUST_TARGET_CCLD}"
+	EOF
+
 	if [ "${HOST_SYS}" != "${BUILD_SYS}" ]; then
-		echo "[target.${BUILD_SYS}]" >> ${CARGO_HOME}/config
-		echo "linker = '${RUST_BUILD_CCLD}'" >> ${CARGO_HOME}/config
+		cat <<- EOF >> ${CARGO_HOME}/config
+
+		# BUILD_SYS
+		[target.${BUILD_SYS}]
+		linker = "${RUST_BUILD_CCLD}"
+		EOF
+	fi
+
+	# Put build output in build directory preferred by bitbake instead of
+	# inside source directory unless they are the same
+	if [ "${B}" != "${S}" ]; then
+		cat <<- EOF >> ${CARGO_HOME}/config
+
+		[build]
+		# Use out of tree build destination to avoid poluting the source tree
+		target-dir = "${B}/target"
+		EOF
 	fi
 }
 
diff --git a/meta/classes/rust-bin.bbclass b/meta/classes/rust-bin.bbclass
index a13fbafb56..6819c9e061 100644
--- a/meta/classes/rust-bin.bbclass
+++ b/meta/classes/rust-bin.bbclass
@@ -1,6 +1,6 @@
 inherit rust
 
-RDEPENDS_${PN}_append_class-target += "${RUSTLIB_DEP}"
+RDEPENDS_${PN}_append_class-target = " ${RUSTLIB_DEP}"
 
 RUSTC_ARCHFLAGS += "-C opt-level=3 -g -L ${STAGING_DIR_HOST}/${rustlibdir} -C linker=${RUST_TARGET_CCLD}"
 EXTRA_OEMAKE += 'RUSTC_ARCHFLAGS="${RUSTC_ARCHFLAGS}"'
diff --git a/meta/classes/rust-common.bbclass b/meta/classes/rust-common.bbclass
index cbc7d3cfe6..ff7b9da8f3 100644
--- a/meta/classes/rust-common.bbclass
+++ b/meta/classes/rust-common.bbclass
@@ -31,6 +31,24 @@ def determine_libc(d, thing):
 
     return libc
 
+def target_is_armv7(d):
+    '''Determine if target is armv7'''
+    # TUNE_FEATURES may include arm* even if the target is not arm
+    # in the case of *-native packages
+    if d.getVar('TARGET_ARCH') != 'arm':
+        return False
+
+    feat = d.getVar('TUNE_FEATURES')
+    feat = frozenset(feat.split())
+    mach_overrides = d.getVar('MACHINEOVERRIDES')
+    mach_overrides = frozenset(mach_overrides.split(':'))
+
+    v7=frozenset(['armv7a', 'armv7r', 'armv7m', 'armv7ve'])
+    if mach_overrides.isdisjoint(v7) and feat.isdisjoint(v7):
+        return False
+    else:
+        return True
+
 # Responsible for taking Yocto triples and converting it to Rust triples
 def rust_base_triple(d, thing):
     '''
@@ -40,7 +58,12 @@ def rust_base_triple(d, thing):
     Note that os is assumed to be some linux form
     '''
 
-    arch = d.getVar('{}_ARCH'.format(thing))
+    # The llvm-target for armv7 is armv7-unknown-linux-gnueabihf
+    if thing == "TARGET" and target_is_armv7(d):
+        arch = "armv7"
+    else:
+        arch = d.getVar('{}_ARCH'.format(thing))
+
     # All the Yocto targets are Linux and are 'unknown'
     vendor = "-unknown"
     os = d.getVar('{}_OS'.format(thing))
@@ -110,7 +133,7 @@ create_wrapper () {
 
 	cat <<- EOF > "${file}"
 	#!/bin/sh
-	$@ "\$@"
+	exec $@ "\$@"
 	EOF
 	chmod +x "${file}"
 }
diff --git a/meta/conf/distro/include/rust_versions.inc b/meta/conf/distro/include/rust_versions.inc
new file mode 100644
index 0000000000..8e328a720f
--- /dev/null
+++ b/meta/conf/distro/include/rust_versions.inc
@@ -0,0 +1,13 @@
+# include this in your distribution to easily switch between versions
+# just by changing RUST_VERSION variable
+
+RUST_VERSION ?= "1.49.0"
+
+PREFERRED_VERSION_cargo ?= "${RUST_VERSION}"
+PREFERRED_VERSION_cargo-native ?= "${RUST_VERSION}"
+PREFERRED_VERSION_libstd-rs ?= "${RUST_VERSION}"
+PREFERRED_VERSION_rust ?= "${RUST_VERSION}"
+PREFERRED_VERSION_rust-cross-${TARGET_ARCH} ?= "${RUST_VERSION}"
+PREFERRED_VERSION_rust-llvm ?= "${RUST_VERSION}"
+PREFERRED_VERSION_rust-llvm-native ?= "${RUST_VERSION}"
+PREFERRED_VERSION_rust-native ?= "${RUST_VERSION}"
diff --git a/meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch b/meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch
deleted file mode 100644
index c804297d48..0000000000
--- a/meta/recipes-devtools/cargo/cargo-1.37.0/0001-Disable-http2.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0e2384133664ebeb548b782ad763c3a627c1bc66 Mon Sep 17 00:00:00 2001
-From: Johan Anderholm <johan.anderholm@gmail.com>
-Date: Sun, 27 Jan 2019 10:19:00 +0100
-Subject: [PATCH] Disable http2
-
-http2 requires that curl is build with nghttp2 which in turn depends on
-many dependencies and ultimately a dependency loop in the case of
-curl-native. As long as multiplexing is disabled in cargo this should
-be fine.
-
-Upstream-Status: Inappropriate
-
----
- src/tools/cargo/Cargo.toml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Cargo.toml b/Cargo.toml
-index d15aa2513..ba9c77d25 100644
---- a/Cargo.toml
-+++ b/Cargo.toml
-@@ -24,7 +24,7 @@ bytesize = "1.0"
- crates-io = { path = "crates/crates-io", version = "0.26" }
- crossbeam-utils = "0.6"
- crypto-hash = "0.3.1"
--curl = { version = "0.4.21", features = ['http2'] }
-+curl = { version = "0.4.21" }
- curl-sys = "0.4.18"
- env_logger = "0.6.0"
- pretty_env_logger = { version = "0.3", optional = true }
diff --git a/meta/recipes-devtools/cargo/cargo-1.36.0/0001-Disable-http2.patch b/meta/recipes-devtools/cargo/cargo-1.47.0/0001-Disable-http2.patch
similarity index 53%
rename from meta/recipes-devtools/cargo/cargo-1.36.0/0001-Disable-http2.patch
rename to meta/recipes-devtools/cargo/cargo-1.47.0/0001-Disable-http2.patch
index 9794ec05f9..b08f7ac133 100644
--- a/meta/recipes-devtools/cargo/cargo-1.36.0/0001-Disable-http2.patch
+++ b/meta/recipes-devtools/cargo/cargo-1.47.0/0001-Disable-http2.patch
@@ -1,4 +1,4 @@
-From 42e65192b6f7520b7a05924856e00600961f6758 Mon Sep 17 00:00:00 2001
+From 40802c3a42fab9cfcd27fda8d00e98f8cc30016a Mon Sep 17 00:00:00 2001
 From: Johan Anderholm <johan.anderholm@gmail.com>
 Date: Sun, 27 Jan 2019 10:19:00 +0100
 Subject: [PATCH] Disable http2
@@ -14,18 +14,18 @@ Upstream-Status: Inappropriate
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/Cargo.toml b/Cargo.toml
-index c3fcacf5..bd6ec50b 100644
+index 95cea90c4..56211532f 100644
 --- a/Cargo.toml
 +++ b/Cargo.toml
-@@ -24,7 +24,7 @@ bytesize = "1.0"
- crates-io = { path = "src/crates-io", version = "0.25" }
- crossbeam-utils = "0.6"
+@@ -25,7 +25,7 @@ cargo-platform = { path = "crates/cargo-platform", version = "0.1.1" }
+ crates-io = { path = "crates/crates-io", version = "0.31.1" }
+ crossbeam-utils = "0.7"
  crypto-hash = "0.3.1"
--curl = { version = "0.4.21", features = ['http2'] }
-+curl = { version = "0.4.21" }
- curl-sys = "0.4.18"
- env_logger = "0.6.0"
- pretty_env_logger = { version = "0.3", optional = true }
+-curl = { version = "0.4.23", features = ["http2"] }
++curl = { version = "0.4.23" }
+ curl-sys = "0.4.22"
+ env_logger = "0.7.0"
+ pretty_env_logger = { version = "0.4", optional = true }
 -- 
-2.11.0
+2.28.0
 
diff --git a/meta/recipes-devtools/cargo/cargo-1.34.2/0001-Disable-http2.patch b/meta/recipes-devtools/cargo/cargo-1.49.0/0001-Disable-http2.patch
similarity index 53%
rename from meta/recipes-devtools/cargo/cargo-1.34.2/0001-Disable-http2.patch
rename to meta/recipes-devtools/cargo/cargo-1.49.0/0001-Disable-http2.patch
index a44482a112..51f37d3b51 100644
--- a/meta/recipes-devtools/cargo/cargo-1.34.2/0001-Disable-http2.patch
+++ b/meta/recipes-devtools/cargo/cargo-1.49.0/0001-Disable-http2.patch
@@ -1,4 +1,4 @@
-From 44cf21036646e4849e9f8566db7decb7da917394 Mon Sep 17 00:00:00 2001
+From 7f8a197af9c33d0575187663f796f882064136dc Mon Sep 17 00:00:00 2001
 From: Johan Anderholm <johan.anderholm@gmail.com>
 Date: Sun, 27 Jan 2019 10:19:00 +0100
 Subject: [PATCH] Disable http2
@@ -9,21 +9,23 @@ curl-native. As long as multiplexing is disabled in cargo this should
 be fine.
 
 Upstream-Status: Inappropriate
-
 ---
  Cargo.toml | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/Cargo.toml b/Cargo.toml
-index 8238380861d9..ced1defea459 100644
+index fde0a3188..a4a51939a 100644
 --- a/Cargo.toml
 +++ b/Cargo.toml
-@@ -24,7 +24,7 @@ bytesize = "1.0"
- crates-io = { path = "src/crates-io", version = "0.23" }
- crossbeam-utils = "0.6"
+@@ -25,7 +25,7 @@ cargo-platform = { path = "crates/cargo-platform", version = "0.1.1" }
+ crates-io = { path = "crates/crates-io", version = "0.31.1" }
+ crossbeam-utils = "0.8"
  crypto-hash = "0.3.1"
--curl = { version = "0.4.19", features = ['http2'] }
-+curl = { version = "0.4.19" }
- curl-sys = "0.4.15"
- env_logger = "0.6.0"
- pretty_env_logger = { version = "0.3", optional = true }
+-curl = { version = "0.4.23", features = ["http2"] }
++curl = { version = "0.4.23" }
+ curl-sys = "0.4.22"
+ env_logger = "0.8.1"
+ pretty_env_logger = { version = "0.4", optional = true }
+-- 
+2.28.0
+
diff --git a/meta/recipes-devtools/cargo/cargo.inc b/meta/recipes-devtools/cargo/cargo.inc
index 48012520d9..9645b90df6 100644
--- a/meta/recipes-devtools/cargo/cargo.inc
+++ b/meta/recipes-devtools/cargo/cargo.inc
@@ -3,10 +3,12 @@ HOMEPAGE = "https://crates.io"
 LICENSE = "MIT | Apache-2.0"
 SECTION = "devel"
 
-DEPENDS = "openssl zlib libgit2 curl ca-certificates libssh2"
+DEPENDS = "openssl zlib curl ca-certificates libssh2"
 
 LIC_FILES_CHKSUM = " \
     file://LICENSE-MIT;md5=b377b220f43d747efdec40d69fcaa69d \
+    file://LICENSE-APACHE;md5=71b224ca933f0676e26d5c2e2271331c \
+    file://LICENSE-THIRD-PARTY;md5=f257ad009884cb88a3a87d6920e7180a \
 "
 
 SRC_URI += "file://0001-Disable-http2.patch"
@@ -29,15 +31,21 @@ do_compile_prepend () {
 
 do_install () {
 	install -d "${D}${bindir}"
-	install -m 755 "${RUSTSRC}/target/${CARGO_TARGET_SUBDIR}/cargo" "${D}${bindir}"
+	install -m 755 "${B}/target/${CARGO_TARGET_SUBDIR}/cargo" "${D}${bindir}"
 }
 
+# Disabled due to incompatibility with libgit2 0.28.x (https://github.com/rust-lang/git2-rs/issues/458, https://bugs.gentoo.org/707746#c1)
+# as shipped by Yocto Dunfell.
+# According to https://github.com/rust-lang/git2-rs/issues/458#issuecomment-522567539, there are no compatibility guarantees between
+# libgit2-sys and arbitrary system libgit2 versions, so better keep this turned off.
+#export LIBGIT2_SYS_USE_PKG_CONFIG = "1"
+
 # Needed for pkg-config to be used
-export LIBGIT2_SYS_USE_PKG_CONFIG = "1"
 export LIBSSH2_SYS_USE_PKG_CONFIG = "1"
 
 BBCLASSEXTEND = "native"
 
-# When building cargo-native we don't have a built cargo to use so we must use
-# the snapshot to bootstrap the build of cargo
+# When building cargo-native we don't have cargo-native to use and depend on,
+# so we must use the locally set up snapshot to bootstrap the build.
+BASEDEPENDS_remove_class-native = "cargo-native"
 CARGO_class-native = "${WORKDIR}/${CARGO_SNAPSHOT}/bin/cargo"
diff --git a/meta/recipes-devtools/cargo/cargo_1.34.2.bb b/meta/recipes-devtools/cargo/cargo_1.34.2.bb
deleted file mode 100644
index d79f958c6e..0000000000
--- a/meta/recipes-devtools/cargo/cargo_1.34.2.bb
+++ /dev/null
@@ -1,8 +0,0 @@
-require recipes-devtools/rust/rust-source-${PV}.inc
-require recipes-devtools/rust/rust-snapshot-${PV}.inc
-require cargo.inc
-
-LIC_FILES_CHKSUM += " \
-    file://LICENSE-APACHE;md5=1836efb2eb779966696f473ee8540542 \
-    file://LICENSE-THIRD-PARTY;md5=892ea68b169e69cfe75097fc38a15b56 \
-"
diff --git a/meta/recipes-devtools/cargo/cargo_1.36.0.bb b/meta/recipes-devtools/cargo/cargo_1.36.0.bb
deleted file mode 100644
index f048779aae..0000000000
--- a/meta/recipes-devtools/cargo/cargo_1.36.0.bb
+++ /dev/null
@@ -1,8 +0,0 @@
-require recipes-devtools/rust/rust-source-${PV}.inc
-require recipes-devtools/rust/rust-snapshot-${PV}.inc
-require cargo.inc
-
-LIC_FILES_CHKSUM += " \
-    file://LICENSE-APACHE;md5=71b224ca933f0676e26d5c2e2271331c \
-    file://LICENSE-THIRD-PARTY;md5=f257ad009884cb88a3a87d6920e7180a \
-"
diff --git a/meta/recipes-devtools/cargo/cargo_1.37.0.bb b/meta/recipes-devtools/cargo/cargo_1.37.0.bb
deleted file mode 100644
index f048779aae..0000000000
--- a/meta/recipes-devtools/cargo/cargo_1.37.0.bb
+++ /dev/null
@@ -1,8 +0,0 @@
-require recipes-devtools/rust/rust-source-${PV}.inc
-require recipes-devtools/rust/rust-snapshot-${PV}.inc
-require cargo.inc
-
-LIC_FILES_CHKSUM += " \
-    file://LICENSE-APACHE;md5=71b224ca933f0676e26d5c2e2271331c \
-    file://LICENSE-THIRD-PARTY;md5=f257ad009884cb88a3a87d6920e7180a \
-"
diff --git a/meta/recipes-devtools/cargo/cargo_1.47.0.bb b/meta/recipes-devtools/cargo/cargo_1.47.0.bb
new file mode 100644
index 0000000000..dd050a82a0
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo_1.47.0.bb
@@ -0,0 +1,3 @@
+require recipes-devtools/rust/rust-source-${PV}.inc
+require recipes-devtools/rust/rust-snapshot-${PV}.inc
+require cargo.inc
diff --git a/meta/recipes-devtools/cargo/cargo_1.49.0.bb b/meta/recipes-devtools/cargo/cargo_1.49.0.bb
new file mode 100644
index 0000000000..dd050a82a0
--- /dev/null
+++ b/meta/recipes-devtools/cargo/cargo_1.49.0.bb
@@ -0,0 +1,3 @@
+require recipes-devtools/rust/rust-source-${PV}.inc
+require recipes-devtools/rust/rust-snapshot-${PV}.inc
+require cargo.inc
diff --git a/meta/recipes-devtools/rust/README-rust.md b/meta/recipes-devtools/rust/README-rust.md
index 329d59ab7b..400baf700d 100644
--- a/meta/recipes-devtools/rust/README-rust.md
+++ b/meta/recipes-devtools/rust/README-rust.md
@@ -13,7 +13,7 @@ This OpenEmbedded layer provides the rust compiler, tools for building packages
 ## What doesn't:
 
  - Using anything but x86_64 as the build environment
- - rust (built for target) issue #81
+ - rust (built for target) [issue #81](https://github.com/meta-rust/meta-rust/issues/81)
 
 ## What's untested:
 
@@ -27,7 +27,7 @@ rust packages do), then it's especially easy.  Otherwise you should probably
 get the code building in cargo first.
 
 Once your package builds in cargo, you can use
-[cargo-bitbake](https://github.com/cardoe/cargo-bitbake) to generate a bitbake
+[cargo-bitbake](https://github.com/meta-rust/cargo-bitbake) to generate a bitbake
 recipe for it.  This allows bitbake to fetch all the necessary dependent
 crates, as well as a pegged version of the crates.io index, to ensure maximum
 reproducibility.
@@ -39,7 +39,7 @@ contained within it
 
 ## Pitfalls
 
- - TARGET_SYS _must_ be different from BUILD_SYS. This is due to the way Rust configuration options are tracked for different targets. This is the reason we use the Yocto triples instead of the native Rust triples. See rust-lang/cargo#3349.
+ - TARGET_SYS _must_ be different from BUILD_SYS. This is due to the way Rust configuration options are tracked for different targets. This is the reason we use the Yocto triples instead of the native Rust triples. See [rust-lang/cargo#3349](https://github.com/rust-lang/cargo/issues/3349).
 
 ## Dependencies
 
diff --git a/meta/recipes-devtools/rust/libstd-rs.inc b/meta/recipes-devtools/rust/libstd-rs.inc
index 5298c00706..1bf2dab0a5 100644
--- a/meta/recipes-devtools/rust/libstd-rs.inc
+++ b/meta/recipes-devtools/rust/libstd-rs.inc
@@ -2,17 +2,26 @@ SUMMARY = "Rust standard libaries"
 HOMEPAGE = "http://www.rust-lang.org"
 SECTION = "devel"
 LICENSE = "MIT | Apache-2.0"
+LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
 
 RUSTLIB_DEP = ""
 inherit cargo
 
 DEPENDS_append_libc-musl = " libunwind"
+# rv32 does not have libunwind ported yet
+DEPENDS_remove_riscv32 = "libunwind"
+DEPENDS_remove_riscv64 = "libunwind"
+
+# Embed bitcode in order to allow compiling both with and without LTO
+RUSTFLAGS += "-Cembed-bitcode=yes"
 # Needed so cargo can find libbacktrace
 RUSTFLAGS += "-L ${STAGING_LIBDIR} -C link-arg=-Wl,-soname,libstd.so"
 
 S = "${RUSTSRC}/src/libstd"
 
+CARGO_FEATURES ?= "panic-unwind backtrace"
 CARGO_BUILD_FLAGS += "--features '${CARGO_FEATURES}'"
+CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
 
 do_compile_prepend () {
     export CARGO_TARGET_DIR="${B}"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.34.2.bb b/meta/recipes-devtools/rust/libstd-rs_1.34.2.bb
deleted file mode 100644
index 69cb48ad07..0000000000
--- a/meta/recipes-devtools/rust/libstd-rs_1.34.2.bb
+++ /dev/null
@@ -1,8 +0,0 @@
-require rust-source-${PV}.inc
-require libstd-rs.inc
-
-LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
-
-CARGO_FEATURES ?= "panic-unwind backtrace"
-
-CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.36.0.bb b/meta/recipes-devtools/rust/libstd-rs_1.36.0.bb
deleted file mode 100644
index 69cb48ad07..0000000000
--- a/meta/recipes-devtools/rust/libstd-rs_1.36.0.bb
+++ /dev/null
@@ -1,8 +0,0 @@
-require rust-source-${PV}.inc
-require libstd-rs.inc
-
-LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
-
-CARGO_FEATURES ?= "panic-unwind backtrace"
-
-CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.37.0.bb b/meta/recipes-devtools/rust/libstd-rs_1.37.0.bb
deleted file mode 100644
index 69cb48ad07..0000000000
--- a/meta/recipes-devtools/rust/libstd-rs_1.37.0.bb
+++ /dev/null
@@ -1,8 +0,0 @@
-require rust-source-${PV}.inc
-require libstd-rs.inc
-
-LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
-
-CARGO_FEATURES ?= "panic-unwind backtrace"
-
-CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.47.0.bb b/meta/recipes-devtools/rust/libstd-rs_1.47.0.bb
new file mode 100644
index 0000000000..4398a22986
--- /dev/null
+++ b/meta/recipes-devtools/rust/libstd-rs_1.47.0.bb
@@ -0,0 +1,5 @@
+require rust-source-${PV}.inc
+require libstd-rs.inc
+
+# libstd moved from src/libstd to library/std in 1.47+
+S = "${RUSTSRC}/library/std"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.49.0.bb b/meta/recipes-devtools/rust/libstd-rs_1.49.0.bb
new file mode 100644
index 0000000000..4398a22986
--- /dev/null
+++ b/meta/recipes-devtools/rust/libstd-rs_1.49.0.bb
@@ -0,0 +1,5 @@
+require rust-source-${PV}.inc
+require libstd-rs.inc
+
+# libstd moved from src/libstd to library/std in 1.47+
+S = "${RUSTSRC}/library/std"
diff --git a/meta/recipes-devtools/rust/rust-cross.inc b/meta/recipes-devtools/rust/rust-cross.inc
index 4869b85c03..b3698cdb20 100644
--- a/meta/recipes-devtools/rust/rust-cross.inc
+++ b/meta/recipes-devtools/rust/rust-cross.inc
@@ -1,6 +1,25 @@
 require rust.inc
 inherit cross
 
+python do_rust_gen_targets () {
+    wd = d.getVar('WORKDIR') + '/targets/'
+    # It is important 'TARGET' is last here so that it overrides our less
+    # informed choices for BUILD & HOST if TARGET happens to be the same as
+    # either of them.
+    for thing in ['BUILD', 'HOST', 'TARGET']:
+        bb.debug(1, "rust_gen_target for " + thing)
+        features = ""
+        cpu = "generic"
+        arch = d.getVar('{}_ARCH'.format(thing))
+        if thing is "TARGET":
+            # arm and armv7 have different targets in llvm
+            if arch == "arm" and target_is_armv7(d):
+                arch = 'armv7'
+            features = d.getVar('TARGET_LLVM_FEATURES') or ""
+            cpu = d.getVar('TARGET_LLVM_CPU')
+        rust_gen_target(d, thing, wd, features, cpu, arch)
+}
+
 # Otherwise we'll depend on what we provide
 INHIBIT_DEFAULT_RUST_DEPS = "1"
 
diff --git a/meta/recipes-devtools/rust/rust-cross_1.34.2.bb b/meta/recipes-devtools/rust/rust-cross_1.47.0.bb
similarity index 98%
rename from meta/recipes-devtools/rust/rust-cross_1.34.2.bb
rename to meta/recipes-devtools/rust/rust-cross_1.47.0.bb
index bb92b99ccc..ddc25d36b5 100644
--- a/meta/recipes-devtools/rust/rust-cross_1.34.2.bb
+++ b/meta/recipes-devtools/rust/rust-cross_1.47.0.bb
@@ -1,3 +1,2 @@
 require rust-cross.inc
 require rust-source-${PV}.inc
-
diff --git a/meta/recipes-devtools/rust/rust-cross_1.36.0.bb b/meta/recipes-devtools/rust/rust-cross_1.49.0.bb
similarity index 98%
rename from meta/recipes-devtools/rust/rust-cross_1.36.0.bb
rename to meta/recipes-devtools/rust/rust-cross_1.49.0.bb
index bb92b99ccc..ddc25d36b5 100644
--- a/meta/recipes-devtools/rust/rust-cross_1.36.0.bb
+++ b/meta/recipes-devtools/rust/rust-cross_1.49.0.bb
@@ -1,3 +1,2 @@
 require rust-cross.inc
 require rust-source-${PV}.inc
-
diff --git a/meta/recipes-devtools/rust/rust-llvm.inc b/meta/recipes-devtools/rust/rust-llvm.inc
index b4bef3875c..53ae87ed0f 100644
--- a/meta/recipes-devtools/rust/rust-llvm.inc
+++ b/meta/recipes-devtools/rust/rust-llvm.inc
@@ -1,13 +1,13 @@
 SUMMARY = "LLVM compiler framework (packaged with rust)"
-LICENSE = "NCSA"
+LICENSE ?= "Apache-2.0-with-LLVM-exception"
 
 SRC_URI += "file://0002-llvm-allow-env-override-of-exe-path.patch"
 
 S = "${RUSTSRC}/src/llvm-project/llvm"
 
-LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=4c0bc17c954e99fd547528d938832bfa"
+LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=8a15a0759ef07f2682d2ba4b893c9afe"
 
-inherit cmake pythonnative
+inherit cmake python3native
 
 DEPENDS += "ninja-native rust-llvm-native"
 
@@ -19,7 +19,7 @@ LLVM_DIR = "llvm${LLVM_RELEASE}"
 
 EXTRA_OECMAKE = " \
     -DCMAKE_BUILD_TYPE=Release \
-    -DLLVM_TARGETS_TO_BUILD='X86;ARM;AArch64;PowerPC;Mips' \
+    -DLLVM_TARGETS_TO_BUILD='ARM;AArch64;Mips;PowerPC;RISCV;X86' \
     -DLLVM_BUILD_DOCS=OFF \
     -DLLVM_ENABLE_TERMINFO=OFF \
     -DLLVM_ENABLE_ZLIB=OFF \
@@ -44,9 +44,11 @@ EXTRA_OECMAKE_append_class-target = "\
 # provide almost no value. If you really need them then override this
 INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
 
-do_install_append_class-target() {
-    # Disable checks on the native tools, since these should came from the native recipe
-    sed -i -e 's/\(.*APPEND.*_IMPORT_CHECK_FILES_FOR_.*{_IMPORT_PREFIX}\/bin\/.*\)/#\1/' ${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake
+export YOCTO_ALTERNATE_EXE_PATH = "${STAGING_LIBDIR}/llvm-rust/bin/llvm-config"
+
+do_install_append () {
+    # we don't need any of this stuff to build Rust
+    rm -rf "${D}/usr/lib/cmake"
 }
 
 PACKAGES =+ "${PN}-bugpointpasses ${PN}-llvmhello ${PN}-liblto"
diff --git a/meta/recipes-devtools/rust/rust-llvm_1.34.2.bb b/meta/recipes-devtools/rust/rust-llvm_1.34.2.bb
deleted file mode 100644
index d41fa28477..0000000000
--- a/meta/recipes-devtools/rust/rust-llvm_1.34.2.bb
+++ /dev/null
@@ -1,16 +0,0 @@
-require rust-source-${PV}.inc
-require rust-llvm.inc
-
-LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=c6b766a4e85dd28301eeed54a6684648"
-
-do_install_prepend () {
-	# the install does a sed on this without installing the file
-	# we don't need it for anything
-	mkdir -p "${D}/usr/share/llvm/cmake"
-	touch "${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake"
-}
-
-do_install_append () {
-	# we don't need any of this stuff to build Rust
-	rm -rf "${D}/usr/lib/cmake"
-}
diff --git a/meta/recipes-devtools/rust/rust-llvm_1.36.0.bb b/meta/recipes-devtools/rust/rust-llvm_1.36.0.bb
deleted file mode 100644
index d41fa28477..0000000000
--- a/meta/recipes-devtools/rust/rust-llvm_1.36.0.bb
+++ /dev/null
@@ -1,16 +0,0 @@
-require rust-source-${PV}.inc
-require rust-llvm.inc
-
-LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=c6b766a4e85dd28301eeed54a6684648"
-
-do_install_prepend () {
-	# the install does a sed on this without installing the file
-	# we don't need it for anything
-	mkdir -p "${D}/usr/share/llvm/cmake"
-	touch "${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake"
-}
-
-do_install_append () {
-	# we don't need any of this stuff to build Rust
-	rm -rf "${D}/usr/lib/cmake"
-}
diff --git a/meta/recipes-devtools/rust/rust-llvm_1.37.0.bb b/meta/recipes-devtools/rust/rust-llvm_1.37.0.bb
deleted file mode 100644
index d41fa28477..0000000000
--- a/meta/recipes-devtools/rust/rust-llvm_1.37.0.bb
+++ /dev/null
@@ -1,16 +0,0 @@
-require rust-source-${PV}.inc
-require rust-llvm.inc
-
-LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=c6b766a4e85dd28301eeed54a6684648"
-
-do_install_prepend () {
-	# the install does a sed on this without installing the file
-	# we don't need it for anything
-	mkdir -p "${D}/usr/share/llvm/cmake"
-	touch "${D}/usr/share/llvm/cmake/LLVMExports-noconfig.cmake"
-}
-
-do_install_append () {
-	# we don't need any of this stuff to build Rust
-	rm -rf "${D}/usr/lib/cmake"
-}
diff --git a/meta/recipes-devtools/rust/rust-cross_1.37.0.bb b/meta/recipes-devtools/rust/rust-llvm_1.47.0.bb
similarity index 55%
rename from meta/recipes-devtools/rust/rust-cross_1.37.0.bb
rename to meta/recipes-devtools/rust/rust-llvm_1.47.0.bb
index bb92b99ccc..1dca22bd60 100644
--- a/meta/recipes-devtools/rust/rust-cross_1.37.0.bb
+++ b/meta/recipes-devtools/rust/rust-llvm_1.47.0.bb
@@ -1,3 +1,2 @@
-require rust-cross.inc
 require rust-source-${PV}.inc
-
+require rust-llvm.inc
diff --git a/meta/recipes-devtools/rust/rust-llvm_1.49.0.bb b/meta/recipes-devtools/rust/rust-llvm_1.49.0.bb
new file mode 100644
index 0000000000..1dca22bd60
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-llvm_1.49.0.bb
@@ -0,0 +1,2 @@
+require rust-source-${PV}.inc
+require rust-llvm.inc
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc b/meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc
deleted file mode 100644
index d0209bb864..0000000000
--- a/meta/recipes-devtools/rust/rust-snapshot-1.34.2.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-## This is information on the rust-snapshot (binary) used to build our current release.
-## snapshot info is taken from rust/src/stage0.txt
-## TODO: find a way to add additional SRC_URIs based on the contents of an
-##       earlier SRC_URI.
-RS_VERSION = "1.33.0"
-
-RUST_STD_SNAPSHOT = "rust-std-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-RUSTC_SNAPSHOT = "rustc-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-CARGO_VERSION = "0.34.0"
-CARGO_SNAPSHOT = "cargo-${CARGO_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-
-SRC_URI += " \
-	https://static.rust-lang.org/dist/${RUST_STD_SNAPSHOT}.tar.gz;name=rust-std-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	https://static.rust-lang.org/dist/${RUSTC_SNAPSHOT}.tar.gz;name=rustc-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	https://static.rust-lang.org/dist/${CARGO_SNAPSHOT}.tar.gz;name=cargo-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	"
-
-# TODO: Add hashes for other architecture toolchains as well. Make a script?
-SRC_URI[rustc-snapshot-x86_64.md5sum] = "c1ec989c1965dce754dda1e54274a68c"
-SRC_URI[rustc-snapshot-x86_64.sha256sum] = "54a342f718b712d8a17fd7878ebd37d22a82ebc70b59c421168cd4153fd04c2b"
-SRC_URI[rust-std-snapshot-x86_64.md5sum] = "d573c5bd3a965c973734c1606968a91e"
-SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "661c2ba717ae1502f002b4c6e7aeb8941685c7ea8fe7ac26ed9ede26f615b7af"
-SRC_URI[cargo-snapshot-x86_64.md5sum] = "de0e635afa9bf495cefecea476bfce36"
-SRC_URI[cargo-snapshot-x86_64.sha256sum] = "4795ae5ca3bb8c7c83ca338676bb02b670efa1eb474e346284b629dc872bcce8"
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc b/meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc
deleted file mode 100644
index e4b6813e84..0000000000
--- a/meta/recipes-devtools/rust/rust-snapshot-1.36.0.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-## This is information on the rust-snapshot (binary) used to build our current release.
-## snapshot info is taken from rust/src/stage0.txt
-## TODO: find a way to add additional SRC_URIs based on the contents of an
-##       earlier SRC_URI.
-RS_VERSION = "1.35.0"
-
-RUSTC_SNAPSHOT = "rustc-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-RUST_STD_SNAPSHOT = "rust-std-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-CARGO_VERSION = "0.36.0"
-CARGO_SNAPSHOT = "cargo-${CARGO_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-
-SRC_URI += " \
-	https://static.rust-lang.org/dist/${RUSTC_SNAPSHOT}.tar.xz;name=rustc-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	https://static.rust-lang.org/dist/${RUST_STD_SNAPSHOT}.tar.xz;name=rust-std-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	https://static.rust-lang.org/dist/${CARGO_SNAPSHOT}.tar.xz;name=cargo-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	"
-
-# TODO: Add hashes for other architecture toolchains as well. Make a script?
-SRC_URI[rustc-snapshot-x86_64.md5sum] = "47ea78f6b3f68e30f24b9c94e465d6bd"
-SRC_URI[rustc-snapshot-x86_64.sha256sum] = "5d6dc216ba429ddf3a1657e70f3e5e380549b546fe56de897677a11d72aa4e07"
-SRC_URI[rust-std-snapshot-x86_64.md5sum] = "348ec23ca8e47fc65079bc80e63cca5f"
-SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "ccff05d0e2d88499505b10f8e33e8b1645df057f918edc81f8acb0fcee9f90b2"
-SRC_URI[cargo-snapshot-x86_64.md5sum] = "93a375e771f3d9b3a139e612dd4730ee"
-SRC_URI[cargo-snapshot-x86_64.sha256sum] = "ab5a6ff1947463dbd2477ca5dac2012494dae821112098ae0c54add652adfdc3"
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc b/meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc
deleted file mode 100644
index 8d4c1801ed..0000000000
--- a/meta/recipes-devtools/rust/rust-snapshot-1.37.0.inc
+++ /dev/null
@@ -1,24 +0,0 @@
-## This is information on the rust-snapshot (binary) used to build our current release.
-## snapshot info is taken from rust/src/stage0.txt
-## TODO: find a way to add additional SRC_URIs based on the contents of an
-##       earlier SRC_URI.
-RS_VERSION = "1.36.0"
-
-RUSTC_SNAPSHOT = "rustc-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-RUST_STD_SNAPSHOT = "rust-std-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-CARGO_VERSION = "0.37.0"
-CARGO_SNAPSHOT = "cargo-${CARGO_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
-
-SRC_URI += " \
-	https://static.rust-lang.org/dist/${RUSTC_SNAPSHOT}.tar.xz;name=rustc-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	https://static.rust-lang.org/dist/${RUST_STD_SNAPSHOT}.tar.xz;name=rust-std-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	https://static.rust-lang.org/dist/${CARGO_SNAPSHOT}.tar.xz;name=cargo-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
-	"
-
-# TODO: Add hashes for other architecture toolchains as well. Make a script?
-SRC_URI[rustc-snapshot-x86_64.md5sum] = "ec27794c94cc1df1a0a69f7244a09176"
-SRC_URI[rustc-snapshot-x86_64.sha256sum] = "fff0158da6f5af2a89936dc3e0c361077c06c2983eb310615e02f81ebbde1416"
-SRC_URI[rust-std-snapshot-x86_64.md5sum] = "b71a6fd6f44527c3bf09584e89ad8958"
-SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "ce8e12684b568a8a4f7d346a743383429849cf3f028f5712ad3d3e31590c8db3"
-SRC_URI[cargo-snapshot-x86_64.md5sum] = "8c661276a0da7a1aa48affbe33b347e6"
-SRC_URI[cargo-snapshot-x86_64.sha256sum] = "d20fa121951339d5492cf8862f8a7af59efc99d18f3c27b95ab6d4658b6a7d67"
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.47.0.inc b/meta/recipes-devtools/rust/rust-snapshot-1.47.0.inc
new file mode 100644
index 0000000000..cdd52f6d3a
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-snapshot-1.47.0.inc
@@ -0,0 +1,13 @@
+require rust-snapshot.inc
+
+## This is information on the rust-snapshot (binary) used to build our current release.
+## snapshot info is taken from rust/src/stage0.txt
+## TODO: find a way to add additional SRC_URIs based on the contents of an
+##       earlier SRC_URI.
+RS_VERSION = "1.46.0"
+CARGO_VERSION = "0.47.0"
+
+# TODO: Add hashes for other architecture toolchains as well. Make a script?
+SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "e631d80cb03539769c041ee4566e94e36a271d4b3cdd149e1447d1f77fda979c"
+SRC_URI[rustc-snapshot-x86_64.sha256sum] = "6edcec5367f9fcaee78cbcabfb1f6757fa95d7fd2c0853913223fe20ad534f12"
+SRC_URI[cargo-snapshot-x86_64.sha256sum] = "9da5c4888c6025fa174eaef330337e49666ca9562f876a34d40c03a80d432b8d"
diff --git a/meta/recipes-devtools/rust/rust-snapshot-1.49.0.inc b/meta/recipes-devtools/rust/rust-snapshot-1.49.0.inc
new file mode 100644
index 0000000000..18f2b7c25e
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-snapshot-1.49.0.inc
@@ -0,0 +1,13 @@
+require rust-snapshot.inc
+
+## This is information on the rust-snapshot (binary) used to build our current release.
+## snapshot info is taken from rust/src/stage0.txt
+## TODO: find a way to add additional SRC_URIs based on the contents of an
+##       earlier SRC_URI.
+RS_VERSION = "1.48.0"
+CARGO_VERSION = "1.48.0"
+
+# TODO: Add hashes for other architecture toolchains as well. Make a script?
+SRC_URI[rust-std-snapshot-x86_64.sha256sum] = "1c00a6a0dabbf6290728b09f9307d9fa6cc985487f727075c68acd4a600ef3f8"
+SRC_URI[rustc-snapshot-x86_64.sha256sum] = "fc4d292a52cbb6b84fb9f065d0d7596064a9b957381d639d5a750d6e2bf02483"
+SRC_URI[cargo-snapshot-x86_64.sha256sum] = "b11d595581e2580c069b5039214e1031a0e4f87ff6490ac39f92f77857e37055"
diff --git a/meta/recipes-devtools/rust/rust-snapshot.inc b/meta/recipes-devtools/rust/rust-snapshot.inc
new file mode 100644
index 0000000000..79d03afd1b
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-snapshot.inc
@@ -0,0 +1,9 @@
+SRC_URI += " \
+    https://static.rust-lang.org/dist/${RUST_STD_SNAPSHOT}.tar.xz;name=rust-std-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+    https://static.rust-lang.org/dist/${RUSTC_SNAPSHOT}.tar.xz;name=rustc-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+    https://static.rust-lang.org/dist/${CARGO_SNAPSHOT}.tar.xz;name=cargo-snapshot-${BUILD_ARCH};subdir=rust-snapshot-components \
+"
+
+RUST_STD_SNAPSHOT = "rust-std-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+RUSTC_SNAPSHOT = "rustc-${RS_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
+CARGO_SNAPSHOT = "cargo-${CARGO_VERSION}-${BUILD_ARCH}-unknown-linux-gnu"
diff --git a/meta/recipes-devtools/rust/rust-source-1.34.2.inc b/meta/recipes-devtools/rust/rust-source-1.34.2.inc
deleted file mode 100644
index 5c83f6f000..0000000000
--- a/meta/recipes-devtools/rust/rust-source-1.34.2.inc
+++ /dev/null
@@ -1,11 +0,0 @@
-SRC_URI += "https://static.rust-lang.org/dist/rustc-${PV}-src.tar.gz;name=rust"
-
-SRC_URI[rust.md5sum] = "7c85e6a60dda740295f7e004a1fb15e1"
-SRC_URI[rust.sha256sum] = "c69a4a85a1c464368597df8878cb9e1121aae93e215616d45ad7d23af3052f56"
-
-# later versions of rust change the directory that they unextract to
-RUSTSRC = "${WORKDIR}/rustc-${PV}-src"
-# set this as our default
-S = "${RUSTSRC}"
-
-LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
diff --git a/meta/recipes-devtools/rust/rust-source-1.36.0.inc b/meta/recipes-devtools/rust/rust-source-1.36.0.inc
deleted file mode 100644
index 1a1d07c72f..0000000000
--- a/meta/recipes-devtools/rust/rust-source-1.36.0.inc
+++ /dev/null
@@ -1,11 +0,0 @@
-SRC_URI += "https://static.rust-lang.org/dist/rustc-${PV}-src.tar.xz;name=rust"
-
-SRC_URI[rust.md5sum] = "78ffc0b029aaed216b45c3fe24747d46"
-SRC_URI[rust.sha256sum] = "f51645b9f787af4a5d94db17f6af39db0c55980ed24fe366cad55b57900f8f2d"
-
-# later versions of rust change the directory that they unextract to
-RUSTSRC = "${WORKDIR}/rustc-${PV}-src"
-# set this as our default
-S = "${RUSTSRC}"
-
-LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
diff --git a/meta/recipes-devtools/rust/rust-source-1.37.0.inc b/meta/recipes-devtools/rust/rust-source-1.37.0.inc
deleted file mode 100644
index 0169cd3fbd..0000000000
--- a/meta/recipes-devtools/rust/rust-source-1.37.0.inc
+++ /dev/null
@@ -1,11 +0,0 @@
-SRC_URI += "https://static.rust-lang.org/dist/rustc-${PV}-src.tar.xz;name=rust"
-
-SRC_URI[rust.md5sum] = "ee6300b1d7e5767115492915c4c0d8ef"
-SRC_URI[rust.sha256sum] = "10abffac50a729cf74cef6dd03193a2f4647541bd19ee9281be9e5b12ca8cdfd"
-
-# later versions of rust change the directory that they unextract to
-RUSTSRC = "${WORKDIR}/rustc-${PV}-src"
-# set this as our default
-S = "${RUSTSRC}"
-
-LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
diff --git a/meta/recipes-devtools/rust/rust-source-1.47.0.inc b/meta/recipes-devtools/rust/rust-source-1.47.0.inc
new file mode 100644
index 0000000000..6bf6e726b1
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-source-1.47.0.inc
@@ -0,0 +1,3 @@
+require rust-source.inc
+
+SRC_URI[rust.sha256sum] = "ec2c81d2d34890486094a6407589be96161e4e301c238332d32c6dbae4f38ea2"
diff --git a/meta/recipes-devtools/rust/rust-source-1.49.0.inc b/meta/recipes-devtools/rust/rust-source-1.49.0.inc
new file mode 100644
index 0000000000..645fa2819b
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-source-1.49.0.inc
@@ -0,0 +1,3 @@
+require rust-source.inc
+
+SRC_URI[rust.sha256sum] = "ebe910edc824a0a037a10be443446a0511923ba8342fa3c331ec8a22481d5d15"
diff --git a/meta/recipes-devtools/rust/rust-source.inc b/meta/recipes-devtools/rust/rust-source.inc
new file mode 100644
index 0000000000..52502fb49f
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust-source.inc
@@ -0,0 +1,3 @@
+SRC_URI += "https://static.rust-lang.org/dist/rustc-${PV}-src.tar.xz;name=rust"
+
+RUSTSRC = "${WORKDIR}/rustc-${PV}-src"
diff --git a/meta/recipes-devtools/rust/rust_1.36.0.bb b/meta/recipes-devtools/rust/rust-target.inc
similarity index 82%
rename from meta/recipes-devtools/rust/rust_1.36.0.bb
rename to meta/recipes-devtools/rust/rust-target.inc
index c7f9f4fd87..0a5b127f3c 100644
--- a/meta/recipes-devtools/rust/rust_1.36.0.bb
+++ b/meta/recipes-devtools/rust/rust-target.inc
@@ -1,6 +1,4 @@
 require rust.inc
-require rust-source-${PV}.inc
-require rust-snapshot-${PV}.inc
 
 DEPENDS += "rust-llvm (=${PV})"
 
diff --git a/meta/recipes-devtools/rust/rust.inc b/meta/recipes-devtools/rust/rust.inc
index abd4e0e4bc..aeb5432a16 100644
--- a/meta/recipes-devtools/rust/rust.inc
+++ b/meta/recipes-devtools/rust/rust.inc
@@ -2,12 +2,15 @@ SUMMARY = "Rust compiler and runtime libaries"
 HOMEPAGE = "http://www.rust-lang.org"
 SECTION = "devel"
 LICENSE = "MIT | Apache-2.0"
+LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=93a95682d51b4cb0a633a97046940ef0"
 
 inherit rust
 inherit cargo_common
 
-DEPENDS += "file-native python-native"
+DEPENDS += "file-native python3-native"
 DEPENDS_append_class-native = " rust-llvm-native"
+EXCLUDE_FROM_WORLD = "1"
+S = "${RUSTSRC}"
 
 # We generate local targets, and need to be able to locate them
 export RUST_TARGET_PATH="${WORKDIR}/targets/"
@@ -47,6 +50,9 @@ def llvm_features_from_tune(d):
         return []
     feat = frozenset(feat.split())
 
+    mach_overrides = d.getVar('MACHINEOVERRIDES')
+    mach_overrides = frozenset(mach_overrides.split(':'))
+
     if 'vfpv4' in feat:
         f.append("+vfp4")
     if 'vfpv3' in feat:
@@ -60,19 +66,16 @@ def llvm_features_from_tune(d):
     if 'neon' in feat:
         f.append("+neon")
 
-    if 'aarch64' in feat:
-        f.append("+v8")
-
     if 'mips32' in feat:
         f.append("+mips32")
 
     if 'mips32r2' in feat:
         f.append("+mips32r2")
 
-    v7=frozenset(['armv7a', 'armv7r', 'armv7m', 'armv7ve'])
-    if not feat.isdisjoint(v7):
-        f.append("+v7")
-    if 'armv6' in feat:
+    if target_is_armv7(d):
+        f.append('+v7')
+
+    if ('armv6' in mach_overrides) or ('armv6' in feat):
         f.append("+v6")
 
     if 'dsp' in feat:
@@ -80,8 +83,8 @@ def llvm_features_from_tune(d):
 
     if 'thumb' in feat:
         if d.getVar('ARM_THUMB_OPT') is "thumb":
-            if not feat.isdisjoint(v7):
-                f.append("+thumb2")
+            if target_is_armv7(d):
+                f.append('+thumb2')
             f.append("+thumb-mode")
 
     if 'cortexa5' in feat:
@@ -94,7 +97,8 @@ def llvm_features_from_tune(d):
         f.append("+a15")
     if 'cortexa17' in feat:
         f.append("+a17")
-
+    if ('riscv64' in feat) or ('riscv32' in feat):
+        f.append("+a,+c,+d,+f,+m")
     return f
 
 # TARGET_CC_ARCH changes from build/cross/target so it'll do the right thing
@@ -151,6 +155,15 @@ TARGET_C_INT_WIDTH[arm] = "32"
 MAX_ATOMIC_WIDTH[arm] = "64"
 FEATURES[arm] = "+v6,+vfp2"
 
+## armv7-unknown-linux-gnueabihf
+DATA_LAYOUT[armv7] = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+LLVM_TARGET[armv7] = "${RUST_TARGET_SYS}"
+TARGET_ENDIAN[armv7] = "little"
+TARGET_POINTER_WIDTH[armv7] = "32"
+TARGET_C_INT_WIDTH[armv7] = "32"
+MAX_ATOMIC_WIDTH[armv7] = "64"
+FEATURES[armv7] = "+v7,+vfp2,+thumb2"
+
 ## aarch64-unknown-linux-{gnu, musl}
 DATA_LAYOUT[aarch64] = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 LLVM_TARGET[aarch64] = "${RUST_TARGET_SYS}"
@@ -224,7 +237,7 @@ TARGET_C_INT_WIDTH[powerpc] = "32"
 MAX_ATOMIC_WIDTH[powerpc] = "32"
 
 ## riscv32-unknown-linux-{gnu, musl}
-DATA_LAYOUT[riscv32] = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
+DATA_LAYOUT[riscv32] = "e-m:e-p:32:32-i64:64-n32-S128"
 LLVM_TARGET[riscv32] = "${RUST_TARGET_SYS}"
 TARGET_ENDIAN[riscv32] = "little"
 TARGET_POINTER_WIDTH[riscv32] = "32"
@@ -239,9 +252,6 @@ TARGET_POINTER_WIDTH[riscv64] = "64"
 TARGET_C_INT_WIDTH[riscv64] = "64"
 MAX_ATOMIC_WIDTH[riscv64] = "64"
 
-def arch_for(d, thing):
-    return d.getVar('{}_ARCH'.format(thing))
-
 def sys_for(d, thing):
     return d.getVar('{}_SYS'.format(thing))
 
@@ -257,6 +267,8 @@ def arch_to_rust_target_arch(arch):
         return "mips"
     elif arch == "mip64sel":
         return "mips64"
+    elif arch == "armv7":
+        return "arm"
     else:
         return arch
 
@@ -274,6 +286,8 @@ def llvm_cpu(d):
     trans['powerpc'] = "powerpc"
     trans['mips64'] = "mips64"
     trans['mips64el'] = "mips64"
+    trans['riscv64'] = "generic-rv64"
+    trans['riscv32'] = "generic-rv32"
 
     if target in ["mips", "mipsel"]:
         feat = frozenset(d.getVar('TUNE_FEATURES').split())
@@ -296,18 +310,12 @@ TARGET_LLVM_FEATURES = "${@llvm_features(d)}"
 # (original) target.
 TARGET_LLVM_FEATURES_class-native = "${@','.join(llvm_features_from_cc_arch(d))}"
 
-def rust_gen_target(d, thing, wd):
+def rust_gen_target(d, thing, wd, features, cpu, arch):
     import json
     from distutils.version import LooseVersion
-    arch = arch_for(d, thing)
     sys = sys_for(d, thing)
     prefix = prefix_for(d, thing)
 
-    features = ""
-    cpu = "generic"
-    if thing is "TARGET":
-        features = d.getVar('TARGET_LLVM_FEATURES') or ""
-        cpu = d.getVar('TARGET_LLVM_CPU')
     features = features or d.getVarFlag('FEATURES', arch) or ""
     features = features.strip()
 
@@ -315,7 +323,7 @@ def rust_gen_target(d, thing, wd):
     tspec = {}
     tspec['llvm-target'] = d.getVarFlag('LLVM_TARGET', arch)
     tspec['data-layout'] = d.getVarFlag('DATA_LAYOUT', arch)
-    tspec['max-atomic-width'] = d.getVarFlag('MAX_ATOMIC_WIDTH', arch)
+    tspec['max-atomic-width'] = int(d.getVarFlag('MAX_ATOMIC_WIDTH', arch))
     tspec['target-pointer-width'] = d.getVarFlag('TARGET_POINTER_WIDTH', arch)
     tspec['target-c-int-width'] = d.getVarFlag('TARGET_C_INT_WIDTH', arch)
     tspec['target-endian'] = d.getVarFlag('TARGET_ENDIAN', arch)
@@ -325,6 +333,10 @@ def rust_gen_target(d, thing, wd):
         tspec['env'] = "musl"
     else:
         tspec['env'] = "gnu"
+    if "riscv64" in tspec['llvm-target']:
+        tspec['llvm-abiname'] = "lp64d"
+    if "riscv32" in tspec['llvm-target']:
+        tspec['llvm-abiname'] = "ilp32d"
     tspec['vendor'] = "unknown"
     tspec['target-family'] = "unix"
     tspec['linker'] = "{}{}gcc".format(d.getVar('CCACHE'), prefix)
@@ -352,20 +364,15 @@ def rust_gen_target(d, thing, wd):
     with open(wd + sys + '.json', 'w') as f:
         json.dump(tspec, f, indent=4)
 
-
 python do_rust_gen_targets () {
     wd = d.getVar('WORKDIR') + '/targets/'
-    # It is important 'TARGET' is last here so that it overrides our less
-    # informed choices for BUILD & HOST if TARGET happens to be the same as
-    # either of them.
-    for thing in ['BUILD', 'HOST', 'TARGET']:
-        bb.debug(1, "rust_gen_target for " + thing)
-        rust_gen_target(d, thing, wd)
+    build_arch = d.getVar('BUILD_ARCH')
+    rust_gen_target(d, 'BUILD', wd, "", "generic", build_arch)
 }
+
 addtask rust_gen_targets after do_patch before do_compile
 do_rust_gen_targets[dirs] += "${WORKDIR}/targets"
 
-
 do_rust_setup_snapshot () {
     for installer in "${WORKDIR}/rust-snapshot-components/"*"/install.sh"; do
         "${installer}" --prefix="${WORKDIR}/rust-snapshot" --disable-ldconfig
@@ -450,7 +457,18 @@ python do_configure() {
     # nothing about when trying to build some stage0 tools (like fabricate)
     config.set("build", "build", e(d.getVar("SNAPSHOT_BUILD_SYS", True)))
 
+    # [install]
+    config.add_section("install")
+    # ./x.py install doesn't have any notion of "destdir"
+    # but we can prepend ${D} to all the directories instead
+    config.set("install", "prefix",  e(d.getVar("D", True) + d.getVar("prefix", True)))
+    config.set("install", "bindir",  e(d.getVar("D", True) + d.getVar("bindir", True)))
+    config.set("install", "libdir",  e(d.getVar("D", True) + d.getVar("libdir", True)))
+    config.set("install", "datadir", e(d.getVar("D", True) + d.getVar("datadir", True)))
+    config.set("install", "mandir",  e(d.getVar("D", True) + d.getVar("mandir", True)))
+
     with open("config.toml", "w") as f:
+        f.write('changelog-seen = 2\n\n')
         config.write(f)
 
     # set up ${WORKDIR}/cargo_home
@@ -471,39 +489,36 @@ rust_runx () {
 
     oe_cargo_fix_env
 
-    python src/bootstrap/bootstrap.py "$@" --verbose
+    python3 src/bootstrap/bootstrap.py ${@oe.utils.parallel_make_argument(d, '-j %d')} "$@" --verbose
 }
+rust_runx[vardepsexclude] += "PARALLEL_MAKE"
 
 do_compile () {
     rust_runx build
-    rust_runx dist
 }
 
 rust_do_install () {
-    # Only install compiler generated for the HOST_SYS. There will be
-    # one for SNAPSHOT_BUILD_SYS as well.
-    local installer=build/tmp/dist/rustc-${PV}-${HOST_SYS}/install.sh
-    ${installer} --destdir="${D}" --prefix="${prefix}" --disable-ldconfig
+    mkdir -p ${D}${bindir}
+    cp build/${HOST_SYS}/stage2/bin/* ${D}${bindir}
 
-    installer=build/tmp/dist/rust-std-${PV}-${HOST_SYS}/install.sh
-    ${installer} --destdir="${D}" --prefix="${prefix}" --disable-ldconfig
+    mkdir -p ${D}${libdir}/rustlib
+    cp -pRd build/${HOST_SYS}/stage2/lib/* ${D}${libdir}
+    # Remove absolute symlink so bitbake doesn't complain
+    rm -f ${D}${libdir}/rustlib/src/rust
+}
 
+rust_install_targets() {
     # Install our custom target.json files
     local td="${D}${libdir}/rustlib/"
     install -d "$td"
     for tgt in "${WORKDIR}/targets/"* ; do
         install -m 0644 "$tgt" "$td"
     done
-
-    # cleanup after rust-installer since we don't need these bits
-    rm ${D}/${libdir}/rustlib/install.log
-    rm ${D}/${libdir}/rustlib/rust-installer-version
-    rm ${D}/${libdir}/rustlib/uninstall.sh
-    rm ${D}/${libdir}/rustlib/components
 }
 
 
 do_install () {
     rust_do_install
+    rust_install_targets
 }
 # ex: sts=4 et sw=4 ts=8
diff --git a/meta/recipes-devtools/rust/rust/0001-rustc_target-Fix-dash-vs-underscore-mismatches-in-op.patch b/meta/recipes-devtools/rust/rust/0001-rustc_target-Fix-dash-vs-underscore-mismatches-in-op.patch
new file mode 100644
index 0000000000..13d81eaa37
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust/0001-rustc_target-Fix-dash-vs-underscore-mismatches-in-op.patch
@@ -0,0 +1,75 @@
+From dd682cb48c8b667859dded98a4bbfbd891a1eca4 Mon Sep 17 00:00:00 2001
+From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
+Date: Thu, 12 Nov 2020 19:16:59 +0300
+Subject: [PATCH] rustc_target: Fix dash vs underscore mismatches in option
+ names
+
+---
+ compiler/rustc_target/src/spec/mod.rs | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
+index f949bf95a50..f837114ee74 100644
+--- a/compiler/rustc_target/src/spec/mod.rs
++++ b/compiler/rustc_target/src/spec/mod.rs
+@@ -1428,8 +1428,8 @@ pub fn from_json(obj: Json) -> Result<Target, String> {
+         }
+ 
+         key!(is_builtin, bool);
+-        key!(endian = "target_endian");
+-        key!(c_int_width = "target_c_int_width");
++        key!(endian = "target-endian");
++        key!(c_int_width = "target-c-int-width");
+         key!(os);
+         key!(env);
+         key!(vendor);
+@@ -1466,7 +1466,7 @@ pub fn from_json(obj: Json) -> Result<Target, String> {
+         key!(exe_suffix);
+         key!(staticlib_prefix);
+         key!(staticlib_suffix);
+-        key!(os_family = "target_family", optional);
++        key!(os_family = "target-family", optional);
+         key!(abi_return_struct_as_int, bool);
+         key!(is_like_osx, bool);
+         key!(is_like_solaris, bool);
+@@ -1511,7 +1511,7 @@ pub fn from_json(obj: Json) -> Result<Target, String> {
+         key!(limit_rdylib_exports, bool);
+         key!(override_export_symbols, opt_list);
+         key!(merge_functions, MergeFunctions)?;
+-        key!(mcount = "target_mcount");
++        key!(mcount = "target-mcount");
+         key!(llvm_abiname);
+         key!(relax_elf_relocations, bool);
+         key!(llvm_args, list);
+@@ -1663,8 +1663,8 @@ fn to_json(&self) -> Json {
+         target_val!(data_layout);
+ 
+         target_option_val!(is_builtin);
+-        target_option_val!(endian, "target_endian");
+-        target_option_val!(c_int_width, "target_c_int_width");
++        target_option_val!(endian, "target-endian");
++        target_option_val!(c_int_width, "target-c-int-width");
+         target_option_val!(os);
+         target_option_val!(env);
+         target_option_val!(vendor);
+@@ -1701,7 +1701,7 @@ fn to_json(&self) -> Json {
+         target_option_val!(exe_suffix);
+         target_option_val!(staticlib_prefix);
+         target_option_val!(staticlib_suffix);
+-        target_option_val!(os_family, "target_family");
++        target_option_val!(os_family, "target-family");
+         target_option_val!(abi_return_struct_as_int);
+         target_option_val!(is_like_osx);
+         target_option_val!(is_like_solaris);
+@@ -1746,7 +1746,7 @@ fn to_json(&self) -> Json {
+         target_option_val!(limit_rdylib_exports);
+         target_option_val!(override_export_symbols);
+         target_option_val!(merge_functions);
+-        target_option_val!(mcount, "target_mcount");
++        target_option_val!(mcount, "target-mcount");
+         target_option_val!(llvm_abiname);
+         target_option_val!(relax_elf_relocations);
+         target_option_val!(llvm_args);
+-- 
+2.28.0
+
diff --git a/meta/recipes-devtools/rust/rust_1.34.2.bb b/meta/recipes-devtools/rust/rust_1.34.2.bb
deleted file mode 100644
index c7f9f4fd87..0000000000
--- a/meta/recipes-devtools/rust/rust_1.34.2.bb
+++ /dev/null
@@ -1,12 +0,0 @@
-require rust.inc
-require rust-source-${PV}.inc
-require rust-snapshot-${PV}.inc
-
-DEPENDS += "rust-llvm (=${PV})"
-
-# Otherwise we'll depend on what we provide
-INHIBIT_DEFAULT_RUST_DEPS_class-native = "1"
-# We don't need to depend on gcc-native because yocto assumes it exists
-PROVIDES_class-native = "virtual/${TARGET_PREFIX}rust"
-
-BBCLASSEXTEND = "native"
diff --git a/meta/recipes-devtools/rust/rust_1.37.0.bb b/meta/recipes-devtools/rust/rust_1.37.0.bb
deleted file mode 100644
index c7f9f4fd87..0000000000
--- a/meta/recipes-devtools/rust/rust_1.37.0.bb
+++ /dev/null
@@ -1,12 +0,0 @@
-require rust.inc
-require rust-source-${PV}.inc
-require rust-snapshot-${PV}.inc
-
-DEPENDS += "rust-llvm (=${PV})"
-
-# Otherwise we'll depend on what we provide
-INHIBIT_DEFAULT_RUST_DEPS_class-native = "1"
-# We don't need to depend on gcc-native because yocto assumes it exists
-PROVIDES_class-native = "virtual/${TARGET_PREFIX}rust"
-
-BBCLASSEXTEND = "native"
diff --git a/meta/recipes-devtools/rust/rust_1.47.0.bb b/meta/recipes-devtools/rust/rust_1.47.0.bb
new file mode 100644
index 0000000000..894f715e16
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust_1.47.0.bb
@@ -0,0 +1,9 @@
+require rust-target.inc
+require rust-source-${PV}.inc
+require rust-snapshot-${PV}.inc
+
+# The default behaviour of x.py changed in 1.47+ so now we need to
+# explicitly ask for the stage 2 compiler to be assembled.
+do_compile () {
+    rust_runx build --stage 2 src/rustc
+}
diff --git a/meta/recipes-devtools/rust/rust_1.49.0.bb b/meta/recipes-devtools/rust/rust_1.49.0.bb
new file mode 100644
index 0000000000..96d625f6c3
--- /dev/null
+++ b/meta/recipes-devtools/rust/rust_1.49.0.bb
@@ -0,0 +1,15 @@
+require rust-target.inc
+require rust-source-${PV}.inc
+require rust-snapshot-${PV}.inc
+
+SRC_URI += "\
+    file://0001-rustc_target-Fix-dash-vs-underscore-mismatches-in-op.patch \
+    "
+
+do_compile () {
+    rust_runx build --stage 2
+}
+
+rust_do_install() {
+    rust_runx install
+}
diff --git a/meta/recipes-example/rust-hello-world/rust-hello-world/0001-enable-LTO.patch b/meta/recipes-example/rust-hello-world/rust-hello-world/0001-enable-LTO.patch
new file mode 100644
index 0000000000..56ef9e73e6
--- /dev/null
+++ b/meta/recipes-example/rust-hello-world/rust-hello-world/0001-enable-LTO.patch
@@ -0,0 +1,23 @@
+From fa40b874f6470ec11a8fd7b0c9909d0cdd2d6feb Mon Sep 17 00:00:00 2001
+From: Dan Callaghan <dan.callaghan@opengear.com>
+Date: Fri, 5 Feb 2021 08:56:34 +1000
+Subject: [PATCH] enable LTO
+
+---
+ Cargo.toml | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/Cargo.toml b/Cargo.toml
+index 7a2f6c8..cdb6b5d 100644
+--- a/Cargo.toml
++++ b/Cargo.toml
+@@ -3,3 +3,6 @@
+ name = "rust-hello-world"
+ version = "0.0.1"
+ authors = ["Cody P Schafer <dev@codyps.com>"]
++
++[profile.release]
++lto = true
+-- 
+2.28.0
+
diff --git a/meta/recipes-example/rust-hello-world/rust-hello-world_git.bb b/meta/recipes-example/rust-hello-world/rust-hello-world_git.bb
index ba8854849d..c29eac34e5 100644
--- a/meta/recipes-example/rust-hello-world/rust-hello-world_git.bb
+++ b/meta/recipes-example/rust-hello-world/rust-hello-world_git.bb
@@ -1,11 +1,15 @@
 inherit cargo
 
-SRC_URI = "git://github.com/jmesmon/rust-hello-world.git;protocol=https"
+SRC_URI = "git://github.com/meta-rust/rust-hello-world.git;protocol=https"
 SRCREV="e0fa23f1a3cb1eb1407165bd2fc36d2f6e6ad728"
 LIC_FILES_CHKSUM="file://COPYRIGHT;md5=e6b2207ac3740d2d01141c49208c2147"
 
+SRC_URI += "\
+    file://0001-enable-LTO.patch \
+    "
+
 SUMMARY = "Hello World by Cargo for Rust"
-HOMEPAGE = "https://github.com/jmesmon/rust-hello-world"
+HOMEPAGE = "https://github.com/meta-rust/rust-hello-world"
 LICENSE = "MIT | Apache-2.0"
 
 S = "${WORKDIR}/git"
diff --git a/meta/recipes-example/rustfmt/rustfmt_0.8.0.bb b/meta/recipes-example/rustfmt/rustfmt_0.8.0.bb
deleted file mode 100644
index 0c94e38e66..0000000000
--- a/meta/recipes-example/rustfmt/rustfmt_0.8.0.bb
+++ /dev/null
@@ -1,67 +0,0 @@
-# Auto-Generated by cargo-bitbake 0.3.6
-#
-inherit cargo
-
-# If this is git based prefer versioned ones if they exist
-# DEFAULT_PREFERENCE = "-1"
-
-# how to get rustfmt could be as easy as but default to a git checkout:
-# SRC_URI += "crate://crates.io/rustfmt/0.8.0"
-SRC_URI += "git://github.com/rust-lang-nursery/rustfmt.git;protocol=https;branch=syntex"
-SRCREV = "4ed5a3bac71ed104e27797ee63729b0333e39d39"
-S = "${WORKDIR}/git"
-CARGO_SRC_DIR=""
-
-
-# please note if you have entries that do not begin with crate://
-# you must change them to how that package can be fetched
-SRC_URI += " \
-crate://crates.io/aho-corasick/0.6.2 \
-crate://crates.io/bitflags/0.8.0 \
-crate://crates.io/diff/0.1.10 \
-crate://crates.io/either/1.0.3 \
-crate://crates.io/env_logger/0.4.1 \
-crate://crates.io/getopts/0.2.14 \
-crate://crates.io/itertools/0.5.9 \
-crate://crates.io/kernel32-sys/0.2.2 \
-crate://crates.io/libc/0.2.21 \
-crate://crates.io/log/0.3.6 \
-crate://crates.io/memchr/1.0.1 \
-crate://crates.io/multimap/0.3.0 \
-crate://crates.io/regex-syntax/0.4.0 \
-crate://crates.io/regex/0.2.1 \
-crate://crates.io/rustc-serialize/0.3.22 \
-crate://crates.io/same-file/0.1.3 \
-crate://crates.io/strings/0.0.1 \
-crate://crates.io/syntex_errors/0.58.1 \
-crate://crates.io/syntex_pos/0.58.1 \
-crate://crates.io/syntex_syntax/0.58.1 \
-crate://crates.io/term/0.4.5 \
-crate://crates.io/thread-id/3.0.0 \
-crate://crates.io/thread_local/0.3.3 \
-crate://crates.io/toml/0.2.1 \
-crate://crates.io/unicode-segmentation/1.1.0 \
-crate://crates.io/unicode-xid/0.0.4 \
-crate://crates.io/unreachable/0.1.1 \
-crate://crates.io/utf8-ranges/1.0.0 \
-crate://crates.io/void/1.0.2 \
-crate://crates.io/walkdir/1.0.7 \
-crate://crates.io/winapi-build/0.1.1 \
-crate://crates.io/winapi/0.2.8 \
-"
-
-
-
-LIC_FILES_CHKSUM=" \
-file://LICENSE-APACHE;md5=1836efb2eb779966696f473ee8540542 \
-file://LICENSE-MIT;md5=0b29d505d9225d1f0815cbdcf602b901 \
-"
-
-SUMMARY = "Tool to find and fix Rust formatting issues"
-HOMEPAGE = "https://github.com/rust-lang-nursery/rustfmt"
-LICENSE = "Apache-2.0 | MIT"
-
-# includes this file if it exists but does not fail
-# this is useful for anything you may want to override from
-# what cargo-bitbake generates.
-include rustfmt.inc
diff --git a/meta/recipes-example/rustfmt/rustfmt_1.4.2.bb b/meta/recipes-example/rustfmt/rustfmt_1.4.2.bb
new file mode 100644
index 0000000000..ecced49049
--- /dev/null
+++ b/meta/recipes-example/rustfmt/rustfmt_1.4.2.bb
@@ -0,0 +1,171 @@
+# Auto-Generated by cargo-bitbake 0.3.13
+#
+inherit cargo
+
+# If this is git based prefer versioned ones if they exist
+# DEFAULT_PREFERENCE = "-1"
+
+# how to get rustfmt-nightly could be as easy as but default to a git checkout:
+# SRC_URI += "crate://crates.io/rustfmt-nightly/1.4.2"
+SRC_URI += "git://github.com/rust-lang/rustfmt/;protocol=https;nobranch=1"
+SRCREV = "aeb3496f31a0dfa90fc511520d2023634e885260"
+S = "${WORKDIR}/git"
+CARGO_SRC_DIR = ""
+
+
+# please note if you have entries that do not begin with crate://
+# you must change them to how that package can be fetched
+SRC_URI += " \
+    crate://crates.io/aho-corasick/0.7.4 \
+    crate://crates.io/annotate-snippets/0.6.1 \
+    crate://crates.io/ansi_term/0.11.0 \
+    crate://crates.io/argon2rs/0.2.5 \
+    crate://crates.io/arrayvec/0.4.11 \
+    crate://crates.io/atty/0.2.13 \
+    crate://crates.io/autocfg/0.1.5 \
+    crate://crates.io/backtrace-sys/0.1.31 \
+    crate://crates.io/backtrace/0.3.33 \
+    crate://crates.io/bitflags/1.1.0 \
+    crate://crates.io/blake2-rfc/0.2.18 \
+    crate://crates.io/bstr/0.2.6 \
+    crate://crates.io/bytecount/0.5.1 \
+    crate://crates.io/byteorder/1.3.2 \
+    crate://crates.io/c2-chacha/0.2.2 \
+    crate://crates.io/cargo_metadata/0.8.1 \
+    crate://crates.io/cc/1.0.38 \
+    crate://crates.io/cfg-if/0.1.9 \
+    crate://crates.io/clap/2.33.0 \
+    crate://crates.io/cloudabi/0.0.3 \
+    crate://crates.io/constant_time_eq/0.1.3 \
+    crate://crates.io/crossbeam-channel/0.3.9 \
+    crate://crates.io/crossbeam-deque/0.2.0 \
+    crate://crates.io/crossbeam-epoch/0.3.1 \
+    crate://crates.io/crossbeam-utils/0.2.2 \
+    crate://crates.io/crossbeam-utils/0.6.6 \
+    crate://crates.io/derive-new/0.5.7 \
+    crate://crates.io/diff/0.1.11 \
+    crate://crates.io/dirs-sys/0.3.3 \
+    crate://crates.io/dirs/2.0.1 \
+    crate://crates.io/either/1.5.2 \
+    crate://crates.io/ena/0.13.0 \
+    crate://crates.io/env_logger/0.6.2 \
+    crate://crates.io/failure/0.1.5 \
+    crate://crates.io/failure_derive/0.1.5 \
+    crate://crates.io/fnv/1.0.6 \
+    crate://crates.io/fuchsia-cprng/0.1.1 \
+    crate://crates.io/getopts/0.2.19 \
+    crate://crates.io/getrandom/0.1.6 \
+    crate://crates.io/globset/0.4.4 \
+    crate://crates.io/heck/0.3.1 \
+    crate://crates.io/humantime/1.2.0 \
+    crate://crates.io/ignore/0.4.8 \
+    crate://crates.io/indexmap/1.0.2 \
+    crate://crates.io/itertools/0.8.0 \
+    crate://crates.io/itoa/0.4.4 \
+    crate://crates.io/jobserver/0.1.16 \
+    crate://crates.io/lazy_static/1.3.0 \
+    crate://crates.io/libc/0.2.60 \
+    crate://crates.io/lock_api/0.1.5 \
+    crate://crates.io/log/0.4.7 \
+    crate://crates.io/memchr/2.2.1 \
+    crate://crates.io/memoffset/0.2.1 \
+    crate://crates.io/nodrop/0.1.13 \
+    crate://crates.io/num_cpus/1.10.1 \
+    crate://crates.io/owning_ref/0.4.0 \
+    crate://crates.io/packed_simd/0.3.3 \
+    crate://crates.io/parking_lot/0.7.1 \
+    crate://crates.io/parking_lot_core/0.4.0 \
+    crate://crates.io/ppv-lite86/0.2.5 \
+    crate://crates.io/proc-macro2/0.4.30 \
+    crate://crates.io/quick-error/1.2.2 \
+    crate://crates.io/quote/0.6.13 \
+    crate://crates.io/rand/0.6.5 \
+    crate://crates.io/rand/0.7.0 \
+    crate://crates.io/rand_chacha/0.1.1 \
+    crate://crates.io/rand_chacha/0.2.1 \
+    crate://crates.io/rand_core/0.3.1 \
+    crate://crates.io/rand_core/0.4.0 \
+    crate://crates.io/rand_core/0.5.0 \
+    crate://crates.io/rand_hc/0.1.0 \
+    crate://crates.io/rand_hc/0.2.0 \
+    crate://crates.io/rand_isaac/0.1.1 \
+    crate://crates.io/rand_jitter/0.1.4 \
+    crate://crates.io/rand_os/0.1.3 \
+    crate://crates.io/rand_pcg/0.1.2 \
+    crate://crates.io/rand_xorshift/0.1.1 \
+    crate://crates.io/rdrand/0.4.0 \
+    crate://crates.io/redox_syscall/0.1.56 \
+    crate://crates.io/redox_users/0.3.0 \
+    crate://crates.io/regex-syntax/0.6.10 \
+    crate://crates.io/regex/1.2.0 \
+    crate://crates.io/rustc-ap-arena/542.0.0 \
+    crate://crates.io/rustc-ap-graphviz/542.0.0 \
+    crate://crates.io/rustc-ap-rustc_data_structures/542.0.0 \
+    crate://crates.io/rustc-ap-rustc_errors/542.0.0 \
+    crate://crates.io/rustc-ap-rustc_lexer/542.0.0 \
+    crate://crates.io/rustc-ap-rustc_macros/542.0.0 \
+    crate://crates.io/rustc-ap-rustc_target/542.0.0 \
+    crate://crates.io/rustc-ap-serialize/542.0.0 \
+    crate://crates.io/rustc-ap-syntax/542.0.0 \
+    crate://crates.io/rustc-ap-syntax_pos/542.0.0 \
+    crate://crates.io/rustc-demangle/0.1.15 \
+    crate://crates.io/rustc-hash/1.0.1 \
+    crate://crates.io/rustc-rayon-core/0.2.0 \
+    crate://crates.io/rustc-rayon/0.2.0 \
+    crate://crates.io/rustc-workspace-hack/1.0.0 \
+    crate://crates.io/rustc_version/0.2.3 \
+    crate://crates.io/ryu/1.0.0 \
+    crate://crates.io/same-file/1.0.5 \
+    crate://crates.io/scoped-tls/1.0.0 \
+    crate://crates.io/scoped_threadpool/0.1.9 \
+    crate://crates.io/scopeguard/0.3.3 \
+    crate://crates.io/semver-parser/0.7.0 \
+    crate://crates.io/semver/0.9.0 \
+    crate://crates.io/serde/1.0.97 \
+    crate://crates.io/serde_derive/1.0.97 \
+    crate://crates.io/serde_json/1.0.40 \
+    crate://crates.io/smallvec/0.6.10 \
+    crate://crates.io/spin/0.5.0 \
+    crate://crates.io/stable_deref_trait/1.1.1 \
+    crate://crates.io/strsim/0.8.0 \
+    crate://crates.io/structopt-derive/0.2.18 \
+    crate://crates.io/structopt/0.2.18 \
+    crate://crates.io/syn/0.15.42 \
+    crate://crates.io/synstructure/0.10.2 \
+    crate://crates.io/term/0.6.0 \
+    crate://crates.io/termcolor/1.0.5 \
+    crate://crates.io/textwrap/0.11.0 \
+    crate://crates.io/thread_local/0.3.6 \
+    crate://crates.io/toml/0.5.1 \
+    crate://crates.io/ucd-util/0.1.5 \
+    crate://crates.io/unicode-segmentation/1.3.0 \
+    crate://crates.io/unicode-width/0.1.5 \
+    crate://crates.io/unicode-xid/0.1.0 \
+    crate://crates.io/unicode_categories/0.1.1 \
+    crate://crates.io/utf8-ranges/1.0.3 \
+    crate://crates.io/vec_map/0.8.1 \
+    crate://crates.io/walkdir/2.2.9 \
+    crate://crates.io/winapi-i686-pc-windows-gnu/0.4.0 \
+    crate://crates.io/winapi-util/0.1.2 \
+    crate://crates.io/winapi-x86_64-pc-windows-gnu/0.4.0 \
+    crate://crates.io/winapi/0.3.7 \
+    crate://crates.io/wincolor/1.0.1 \
+"
+
+
+
+# FIXME: update generateme with the real MD5 of the license file
+LIC_FILES_CHKSUM = " \
+    file://LICENSE-APACHE;md5=1836efb2eb779966696f473ee8540542 \
+    file://LICENSE-MIT;md5=0b29d505d9225d1f0815cbdcf602b901 \
+"
+
+SUMMARY = "Tool to find and fix Rust formatting issues"
+HOMEPAGE = "https://github.com/rust-lang/rustfmt"
+LICENSE = "Apache-2.0 | MIT"
+
+# includes this file if it exists but does not fail
+# this is useful for anything you may want to override from
+# what cargo-bitbake generates.
+include rustfmt-nightly-${PV}.inc
+include rustfmt-nightly.inc
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/8] cargo/rust/rustfmt: exclude from world
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
                   ` (5 preceding siblings ...)
  2021-02-24  3:01 ` [PATCH 6/8] meta-rust: merge commits Randy MacLeod
@ 2021-02-24  3:02 ` Randy MacLeod
  2021-02-24  3:02 ` [PATCH 8/8] rust: add a language demo image to test reproducibility Randy MacLeod
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:02 UTC (permalink / raw)
  To: openembedded-core

cargo, rust, and rustfmt can't be built for the targets yet
so exclude them from world builds.

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
---
 meta/recipes-devtools/cargo/cargo.inc         | 1 +
 meta/recipes-example/rustfmt/rustfmt_1.4.2.bb | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/meta/recipes-devtools/cargo/cargo.inc b/meta/recipes-devtools/cargo/cargo.inc
index 9645b90df6..5118cc1ab1 100644
--- a/meta/recipes-devtools/cargo/cargo.inc
+++ b/meta/recipes-devtools/cargo/cargo.inc
@@ -15,6 +15,7 @@ SRC_URI += "file://0001-Disable-http2.patch"
 
 S = "${RUSTSRC}/src/tools/cargo"
 CARGO_VENDORING_DIRECTORY = "${RUSTSRC}/vendor"
+EXCLUDE_FROM_WORLD = "1"
 
 inherit cargo
 
diff --git a/meta/recipes-example/rustfmt/rustfmt_1.4.2.bb b/meta/recipes-example/rustfmt/rustfmt_1.4.2.bb
index ecced49049..b7deb4097c 100644
--- a/meta/recipes-example/rustfmt/rustfmt_1.4.2.bb
+++ b/meta/recipes-example/rustfmt/rustfmt_1.4.2.bb
@@ -11,7 +11,7 @@ SRC_URI += "git://github.com/rust-lang/rustfmt/;protocol=https;nobranch=1"
 SRCREV = "aeb3496f31a0dfa90fc511520d2023634e885260"
 S = "${WORKDIR}/git"
 CARGO_SRC_DIR = ""
-
+EXCLUDE_FROM_WORLD = "1"
 
 # please note if you have entries that do not begin with crate://
 # you must change them to how that package can be fetched
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 8/8] rust: add a language demo image to test reproducibility
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
                   ` (6 preceding siblings ...)
  2021-02-24  3:02 ` [PATCH 7/8] cargo/rust/rustfmt: exclude from world Randy MacLeod
@ 2021-02-24  3:02 ` Randy MacLeod
  2021-02-24  9:39 ` [OE-core] Merge meta-rust to oe-core Richard Purdie
       [not found] ` <1666A58EF14596DD.29651@lists.openembedded.org>
  9 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24  3:02 UTC (permalink / raw)
  To: openembedded-core

The image should contain a demo program from a variety
of languages but let's start with rust.

Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
---
 meta/recipes-devtools/images/core-image-languages.bb | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 meta/recipes-devtools/images/core-image-languages.bb

diff --git a/meta/recipes-devtools/images/core-image-languages.bb b/meta/recipes-devtools/images/core-image-languages.bb
new file mode 100644
index 0000000000..087a2a8aba
--- /dev/null
+++ b/meta/recipes-devtools/images/core-image-languages.bb
@@ -0,0 +1,12 @@
+SUMMARY = "A small image to test language support."
+
+IMAGE_INSTALL = "packagegroup-core-boot rust-hello-world ${CORE_IMAGE_EXTRA_INSTALL}"
+
+IMAGE_LINGUAS = " "
+
+LICENSE = "MIT"
+
+inherit core-image
+
+IMAGE_ROOTFS_SIZE ?= "8192"
+IMAGE_ROOTFS_EXTRA_SPACE_append = "${@bb.utils.contains("DISTRO_FEATURES", "systemd", " + 4096", "" ,d)}"
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [OE-core] Merge meta-rust to oe-core
  2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
                   ` (7 preceding siblings ...)
  2021-02-24  3:02 ` [PATCH 8/8] rust: add a language demo image to test reproducibility Randy MacLeod
@ 2021-02-24  9:39 ` Richard Purdie
  2021-02-24 18:23   ` Randy MacLeod
       [not found] ` <1666A58EF14596DD.29651@lists.openembedded.org>
  9 siblings, 1 reply; 13+ messages in thread
From: Richard Purdie @ 2021-02-24  9:39 UTC (permalink / raw)
  To: Randy MacLeod, openembedded-core

On Tue, 2021-02-23 at 22:01 -0500, Randy MacLeod wrote:
> Clean-up the merge of meta-rust to oe-core by squashing most of the 
> meta-rust history so we are left with:
> 
>   35da4b252f rust: add a language demo image to test reproducibility
>   088374371b cargo/rust/rustfmt: exclude from world
>   7df10d2a22 meta-rust: merge commits
>   4187796cd6 rust: mv README.md to recipes-devtools/rust/README-rust.md
>   03b9c60ef4 meta-rust: move code to oe-core from meta-rust layer
>   2c62874204 libgit2: pull in updates from meta-oe
>   24cb3db88c libssh2: pull in additional commits from meta-oe
>   e9a0a3bad2 Add libgit2, libssh2 from meta-oe for rust
> 
> The full diffstat is below. (1)
> 
> I didn't really notice the scripts shown below since they are mostly harmless.
> I'll review them and remove them in v2 if they don't make sense for oe-core.

This is better, thanks. My feedback from a quick glance:

a) Need maintainer entries for the new recipes
b) The scripts in scripts/ look at the very least inappropriately named
   for OE-Core, I suspect we don't want/need those.
c) Not entirely sure about the languages demo image, its not how we test
   any other language
d) There aren't any tests in meta/lib/oeqa!
e) The rust README starts "This OpenEmbedded layer provides" and has a few other
   issues.

Cheers,

Richard



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [OE-core] Merge meta-rust to oe-core
       [not found] ` <1666A58EF14596DD.29651@lists.openembedded.org>
@ 2021-02-24 16:53   ` Richard Purdie
  0 siblings, 0 replies; 13+ messages in thread
From: Richard Purdie @ 2021-02-24 16:53 UTC (permalink / raw)
  To: Randy MacLeod, openembedded-core

On Wed, 2021-02-24 at 09:39 +0000, Richard Purdie via lists.openembedded.org wrote:
> On Tue, 2021-02-23 at 22:01 -0500, Randy MacLeod wrote:
> > Clean-up the merge of meta-rust to oe-core by squashing most of the 
> > meta-rust history so we are left with:
> > 
> >   35da4b252f rust: add a language demo image to test reproducibility
> >   088374371b cargo/rust/rustfmt: exclude from world
> >   7df10d2a22 meta-rust: merge commits
> >   4187796cd6 rust: mv README.md to recipes-devtools/rust/README-rust.md
> >   03b9c60ef4 meta-rust: move code to oe-core from meta-rust layer
> >   2c62874204 libgit2: pull in updates from meta-oe
> >   24cb3db88c libssh2: pull in additional commits from meta-oe
> >   e9a0a3bad2 Add libgit2, libssh2 from meta-oe for rust
> > 
> > The full diffstat is below. (1)
> > 
> > I didn't really notice the scripts shown below since they are mostly harmless.
> > I'll review them and remove them in v2 if they don't make sense for oe-core.
> 
> This is better, thanks. My feedback from a quick glance:
> 
> a) Need maintainer entries for the new recipes

In the interests of moving things forward, I added entries for libgit2
and libssh2 and queued those bits in master-next since they seem
near enough ready.

There are other recipes which will need maintainers entries.

Cheers,

Richard


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [OE-core] Merge meta-rust to oe-core
  2021-02-24  9:39 ` [OE-core] Merge meta-rust to oe-core Richard Purdie
@ 2021-02-24 18:23   ` Randy MacLeod
  2021-02-24 20:26     ` Randy MacLeod
  0 siblings, 1 reply; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24 18:23 UTC (permalink / raw)
  To: Richard Purdie, openembedded-core

On 2021-02-24 4:39 a.m., Richard Purdie wrote:
> On Tue, 2021-02-23 at 22:01 -0500, Randy MacLeod wrote:
>> Clean-up the merge of meta-rust to oe-core by squashing most of the
>> meta-rust history so we are left with:
>>
>>    35da4b252f rust: add a language demo image to test reproducibility
>>    088374371b cargo/rust/rustfmt: exclude from world
>>    7df10d2a22 meta-rust: merge commits
>>    4187796cd6 rust: mv README.md to recipes-devtools/rust/README-rust.md
>>    03b9c60ef4 meta-rust: move code to oe-core from meta-rust layer
>>    2c62874204 libgit2: pull in updates from meta-oe
>>    24cb3db88c libssh2: pull in additional commits from meta-oe
>>    e9a0a3bad2 Add libgit2, libssh2 from meta-oe for rust
>>
>> The full diffstat is below. (1)
>>
>> I didn't really notice the scripts shown below since they are mostly harmless.
>> I'll review them and remove them in v2 if they don't make sense for oe-core.
> 
> This is better, thanks. My feedback from a quick glance:

Thanks for the comments.

> 
> a) Need maintainer entries for the new recipes

Fixed by adding myself but making it clear that other maintainers
are welcome. Once libssh/libgit2 are in master, I'll do the same for
them since they are unassigned in master-next.

> b) The scripts in scripts/ look at the very least inappropriately named
>     for OE-Core, I suspect we don't want/need those.

Working on that next (after 2 more meetings...).

> c) Not entirely sure about the languages demo image, its not how we test
>     any other language

Removed.

> d) There aren't any tests in meta/lib/oeqa!

To come. Is:
   meta/lib/oeqa/selftest/cases/gotoolchain.py
a good first step as I mentioned earlier?

> e) The rust README starts "This OpenEmbedded layer provides" and has a few other
>     issues.

Fixed.



To Do List
==========

1) cargo-bitbake - the README suggest adding this using desktop
    cargo but once we get the SDK merged, it should be added there.
    Someone suggested using devtool for this rather than cargo-bitbake.

2) Fix the SDK libcrypto, libstdc++ glibc-2.33 problem. I'm running a
git bisect using poky, meta-oe/master, meta-rust+SDK patches.

N) Remaining bugs in:

---



Would it be worth adding this to master-next in the next few days
to confirm that rust-hello-world builds for all the supported machines?
I suspect that will work but I've mostly used Ubuntu so it'd be good
to get some coverage testing.


-- 
# Randy MacLeod
# Wind River Linux

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [OE-core] Merge meta-rust to oe-core
  2021-02-24 18:23   ` Randy MacLeod
@ 2021-02-24 20:26     ` Randy MacLeod
  0 siblings, 0 replies; 13+ messages in thread
From: Randy MacLeod @ 2021-02-24 20:26 UTC (permalink / raw)
  To: Richard Purdie, openembedded-core

On 2021-02-24 1:23 p.m., Randy MacLeod wrote:
> On 2021-02-24 4:39 a.m., Richard Purdie wrote:
>> On Tue, 2021-02-23 at 22:01 -0500, Randy MacLeod wrote:
>>> Clean-up the merge of meta-rust to oe-core by squashing most of the
>>> meta-rust history so we are left with:
>>>
>>>    35da4b252f rust: add a language demo image to test reproducibility
>>>    088374371b cargo/rust/rustfmt: exclude from world
>>>    7df10d2a22 meta-rust: merge commits
>>>    4187796cd6 rust: mv README.md to recipes-devtools/rust/README-rust.md
>>>    03b9c60ef4 meta-rust: move code to oe-core from meta-rust layer
>>>    2c62874204 libgit2: pull in updates from meta-oe
>>>    24cb3db88c libssh2: pull in additional commits from meta-oe
>>>    e9a0a3bad2 Add libgit2, libssh2 from meta-oe for rust
>>>
>>> The full diffstat is below. (1)
>>>
>>> I didn't really notice the scripts shown below since they are mostly 
>>> harmless.
>>> I'll review them and remove them in v2 if they don't make sense for 
>>> oe-core.
>>
>> This is better, thanks. My feedback from a quick glance:
> 
> Thanks for the comments.
> 
>>
>> a) Need maintainer entries for the new recipes
> 
> Fixed by adding myself but making it clear that other maintainers
> are welcome. Once libssh/libgit2 are in master, I'll do the same for
> them since they are unassigned in master-next.
> 
>> b) The scripts in scripts/ look at the very least inappropriately named
>>     for OE-Core, I suspect we don't want/need those.
> 
> Working on that next (after 2 more meetings...).

You're right, they are not useful for oe-core.
Removed.


> 
>> c) Not entirely sure about the languages demo image, its not how we test
>>     any other language
> 
> Removed.
> 
>> d) There aren't any tests in meta/lib/oeqa!
> 
> To come. Is:
>    meta/lib/oeqa/selftest/cases/gotoolchain.py
> a good first step as I mentioned earlier?

??
I'll start on that next.

> 
>> e) The rust README starts "This OpenEmbedded layer provides" and has a 
>> few other
>>     issues.
> 
> Fixed.
> 
> 
> 
> To Do List
> ==========
> 
> 1) cargo-bitbake - the README suggest adding this using desktop
>     cargo but once we get the SDK merged, it should be added there.
>     Someone suggested using devtool for this rather than cargo-bitbake.
> 
> 2) Fix the SDK libcrypto, libstdc++ glibc-2.33 problem. I'm running a
> git bisect using poky, meta-oe/master, meta-rust+SDK patches.

Coming along.

> 
> N) Remaining bugs in:

   *Some* of the remaining bugs in:
       https://github.com/meta-rust/meta-rust/issues
> 
> ---
> 
> 
> 
> Would it be worth adding this to master-next in the next few days
> to confirm that rust-hello-world builds for all the supported machines?
> I suspect that will work but I've mostly used Ubuntu so it'd be good
> to get some coverage testing.
> 
> 

Updated commit history:

86109491bc maintainers: Add myself as maintainer for rust pkgs
791684e0c1 cargo/rust/rustfmt: exclude from world
b411e322b3 rust: remove container build scripts used by meta-rust
c646d47ebc rust: update the README to conform to being in oe-core
e19d823567 meta-rust: merge commits
...

This last commit also squashes a new commit from meta-rust:
    f8b9103 Remove checks for Rust versions we don't build anymore.

I'll test it and if you have capacity on the AB tonight,
I can send you a v2 in an hour or so.

-- 
# Randy MacLeod
# Wind River Linux

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-02-24 20:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-24  3:01 Merge meta-rust to oe-core Randy MacLeod
2021-02-24  3:01 ` [PATCH 1/8] Add libgit2, libssh2 from meta-oe for rust Randy MacLeod
2021-02-24  3:01 ` [PATCH 2/8] libssh2: pull in additional commits from meta-oe Randy MacLeod
2021-02-24  3:01 ` [PATCH 3/8] libgit2: pull in updates " Randy MacLeod
2021-02-24  3:01 ` [PATCH 4/8] meta-rust: move code to oe-core from meta-rust layer Randy MacLeod
2021-02-24  3:01 ` [PATCH 5/8] rust: mv README.md to recipes-devtools/rust/README-rust.md Randy MacLeod
2021-02-24  3:01 ` [PATCH 6/8] meta-rust: merge commits Randy MacLeod
2021-02-24  3:02 ` [PATCH 7/8] cargo/rust/rustfmt: exclude from world Randy MacLeod
2021-02-24  3:02 ` [PATCH 8/8] rust: add a language demo image to test reproducibility Randy MacLeod
2021-02-24  9:39 ` [OE-core] Merge meta-rust to oe-core Richard Purdie
2021-02-24 18:23   ` Randy MacLeod
2021-02-24 20:26     ` Randy MacLeod
     [not found] ` <1666A58EF14596DD.29651@lists.openembedded.org>
2021-02-24 16:53   ` Richard Purdie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.