1The goal of the libc crate is to have CI running everywhere to have the 2strongest guarantees about the definitions that this library contains, and as a 3result the CI is pretty complicated and also pretty large! Hopefully this can 4serve as a guide through the sea of scripts in this directory and elsewhere in 5this project. 6 7Note that this documentation is quite outdated. See CI config and scripts in the 8`ci` directory how we run CI now. 9 10# Files 11 12First up, let's talk about the files in this directory: 13 14* `run-docker.sh` - a shell script run by most builders, it will execute 15 `run.sh` inside a Docker container configured for the target. 16 17* `run.sh` - the actual script which runs tests for a particular architecture. 18 19* `dox.sh` - build the documentation of the crate and publish it to gh-pages. 20 21# CI Systems 22 23Currently this repository leverages a combination of GitHub Actions and Cirrus 24CI for running tests. You can find tested triples in [Actions config] or 25[Cirrus config]. 26 27The Windows triples are all pretty standard, they just set up their environment 28then run tests, no need for downloading any extra target libs (we just download 29the right installer). The Intel Linux/OSX builds are similar in that we just 30download the right target libs and run tests. Note that the Intel Linux/OSX 31builds are run on stable/beta/nightly, but are the only ones that do so. 32 33The remaining architectures look like: 34 35* Android runs in a [docker image][android-docker] with an emulator, the NDK, 36 and the SDK already set up. The entire build happens within the docker image. 37* The MIPS, ARM, and AArch64 builds all use the QEMU userspace emulator to run 38 the generated binary to actually verify the tests pass. 39* The MUSL build just has to download a MUSL compiler and target libraries and 40 then otherwise runs tests normally. 41* iOS builds need an extra linker flag currently, but beyond that they're built 42 as standard as everything else. 43* The BSD builds, currently OpenBSD and FreeBSD, use QEMU to boot up a system 44 and compile/run tests. More information on that below. 45 46[Actions config]: https://github.com/rust-lang/libc/tree/HEAD/.github/workflows 47[Cirrus config]: https://github.com/rust-lang/libc/blob/HEAD/.cirrus.yml 48[android-docker]: https://github.com/rust-lang/libc/blob/HEAD/ci/docker/x86_64-linux-android/Dockerfile 49 50## QEMU 51 52Lots of the architectures tested here use QEMU in the tests, so it's worth going 53over all the crazy capabilities QEMU has and the various flavors in which we use 54it! 55 56First up, QEMU has userspace emulation where it doesn't boot a full kernel, it 57just runs a binary from another architecture (using the `qemu-<arch>` wrappers). 58We provide it the runtime path for the dynamically loaded system libraries, 59however. This strategy is used for all Linux architectures that aren't intel. 60Note that one downside of this QEMU system is that threads are barely 61implemented, so we're careful to not spawn many threads. 62 63Finally, the fun part, the BSDs. Quite a few hoops are jumped through to get CI 64working for these platforms, but the gist of it looks like: 65 66* Cross compiling from Linux to any of the BSDs seems to be quite non-standard. 67 We may be able to get it working but it might be difficult at that point to 68 ensure that the libc definitions align with what you'd get on the BSD itself. 69 As a result, we try to do compiles within the BSD distro. 70* We resort to userspace emulation (QEMU). 71 72With all that in mind, the way BSD is tested looks like: 73 741. Download a pre-prepared image for the OS being tested. 752. Generate the tests for the OS being tested. This involves running the `ctest` 76 library over libc to generate a Rust file and a C file which will then be 77 compiled into the final test. 783. Generate a disk image which will later be mounted by the OS being tested. 79 This image is mostly just the libc directory, but some modifications are made 80 to compile the generated files from step 2. 814. The kernel is booted in QEMU, and it is configured to detect the libc-test 82 image being available, run the test script, and then shut down afterwards. 835. Look for whether the tests passed in the serial console output of the kernel. 84 85There's some pretty specific instructions for setting up each image (detailed 86below), but the main gist of this is that we must avoid a vanilla `cargo run` 87inside of the `libc-test` directory (which is what it's intended for) because 88that would compile `syntex_syntax`, a large library, with userspace emulation. 89This invariably times out on CI, so we can't do that. 90 91Once all those hoops are jumped through, however, we can be happy that we're 92testing almost everything! 93 94Below are some details of how to set up the initial OS images which are 95downloaded. Each image must be enabled have input/output over the serial 96console, log in automatically at the serial console, detect if a second drive in 97QEMU is available, and if so mount it, run a script (it'll specifically be 98`run-qemu.sh` in this folder which is copied into the generated image talked 99about above), and then shut down. 100 101### QEMU Setup - FreeBSD 102 1031. [Download the latest stable amd64-bootonly release ISO](https://www.freebsd.org/where.html). 104 E.g. FreeBSD-11.1-RELEASE-amd64-bootonly.iso 1052. Create the disk image: 106 `qemu-img create -f qcow2 FreeBSD-11.1-RELEASE-amd64.qcow2 2G` 1073. Boot the machine: 108 `qemu-system-x86_64 -cdrom FreeBSD-11.1-RELEASE-amd64-bootonly.iso -drive if=virtio,file=FreeBSD-11.1-RELEASE-amd64.qcow2 -net nic,model=virtio -net user` 1094. Run the installer, and install FreeBSD: 110 1. Install 111 1. Continue with default keymap 112 1. Set Hostname: freebsd-ci 113 1. Distribution Select: 114 1. Uncheck lib32 115 1. Uncheck ports 116 1. Network Configuration: vtnet0 117 1. Configure IPv4? Yes 118 1. DHCP? Yes 119 1. Configure IPv6? No 120 1. Resolver Configuration: Ok 121 1. Mirror Selection: Main Site 122 1. Partitioning: Auto (UFS) 123 1. Partition: Entire Disk 124 1. Partition Scheme: MBR 125 1. App Partition: Ok 126 1. Partition Editor: Finish 127 1. Confirmation: Commit 128 1. Wait for sets to install 129 1. Set the root password to nothing (press enter twice) 130 1. Set time zone to UTC 131 1. Set Date: Skip 132 1. Set Time: Skip 133 1. System Configuration: 134 1. Disable sshd 135 1. Disable dumpdev 136 1. System Hardening 137 1. Disable Sendmail service 138 1. Add User Accounts: No 139 1. Final Configuration: Exit 140 1. Manual Configuration: Yes 141 1. `echo 'console="comconsole"' >> /boot/loader.conf` 142 1. `echo 'autoboot_delay="0"' >> /boot/loader.conf` 143 1. `echo 'ext2fs_load="YES"' >> /boot/loader.conf` 144 1. Look at `/etc/ttys`, see what getty argument is for `ttyu0` (E.g. `3wire`) 145 1. Edit `/etc/gettytab` (with `vi` for example), look for `ttyu0` argument, 146 prepend `:al=root` to the line beneath to have the machine auto-login as 147 root. E.g. 148 149 3wire:\ 150 :np:nc:sp#0: 151 becomes: 152 153 3wire:\ 154 :al=root:np:nc:sp#0: 155 156 1. Edit `/root/.login` and put this in it: 157 158 [ -e /dev/vtbd1 ] || exit 0 159 mount -t ext2fs /dev/vtbd1 /mnt 160 sh /mnt/run.sh /mnt 161 poweroff 162 163 1. Exit the post install shell: `exit` 164 1. Back in the installer choose Reboot 165 1. If all went well the machine should reboot and show a login prompt. If you 166 switch to the serial console by choosing View > serial0 in the qemu menu, 167 you should be logged in as root. 168 1. Shutdown the machine: `shutdown -p now` 169 170Helpful links 171 172* https://en.wikibooks.org/wiki/QEMU/Images 173* https://blog.nekoconeko.nl/blog/2015/06/04/creating-an-openstack-freebsd-image.html 174* https://www.freebsd.org/doc/handbook/serialconsole-setup.html 175 176### QEMU setup - OpenBSD 177 1781. Download CD installer 1792. `qemu-img create -f qcow2 foo.qcow2 2G` 1803. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user` 1814. run installer 1825. `echo 'set tty com0' >> /etc/boot.conf` 1836. `echo 'boot' >> /etc/boot.conf` 1847. Modify /etc/ttys, change the `tty00` at the end from 'unknown off' to 'vt220 185 on secure' 1868. Modify same line in /etc/ttys to have `"/root/foo.sh"` as the shell 1879. Add this script to `/root/foo.sh` 188 189``` 190#!/bin/sh 191exec 1>/dev/tty00 192exec 2>&1 193 194if mount -t ext2fs /dev/sd1c /mnt; then 195 sh /mnt/run.sh /mnt 196 shutdown -ph now 197fi 198 199# limited shell... 200exec /bin/sh < /dev/tty00 201``` 202 20310. `chmod +x /root/foo.sh` 204 205Helpful links: 206 207* https://en.wikibooks.org/wiki/QEMU/Images 208* http://www.openbsd.org/faq/faq7.html#SerCon 209 210# Questions? 211 212Hopefully that's at least somewhat of an introduction to everything going on 213here, and feel free to ping @alexcrichton with questions! 214