Message ID | 20170402194651.28684-4-eric.le.bihan.dev@free.fr |
---|---|
State | Changes Requested |
Headers | show |
Hi Eric, On Sun, 2017-04-02 at 21:46 +0200, Eric Le Bihan wrote: > This new package provides the compiler for the Rust programming > language. > > Currently, only the host variant is built. > > The Rust compiler uses LLVM as its backend: a copy of LLVM source > code > is provided and CMake is used to build it. It is possible to use a > pre-built external copy. When LLVM/clang will be available in > Buildroot, > it would be possible to benefit from this feature and thus decrease > build time. > > LLVM is configured to generate code for x86, ARM, PowerPC and MIPS > architectures. > > The Rust compiler uses Cargo as its build system and is written in > Rust. > Therefore this package depends on cargo-bootstrap and rust-bootstrap. > > The internal build process is as follows: > > 1. rustc-stage0, provided by rust-bootstrap, is used to build > rustc-stage1. > 2. rust-stage1 builds the final Rust compiler (rust-stage2) > and the standard library for the host architecture. > 3. the standard library for the target architecture is built. So, we are doing the following: fetch the predecessor rust version 1.15.1 as binary to use it as stage0 compiler for building the latest rust stable version 1.16.0. Why not just fetch the latest stable version and install it into the host dir? The same goes with libstd and cargo. I mean, we have to fetch some binaries anyway, so why do the time-consuming build steps anyway? Shouldn't there be at least the option just to fetch the latest stable version? > The target architecture to support is given by the GNU/LLVM target > triple. Rust supports some predefined targets [1]. As the build > system > expects the triple to be in the form of <arch>-unknown-<system> and > Buildroot toolchain wrapper uses <arch>-buildroot-<system>, the > package > Makefile defines the $(RUST_TARGET_NAME) and uses it instead of > $(GNU_TARGET_NAME). > > When compiling Rust code with this compiler, the generated program > only > depends on the target C library, as it is statically linked to the > Rust > standard library and any other code from Rust packages (a.k.a. > "crates"). > > If the jemalloc package is selected, support for this memory > allocator > will be enabled in the target standard library. > > [1] https://forge.rust-lang.org/platform-support.html > > Signed-off-by: Eric Le Bihan <eric.le.bihan.dev@free.fr> > --- > DEVELOPERS | 1 + > package/Config.in.host | 1 + > package/rust/Config.in.host | 33 ++++++++++++++++++ > package/rust/rust.hash | 2 ++ > package/rust/rust.mk | 85 > +++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 122 insertions(+) > create mode 100644 package/rust/Config.in.host > create mode 100644 package/rust/rust.hash > create mode 100644 package/rust/rust.mk > > diff --git a/DEVELOPERS b/DEVELOPERS > index 1fed408..c0e7833 100644 > --- a/DEVELOPERS > +++ b/DEVELOPERS > @@ -450,6 +450,7 @@ F: package/hicolor-icon-theme/ > F: package/jemalloc/ > F: package/ninja/ > F: package/rust-bootstrap > +F: package/rust > F: package/s6/ > F: package/s6-dns/ > F: package/s6-linux-init/ > diff --git a/package/Config.in.host b/package/Config.in.host > index 38f919a..ef5f23f 100644 > --- a/package/Config.in.host > +++ b/package/Config.in.host > @@ -39,6 +39,7 @@ menu "Host utilities" > source "package/python-lxml/Config.in.host" > source "package/qemu/Config.in.host" > source "package/raspberrypi-usbboot/Config.in.host" > + source "package/rust/Config.in.host" > source "package/s6-rc/Config.in.host" > source "package/sam-ba/Config.in.host" > source "package/squashfs/Config.in.host" > diff --git a/package/rust/Config.in.host > b/package/rust/Config.in.host > new file mode 100644 > index 0000000..384a071 > --- /dev/null > +++ b/package/rust/Config.in.host > @@ -0,0 +1,33 @@ > +config BR2_PACKAGE_HOST_RUST_ARCH_SUPPORTS > + bool > + default y > + depends on BR2_HOSTARCH = "x86_64" || BR2_HOSTARCH = "x86" > + depends on BR2_i386 || BR2_x86_64 \ > + || BR2_arm || BR2_aarch64 \ > + || BR2_powerpc || BR2_powerpc64 \ > + || BR2_mips || BR2_mipsel || BR2_mips64 || > BR2_mips64el > + depends on !BR2_ARM_CPU_ARMV4 && !BR2_ARM_CPU_ARMV5 > + depends on !BR2_MIPS_NABI32 > + depends on BR2_TOOLCHAIN_USES_GLIBC > + depends on BR2_HOST_GCC_AT_LEAST_4_7 # required by LLVM > + # triggers ICE on trunc_int_for_mode, at explow.c:56 > + depends on BR2_TOOLCHAIN_GCC_AT_LEAST_5 || !BR2_aarch64 > + > +comment "host-rust needs a toolchain w/ gcc >= 5" > + depends on !BR2_TOOLCHAIN_GCC_AT_LEAST_5 && BR2_aarch64 > + > +config BR2_PACKAGE_HOST_RUST > + bool "host rust" > + depends on BR2_PACKAGE_HOST_RUST_ARCH_SUPPORTS > + help > + Compiler for the Rust programming language. > + > + This package will build the compiler for the host as well > as > + a cross-compiled version of the Rust standard library for > the > + target. > + > + Note that the target standard library does not need to be > + present on the target root filesystem, as it is statically > + linked to the program. > + > + http://www.rust-lang.org > diff --git a/package/rust/rust.hash b/package/rust/rust.hash > new file mode 100644 > index 0000000..3b04dfd > --- /dev/null > +++ b/package/rust/rust.hash > @@ -0,0 +1,2 @@ > +# Locally calculated > +sha256 > f966b31eb1cd9bd2df817c391a338eeb5b9253ae0a19bf8a11960c560f96e8b4 rus > tc-1.16.0-src.tar.gz > diff --git a/package/rust/rust.mk b/package/rust/rust.mk > new file mode 100644 > index 0000000..12f4428 > --- /dev/null > +++ b/package/rust/rust.mk > @@ -0,0 +1,85 @@ > +#################################################################### > ############ > +# > +# rust > +# > +#################################################################### > ############ > + > +RUST_VERSION = 1.16.0 > +RUST_SOURCE = rustc-$(RUST_VERSION)-src.tar.gz > +RUST_SITE = https://static.rust-lang.org/dist > +RUST_LICENSE = Apache-2.0 or MIT > +RUST_LICENSE_FILES = LICENSE-APACHE LICENSE-MIT > + > +HOST_RUST_DEPENDENCIES = \ > + toolchain \ > + host-rust-bootstrap \ > + host-cargo-bootstrap \ > + host-python \ > + host-cmake > + > +ifeq ($(BR2_PACKAGE_JEMALLOC),y) > +HOST_RUST_DEPENDENCIES += jemalloc > +HOST_RUST_JEMALLOC_ENABLED = true > +HOST_RUST_JEMALLOC_CONF = 'jemalloc = > "$(STAGING_DIR)/usr/lib/libjemalloc_pic.a"' > +else > +HOST_RUST_JEMALLOC_ENABLED = false > +endif > + > +HOST_RUST_BUILD_OPTS = $(if $(VERBOSE),--verbose) > + > +RUST_TARGET_NAME := $(subst buildroot,unknown,$(GNU_TARGET_NAME)) > + > +ifeq ($(BR2_ARM_CPU_ARMV7A),y) > +RUST_TARGET_NAME := $(subst arm-,armv7-,$(RUST_TARGET_NAME)) > +endif > + > +ifeq ($(BR2_MIPS_NABI64),y) > +RUST_TARGET_NAME := $(subst -gnu,-gnuabi64,$(RUST_TARGET_NAME)) > +endif > + > +define HOST_RUST_CONFIGURE_CMDS > + (cd $(@D); \ > + echo '[build]' > config.toml; \ > + echo 'target = ["$(RUST_TARGET_NAME)"]' >> > config.toml; \ > + echo 'cargo = > "$(HOST_CARGO_BOOTSTRAP_DIR)/cargo/bin/cargo"' >> config.toml; \ > + echo 'rustc = > "$(HOST_RUST_BOOTSTRAP_DIR)/rustc/bin/rustc"' >> config.toml; \ > + echo 'python = "$(HOST_DIR)/usr/bin/python2"' >> > config.toml; \ > + echo 'submodules = false' >> config.toml; \ > + echo 'vendor = true' >> config.toml; \ > + echo 'compiler-docs = false' >> config.toml; \ > + echo 'docs = false' >> config.toml; \ > + echo '[install]' >> config.toml; \ > + echo 'prefix = "$(HOST_DIR)/usr"' >> config.toml; \ > + echo '[rust]' >> config.toml; \ > + echo 'use-jemalloc = $(HOST_RUST_JEMALLOC_ENABLED)' > >> config.toml; \ > + echo '[target.$(RUST_TARGET_NAME)]' >> config.toml; > \ > + echo 'cc = "$(TARGET_CROSS)gcc"' >> config.toml; \ > + echo 'cxx = "$(TARGET_CROSS)g++"' >> config.toml; \ > + echo $(HOST_RUST_JEMALLOC_CONF) >> config.toml; \ > + ) > +endef > + > +define HOST_RUST_BUILD_CMDS > + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 > x.py \ > + build $(HOST_RUST_BUILD_OPTS)) > +endef > + > +define HOST_RUST_INSTALL_LIBSTD_TARGET > + (cd $(@D)/build/tmp/dist/rust-std-$(RUST_VERSION)-dev- > $(RUST_TARGET_NAME); \ > + ./install.sh \ > + --prefix=$(HOST_DIR)/usr \ > + --docdir=$(HOST_DIR)/usr/share/doc/rust \ > + --libdir=$(HOST_DIR)/usr/lib \ > + --mandir=$(HOST_DIR)/usr/share/man \ > + --disable-ldconfig) > +endef > + > +define HOST_RUST_INSTALL_CMDS > + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 > x.py \ > + dist $(HOST_RUST_BUILD_OPTS)) > + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 > x.py \ > + dist --install $(HOST_RUST_BUILD_OPTS)) > + $(HOST_RUST_INSTALL_LIBSTD_TARGET) > +endef > + > +$(eval $(host-generic-package)) Best regards, Jörg Krause
Hi! On 17-04-07 09:18:42, Jörg Krause wrote: > Hi Eric, > > On Sun, 2017-04-02 at 21:46 +0200, Eric Le Bihan wrote: > > This new package provides the compiler for the Rust programming > > language. > > > > Currently, only the host variant is built. > > > > The Rust compiler uses LLVM as its backend: a copy of LLVM source > > code > > is provided and CMake is used to build it. It is possible to use a > > pre-built external copy. When LLVM/clang will be available in > > Buildroot, > > it would be possible to benefit from this feature and thus decrease > > build time. > > > > LLVM is configured to generate code for x86, ARM, PowerPC and MIPS > > architectures. > > > > The Rust compiler uses Cargo as its build system and is written in > > Rust. > > Therefore this package depends on cargo-bootstrap and rust-bootstrap. > > > > The internal build process is as follows: > > > > 1. rustc-stage0, provided by rust-bootstrap, is used to build > > rustc-stage1. > > 2. rust-stage1 builds the final Rust compiler (rust-stage2) > > and the standard library for the host architecture. > > 3. the standard library for the target architecture is built. > > So, we are doing the following: fetch the predecessor rust version > 1.15.1 as binary to use it as stage0 compiler for building the latest > rust stable version 1.16.0. Why not just fetch the latest stable > version and install it into the host dir? The same goes with libstd and > cargo. I mean, we have to fetch some binaries anyway, so why do the > time-consuming build steps anyway? Shouldn't there be at least the > option just to fetch the latest stable version? > It is true that building the Rust compiler is time consuming. As stated in the comment, this can be decreased if LLVM was already available. But if LLVM itself is built from source and not fetched as binary from Internet, then the issue is still there. Currently Buildroot only offers downloading binary versions of the C/C++ cross-compilers. It does not take into account alternative C/C++ cross-compilers like LLVM/Clang or compilers for new languages like Rust, D, or Haskell (though I do not know if Haskell is useful on embedded systems). So, would it help to have a "Programming Languages" section in menuconfig where you can select Rust (or any other language) and choose between a using a pre-built compiler or build it from source? And where shoud LLVM/clang be exposed? Note: Building a cross-compiler for D can be done via a patch to GCC thanks to GDC [1], but IIRC cross-compiling libphobos, the standard library, is another matter. [1] https://github.com/D-Programming-GDC/GDC/releases > > The target architecture to support is given by the GNU/LLVM target > > triple. Rust supports some predefined targets [1]. As the build > > system > > expects the triple to be in the form of <arch>-unknown-<system> and > > Buildroot toolchain wrapper uses <arch>-buildroot-<system>, the > > package > > Makefile defines the $(RUST_TARGET_NAME) and uses it instead of > > $(GNU_TARGET_NAME). > > > > When compiling Rust code with this compiler, the generated program > > only > > depends on the target C library, as it is statically linked to the > > Rust > > standard library and any other code from Rust packages (a.k.a. > > "crates"). > > > > If the jemalloc package is selected, support for this memory > > allocator > > will be enabled in the target standard library. > > > > [1] https://forge.rust-lang.org/platform-support.html > > > > Signed-off-by: Eric Le Bihan <eric.le.bihan.dev@free.fr> > > --- > > DEVELOPERS | 1 + > > package/Config.in.host | 1 + > > package/rust/Config.in.host | 33 ++++++++++++++++++ > > package/rust/rust.hash | 2 ++ > > package/rust/rust.mk | 85 > > +++++++++++++++++++++++++++++++++++++++++++++ > > 5 files changed, 122 insertions(+) > > create mode 100644 package/rust/Config.in.host > > create mode 100644 package/rust/rust.hash > > create mode 100644 package/rust/rust.mk > > > > diff --git a/DEVELOPERS b/DEVELOPERS > > index 1fed408..c0e7833 100644 > > --- a/DEVELOPERS > > +++ b/DEVELOPERS > > @@ -450,6 +450,7 @@ F: package/hicolor-icon-theme/ > > F: package/jemalloc/ > > F: package/ninja/ > > F: package/rust-bootstrap > > +F: package/rust > > F: package/s6/ > > F: package/s6-dns/ > > F: package/s6-linux-init/ > > diff --git a/package/Config.in.host b/package/Config.in.host > > index 38f919a..ef5f23f 100644 > > --- a/package/Config.in.host > > +++ b/package/Config.in.host > > @@ -39,6 +39,7 @@ menu "Host utilities" > > source "package/python-lxml/Config.in.host" > > source "package/qemu/Config.in.host" > > source "package/raspberrypi-usbboot/Config.in.host" > > + source "package/rust/Config.in.host" > > source "package/s6-rc/Config.in.host" > > source "package/sam-ba/Config.in.host" > > source "package/squashfs/Config.in.host" > > diff --git a/package/rust/Config.in.host > > b/package/rust/Config.in.host > > new file mode 100644 > > index 0000000..384a071 > > --- /dev/null > > +++ b/package/rust/Config.in.host > > @@ -0,0 +1,33 @@ > > +config BR2_PACKAGE_HOST_RUST_ARCH_SUPPORTS > > + bool > > + default y > > + depends on BR2_HOSTARCH = "x86_64" || BR2_HOSTARCH = "x86" > > + depends on BR2_i386 || BR2_x86_64 \ > > + || BR2_arm || BR2_aarch64 \ > > + || BR2_powerpc || BR2_powerpc64 \ > > + || BR2_mips || BR2_mipsel || BR2_mips64 || > > BR2_mips64el > > + depends on !BR2_ARM_CPU_ARMV4 && !BR2_ARM_CPU_ARMV5 > > + depends on !BR2_MIPS_NABI32 > > + depends on BR2_TOOLCHAIN_USES_GLIBC > > + depends on BR2_HOST_GCC_AT_LEAST_4_7 # required by LLVM > > + # triggers ICE on trunc_int_for_mode, at explow.c:56 > > + depends on BR2_TOOLCHAIN_GCC_AT_LEAST_5 || !BR2_aarch64 > > + > > +comment "host-rust needs a toolchain w/ gcc >= 5" > > + depends on !BR2_TOOLCHAIN_GCC_AT_LEAST_5 && BR2_aarch64 > > + > > +config BR2_PACKAGE_HOST_RUST > > + bool "host rust" > > + depends on BR2_PACKAGE_HOST_RUST_ARCH_SUPPORTS > > + help > > + Compiler for the Rust programming language. > > + > > + This package will build the compiler for the host as well > > as > > + a cross-compiled version of the Rust standard library for > > the > > + target. > > + > > + Note that the target standard library does not need to be > > + present on the target root filesystem, as it is statically > > + linked to the program. > > + > > + http://www.rust-lang.org > > diff --git a/package/rust/rust.hash b/package/rust/rust.hash > > new file mode 100644 > > index 0000000..3b04dfd > > --- /dev/null > > +++ b/package/rust/rust.hash > > @@ -0,0 +1,2 @@ > > +# Locally calculated > > +sha256 > > f966b31eb1cd9bd2df817c391a338eeb5b9253ae0a19bf8a11960c560f96e8b4 rus > > tc-1.16.0-src.tar.gz > > diff --git a/package/rust/rust.mk b/package/rust/rust.mk > > new file mode 100644 > > index 0000000..12f4428 > > --- /dev/null > > +++ b/package/rust/rust.mk > > @@ -0,0 +1,85 @@ > > +#################################################################### > > ############ > > +# > > +# rust > > +# > > +#################################################################### > > ############ > > + > > +RUST_VERSION = 1.16.0 > > +RUST_SOURCE = rustc-$(RUST_VERSION)-src.tar.gz > > +RUST_SITE = https://static.rust-lang.org/dist > > +RUST_LICENSE = Apache-2.0 or MIT > > +RUST_LICENSE_FILES = LICENSE-APACHE LICENSE-MIT > > + > > +HOST_RUST_DEPENDENCIES = \ > > + toolchain \ > > + host-rust-bootstrap \ > > + host-cargo-bootstrap \ > > + host-python \ > > + host-cmake > > + > > +ifeq ($(BR2_PACKAGE_JEMALLOC),y) > > +HOST_RUST_DEPENDENCIES += jemalloc > > +HOST_RUST_JEMALLOC_ENABLED = true > > +HOST_RUST_JEMALLOC_CONF = 'jemalloc = > > "$(STAGING_DIR)/usr/lib/libjemalloc_pic.a"' > > +else > > +HOST_RUST_JEMALLOC_ENABLED = false > > +endif > > + > > +HOST_RUST_BUILD_OPTS = $(if $(VERBOSE),--verbose) > > + > > +RUST_TARGET_NAME := $(subst buildroot,unknown,$(GNU_TARGET_NAME)) > > + > > +ifeq ($(BR2_ARM_CPU_ARMV7A),y) > > +RUST_TARGET_NAME := $(subst arm-,armv7-,$(RUST_TARGET_NAME)) > > +endif > > + > > +ifeq ($(BR2_MIPS_NABI64),y) > > +RUST_TARGET_NAME := $(subst -gnu,-gnuabi64,$(RUST_TARGET_NAME)) > > +endif > > + > > +define HOST_RUST_CONFIGURE_CMDS > > + (cd $(@D); \ > > + echo '[build]' > config.toml; \ > > + echo 'target = ["$(RUST_TARGET_NAME)"]' >> > > config.toml; \ > > + echo 'cargo = > > "$(HOST_CARGO_BOOTSTRAP_DIR)/cargo/bin/cargo"' >> config.toml; \ > > + echo 'rustc = > > "$(HOST_RUST_BOOTSTRAP_DIR)/rustc/bin/rustc"' >> config.toml; \ > > + echo 'python = "$(HOST_DIR)/usr/bin/python2"' >> > > config.toml; \ > > + echo 'submodules = false' >> config.toml; \ > > + echo 'vendor = true' >> config.toml; \ > > + echo 'compiler-docs = false' >> config.toml; \ > > + echo 'docs = false' >> config.toml; \ > > + echo '[install]' >> config.toml; \ > > + echo 'prefix = "$(HOST_DIR)/usr"' >> config.toml; \ > > + echo '[rust]' >> config.toml; \ > > + echo 'use-jemalloc = $(HOST_RUST_JEMALLOC_ENABLED)' > > >> config.toml; \ > > + echo '[target.$(RUST_TARGET_NAME)]' >> config.toml; > > \ > > + echo 'cc = "$(TARGET_CROSS)gcc"' >> config.toml; \ > > + echo 'cxx = "$(TARGET_CROSS)g++"' >> config.toml; \ > > + echo $(HOST_RUST_JEMALLOC_CONF) >> config.toml; \ > > + ) > > +endef > > + > > +define HOST_RUST_BUILD_CMDS > > + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 > > x.py \ > > + build $(HOST_RUST_BUILD_OPTS)) > > +endef > > + > > +define HOST_RUST_INSTALL_LIBSTD_TARGET > > + (cd $(@D)/build/tmp/dist/rust-std-$(RUST_VERSION)-dev- > > $(RUST_TARGET_NAME); \ > > + ./install.sh \ > > + --prefix=$(HOST_DIR)/usr \ > > + --docdir=$(HOST_DIR)/usr/share/doc/rust \ > > + --libdir=$(HOST_DIR)/usr/lib \ > > + --mandir=$(HOST_DIR)/usr/share/man \ > > + --disable-ldconfig) > > +endef > > + > > +define HOST_RUST_INSTALL_CMDS > > + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 > > x.py \ > > + dist $(HOST_RUST_BUILD_OPTS)) > > + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 > > x.py \ > > + dist --install $(HOST_RUST_BUILD_OPTS)) > > + $(HOST_RUST_INSTALL_LIBSTD_TARGET) > > +endef > > + > > +$(eval $(host-generic-package)) > > Best regards, > Jörg Krause -- ELB
Hi, On Sat, 2017-04-08 at 12:09 +0200, Eric Le Bihan wrote: > Hi! > > On 17-04-07 09:18:42, Jörg Krause wrote: > > Hi Eric, > > > > On Sun, 2017-04-02 at 21:46 +0200, Eric Le Bihan wrote: > > > This new package provides the compiler for the Rust programming > > > language. > > > > > > Currently, only the host variant is built. > > > > > > The Rust compiler uses LLVM as its backend: a copy of LLVM source > > > code > > > is provided and CMake is used to build it. It is possible to use a > > > pre-built external copy. When LLVM/clang will be available in > > > Buildroot, > > > it would be possible to benefit from this feature and thus decrease > > > build time. > > > > > > LLVM is configured to generate code for x86, ARM, PowerPC and MIPS > > > architectures. > > > > > > The Rust compiler uses Cargo as its build system and is written in > > > Rust. > > > Therefore this package depends on cargo-bootstrap and rust-bootstrap. > > > > > > The internal build process is as follows: > > > > > > 1. rustc-stage0, provided by rust-bootstrap, is used to build > > > rustc-stage1. > > > 2. rust-stage1 builds the final Rust compiler (rust-stage2) > > > and the standard library for the host architecture. > > > 3. the standard library for the target architecture is built. > > > > So, we are doing the following: fetch the predecessor rust version > > 1.15.1 as binary to use it as stage0 compiler for building the latest > > rust stable version 1.16.0. Why not just fetch the latest stable > > version and install it into the host dir? The same goes with libstd and > > cargo. I mean, we have to fetch some binaries anyway, so why do the > > time-consuming build steps anyway? Shouldn't there be at least the > > option just to fetch the latest stable version? > > > > It is true that building the Rust compiler is time consuming. As stated > in the comment, this can be decreased if LLVM was already available. But > if LLVM itself is built from source and not fetched as binary from > Internet, then the issue is still there. > > Currently Buildroot only offers downloading binary versions of the C/C++ > cross-compilers. It does not take into account alternative C/C++ > cross-compilers like LLVM/Clang or compilers for new languages like > Rust, D, or Haskell (though I do not know if Haskell is useful on > embedded systems). For now, we could use the host rustc package to fetch the latest stable binary for the host architecture. Additionally, we could add the option to build the Rust compiler within Buildroot. In my opinion, this option only makes sense if the compiler can be configured meaningfully. > So, would it help to have a "Programming Languages" section in > menuconfig where you can select Rust (or any other language) and choose > between a using a pre-built compiler or build it from source? In my opinion it would make more sense to have a menu "Toolchains" with the submenus "C/C++ Toolchain", "Rust Toolchain", ... > And where shoud LLVM/clang be exposed? I would put it into "C/C++ Toolchain" (if we had such a menu). > Note: Building a cross-compiler for D can be done via a patch to GCC > thanks to GDC [1], but IIRC cross-compiling libphobos, the standard > library, is another matter. > > [1] https://github.com/D-Programming-GDC/GDC/releases Jörg
On 10-04-17 21:02, Jörg Krause wrote: > Hi, > > On Sat, 2017-04-08 at 12:09 +0200, Eric Le Bihan wrote: [snip] >> Currently Buildroot only offers downloading binary versions of the C/C++ >> cross-compilers. It does not take into account alternative C/C++ >> cross-compilers like LLVM/Clang or compilers for new languages like >> Rust, D, or Haskell (though I do not know if Haskell is useful on >> embedded systems). There's a huge difference between alternative C/C++ compilers and compilers for other languages. Compilers for other languages we already have: python, mono, erlang. These are just normal packages, and any package in that language depends on the host-xxx package to provide the compiler. Similar to how packages that use the cmake buildsystem depend on the host-cmake package. Alternative C/C++ compilers are something else entirely, because they replace the special 'toolchain' target. Only when you can build an entire system with only the Rust compiler and without C/C++ compiler you can consider them equivalent. That day is still far away. > For now, we could use the host rustc package to fetch the latest stable > binary for the host architecture. Additionally, we could add the option > to build the Rust compiler within Buildroot. In my opinion, this option > only makes sense if the compiler can be configured meaningfully. I agree. >> So, would it help to have a "Programming Languages" section in >> menuconfig where you can select Rust (or any other language) and choose >> between a using a pre-built compiler or build it from source? > > In my opinion it would make more sense to have a menu "Toolchains" with > the submenus "C/C++ Toolchain", "Rust Toolchain", ... Given what I wrote above, I disagree. For the time being it's fine in the host packages menu. If that menu becomes too large, we could add something like an 'Alternative programming languages' menu. >> And where shoud LLVM/clang be exposed? > > I would put it into "C/C++ Toolchain" (if we had such a menu). That's slightly more complicated. LLVM is just a library so it's just in the host menu. clang is a compiler that can be a replacement for gcc, so it'd have to go into the toolchain menu. Actually, Romain is working on LLVM/Clang. He's going to start adding it as a normal host package, so not as a replacement of gcc as the toolchain. Regards, Arnout > >> Note: Building a cross-compiler for D can be done via a patch to GCC >> thanks to GDC [1], but IIRC cross-compiling libphobos, the standard >> library, is another matter. >> >> [1] https://github.com/D-Programming-GDC/GDC/releases > > Jörg > _______________________________________________ > buildroot mailing list > buildroot@busybox.net > http://lists.busybox.net/mailman/listinfo/buildroot >
Hi, On Mon, 2017-04-10 at 23:43 +0200, Arnout Vandecappelle wrote: > > On 10-04-17 21:02, Jörg Krause wrote: > > Hi, > > > > On Sat, 2017-04-08 at 12:09 +0200, Eric Le Bihan wrote: > > [snip] > > > Currently Buildroot only offers downloading binary versions of the C/C++ > > > cross-compilers. It does not take into account alternative C/C++ > > > cross-compilers like LLVM/Clang or compilers for new languages like > > > Rust, D, or Haskell (though I do not know if Haskell is useful on > > > embedded systems). > > There's a huge difference between alternative C/C++ compilers and compilers for > other languages. > > Compilers for other languages we already have: python, mono, erlang. These are > just normal packages, and any package in that language depends on the host-xxx > package to provide the compiler. Similar to how packages that use the cmake > buildsystem depend on the host-cmake package. > > Alternative C/C++ compilers are something else entirely, because they replace > the special 'toolchain' target. > > Only when you can build an entire system with only the Rust compiler and > without C/C++ compiler you can consider them equivalent. That day is still far away. I see! > > For now, we could use the host rustc package to fetch the latest stable > > binary for the host architecture. Additionally, we could add the option > > to build the Rust compiler within Buildroot. In my opinion, this option > > only makes sense if the compiler can be configured meaningfully. > > I agree. Cool. @Eric: Do you mind to do that? By default fetch the latest stable release, and alternatively offer an option to build a "Custom Rust package". I think it would also be helpful to have at least one Rust package to add as a proof of concept. > > > > So, would it help to have a "Programming Languages" section in > > > menuconfig where you can select Rust (or any other language) and choose > > > between a using a pre-built compiler or build it from source? > > > > In my opinion it would make more sense to have a menu "Toolchains" with > > the submenus "C/C++ Toolchain", "Rust Toolchain", ... > > Given what I wrote above, I disagree. For the time being it's fine in the host > packages menu. If that menu becomes too large, we could add something like an > 'Alternative programming languages' menu. > Sounds reasonable. > > > > And where shoud LLVM/clang be exposed? > > > > I would put it into "C/C++ Toolchain" (if we had such a menu). > > That's slightly more complicated. LLVM is just a library so it's just in the > host menu. clang is a compiler that can be a replacement for gcc, so it'd have > to go into the toolchain menu. > > Actually, Romain is working on LLVM/Clang. He's going to start adding it as a > normal host package, so not as a replacement of gcc as the toolchain. Nice! Jörg
Le 2017-04-13 06:05, Jörg Krause a écrit : > Hi, > > On Mon, 2017-04-10 at 23:43 +0200, Arnout Vandecappelle wrote: >> >> On 10-04-17 21:02, Jörg Krause wrote: [snip] >> > For now, we could use the host rustc package to fetch the latest stable >> > binary for the host architecture. Additionally, we could add the option >> > to build the Rust compiler within Buildroot. In my opinion, this option >> > only makes sense if the compiler can be configured meaningfully. >> >> I agree. > > Cool. > > @Eric: Do you mind to do that? By default fetch the latest stable > release, and alternatively offer an option to build a "Custom Rust > package". I think it would also be helpful to have at least one Rust > package to add as a proof of concept. Currently this patch series provides: - rust-bootstrap, which fetches the binary version N-1 of rust. - cargo-bootstrap, which fetches a nightly binary version of cargo. - rust, which uses the two previous packages to build version N of rust. I also have another patch series which adds a new package for cargo, which uses cargo-bootstrap and rust to build Cargo from source. IMHO, modifying the current version of the rust package to download the latest version and providing an option to build from source would make the Makefile of the package more complicated. Would it not be better to use host virtual packages? Something like: - rust-rustc: host virtual package, with two providers: * rustc-bin: fetches binary version N of rustc and libstd (host and target). * rustc: builds version N of rustc and libstd (host and target). Depends on rust-bootstrap (version N-1) and cargo-bootstrap. - rust-cargo: host virtual package with two providers: * cargo-bin: fetches binary version N of Cargo. * cargo: builds version N of Cargo using rust and cargo-bootstrap. And instead of littering the package directory with rust-* and cargo-*, how about putting all these packages in a parent directory named package/rust? The file package/Config.in.host should also be modified to include package/rust/Config.in.host, which would present the options to select the providers for rust-rustc and rust-cargo.
On 13-04-17 18:49, Eric Le Bihan wrote: > Le 2017-04-13 06:05, Jörg Krause a écrit : >> Hi, >> >> On Mon, 2017-04-10 at 23:43 +0200, Arnout Vandecappelle wrote: >>> >>> On 10-04-17 21:02, Jörg Krause wrote: > [snip] >>> > For now, we could use the host rustc package to fetch the latest stable >>> > binary for the host architecture. Additionally, we could add the option >>> > to build the Rust compiler within Buildroot. In my opinion, this option >>> > only makes sense if the compiler can be configured meaningfully. >>> >>> I agree. >> >> Cool. >> >> @Eric: Do you mind to do that? By default fetch the latest stable >> release, and alternatively offer an option to build a "Custom Rust >> package". I think it would also be helpful to have at least one Rust >> package to add as a proof of concept. > > Currently this patch series provides: > > - rust-bootstrap, which fetches the binary version N-1 of rust. > - cargo-bootstrap, which fetches a nightly binary version of cargo. > - rust, which uses the two previous packages to build version N of rust. > > I also have another patch series which adds a new package for cargo, which > uses cargo-bootstrap and rust to build Cargo from source. > > IMHO, modifying the current version of the rust package to download the > latest version and providing an option to build from source would make > the Makefile of the package more complicated. I think Joerg's point is that we could just as well have *only* rust-bootstrap (which would then be named "rust", of course). Why would you fetch version N-1 to build version N, if you can just fetch version N? If there is a reason to actually build it (like we need to set some options), then it makes sense to have the -bootstrap. > > Would it not be better to use host virtual packages? Something like: > > - rust-rustc: host virtual package, with two providers: > * rustc-bin: fetches binary version N of rustc and libstd (host and > target). > * rustc: builds version N of rustc and libstd (host and target). > Depends on rust-bootstrap (version N-1) and cargo-bootstrap. > - rust-cargo: host virtual package with two providers: > * cargo-bin: fetches binary version N of Cargo. > * cargo: builds version N of Cargo using rust and cargo-bootstrap. This actually sounds like an elegant solution to me. And it scales, i.e. you can start just adding rustc-bin and cargo-bin, and later add rustc and cargo if it's useful for something. > And instead of littering the package directory with rust-* and cargo-*, > how about putting all these packages in a parent directory named > package/rust? Since you haven't proposed any package yet that depends on rust, it's hard to say. We prefer to avoid subdirectories because it makes things harder to find - we actually moved things out of a few subdirectories some years ago. The ones that are left are the obvious ones: qt5, gstreamer{,1}, x11r7. For Rust, I don't see how it makes much sense. It could make sense for things like perl, python and lua because there the packages are really tied to the language (except for a few user-facing applications, but these don't usually have a python- prefix). For Rust, however, I think the packages that depend on it are not so tied to the language. They'll either be user-facing applications, or libraries that may just as well be linked with C code. No? So the rust/ directory would have just rust and cargo... What *does* make sense, is to keep rust and cargo together in Config.in.host. Regards, Arnout > The file package/Config.in.host should also be modified to include > package/rust/Config.in.host, which would present the options to select > the providers for rust-rustc and rust-cargo. > >
diff --git a/DEVELOPERS b/DEVELOPERS index 1fed408..c0e7833 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -450,6 +450,7 @@ F: package/hicolor-icon-theme/ F: package/jemalloc/ F: package/ninja/ F: package/rust-bootstrap +F: package/rust F: package/s6/ F: package/s6-dns/ F: package/s6-linux-init/ diff --git a/package/Config.in.host b/package/Config.in.host index 38f919a..ef5f23f 100644 --- a/package/Config.in.host +++ b/package/Config.in.host @@ -39,6 +39,7 @@ menu "Host utilities" source "package/python-lxml/Config.in.host" source "package/qemu/Config.in.host" source "package/raspberrypi-usbboot/Config.in.host" + source "package/rust/Config.in.host" source "package/s6-rc/Config.in.host" source "package/sam-ba/Config.in.host" source "package/squashfs/Config.in.host" diff --git a/package/rust/Config.in.host b/package/rust/Config.in.host new file mode 100644 index 0000000..384a071 --- /dev/null +++ b/package/rust/Config.in.host @@ -0,0 +1,33 @@ +config BR2_PACKAGE_HOST_RUST_ARCH_SUPPORTS + bool + default y + depends on BR2_HOSTARCH = "x86_64" || BR2_HOSTARCH = "x86" + depends on BR2_i386 || BR2_x86_64 \ + || BR2_arm || BR2_aarch64 \ + || BR2_powerpc || BR2_powerpc64 \ + || BR2_mips || BR2_mipsel || BR2_mips64 || BR2_mips64el + depends on !BR2_ARM_CPU_ARMV4 && !BR2_ARM_CPU_ARMV5 + depends on !BR2_MIPS_NABI32 + depends on BR2_TOOLCHAIN_USES_GLIBC + depends on BR2_HOST_GCC_AT_LEAST_4_7 # required by LLVM + # triggers ICE on trunc_int_for_mode, at explow.c:56 + depends on BR2_TOOLCHAIN_GCC_AT_LEAST_5 || !BR2_aarch64 + +comment "host-rust needs a toolchain w/ gcc >= 5" + depends on !BR2_TOOLCHAIN_GCC_AT_LEAST_5 && BR2_aarch64 + +config BR2_PACKAGE_HOST_RUST + bool "host rust" + depends on BR2_PACKAGE_HOST_RUST_ARCH_SUPPORTS + help + Compiler for the Rust programming language. + + This package will build the compiler for the host as well as + a cross-compiled version of the Rust standard library for the + target. + + Note that the target standard library does not need to be + present on the target root filesystem, as it is statically + linked to the program. + + http://www.rust-lang.org diff --git a/package/rust/rust.hash b/package/rust/rust.hash new file mode 100644 index 0000000..3b04dfd --- /dev/null +++ b/package/rust/rust.hash @@ -0,0 +1,2 @@ +# Locally calculated +sha256 f966b31eb1cd9bd2df817c391a338eeb5b9253ae0a19bf8a11960c560f96e8b4 rustc-1.16.0-src.tar.gz diff --git a/package/rust/rust.mk b/package/rust/rust.mk new file mode 100644 index 0000000..12f4428 --- /dev/null +++ b/package/rust/rust.mk @@ -0,0 +1,85 @@ +################################################################################ +# +# rust +# +################################################################################ + +RUST_VERSION = 1.16.0 +RUST_SOURCE = rustc-$(RUST_VERSION)-src.tar.gz +RUST_SITE = https://static.rust-lang.org/dist +RUST_LICENSE = Apache-2.0 or MIT +RUST_LICENSE_FILES = LICENSE-APACHE LICENSE-MIT + +HOST_RUST_DEPENDENCIES = \ + toolchain \ + host-rust-bootstrap \ + host-cargo-bootstrap \ + host-python \ + host-cmake + +ifeq ($(BR2_PACKAGE_JEMALLOC),y) +HOST_RUST_DEPENDENCIES += jemalloc +HOST_RUST_JEMALLOC_ENABLED = true +HOST_RUST_JEMALLOC_CONF = 'jemalloc = "$(STAGING_DIR)/usr/lib/libjemalloc_pic.a"' +else +HOST_RUST_JEMALLOC_ENABLED = false +endif + +HOST_RUST_BUILD_OPTS = $(if $(VERBOSE),--verbose) + +RUST_TARGET_NAME := $(subst buildroot,unknown,$(GNU_TARGET_NAME)) + +ifeq ($(BR2_ARM_CPU_ARMV7A),y) +RUST_TARGET_NAME := $(subst arm-,armv7-,$(RUST_TARGET_NAME)) +endif + +ifeq ($(BR2_MIPS_NABI64),y) +RUST_TARGET_NAME := $(subst -gnu,-gnuabi64,$(RUST_TARGET_NAME)) +endif + +define HOST_RUST_CONFIGURE_CMDS + (cd $(@D); \ + echo '[build]' > config.toml; \ + echo 'target = ["$(RUST_TARGET_NAME)"]' >> config.toml; \ + echo 'cargo = "$(HOST_CARGO_BOOTSTRAP_DIR)/cargo/bin/cargo"' >> config.toml; \ + echo 'rustc = "$(HOST_RUST_BOOTSTRAP_DIR)/rustc/bin/rustc"' >> config.toml; \ + echo 'python = "$(HOST_DIR)/usr/bin/python2"' >> config.toml; \ + echo 'submodules = false' >> config.toml; \ + echo 'vendor = true' >> config.toml; \ + echo 'compiler-docs = false' >> config.toml; \ + echo 'docs = false' >> config.toml; \ + echo '[install]' >> config.toml; \ + echo 'prefix = "$(HOST_DIR)/usr"' >> config.toml; \ + echo '[rust]' >> config.toml; \ + echo 'use-jemalloc = $(HOST_RUST_JEMALLOC_ENABLED)' >> config.toml; \ + echo '[target.$(RUST_TARGET_NAME)]' >> config.toml; \ + echo 'cc = "$(TARGET_CROSS)gcc"' >> config.toml; \ + echo 'cxx = "$(TARGET_CROSS)g++"' >> config.toml; \ + echo $(HOST_RUST_JEMALLOC_CONF) >> config.toml; \ + ) +endef + +define HOST_RUST_BUILD_CMDS + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 x.py \ + build $(HOST_RUST_BUILD_OPTS)) +endef + +define HOST_RUST_INSTALL_LIBSTD_TARGET + (cd $(@D)/build/tmp/dist/rust-std-$(RUST_VERSION)-dev-$(RUST_TARGET_NAME); \ + ./install.sh \ + --prefix=$(HOST_DIR)/usr \ + --docdir=$(HOST_DIR)/usr/share/doc/rust \ + --libdir=$(HOST_DIR)/usr/lib \ + --mandir=$(HOST_DIR)/usr/share/man \ + --disable-ldconfig) +endef + +define HOST_RUST_INSTALL_CMDS + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 x.py \ + dist $(HOST_RUST_BUILD_OPTS)) + (cd $(@D); $(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) python2 x.py \ + dist --install $(HOST_RUST_BUILD_OPTS)) + $(HOST_RUST_INSTALL_LIBSTD_TARGET) +endef + +$(eval $(host-generic-package))
This new package provides the compiler for the Rust programming language. Currently, only the host variant is built. The Rust compiler uses LLVM as its backend: a copy of LLVM source code is provided and CMake is used to build it. It is possible to use a pre-built external copy. When LLVM/clang will be available in Buildroot, it would be possible to benefit from this feature and thus decrease build time. LLVM is configured to generate code for x86, ARM, PowerPC and MIPS architectures. The Rust compiler uses Cargo as its build system and is written in Rust. Therefore this package depends on cargo-bootstrap and rust-bootstrap. The internal build process is as follows: 1. rustc-stage0, provided by rust-bootstrap, is used to build rustc-stage1. 2. rust-stage1 builds the final Rust compiler (rust-stage2) and the standard library for the host architecture. 3. the standard library for the target architecture is built. The target architecture to support is given by the GNU/LLVM target triple. Rust supports some predefined targets [1]. As the build system expects the triple to be in the form of <arch>-unknown-<system> and Buildroot toolchain wrapper uses <arch>-buildroot-<system>, the package Makefile defines the $(RUST_TARGET_NAME) and uses it instead of $(GNU_TARGET_NAME). When compiling Rust code with this compiler, the generated program only depends on the target C library, as it is statically linked to the Rust standard library and any other code from Rust packages (a.k.a. "crates"). If the jemalloc package is selected, support for this memory allocator will be enabled in the target standard library. [1] https://forge.rust-lang.org/platform-support.html Signed-off-by: Eric Le Bihan <eric.le.bihan.dev@free.fr> --- DEVELOPERS | 1 + package/Config.in.host | 1 + package/rust/Config.in.host | 33 ++++++++++++++++++ package/rust/rust.hash | 2 ++ package/rust/rust.mk | 85 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 package/rust/Config.in.host create mode 100644 package/rust/rust.hash create mode 100644 package/rust/rust.mk