All of lore.kernel.org
 help / color / mirror / Atom feed
From: Romain Naour <romain.naour@gmail.com>
To: buildroot@busybox.net
Subject: [Buildroot] [Patch v2 3/3] rust: new package
Date: Tue, 5 Jul 2016 12:11:13 +0200	[thread overview]
Message-ID: <78101ffb-56d4-75be-465a-69b1a236798c@gmail.com> (raw)
In-Reply-To: <1466797592-5565-4-git-send-email-eric.le.bihan.dev@free.fr>

Hi Eric,

Le 24/06/2016 ? 21:46, Eric Le Bihan a ?crit :
> This new package provides the compiler for the Rust programming language.
> 
> Currently, only the host variant is built.
> 
> 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 build.
> 
> The Rust compiler uses LLVM as its backend, compiled with support for
> x86, ARM, PowerPC and MIPS architectures.

rust build it's own bundled copy of llvm if it's not available on the host.
If host-rust require a llvm compiler we need to add llvm support in Buildroot first.

I have some WIP patches about llvm/clang, if you want to take a look:
https://github.com/RomainNaour/buildroot/tree/clang-llvm

Best regards,
Romain

> 
> To properly build the standard library for the target, two files are
> needed:
> 
>  - the target configuration: a Makefile fragment telling the build system
>    about the cross-compiler and such.
>  - the target specification: a JSON file describing the target
>    architecture to the LLVM backend.
> 
> These files are generated with a Python script which takes info from the
> Buildroot configuration: `rust-target-gen`.
> 
> 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.
> 
> Signed-off-by: Eric Le Bihan <eric.le.bihan.dev@free.fr>
> ---
>  package/Config.in.host                             |   1 +
>  ...monize-use-of-CROSS_PREFIX_-in-mk-cfg-.mk.patch |  53 ++++
>  .../0002-Expand-CC-to-gcc-in-x86-mk-cfg-.cfg.patch |  71 +++++
>  ...eclaration-in-mipsel-unknown-linux-gnu.mk.patch |  26 ++
>  package/rust/Config.in.host                        |   7 +
>  package/rust/rust-target-gen                       | 315 +++++++++++++++++++++
>  package/rust/rust.hash                             |   2 +
>  package/rust/rust.mk                               |  67 +++++
>  8 files changed, 542 insertions(+)
>  create mode 100644 package/rust/0001-Harmonize-use-of-CROSS_PREFIX_-in-mk-cfg-.mk.patch
>  create mode 100644 package/rust/0002-Expand-CC-to-gcc-in-x86-mk-cfg-.cfg.patch
>  create mode 100644 package/rust/0003-Fix-CPP-declaration-in-mipsel-unknown-linux-gnu.mk.patch
>  create mode 100644 package/rust/Config.in.host
>  create mode 100755 package/rust/rust-target-gen
>  create mode 100644 package/rust/rust.hash
>  create mode 100644 package/rust/rust.mk
> 
> diff --git a/package/Config.in.host b/package/Config.in.host
> index 04b7f19..5d3df08 100644
> --- a/package/Config.in.host
> +++ b/package/Config.in.host
> @@ -30,6 +30,7 @@ menu "Host utilities"
>  	source "package/patchelf/Config.in.host"
>  	source "package/pwgen/Config.in.host"
>  	source "package/qemu/Config.in.host"
> +	source "package/rust/Config.in.host"
>  	source "package/sam-ba/Config.in.host"
>  	source "package/squashfs/Config.in.host"
>  	source "package/sunxi-tools/Config.in.host"
> diff --git a/package/rust/0001-Harmonize-use-of-CROSS_PREFIX_-in-mk-cfg-.mk.patch b/package/rust/0001-Harmonize-use-of-CROSS_PREFIX_-in-mk-cfg-.mk.patch
> new file mode 100644
> index 0000000..6c09495
> --- /dev/null
> +++ b/package/rust/0001-Harmonize-use-of-CROSS_PREFIX_-in-mk-cfg-.mk.patch
> @@ -0,0 +1,53 @@
> +From 23d9dbfb3ad4a8d5d5997738e8b1436d076898e9 Mon Sep 17 00:00:00 2001
> +From: Eric Le Bihan <eric.le.bihan.dev@free.fr>
> +Date: Tue, 19 Apr 2016 10:49:20 +0200
> +Subject: [PATCH 1/3] Harmonize use of CROSS_PREFIX_* in mk/cfg/*.mk
> +
> +Use CROSS_PREFIX_ in Makefile fragments for cross-compiling on Linux
> +wherever possible.
> +
> +Signed-off-by: Eric Le Bihan <eric.le.bihan.dev@free.fr>
> +---
> + mk/cfg/mips-unknown-linux-gnu.mk   | 9 +++++----
> + mk/cfg/mipsel-unknown-linux-gnu.mk | 9 +++++----
> + 2 files changed, 10 insertions(+), 8 deletions(-)
> +
> +diff --git a/mk/cfg/mips-unknown-linux-gnu.mk b/mk/cfg/mips-unknown-linux-gnu.mk
> +index 65b0877..0fe95de 100644
> +--- a/mk/cfg/mips-unknown-linux-gnu.mk
> ++++ b/mk/cfg/mips-unknown-linux-gnu.mk
> +@@ -1,8 +1,9 @@
> + # mips-unknown-linux-gnu configuration
> +-CC_mips-unknown-linux-gnu=mips-linux-gnu-gcc
> +-CXX_mips-unknown-linux-gnu=mips-linux-gnu-g++
> +-CPP_mips-unknown-linux-gnu=mips-linux-gnu-gcc -E
> +-AR_mips-unknown-linux-gnu=mips-linux-gnu-ar
> ++CROSS_PREFIX_mips-unknown-linux-gnu=mips-linux-gnu-
> ++CC_mips-unknown-linux-gnu=gcc
> ++CXX_mips-unknown-linux-gnu=g++
> ++CPP_mips-unknown-linux-gnu=gcc -E
> ++AR_mips-unknown-linux-gnu=ar
> + CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
> + CFG_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a
> + CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
> +diff --git a/mk/cfg/mipsel-unknown-linux-gnu.mk b/mk/cfg/mipsel-unknown-linux-gnu.mk
> +index 4dadfc2..9340c46 100644
> +--- a/mk/cfg/mipsel-unknown-linux-gnu.mk
> ++++ b/mk/cfg/mipsel-unknown-linux-gnu.mk
> +@@ -1,8 +1,9 @@
> + # mipsel-unknown-linux-gnu configuration
> +-CC_mipsel-unknown-linux-gnu=mipsel-linux-gnu-gcc
> +-CXX_mipsel-unknown-linux-gnu=mipsel-linux-gnu-g++
> +-CPP_mipsel-unknown-linux-gnu=mipsel-linux-gnu-gcc
> +-AR_mipsel-unknown-linux-gnu=mipsel-linux-gnu-ar
> ++CROSS_PREFIX_mipsel-unknown-linux-gnu=mipsel-linux-gnu-
> ++CC_mipsel-unknown-linux-gnu=gcc
> ++CXX_mipsel-unknown-linux-gnu=g++
> ++CPP_mipsel-unknown-linux-gnu=gcc
> ++AR_mipsel-unknown-linux-gnu=ar
> + CFG_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).so
> + CFG_STATIC_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).a
> + CFG_LIB_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.so
> +--
> +2.1.4
> +
> diff --git a/package/rust/0002-Expand-CC-to-gcc-in-x86-mk-cfg-.cfg.patch b/package/rust/0002-Expand-CC-to-gcc-in-x86-mk-cfg-.cfg.patch
> new file mode 100644
> index 0000000..e473e18
> --- /dev/null
> +++ b/package/rust/0002-Expand-CC-to-gcc-in-x86-mk-cfg-.cfg.patch
> @@ -0,0 +1,71 @@
> +From a371eb06fef803dcf9894fa0ad6941341887d2d8 Mon Sep 17 00:00:00 2001
> +From: Eric Le Bihan <eric.le.bihan.dev@free.fr>
> +Date: Tue, 19 Apr 2016 12:51:29 +0200
> +Subject: [PATCH 2/3] Expand $(CC) to gcc in x86 mk/cfg/*.cfg
> +
> +Expand $(CC) and friends to gcc and introduce empty CROSS_PREFIX_ in
> +Makefile fragments for cross-compilation of i586, i686 and x86_64 Linux
> +platforms to allow use of Sourcery CodeBench toolchains.
> +---
> + mk/cfg/i586-unknown-linux-gnu.mk   | 9 +++++----
> + mk/cfg/i686-unknown-linux-gnu.mk   | 9 +++++----
> + mk/cfg/x86_64-unknown-linux-gnu.mk | 9 +++++----
> + 3 files changed, 15 insertions(+), 12 deletions(-)
> +
> +diff --git a/mk/cfg/i586-unknown-linux-gnu.mk b/mk/cfg/i586-unknown-linux-gnu.mk
> +index 0609f36..45af3b8 100644
> +--- a/mk/cfg/i586-unknown-linux-gnu.mk
> ++++ b/mk/cfg/i586-unknown-linux-gnu.mk
> +@@ -1,8 +1,9 @@
> + # i586-unknown-linux-gnu configuration
> +-CC_i586-unknown-linux-gnu=$(CC)
> +-CXX_i586-unknown-linux-gnu=$(CXX)
> +-CPP_i586-unknown-linux-gnu=$(CPP)
> +-AR_i586-unknown-linux-gnu=$(AR)
> ++CROSS_PREFIX_i686-unknown-linux-gnu=
> ++CC_i586-unknown-linux-gnu=gcc
> ++CXX_i586-unknown-linux-gnu=g++
> ++CPP_i586-unknown-linux-gnu=gcc -E
> ++AR_i586-unknown-linux-gnu=ar
> + CFG_LIB_NAME_i586-unknown-linux-gnu=lib$(1).so
> + CFG_STATIC_LIB_NAME_i586-unknown-linux-gnu=lib$(1).a
> + CFG_LIB_GLOB_i586-unknown-linux-gnu=lib$(1)-*.so
> +diff --git a/mk/cfg/i686-unknown-linux-gnu.mk b/mk/cfg/i686-unknown-linux-gnu.mk
> +index 88c0907..aa4ce42 100644
> +--- a/mk/cfg/i686-unknown-linux-gnu.mk
> ++++ b/mk/cfg/i686-unknown-linux-gnu.mk
> +@@ -1,8 +1,9 @@
> + # i686-unknown-linux-gnu configuration
> +-CC_i686-unknown-linux-gnu=$(CC)
> +-CXX_i686-unknown-linux-gnu=$(CXX)
> +-CPP_i686-unknown-linux-gnu=$(CPP)
> +-AR_i686-unknown-linux-gnu=$(AR)
> ++CROSS_PREFIX_i686-unknown-linux-gnu=
> ++CC_i686-unknown-linux-gnu=gcc
> ++CXX_i686-unknown-linux-gnu=g++
> ++CPP_i686-unknown-linux-gnu=gcc -E
> ++AR_i686-unknown-linux-gnu=ar
> + CFG_LIB_NAME_i686-unknown-linux-gnu=lib$(1).so
> + CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
> + CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
> +diff --git a/mk/cfg/x86_64-unknown-linux-gnu.mk b/mk/cfg/x86_64-unknown-linux-gnu.mk
> +index 044c687..bdd88cd 100644
> +--- a/mk/cfg/x86_64-unknown-linux-gnu.mk
> ++++ b/mk/cfg/x86_64-unknown-linux-gnu.mk
> +@@ -1,8 +1,9 @@
> + # x86_64-unknown-linux-gnu configuration
> +-CC_x86_64-unknown-linux-gnu=$(CC)
> +-CXX_x86_64-unknown-linux-gnu=$(CXX)
> +-CPP_x86_64-unknown-linux-gnu=$(CPP)
> +-AR_x86_64-unknown-linux-gnu=$(AR)
> ++CROSS_PREFIX_x86_64-unknown-linux-gnu=
> ++CC_x86_64-unknown-linux-gnu=gcc
> ++CXX_x86_64-unknown-linux-gnu=g++
> ++CPP_x86_64-unknown-linux-gnu=gcc -E
> ++AR_x86_64-unknown-linux-gnu=ar
> + CFG_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).so
> + CFG_STATIC_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).a
> + CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
> +--
> +2.1.4
> +
> diff --git a/package/rust/0003-Fix-CPP-declaration-in-mipsel-unknown-linux-gnu.mk.patch b/package/rust/0003-Fix-CPP-declaration-in-mipsel-unknown-linux-gnu.mk.patch
> new file mode 100644
> index 0000000..00d338f
> --- /dev/null
> +++ b/package/rust/0003-Fix-CPP-declaration-in-mipsel-unknown-linux-gnu.mk.patch
> @@ -0,0 +1,26 @@
> +From f6d8c8f6dcdbabead3a06ed8f592143afaad16ba Mon Sep 17 00:00:00 2001
> +From: Eric Le Bihan <eric.le.bihan.dev@free.fr>
> +Date: Tue, 19 Apr 2016 12:57:24 +0200
> +Subject: [PATCH 3/3] Fix CPP declaration in mipsel-unknown-linux-gnu.mk
> +
> +Signed-off-by: Eric Le Bihan <eric.le.bihan.dev@free.fr>
> +---
> + mk/cfg/mipsel-unknown-linux-gnu.mk | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +diff --git a/mk/cfg/mipsel-unknown-linux-gnu.mk b/mk/cfg/mipsel-unknown-linux-gnu.mk
> +index 9340c46..aaa18c2 100644
> +--- a/mk/cfg/mipsel-unknown-linux-gnu.mk
> ++++ b/mk/cfg/mipsel-unknown-linux-gnu.mk
> +@@ -2,7 +2,7 @@
> + CROSS_PREFIX_mipsel-unknown-linux-gnu=mipsel-linux-gnu-
> + CC_mipsel-unknown-linux-gnu=gcc
> + CXX_mipsel-unknown-linux-gnu=g++
> +-CPP_mipsel-unknown-linux-gnu=gcc
> ++CPP_mipsel-unknown-linux-gnu=gcc -E
> + AR_mipsel-unknown-linux-gnu=ar
> + CFG_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).so
> + CFG_STATIC_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).a
> +--
> +2.1.4
> +
> diff --git a/package/rust/Config.in.host b/package/rust/Config.in.host
> new file mode 100644
> index 0000000..138e74e
> --- /dev/null
> +++ b/package/rust/Config.in.host
> @@ -0,0 +1,7 @@
> +config BR2_PACKAGE_HOST_RUST_ARCH_SUPPORTS
> +	bool
> +	default y
> +	depends on BR2_HOSTARCH = "x86_64" || BR2_HOSTARCH = "x86"
> +	depends on BR2_arm  || BR2_aarch64 || BR2_i386 \
> +		|| BR2_mips || BR2_mipsel  || BR2_x86_64
> +	depends on !BR2_ARM_CPU_ARMV4 && !BR2_ARM_CPU_ARMV5
> diff --git a/package/rust/rust-target-gen b/package/rust/rust-target-gen
> new file mode 100755
> index 0000000..b34b72a
> --- /dev/null
> +++ b/package/rust/rust-target-gen
> @@ -0,0 +1,315 @@
> +#!/usr/bin/env python2.7
> +# -*- coding: utf-8 -*-
> +#
> +# Copyright (C) 2016 Eric Le Bihan <eric.le.bihan.dev@free.fr>
> +#
> +# This program is free software: you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation, either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# 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, see <http://www.gnu.org/licenses/>.
> +#
> +
> +"""
> +`rust-target-gen ` generates the target configuration or the specification
> +file for the Rust compiler.
> +
> +These files will be used when cross-compiling the standard library or any
> +program.
> +
> +The name of the target is to be formatted in one of the following schemes:
> +
> +- <cpu>-<vendor>-<os>-<system>
> +- <cpu>-<os>-<system>
> +
> +By default, the contents of the configuration file is generated and printed to
> +standard output. Add *-m spec* to the command line to generate the contents of
> +the specification file. Add *-o FILE* to write contents to file FILE.
> +
> +It is possible to explicitly set the type of CPU using the *--cpu* option. To
> +set one or more additional LLVM attributes (a.k.a. "features"), add as many as
> +*--feature* options as needed.
> +
> +"""
> +
> +import os
> +import re
> +import sys
> +import csv
> +import StringIO
> +import argparse
> +
> +__version__ = "0.1.1"
> +
> +
> +class GenerationError(Exception):
> +    """Error raised when generating file contents"""
> +
> +
> +class Target:
> +    """Store information about a target"""
> +    def __init__(self, name):
> +        match = re.match(r'([\w]+)(?:-([\w]+))?-linux-([\w]+)', name)
> +        if not match:
> +            raise ValueError("Invalid target name")
> +        self.cpu = match.group(1)
> +        self.vendor = match.group(2) or 'unknown'
> +        self.system = match.group(3)
> +        self.name = name
> +        self.prefix = name + "-"
> +
> +    def to_pattern(self):
> +        """Format the target name as search pattern"""
> +        if self.vendor == 'unknown':
> +            pattern = "{0.cpu}-[\w]+-linux-{0.system}"
> +        else:
> +            pattern = "{0.cpu}-(?!{0.vendor})[\w]+-linux-{0.system}"
> +        return pattern.format(self)
> +
> +    @property
> +    def canonical_name(self):
> +        """Return the canonical name of the target"""
> +        return "{0.cpu}-{0.vendor}-linux-{0.system}".format(self)
> +
> +
> +#: Default list of pre-link-args
> +DEFAULT_PRE_LINK_ARGS = ["-Wl,--as-needed", "-Wl,-z,noexecstack"]
> +
> +#: Template for the target specifiation JSON file
> +SPEC_TEMPLATE = """{{
> +      "llvm-target": "{name}",
> +      "target-endian": "{endianness}",
> +      "target-pointer-width": "{ptr-width}",
> +      "data-layout": "{data-layout}",
> +      "target-env": "{environment}",
> +      "target-vendor": "{vendor}",
> +      "arch": "{arch}",
> +      "os": "linux",
> +      "cpu": "{cpu}",
> +      "features": "{features}",
> +      "dynamic-linking": true,
> +      "executables": true,
> +      "morestack": true,
> +      "linker-is-gnu": true,
> +      "has-rpath": true,
> +      "pre-link-args": [
> +          {pre-link-args}
> +       ],
> +      "position-independent-executables": true,
> +      "archive-format": "gnu"
> +}}
> +"""
> +
> +#: Contents of the target specifiation database.
> +#: The information has been extracted from the Rust source code
> +#: (src/libbrust_back/target/*.rs) and formatted as CSV.
> +#: The first line is the header of the file, listing the fields of the table.
> +SPEC_DATABASE_CONTENTS = """name;arch;endianness;ptr-width;data-layout;cpu;features;pre-link-args
> +aarch64-unknown-linux-gnu;aarch64;little;64;e-m:e-i64:64-i128:128-n32:64-S128;;;;
> +arm-unknown-linux-gnueabihf;arm;little;32;e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64;;+v6,+vfp2;;
> +arm-unknown-linux-gnueabi;arm;little;32;e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64;;+v6;;
> +i586-unknown-linux-gnu;x86;little;32;e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128;pentium;;-m32
> +i686-unknown-linux-gnu;x86;little;32;e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128;pentium4;;-m32
> +mips-unknown-linux-gnu;mips;big;32;E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64;;+mips32r2,+soft-float;;
> +mipsel-unknown-linux-gnu;mips;little;32;e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64;;+mips32;;
> +x86_64-unknown-linux-gnu;x86_64;little;64;e-m:e-i64:64-f80:128-n8:16:32:64-S128;;;-m64
> +"""
> +
> +
> +def join_quoted(strings, delimiter=','):
> +    """Quote strings and join them as a single string, using a delimiter.
> +
> +    :param strings: list of strings
> +    :type strings: list
> +
> +    :param delimiter: optional delimiter
> +    :type delimiter: Optional[str]
> +
> +    :return: a new string
> +    :rtype: str
> +    """
> +    return delimiter.join(["\"{}\"".format(s) for s in strings])
> +
> +
> +def find_similar_spec(target):
> +    """Find a target specification similar to a given one.
> +
> +    :param target: target to be created
> +    :type target: Target
> +
> +    :return: the reference target specification as a dict
> +    :rtype: dict of str to str
> +    """
> +    expr = re.compile(target.to_pattern() + '$')
> +    f = StringIO.StringIO(SPEC_DATABASE_CONTENTS)
> +    reader = csv.DictReader(f, delimiter=';', quotechar='"')
> +    for row in reader:
> +        if expr.match(row['name']):
> +            spec = dict(row)
> +            fields = spec['name'].split('-')
> +            spec['vendor'] = fields[1]
> +            spec['environment'] = fields[3]
> +            pre_links_args = DEFAULT_PRE_LINK_ARGS + spec['pre-link-args'].split()
> +            spec['pre-link-args'] = join_quoted(pre_links_args, ', ')
> +            spec['cpu'] = spec['cpu'] or 'generic'
> +            return spec
> +
> +    raise GenerationError("Can not find matching specification")
> +
> +
> +def gen_spec(target, cpu=None, features=[]):
> +    """Generate target specification file.
> +
> +    :param target: target to be created
> +    :type target: Target
> +
> +    :param cpu: optional CPU type
> +    :type cpu: Optional[str]
> +
> +    :param features: optional list of additional LLVM features
> +    :type features: Optional[list]
> +
> +    :return: contents of the configuration file
> +    :rtype: str
> +    """
> +    spec = find_similar_spec(target)
> +    spec['name'] = target.name
> +    spec['vendor'] = target.vendor
> +    if features:
> +        spec['features'] += ',' + ','.join(features)
> +    spec['cpu'] = cpu or spec['cpu']
> +    return SPEC_TEMPLATE.format(**spec)
> +
> +
> +def gen_conf_from(target, filename):
> +    """Generate target configuration file from an existing one.
> +
> +    :param target: target to be created
> +    :type target: Target
> +
> +    :param filename: path to an existing configuration file
> +    :type str:
> +
> +    :return: contents of the new configuration file
> +    :rtype: str
> +    """
> +    (name, e) = os.path.splitext(os.path.basename(filename))
> +    expr = re.compile(r'CROSS_PREFIX_[-\w]+=(?:[-\w]+)?\n')
> +    with open(filename) as input:
> +        contents = input.read()
> +        contents = contents.replace(name, target.name)
> +        line = "CROSS_PREFIX_{}={}\n".format(target.name, target.prefix)
> +        if expr.search(contents):
> +            contents = expr.sub(line, contents)
> +        else:
> +            contents += line
> +
> +    return contents
> +
> +
> +def find_similar_conf(target, srcdir):
> +    """Find a configuration file similar to a given target.
> +
> +    :param target: target to be created
> +    :type target: Target
> +
> +    :param srcdir: path to Rust source code
> +    :type srcdir: str
> +
> +    :return: path to the matching configuration file
> +    :rtype: str
> +    """
> +    cfgdir = os.path.join(srcdir, 'mk', 'cfg')
> +    expr = re.compile(target.to_pattern() + '.mk')
> +    candidates = filter(lambda f: expr.match(f), os.listdir(cfgdir))
> +    if len(candidates) != 1:
> +        raise GenerationError("Can not find matching configuration")
> +    return os.path.join(cfgdir, candidates[0])
> +
> +
> +def gen_conf(target, srcdir):
> +    """Generate target configuration file.
> +
> +    :param target: target to be created
> +    :type target: Target
> +
> +    :param srcdir: path to Rust source code
> +    :type srcdir: str
> +
> +    :return: contents of the configuration file
> +    :rtype: str
> +    """
> +    reference = find_similar_conf(target, srcdir)
> +    return gen_conf_from(target, reference)
> +
> +
> +def save_to_file(filename, text):
> +    """Save text to a file.
> +
> +    :param filename: path to the destination filename
> +    :type filename: str
> +
> +    :param text: contents of the file
> +    :type text: str
> +    """
> +    dstdir = os.path.dirname(filename)
> +    if not os.path.exists(dstdir):
> +        os.makedirs(dstdir)
> +    with open(filename, 'w') as f:
> +        f.write(contents)
> +
> +
> +if __name__ == '__main__':
> +    parser = argparse.ArgumentParser()
> +    parser.add_argument('-v', '--version',
> +                        action='version',
> +                        version=__version__)
> +    parser.add_argument('-c', '--cpu',
> +                        help='Set CPU type')
> +    parser.add_argument('-f', '--feature',
> +                        action='append',
> +                        metavar='FEATURE',
> +                        dest='features',
> +                        default=[],
> +                        help='Add new LLVM feature')
> +    parser.add_argument('-i', '--input',
> +                        dest='srcdir',
> +                        metavar='DIR',
> +                        default=os.getcwd(),
> +                        help='set the path to Rust source code')
> +    parser.add_argument('-p', '--prefix',
> +                        help='set the cross-compiler prefix')
> +    parser.add_argument('-m', '--mode',
> +                        choices=('conf', 'spec'),
> +                        default='conf',
> +                        help='set the operating mode')
> +    parser.add_argument('-o', '--output',
> +                        metavar='FILE',
> +                        help='write generated contents to FILE')
> +    parser.add_argument('target',
> +                        help='target name ("<cpu>-<vendor>-<os>-<system>")')
> +
> +    args = parser.parse_args()
> +
> +    target = Target(args.target)
> +    if args.prefix:
> +        target.prefix = args.prefix
> +
> +    if args.mode == 'conf':
> +        contents = gen_conf(target, args.srcdir)
> +    else:
> +        contents = gen_spec(target, args.cpu, args.features)
> +
> +    if not args.output:
> +        sys.stdout.write(contents)
> +    else:
> +        save_to_file(args.output, contents)
> +
> +# vim: ts=4 sw=4 sts=4 et ai
> diff --git a/package/rust/rust.hash b/package/rust/rust.hash
> new file mode 100644
> index 0000000..da2006b
> --- /dev/null
> +++ b/package/rust/rust.hash
> @@ -0,0 +1,2 @@
> +# Locally calculated
> +sha256 b19b21193d7d36039debeaaa1f61cbf98787e0ce94bd85c5cbe2a59462d7cfcd rustc-1.9.0-src.tar.gz
> diff --git a/package/rust/rust.mk b/package/rust/rust.mk
> new file mode 100644
> index 0000000..adb980a
> --- /dev/null
> +++ b/package/rust/rust.mk
> @@ -0,0 +1,67 @@
> +################################################################################
> +#
> +# rust
> +#
> +################################################################################
> +
> +RUST_VERSION = 1.9.0
> +RUST_SOURCE = rustc-$(RUST_VERSION)-src.tar.gz
> +RUST_SITE = https://static.rust-lang.org/dist
> +RUST_LICENSE = Apache-2.0, MIT
> +RUST_LICENSE_FILES = LICENSE-APACHE LICENSE-MIT
> +
> +HOST_RUST_DEPENDENCIES = host-rust-bootstrap host-python toolchain host-jemalloc
> +
> +define HOST_RUST_GEN_CONF
> +	package/rust/rust-target-gen \
> +		--mode conf \
> +		--prefix=$(notdir $(TARGET_CROSS)) \
> +		--input $(@D) \
> +		--output $(@D)/mk/cfg/$(GNU_TARGET_NAME).mk \
> +		$(GNU_TARGET_NAME)
> +endef
> +
> +define HOST_RUST_GEN_SPEC
> +	package/rust/rust-target-gen \
> +		--mode spec \
> +		--input $(@D) \
> +		--output $(HOST_DIR)/etc/rustc/$(GNU_TARGET_NAME).json \
> +		$(GNU_TARGET_NAME)
> +endef
> +
> +HOST_RUST_PRE_CONFIGURE_HOOKS += \
> +	HOST_RUST_GEN_CONF \
> +	HOST_RUST_GEN_SPEC
> +
> +HOST_RUST_MAKE_ENV = RUST_TARGET_PATH=$(HOST_DIR)/etc/rustc
> +HOST_RUST_MAKE_OPTS = $(if $(VERBOSE),VERBOSE=1)
> +
> +# Though not using autotools, Rust follows the ./configure convention, in its
> +# own way...
> +define HOST_RUST_CONFIGURE_CMDS
> +	(cd $(@D); $(HOST_CONFIGURE_OPTS) \
> +		./configure \
> +		--target=$(GNU_TARGET_NAME) \
> +		--prefix="$(HOST_DIR)/usr" \
> +		--jemalloc-root="$(HOST_DIR)/usr/lib" \
> +		--enable-local-rust \
> +		--local-rust-root="$(HOST_RUST_BOOTSTRAP_DIR)" \
> +		--disable-docs \
> +		--disable-manage-submodules \
> +		--sysconfdir="$(HOST_DIR)/etc" \
> +		--localstatedir="$(HOST_DIR)/var/lib" \
> +		--datadir="$(HOST_DIR)/usr/share" \
> +		--infodir="$(HOST_DIR)/usr/share/info")
> +endef
> +
> +define HOST_RUST_BUILD_CMDS
> +	$(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) $(MAKE) \
> +		$(HOST_RUST_MAKE_OPTS) -C $(@D)
> +endef
> +
> +define HOST_RUST_INSTALL_CMDS
> +	$(HOST_MAKE_ENV) $(HOST_RUST_MAKE_ENV) $(MAKE) \
> +		$(HOST_RUST_MAKE_OPTS) -C $(@D) install
> +endef
> +
> +$(eval $(host-generic-package))
> 

  reply	other threads:[~2016-07-05 10:11 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-24 19:46 [Buildroot] [Patch v2 0/3] Add support for the Rust programming language Eric Le Bihan
2016-06-24 19:46 ` [Buildroot] [Patch v2 1/3] jemalloc: new package Eric Le Bihan
2016-07-05  9:09   ` Romain Naour
2016-07-05  9:14   ` Thomas Petazzoni
2016-07-05 17:14   ` Thomas Petazzoni
2016-06-24 19:46 ` [Buildroot] [Patch v2 2/3] rust-bootstrap: " Eric Le Bihan
2016-07-05  9:47   ` Romain Naour
     [not found]     ` <20160709143638.778d7964@itchy>
2016-07-09 20:05       ` Romain Naour
2016-06-24 19:46 ` [Buildroot] [Patch v2 3/3] rust: " Eric Le Bihan
2016-07-05 10:11   ` Romain Naour [this message]
2016-07-09 12:25     ` Eric Le Bihan
2016-07-09 20:48       ` Romain Naour

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=78101ffb-56d4-75be-465a-69b1a236798c@gmail.com \
    --to=romain.naour@gmail.com \
    --cc=buildroot@busybox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.