# `s390x-unknown-linux-gnu`

**Tier: 2 (with Host Tools)**

IBM z/Architecture (s390x) targets (including IBM Z and LinuxONE) running Linux.

## Target maintainers

[@uweigand](https://github.com/uweigand)
[@cuviper](https://github.com/cuviper)

## Requirements

This target requires:

* Linux Kernel version 3.2 or later
* glibc 2.17 or later

Code generated by the target uses the z/Architecture ISA assuming a minimum
architecture level of z10 (Eighth Edition of the z/Architecture Principles
of Operation), and is compliant with the s390x ELF ABI.

Reference material:

* [z/Architecture Principles of Operation][s390x-isa]
* [z/Architecture ELF Application Binary Interface][s390x-abi]

[s390x-isa]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf
[s390x-abi]: https://github.com/IBM/s390x-abi

## Building the target

This target is distributed through `rustup`, and otherwise requires no
special configuration.

If you need to build your own Rust for some reason though, the target can be
enabled in `bootstrap.toml`. For example:

```toml
[build]
target = ["s390x-unknown-linux-gnu"]
```

## Building Rust programs

On a s390x Linux host, the `s390x-unknown-linux-gnu` target should be
automatically installed and used by default.

On a non-s390x host, add the target:

```bash
rustup target add s390x-unknown-linux-gnu
```

Then cross compile crates with:

```bash
cargo build --target s390x-unknown-linux-gnu
```

## Testing

There are no special requirements for testing and running the target.
For testing cross builds on the host, please refer to the "Cross-compilation
toolchains and C code" section below.

If you want to do native testing but do not have your own s390x
machine, there are several options how to get access to one:

* The [IBM LinuxONE Community Cloud][cloud-community] provides a
  self-service portal where you can create s390x virtual machine
  instances.  These are intended for temporary use (limited to 120 days).

* The [IBM LinuxONE Open Source Cloud][cloud-opensource] provides
  permanent access to s390x machines.  This requires approval by IBM,
  which will normally be granted if you're planning to use the machine
  to work on an open-source project that is relevant to the IBM Z
  ecosystem - the Rust compiler would certainly qualify.

[cloud-community]: https://linuxone.cloud.marist.edu/
[cloud-opensource]: https://community.ibm.com/zsystems/form/l1cc-oss-vm-request/

## Cross-compilation toolchains and C code

Rust code built using the target is compatible with C code compiled with
GCC or Clang using the `s390x-unknown-linux-gnu` target triple (via either
native or cross-compilation).

On Ubuntu, a s390x cross-toolchain can be installed with:

```bash
apt install gcc-s390x-linux-gnu g++-s390x-linux-gnu libc6-dev-s390x-cross
```

Depending on your system, you may need to configure the target to use the GNU
GCC linker. To use it, add the following to your `.cargo/config.toml`:

```toml
[target.s390x-unknown-linux-gnu]
linker = "s390x-linux-gnu-gcc"
```

If your `s390x-linux-gnu-*` toolchain is not in your `PATH` you may need to
configure additional settings:

```toml
[target.s390x-unknown-linux-gnu]
# Adjust the paths to point at your toolchain
cc = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-gcc"
cxx = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-g++"
ar = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-ar"
ranlib = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-ranlib"
linker = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-gcc"
```

To test cross compiled binaries on a non-s390x host, you can use
[`qemu`](https://www.qemu.org/docs/master/system/target-s390x.html).
On Ubuntu, a s390x emulator can be obtained with:

```bash
apt install qemu-system-s390x
```

Then, in `.cargo/config.toml` set the `runner`:

```toml
[target.s390x-unknown-linux-gnu]
runner = "qemu-s390x-static -L /usr/s390x-linux-gnu"
```
