Documentation: Reorganize the build documentation

This commit is contained in:
Gunnar Beutner 2021-07-10 00:53:28 +02:00 committed by Gunnar Beutner
parent 9780cdfb33
commit 9026dbbfd6
Notes: sideshowbarker 2024-07-18 09:22:56 +09:00
13 changed files with 419 additions and 389 deletions

View File

@ -0,0 +1,74 @@
# Advanced Build Instructions
This file covers a few advanced scenarios that go beyond what the basic build guide provides.
## Customizing the disk image
To add, modify or remove files of the disk image's file system, e.g. to change the default keyboard layout, you can create a shell script with the name `sync-local.sh` in the project root, with content like this:
```sh
#!/bin/sh
set -e
cat << 'EOF' > mnt/etc/Keyboard.ini
[Mapping]
Keymap=de
EOF
```
This will configure your keymap to German (`de`) instead of US English. See [`Base/res/keymaps/`](../Base/res/keymaps/) for a full list. Note that the `keymap` program itself will also modify the `/etc/Keyboard.ini` config file, but this way the change will persist across image rebuilds.
## CMake build options
There are some optional features that can be enabled during compilation that are intended to help with specific types of development work or introduce experimental features. Currently, the following build options are available:
- `ENABLE_ADDRESS_SANITIZER` and `ENABLE_KERNEL_ADDRESS_SANITIZER`: builds in runtime checks for memory corruption bugs (like buffer overflows and memory leaks) in Lagom test cases and the kernel, respectively.
- `ENABLE_MEMORY_SANITIZER`: enables runtime checks for uninitialized memory accesses in Lagom test cases.
- `ENABLE_UNDEFINED_SANITIZER`: builds in runtime checks for [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) (like null pointer dereferences and signed integer overflows) in Lagom test cases.
- `ENABLE_FUZZER_SANITIZER`: builds [fuzzers](https://en.wikipedia.org/wiki/Fuzzing) for various parts of the system.
- `ENABLE_EXTRA_KERNEL_DEBUG_SYMBOLS`: sets -Og and -ggdb3 compile options for building the Kernel. Allows for easier debugging of Kernel code. By default, the Kernel is built with -Os instead.
- `ENABLE_ALL_THE_DEBUG_MACROS`: used for checking whether debug code compiles on CI. This should not be set normally, as it clutters the console output and makes the system run very slowly. Instead, enable only the needed debug macros, as described below.
- `ENABLE_ALL_DEBUG_FACILITIES`: used for checking whether debug code compiles on CI. Enables both `ENABLE_ALL_THE_DEBUG_MACROS` and `ENABLE_EXTRA_KERNEL_DEBUG_SYMBOLS`.
- `ENABLE_COMPILETIME_FORMAT_CHECK`: checks for the validity of `std::format`-style format string during compilation. Enabled by default.
- `ENABLE_PCI_IDS_DOWNLOAD`: downloads the [`pci.ids` database](https://pci-ids.ucw.cz/) that contains information about PCI devices at build time, if not already present. Enabled by default.
- `BUILD_LAGOM`: builds [Lagom](../Meta/Lagom/ReadMe.md), which makes various SerenityOS libraries and programs available on the host system.
- `PRECOMPILE_COMMON_HEADERS`: precompiles some common headers to speedup compilation.
- `ENABLE_KERNEL_LTO`: builds the kernel with link-time optimization.
- `INCLUDE_WASM_SPEC_TESTS`: downloads and includes the WebAssembly spec testsuite tests
- `BUILD_<component>`: builds the specified component, e.g. `BUILD_HEARTS` (note: must be all caps). Check the components.ini file in your build directory for a list of available components. Make sure to run `ninja clean` and `rm -rf Build/i686/Root` after disabling components. These options can be easily configured by using the `ConfigureComponents` utility. See the [Component Configuration](#component-configuration) section below.
- `BUILD_EVERYTHING`: builds all optional components, overrides other `BUILD_<component>` flags when enabled
Many parts of the SerenityOS codebase have debug functionality, mostly consisting of additional messages printed to the debug console. This is done via the `<component_name>_DEBUG` macros, which can be enabled individually at build time. They are listed in [this file](../Meta/CMake/all_the_debug_macros.cmake).
To toggle a build option, add it to the `cmake` command invocation with a `-D` prefix. To enable it, add `=ON` at the end, or add `=OFF` to disable it. The complete command should look similarly to this:
```console
$ cmake ../.. -G Ninja -DPROCESS_DEBUG=ON -DENABLE_PCI_IDS_DOWNLOAD=OFF
```
For the changes to take effect, SerenityOS needs to be recompiled and the disk image needs to be rebuilt.
## Component Configuration
For selecting which components of the system to build and install, a helper program, `ConfigureComponents` is available.
It requires `whiptail` as a dependency, which is available on most systems in the `newt` or `libnewt` package. To build and run it, run the following commands from the `Build/i686` directory:
```console
$ cmake ../.. -G Ninja # Only required if CMake hasn't been run before.
$ ninja configure-components
```
This will prompt you which build type you want to use and allows you to customize it by manually adding or removing certain components. It will then run a CMake command based on the selection as well as `ninja clean` and `rm -rf Root` to remove old build artifacts.
## Tests
For information on running host and target tests, see [Running Tests](RunningTests.md). The documentation there explains the difference between host tests run with Lagom and
target tests run on SerenityOS. It also contains useful information for debugging CI test failures.
## Running SerenityOS with VirtualBox and VMware
Outside of QEMU, Serenity will run on VirtualBox and VMware. If you're curious, see how to [install Serenity on VirtualBox](VirtualBox.md) or [install Serenity on VMware](VMware.md).
## Running SerenityOS on bare metal
Bare curious users may even consider sourcing suitable hardware to [install Serenity on a physical PC.](BareMetalInstallation.md)

View File

@ -2,7 +2,7 @@
## DISCLAIMER
Whilst it is possible to run Serenity on physical x86-compatible hardware, it is not yet ready to be used by non-technical users who aren't prepared to report bugs or assist with its development. For this reason, there are currently no pre-built install images so a bare-metal installation requires that you build an installation image from source. Current hardware support is extremely limited. Most successful hard disk installations have been on Pentium 4 era hardware but by [network booting Serenity](https://github.com/SerenityOS/serenity/blob/master/Documentation/NetworkBoot.md) users have been able to get it running on more modern hardware such as Core i5 machines.
Whilst it is possible to run Serenity on physical x86-compatible hardware, it is not yet ready to be used by non-technical users who aren't prepared to report bugs or assist with its development. For this reason, there are currently no pre-built install images so a bare-metal installation requires that you build an installation image from source. Current hardware support is extremely limited. Most successful hard disk installations have been on Pentium 4 era hardware but by [network booting Serenity](NetworkBoot.md) users have been able to get it running on more modern hardware such as Core i5 machines.
## Hardware support and requirements
@ -16,11 +16,11 @@ Serenity currently has no support for USB but some machines will emulate PS/2 ke
At present there is no real GPU support so don't expect OpenGL, Vulkan nor accelerated video playback and encoding support. Serenity currently relies upon VESA BIOS extensions to provide its display output and so it only runs on BIOS-based PCs. There is no WiFi support and the only three network card chipsets are currently supported: Realtek RTL8139, Novell NE2000 and Intel e1000. The e1000 driver has only been tested with qemu and VirtualBox although it may work with NICs such as those using the Intel 82545XX, 82540XX, 82546XX or similar chipsets. The sole sound card supported is the SoundBlaster 16 ISA.
For more details on known working hardware see the [SerenityOS Hardware Compatibility List](https://github.com/SerenityOS/serenity/blob/master/Documentation/HardwareCompatibility.md).
For more details on known working hardware see the [SerenityOS Hardware Compatibility List](HardwareCompatibility.md).
## Creating a Serenity GRUB disk image
Before creating a Serenity disk image, you need to build the OS as described in the [SerenityOS build instructions](https://github.com/SerenityOS/serenity/blob/master/Documentation/BuildInstructions.md). Follow those instructions up to and including running **ninja install**. After the OS has built, run **ninja grub-image** to create a new file called **grub_disk_image** with GRUB2 installed that can be booted on a real PC.
Before creating a Serenity disk image, you need to build the OS as described in the [SerenityOS build instructions](BuildInstructions.md). Follow those instructions up to and including running **ninja install**. After the OS has built, run **ninja grub-image** to create a new file called **grub_disk_image** with GRUB2 installed that can be booted on a real PC.
The final step is copying **grub_disk_image** onto the disk you wish to use to boot Serenity using a command such as:

View File

@ -2,23 +2,15 @@
## Prerequisites
### Linux prerequisites
Make sure you have all the dependencies installed:
Ensure your CMake version is >= 3.16 with `cmake --version`. If your system doesn't provide a suitable version of CMake, you can download a binary release from the [CMake website](https://cmake.org/download).
Ensure your [QEMU](https://www.qemu.org/) version is >= 5 with `qemu-system-i386 -version`. Otherwise, install it. You can also build it using the `Toolchain/BuildQemu.sh` script.
Ensure your gcc version is >= 10 with `gcc --version`. Otherwise, install it.
Make sure you have all the dependencies installed (`ninja` is optional, but is faster in practice):
#### Debian / Ubuntu
### Debian / Ubuntu
```console
sudo apt install build-essential cmake curl libmpfr-dev libmpc-dev libgmp-dev e2fsprogs ninja-build qemu-system-i386 qemu-utils ccache rsync
```
##### GCC 10
#### GCC 10
On Ubuntu gcc-10 is available in the repositories of 20.04 (Focal) and later - add the `ubuntu-toolchain-r/test` PPA if you're running an older version:
@ -47,282 +39,62 @@ sudo sed -i '$d' /etc/apt/sources.list
sudo apt update
```
##### QEMU 5
#### QEMU 5 or later
QUEMU version 5 is available in Ubuntu 20.10. For earlier versions, you can build it using the `Toolchain/BuildQemu.sh` script.
QEMU version 5 is available in Ubuntu 20.10. For earlier versions, you can build version 6 using the `Toolchain/BuildQemu.sh` script.
You may need the gtk+ 3.0 dev package:
```console
sudo apt install libgtk-3-dev
sudo apt install libpixman-1-dev libgtk-3-dev
```
#### Fedora
### Fedora
```console
sudo dnf install binutils-devel curl cmake mpfr-devel libmpc-devel gmp-devel e2fsprogs ninja-build patch ccache rsync @"C Development Tools and Libraries" @Virtualization
```
#### openSUSE
### Other systems
```console
sudo zypper install curl cmake mpfr-devel mpc-devel ninja gmp-devel e2fsprogs patch qemu-x86 qemu-audio-pa gcc gcc-c++ ccache rsync patterns-devel-C-C++-devel_C_C++
```
There is also documentation for installing the build prerequisites for some less commonly used systems:
#### Arch Linux / Manjaro
```console
sudo pacman -S --needed base-devel cmake curl mpfr libmpc gmp e2fsprogs ninja qemu qemu-arch-extra ccache rsync
```
#### Void Linux
```console
sudo xbps-install -S base-devel cmake curl mpfr-devel libmpc-devel gmp-devel e2fsprogs ninja qemu ccache rsync
```
#### ALT Linux
```console
apt-get install curl cmake libmpc-devel gmp-devel e2fsprogs libmpfr-devel ninja-build patch gcc ccache rsync
```
#### NixOS
You can use a `nix-shell` script like the following to set up the correct environment:
myshell.nix:
```
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "cpp-env";
nativeBuildInputs = [
gcc10
curl
cmake
mpfr
ninja
gmp
libmpc
e2fsprogs
patch
ccache
rsync
# Example Build-time Additional Dependencies
pkgconfig
];
buildInputs = [
# Example Run-time Additional Dependencies
openssl
x11
# glibc
];
hardeningDisable = [ "format" "fortify" ];
}
```
Then use this script: `nix-shell myshell.nix`.
Once you're in nix-shell, you should be able to follow the build directions.
#### Alpine Linux
First, make sure you have enabled the `community` repository in `/etc/apk/repositories` and run `apk update`. It has been tested on `edge`, YMMV on `stable`.
```console
# the basics, if you have not already done so
apk add bash curl git util-linux sudo
# rough equivalent of build-essential
apk add build-base
# qemu
apk add qemu qemu-system-i386 qemu-img qemu-ui-gtk
# build tools (samurai is a drop-in replacement for ninja)
apk add cmake e2fsprogs grub-bios samurai mpc1-dev mpfr-dev gmp-dev ccache rsync
```
### macOS prerequisites
Make sure you have all the dependencies installed:
```console
# core
brew install coreutils qemu bash gcc@10 ninja cmake ccache rsync
# (option 1) fuse + ext2
brew install e2fsprogs m4 autoconf automake libtool
brew install --cask osxfuse
Toolchain/BuildFuseExt2.sh
# (option 2) genext2fs
brew install genext2fs
```
Notes:
- fuse-ext2 is not available as brew formula so it must be installed using `BuildFuseExt2.sh`
- Xcode and `xcode-tools` must be installed (`git` is required by some scripts)
- coreutils is needed to build gcc cross compiler
- qemu is needed to run the compiled OS image. You can also build it using the `BuildQemu.sh` script
- osxfuse, e2fsprogs, m4, autoconf, automake, libtool and `BuildFuseExt2.sh` are needed if you want to build the root filesystem disk image natively on macOS. This allows mounting an EXT2 fs and also installs commands like `mke2fs` that are not available on stock macOS.
- Installing osxfuse for the first time requires enabling its system extension in System Preferences and then restarting your machine. The output from installing osxfuse with brew says this, but it's easy to miss.
- bash is needed because the default version installed on macOS doesn't support globstar
- If you install some commercial EXT2 macOS fs handler instead of osxfuse and fuse-ext2, you will need to `brew install e2fsprogs` to obtain `mke2fs` anyway.
- As of 2020-08-06, you might need to tell the build system about your newer host compiler. Once you've built the toolchain, navigate to `Build/i686/`, `rm -rf *`, then run `cmake ../.. -G Ninja -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10`, then continue with `ninja install` as usual.
- If you are on macOS Big Sur, you will need to manually enable QEMU's acceleration before running Serenity, by creating a new file called `entitlements.xml` in the `Build/` folder, with the content below, and then run the command: `codesign -s - --entitlements entitlements.xml --force /usr/local/bin/qemu-system-x86_64`; otherwise the run command will fail.
<details>
<summary>Content for 'entitlements.xml'.</summary>
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.hypervisor</key>
<true/>
</dict>
</plist>
```
</details>
### OpenBSD prerequisites
```console
$ doas pkg_add bash cmake g++ gcc git gmake gmp ninja ccache rsync
```
To use `ninja image` and `ninja run`, you'll need Qemu and other utilities:
```console
$ doas pkg_add coreutils qemu sudo
```
### FreeBSD prerequisites
```console
$ pkg install bash coreutils git gmake ninja sudo gmp mpc mpfr ccache rsync
```
### Windows prerequisites
For Windows, you will require Windows Subsystem for Linux 2 (WSL2). [Follow the WSL2 instructions here.](https://github.com/SerenityOS/serenity/blob/master/Documentation/NotesOnWSL.md)
Do note the ```Hardware acceleration``` and ```Note on filesystems``` sections, otherwise performance will be terrible.
Once you have installed a distro for WSL2, follow the Linux prerequisites above for the distro you installed, then continue as normal.
You may also want to install [ninja](https://github.com/ninja-build/ninja/releases)
* [Other Linux distributions and *NIX systems](BuildInstructionsOther.md)
* [Windows](BuildInstructionsWindows.md)
* [macOS](BuildInstructionsMacOS.md)
## Build
Go into the `Toolchain/` directory and run the **BuildIt.sh** script:
In order to build SerenityOS you will first need to build the toolchain by running the following command:
```console
$ cd Toolchain
$ ./BuildIt.sh
$ Meta/serenity.sh rebuild-toolchain
```
Building the toolchain will also automatically create a `Build/i686/` directory for the build to live in. Once the toolchain has been built, go into the `Build/i686/` directory. Specifically, change the current directory to the `Build/` parent directory. To go there from `Toolchain/`, use this command:
Later on, when you use `git pull` to get the latest changes, there's (usually) no need to rebuild the toolchain.
Run the following command to build and run SerenityOS:
```console
$ cd ../Build/i686
$ Meta/serenity.sh run
```
Run the following commands from within the `Build/i686/` directory. Note that while `ninja` seems to be faster, you can also just use GNU make, by omitting `-G Ninja` and calling `make` instead of `ninja`:
This will compile all of SerenityOS and install the built files into the `Build/i686/Root` directory inside your Git
repository. It will also build a disk image and start SerenityOS using QEMU.
```console
$ cmake ../.. -G Ninja
$ ninja install
```
This will compile all of SerenityOS and install the built files into `Root/` inside the build tree. `ninja` will automatically build as many jobs in parallel as it detects processors; `make` builds only one job in parallel. (Use the `-j` option with an argument if you want to change this.)
Now to build a disk image, run `ninja image`, and take it for a spin by using `ninja run`.
```console
$ ninja image
$ ninja run
```
Note that the `anon` user is able to become `root` without password by default, as a development convenience.
Note that the `anon` user is able to become `root` without a password by default, as a development convenience.
To prevent this, remove `anon` from the `wheel` group and he will no longer be able to run `/bin/su`.
On Linux, QEMU is significantly faster if it's able to use KVM. The run script will automatically enable KVM if `/dev/kvm` exists and is readable+writable by the current user.
Bare curious users may even consider sourcing suitable hardware to [install Serenity on a physical PC.](https://github.com/SerenityOS/serenity/blob/master/Documentation/INSTALL.md)
Outside of QEMU, Serenity will run on VirtualBox and VMware. If you're curious, see how to [install Serenity on VirtualBox](https://github.com/SerenityOS/serenity/blob/master/Documentation/VirtualBox.md) or [install Serenity on VMware](https://github.com/SerenityOS/serenity/blob/master/Documentation/VMware.md).
Later on, when you `git pull` to get the latest changes, there's (usually) no need to rebuild the toolchain. You can simply run `ninja install`, `ninja image`, and `ninja run` again. CMake will only rebuild those parts that have been updated.
### CMake build options
There are some optional features that can be enabled during compilation that are intended to help with specific types of development work or introduce experimental features. Currently, the following build options are available:
- `ENABLE_ADDRESS_SANITIZER` and `ENABLE_KERNEL_ADDRESS_SANITIZER`: builds in runtime checks for memory corruption bugs (like buffer overflows and memory leaks) in Lagom test cases and the kernel, respectively.
- `ENABLE_MEMORY_SANITIZER`: enables runtime checks for uninitialized memory accesses in Lagom test cases.
- `ENABLE_UNDEFINED_SANITIZER`: builds in runtime checks for [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) (like null pointer dereferences and signed integer overflows) in Lagom test cases.
- `ENABLE_FUZZER_SANITIZER`: builds [fuzzers](https://en.wikipedia.org/wiki/Fuzzing) for various parts of the system.
- `ENABLE_EXTRA_KERNEL_DEBUG_SYMBOLS`: sets -Og and -ggdb3 compile options for building the Kernel. Allows for easier debugging of Kernel code. By default, the Kernel is built with -Os instead.
- `ENABLE_ALL_THE_DEBUG_MACROS`: used for checking whether debug code compiles on CI. This should not be set normally, as it clutters the console output and makes the system run very slowly. Instead, enable only the needed debug macros, as described below.
- `ENABLE_ALL_DEBUG_FACILITIES`: used for checking whether debug code compiles on CI. Enables both `ENABLE_ALL_THE_DEBUG_MACROS` and `ENABLE_EXTRA_KERNEL_DEBUG_SYMBOLS`.
- `ENABLE_COMPILETIME_FORMAT_CHECK`: checks for the validity of `std::format`-style format string during compilation. Enabled by default.
- `ENABLE_PCI_IDS_DOWNLOAD`: downloads the [`pci.ids` database](https://pci-ids.ucw.cz/) that contains information about PCI devices at build time, if not already present. Enabled by default.
- `BUILD_LAGOM`: builds [Lagom](../Meta/Lagom/ReadMe.md), which makes various SerenityOS libraries and programs available on the host system.
- `PRECOMPILE_COMMON_HEADERS`: precompiles some common headers to speedup compilation.
- `ENABLE_KERNEL_LTO`: builds the kernel with link-time optimization.
- `INCLUDE_WASM_SPEC_TESTS`: downloads and includes the WebAssembly spec testsuite tests
- `BUILD_<component>`: builds the specified component, e.g. `BUILD_HEARTS` (note: must be all caps). Check the components.ini file in your build directory for a list of available components. Make sure to run `ninja clean` and `rm -rf Build/i686/Root` after disabling components. These options can be easily configured by using the `ConfigureComponents` utility. See the [Component Configuration](#component-configuration) section below.
- `BUILD_EVERYTHING`: builds all optional components, overrides other `BUILD_<component>` flags when enabled
Many parts of the SerenityOS codebase have debug functionality, mostly consisting of additional messages printed to the debug console. This is done via the `<component_name>_DEBUG` macros, which can be enabled individually at build time. They are listed in [this file](../Meta/CMake/all_the_debug_macros.cmake).
To toggle a build option, add it to the `cmake` command invocation with a `-D` prefix. To enable it, add `=ON` at the end, or add `=OFF` to disable it. The complete command should look similarly to this:
```console
$ cmake ../.. -G Ninja -DPROCESS_DEBUG=ON -DENABLE_PCI_IDS_DOWNLOAD=OFF
```
For the changes to take effect, SerenityOS needs to be recompiled and the disk image needs to be rebuilt.
## Component Configuration
For selecting which components of the system to build and install, a helper program, `ConfigureComponents` is available.
It requires `whiptail` as a dependency, which is available on most systems in the `newt` or `libnewt` package. To build and run it, run the following commands from the `Build/i686` directory:
```console
$ cmake ../.. -G Ninja # Only required if CMake hasn't been run before.
$ ninja configure-components
```
This will prompt you which build type you want to use and allows you to customize it by manually adding or removing certain components. It will then run a CMake command based on the selection as well as `ninja clean` and `rm -rf Root` to remove old build artifacts.
If you want to test whether your code changes compile without running the VM you can use
`Meta/serenity.sh build`. The `serenity.sh` script also provides a number of other commands. Run the script without
arguments for a list.
## Ports
To add a package from the ports collection to Serenity, for example curl, go into `Ports/curl/` and run `./package.sh`. The sourcecode for the package will be downloaded and the package will be built. After that, rebuild the disk image. The next time you start Serenity, `curl` will be available.
To add a package from the ports collection to Serenity, for example curl, change into the `Ports/curl` directory and
run `./package.sh`. The source code for the package will be downloaded and the package will be built. The next time you
start Serenity, `curl` will be available.
## Tests
## More information
For information on running host and target tests, see [Running Tests](RunningTests.md). The documentation there explains the difference between host tests run with Lagom and
target tests run on SerenityOS. It also contains useful information for debugging CI test failures.
## Customize disk image
To add, modify or remove files of the disk image's file system, e.g. to change the default keyboard layout, you can create a shell script with the name `sync-local.sh` in the project root, with content like this:
```sh
#!/bin/sh
set -e
cat << 'EOF' > mnt/etc/Keyboard.ini
[Mapping]
Keymap=de
EOF
```
This will configure your keymap to German (`de`) instead of US English. See [`Base/res/keymaps/`](../Base/res/keymaps/) for a full list. Note that the `keymap` program itself will also modify the `/etc/Keyboard.ini` config file, but this way the change will persist across image rebuilds.
At this point you should have a fully functioning VM for SerenityOS. The [advanced build instructions guide](AdvancedBuildInstructions.md)
has more information for some less commonly used features of the build system.

View File

@ -0,0 +1,51 @@
# Setting up a development environment on macOS
# Prerequisites
This installation guide assumes that you have Homebrew, Xcode and `xcode-tools` installed.
Make sure you also have all the following dependencies installed:
```console
# core
brew install coreutils qemu bash gcc@10 ninja cmake ccache rsync
# (option 1) fuse + ext2
brew install e2fsprogs m4 autoconf automake libtool
brew install --cask osxfuse
Toolchain/BuildFuseExt2.sh
# (option 2) genext2fs
brew install genext2fs
```
Notes:
- Installing osxfuse for the first time requires enabling its system extension in System Preferences and then restarting
your machine. The output from installing osxfuse with brew says this, but it's easy to miss.
## Hardware acceleration on macOS Big Sur
If you are on macOS Big Sur, you will need to manually enable QEMU's hardware acceleration before running Serenity, by
creating a new file called `entitlements.xml` in the `Build/` folder, with the content below, and then running this
command:
`codesign -s - --entitlements entitlements.xml --force /usr/local/bin/qemu-system-x86_64`
<details>
<summary>Content for 'entitlements.xml'.</summary>
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.hypervisor</key>
<true/>
</dict>
</plist>
```
</details>

View File

@ -0,0 +1,97 @@
# Installing build requisites on other systems
## openSUSE
```console
sudo zypper install curl cmake mpfr-devel mpc-devel ninja gmp-devel e2fsprogs patch qemu-x86 qemu-audio-pa gcc gcc-c++ ccache rsync patterns-devel-C-C++-devel_C_C++
```
## Arch Linux / Manjaro
```console
sudo pacman -S --needed base-devel cmake curl mpfr libmpc gmp e2fsprogs ninja qemu qemu-arch-extra ccache rsync
```
## Void Linux
```console
sudo xbps-install -S base-devel cmake curl mpfr-devel libmpc-devel gmp-devel e2fsprogs ninja qemu ccache rsync
```
## ALT Linux
```console
apt-get install curl cmake libmpc-devel gmp-devel e2fsprogs libmpfr-devel ninja-build patch gcc ccache rsync
```
## NixOS
You can use a `nix-shell` script like the following to set up the correct environment:
myshell.nix:
```
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "cpp-env";
nativeBuildInputs = [
gcc10
curl
cmake
mpfr
ninja
gmp
libmpc
e2fsprogs
patch
ccache
rsync
# Example Build-time Additional Dependencies
pkgconfig
];
buildInputs = [
# Example Run-time Additional Dependencies
openssl
x11
# glibc
];
hardeningDisable = [ "format" "fortify" ];
}
```
Then use this script: `nix-shell myshell.nix`.
Once you're in nix-shell, you should be able to follow the build directions.
## Alpine Linux
First, make sure you have enabled the `community` repository in `/etc/apk/repositories` and run `apk update`. It has been tested on `edge`, YMMV on `stable`.
```console
# the basics, if you have not already done so
apk add bash curl git util-linux sudo
# rough equivalent of build-essential
apk add build-base
# qemu
apk add qemu qemu-system-i386 qemu-img qemu-ui-gtk
# build tools (samurai is a drop-in replacement for ninja)
apk add cmake e2fsprogs grub-bios samurai mpc1-dev mpfr-dev gmp-dev ccache rsync
```
## OpenBSD prerequisites
```console
$ doas pkg_add bash cmake g++ gcc git gmake gmp ninja ccache rsync coreutils qemu sudo
```
## FreeBSD prerequisites
```console
$ pkg install bash coreutils git gmake ninja sudo gmp mpc mpfr ccache rsync
```

View File

@ -0,0 +1,125 @@
# Setting up a development environment on Windows
SerenityOS can be built and run under WSL Version 2.
WSL Version 1 is not supported since Version 1 does not support ext2, which is needed for the setup.
WSL Version 2 requires Windows 10 version 2004 or higher, with OS Build 19041 or greater. Here is a guide on how to
[get WSL2](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
Once installed, you will need to make sure the distribution you want to use (and the new default) is using Version 2:
- `wsl -l -v` lists distros and versions,<br/>
- `wsl --set-version <distro> <version>` is used to convert a distro to another version, and<br/>
- `wsl --set-default-version 2` will set the default version for all new distros (if desired.)<br/>
## Setting up build tools
Please see the general build instructions for a list of tools you need to install in your WSL Linux environment. As a
special exception you should _not_ install QEMU in the Linux environment and instead use the instructions from the next
section to set up QEMU on your host system.
## Setting up QEMU
- Grab the latest QEMU binaries from [here](https://www.qemu.org/download/#windows) and install them.
- Locate the executable `qemu-system-i386.exe` in WSL.
By default this will be located at `/mnt/c/Program Files/qemu/qemu-system-i386.exe`.
- Set the `SERENITY_QEMU_BIN` environment variable to the location above. For example: \
`export SERENITY_QEMU_BIN='/mnt/c/Program Files/qemu/qemu-system-i386.exe'`
- Locate the _Windows_ path to the SerenityOS disk image, as native QEMU will be accessing it via the Windows filesystem.
If your build tree is located in the WSL2 partition, this will be accessible under the `\\wsl$` network file share
(see [notes below](#note-on-filesystems)).
- Set the `SERENITY_KERNEL_CMDLINE` environment variable to disable VirtIO support (Because it is currently broken on
native windows QEMU):
`export SERENITY_KERNEL_CMDLINE="disable_virtio"`
- Set the `SERENITY_DISK_IMAGE` environment variable to the full path of the SerenityOS disk image file from above.
For example: `export SERENITY_DISK_IMAGE='\\wsl$\Ubuntu-20.04\home\username\serenity\Build\i686\_disk_image'`
- `ninja run` as usual.
### Hardware acceleration
The steps above will run QEMU in software virtualisation mode, which is very slow.
QEMU supports hardware acceleration on Windows via the [Windows Hypervisor Platform](https://docs.microsoft.com/en-us/virtualization/api/) (WHPX), a user-mode virtualisation API that can be used alongside Hyper-V.
This is important to note as WSL2 itself runs on top of Hyper-V, which conflicts with other acceleration technologies
such as Intel HAXM.
To run SerenityOS in a WHPX-enabled QEMU VM:
- If you have not already done so, enable Windows Hypervisor Platform, either using "Turn Windows features on or off",
or by running the following command in an elevated PowerShell session: \
`dism /Online /Enable-Feature /All /FeatureName:HypervisorPlatform`
- Specify QEMU acceleration option: \
`export SERENITY_VIRT_TECH_ARG="-accel whpx,kernel-irqchip=off"`
- Disable Virtual Machine eXtensions on the vCPU, otherwise some versions of QEMU will crash out with a "WHPX: Unexpected VP exit code 4" error: \
`export SERENITY_QEMU_CPU="max,vmx=off"`
- `ninja run` as usual.
### Known issues with WHPX
#### Freeze on boot in Scheduler
If Serenity freezes on boot with the log message: `Scheduler[0]: idle loop running` then you are likely missing some emulated CPU features.
Please ensure you have installed the most recent version of [QEMU for Windows](https://qemu.weilnetz.de/) and that you
have followed the step above to enable the maximum feature set available: `export SERENITY_QEMU_CPU="max,vmx=off"`.
If the steps above do not fix the problem, check the boot log for `whpx: injection failed, MSI (0, 0) delivery: 0, dest_mode: 0, trigger mode: 0, vector: 0, lost (c0350005)`.
If present, try disabling the KVM in-kernel interrupt handler by extending the above to `export SERENITY_EXTRA_QEMU_ARGS="-accel whpx,kernel-irqchip=off"`.
This seems to be an issue for some users with QEMU 6.x.
#### Illegal instruction on boot
Using `SERENITY_QEMU_CPU="max"` can trigger a QEMU bug where the OSXSAVE CPUID flag is erroneously set, playing havoc
with feature detection logic in libgcc and resulting in this error.
To workaround this, first adjust the `SERENITY_QEMU_CPU` setting to emulate a more restricted feature set. `SERENITY_QEMU_CPU="qemu32"`
appears to work in some cases, however in others causes the boot freeze issue above. It's worth playing around with
various different values here to see if you can find one that works for you. Running `qemu-system-i386.exe -cpu ?` will
list the supported CPU configurations.
If you cannot find a working CPU feature set, the next workaround is to patch libgcc in the Serenity toolchain build to
remove the offending instruction.
Comment out the `if ((ecx & bit_OSXSAVE))` block in `Toolchain/Tarballs/gcc-<version>/libgcc/config/i386/cpuinfo.c`. In
GCC 10.2.0 this is lines 282-297.
Rebuild the toolchain using `Toolchain/BuildIt.sh` as normal, then rebuild Serenity.
#### Slow boot on HiDPI systems
On some Windows systems running with >100% scaling, the booting phase of Serenity might slow to a crawl. Changing the
zoom settings of the QEMU window will speed up the emulation, but you'll have to squint harder to read the smaller display.
A quick workaround is opening the properties of the QEMU executable at `C:\Program Files\qemu\qemu-system-i386.exe`, and
in the Compatibility tab changing the DPI settings to force the scaling to be performed by the System, by changing the
setting at at the bottom of the window. The QEMU window will now render at normal size while retaining acceptable emulation speeds.
This is being tracked as issue [#7657](https://github.com/SerenityOS/serenity/issues/7657).
## Note on filesystems
WSL2 filesystem performance for IO heavy tasks (such as compiling a large C++ project) on the host Windows filesystem is
terrible. This is because WSL2 runs as a Hyper-V virtual machine and uses the 9P file system protocol to access host
Windows files, over Hyper-V sockets.
For a more in depth explanation of the technical limitations of their approach, see
[this issue on the WSL GitHub project](https://github.com/microsoft/WSL/issues/4197#issuecomment-604592340)
The recommendation from the Microsoft team on that issue is:
> If it's at all possible, store your projects in the Linux file system in WSL2.
In practice, this means cloning and building the project to somewhere such as `/home/username/serenity`.
If you're using the native Windows QEMU binary from the above steps, QEMU is not able to access the ext4 root partition
of the WSL2 installation without going via the 9P network file share. The root of your WSL2 distro will begin at the
network path `\\wsl$\{distro-name}`.
Alternatively, you may prefer to copy `Build/_disk_image` and `Build/Kernel/Kernel` to a native Windows partition (e.g.
`/mnt/c`) before running `ninja run`, in which case `SERENITY_DISK_IMAGE` will be a regular Windows path (e.g.
`'D:\serenity\_disk_image'`).

View File

@ -36,7 +36,7 @@ It is possible to set the embedded terminal in CLion to the one that your WSL di
This way you can build and run serenity without leaving the IDE.
Note that following will only help if you don't use an X-window server to access qemu.
It is possible to install qemu natively on Windows and allow WSL to use it instead of installing qemu first on (wsl) linux and then use X server to launch serenity inside of it.
Check the updated manual [here](https://github.com/SerenityOS/serenity/blob/master/Documentation/NotesOnWSL.md).
Check the updated manual [here](BuildInstructionsWindows.md).
- Locate the terminal emulator for your linux distribution.
Open CMD with elevated privileges and cd to `C:/Program Files/WindowsApps/`.

View File

@ -1,117 +0,0 @@
## Notes on WSL
SerenityOS can also be built and run under WSL Version 2.
WSL Version 1 is not supported since Version 1 does not support ext2, which is needed for the setup.
WSL Version 2 requires Windows version 2004 or higher, with OS Build 19041 or greater. Here is a guide on how to [get WSL2](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
Once installed, you will need to make sure the distribution you want to use (and the new default) is using Version 2:
- `wsl -l -v` will list distros and versions,<br/>
- `wsl --set-version <distro> <version>` is used to convert a distro to another version, and<br/>
- `wsl --set-default-version 2` will set the default version for all new distros (if desired.)<br/>
The installation then proceeds as usual.
WSL2 does not natively support graphical applications.
You can either install QEMU natively on windows and allow WSL to talk to it, or you can install an X Server for windows.
### Setting up an X server with WSL:
- Install [Vcxsrv](https://sourceforge.net/projects/vcxsrv/) on Windows.
- When you start up Vcxsrv, make sure to set the Display number to 0, and to Disable access control.
- Before actually doing **ninja run**, you need to set the DISPLAY environmental variable as such:
```bash
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
```
This is due to a bug in WSL2. For more information, microsoft/WSL#4106.
- Connect to the window server from WSL.
Now you can finally, **ninja run**.
### Using native QEMU install with WSL:
- Grab latest QEMU from [here](https://www.qemu.org/download/#windows) and install for Windows.
- Locate the executable `qemu-system-i386.exe` in WSL.
By default this will be located at `/mnt/c/Program Files/qemu/qemu-system-i386.exe`.
- Set the `SERENITY_QEMU_BIN` environment variable to the location above. For example: \
`export SERENITY_QEMU_BIN='/mnt/c/Program Files/qemu/qemu-system-i386.exe'`
- Locate the _Windows_ path to the SerenityOS disk image, as native QEMU will be accessing it via the Windows filesystem. If your build tree is located in the WSL2 partition, this will be accessible under the `\\wsl$` network file share (see [notes below](#note-on-filesystems)).
- Set the `SERENITY_KERNEL_CMDLINE` environment variable to disable VirtIO support (Because it is currently broken on native windows QEMU):
`export SERENITY_KERNEL_CMDLINE="disable_virtio"`
- Set the `SERENITY_DISK_IMAGE` environment variable to the full path of the SerenityOS disk image file from above. For example: \
`export SERENITY_DISK_IMAGE='\\wsl$\Ubuntu-20.04\home\username\serenity\Build\i686\_disk_image'`
- `ninja run` as usual.
#### Hardware acceleration
The steps above will run QEMU in software virtualisation mode, which is very slow.
QEMU supports hardware acceleration on Windows via the [Windows Hypervisor Platform](https://docs.microsoft.com/en-us/virtualization/api/) (WHPX), a user-mode virtualisation API that can be used alongside Hyper-V.
This is important to note as WSL2 itself runs on top of Hyper-V, which conflicts with other acceleration technologies such as Intel HAXM.
To run SerenityOS in a WHPX-enabled QEMU VM:
- If you have not already done so, enable Windows Hypervisor Platform, either using "Turn Windows features on or off", or by running the following command in an elevated PowerShell session: \
`dism /Online /Enable-Feature /All /FeatureName:HypervisorPlatform`
- Specify QEMU acceleration option: \
`export SERENITY_EXTRA_QEMU_ARGS="-accel whpx"`
- Disable Virtual Machine eXtensions on the vCPU, otherwise some versions of QEMU will crash out with a "WHPX: Unexpected VP exit code 4" error: \
`export SERENITY_QEMU_CPU="max,vmx=off"`
- `ninja run` as usual.
#### Known issues with WHPX
##### Freeze on boot in Scheduler
If Serenity freezes on boot with the log message: `Scheduler[0]: idle loop running` then you are likely missing some emulated CPU features.
Please ensure you have installed the most recent version of [QEMU for Windows](https://qemu.weilnetz.de/) and that you have followed the step above to enable the maximum feature set available:
`export SERENITY_QEMU_CPU="max,vmx=off"`.
If the steps above do not fix the problem, check the boot log for `whpx: injection failed, MSI (0, 0) delivery: 0, dest_mode: 0, trigger mode: 0, vector: 0, lost (c0350005)`. If present, try disabling the KVM in-kernel interrupt handler by extending the above to `export SERENITY_EXTRA_QEMU_ARGS="-accel whpx,kernel-irqchip=off"`. This seems to be an issue for some users with QEMU 6.x.
##### Illegal instruction on boot
Using `SERENITY_QEMU_CPU="max"` can trigger a QEMU bug where the OSXSAVE CPUID flag is erroneously set, playing havoc with feature detection logic in libgcc and resulting in this error.
To workaround this, first adjust the `SERENITY_QEMU_CPU` setting to emulate a more restricted feature set. `SERENITY_QEMU_CPU="qemu32"` appears to work in some cases, however in others causes the boot freeze issue above.
It's worth playing around with various different values here to see if you can find one that works for you. Running `qemu-system-i386.exe -cpu ?` will list the supported CPU configurations.
If you cannot find a working CPU feature set, the next workaround is to patch libgcc in the Serenity toolchain build to remove the offending instruction.
Comment out the `if ((ecx & bit_OSXSAVE))` block in `Toolchain/Tarballs/gcc-<version>/libgcc/config/i386/cpuinfo.c`. In GCC 10.2.0 this is lines 282-297.
Rebuild the toolchain using `Toolchain/BuildIt.sh` as normal, then rebuild Serenity.
##### Slow boot on HiDPI systems
On some Windows systems running with >100% scaling, the booting phase of Serenity might slow to a crawl. Changing the zoom settings of the QEMU window
will speed up the emulation, but you'll have to squint harder to read the smaller display.
A quick workaround is opening the properties of the QEMU executable at `C:\Program Files\qemu\qemu-system-i386.exe`, and in the Compatibility tab changing the DPI settings to force the scaling to be performed by the System, by changing the setting at at the bottom of the window. The QEMU window will now render at normal size while retaining acceptable emulation speeds.
This is being tracked as issue [#7657](https://github.com/SerenityOS/serenity/issues/7657).
### Note on filesystems
WSL2 filesystem performance for IO heavy tasks (such as compiling a large C++ project) on the host Windows filesystem is terrible.
This is because WSL2 runs as a Hyper-V virtual machine and uses the 9P file system protocol to access host windows files, over Hyper-V sockets.
For a more in depth explanation of the technical limitations of their approach, see [this issue on the WSL github](https://github.com/microsoft/WSL/issues/4197#issuecomment-604592340)
The recommendation from the Microsoft team on that issue is:
> If it's at all possible, store your projects in the Linux file system in WSL2.
In practice, this means cloning and building the project to somewhere such as `/home/username/serenity`.
If you're using the native Windows QEMU binary from the above steps, QEMU is not able to access the ext4 root partition of the
WSL2 installation without going via the 9P network file share. The root of your WSL2 distro will begin at the network path `\\wsl$\{distro-name}`.
Alternatively, you may prefer to copy `Build/_disk_image` and `Build/Kernel/Kernel` to a native Windows partition (e.g. `/mnt/c`) before running `ninja run`, in which case `SERENITY_DISK_IMAGE` will be a regular Windows path (e.g. `'D:\serenity\_disk_image'`)

View File

@ -2,18 +2,45 @@
In case of an error, you might find an answer of how to deal it here.
## I build everything, the VM starts and then I see...
## Building SerenityOS
### "Error: Kernel Image too big for memory slot. Halting!"
### CMake fails to configure the build because it's outdated
Ensure your CMake version is >= 3.16 with `cmake --version`. If your system doesn't provide a suitable
version of CMake, you can download a binary release from the [CMake website](https://cmake.org/download).
### QEMU is missing or is outdated
Ensure your [QEMU](https://www.qemu.org/) version is >= 5 with `qemu-system-i386 -version`. Otherwise,
install it. You can also build it using the `Toolchain/BuildQemu.sh` script.
### GCC is missing or is outdated
Ensure your gcc version is >= 10 with `gcc --version`. Otherwise, install it. If your gcc binary is not
called `gcc` you have to specify the names of your C and C++ compiler when you run cmake, e.g.
`cmake ../.. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11`.
## Running SerenityOS
### The VM is really slow
On Linux, QEMU is significantly faster if it's able to use KVM. The run script will automatically enable KVM
if `/dev/kvm` exists and is readable+writable by the current user. On Windows, ensure that you have
WHPX acceleration enabled.
### Boot fails with "Error: Kernel Image too big for memory slot. Halting!"
This means the kernel is too large again. Contact us on the discord server or open a GitHub Issue about it.
You might want to revert latest changes in tree to see if that solves the problem temporarily.
### "Your computer does not support long mode (64-bit mode). Halting!"
### Boot fails with "Your computer does not support long mode (64-bit mode). Halting!"
Either your machine (if you try to boot on bare metal) is very old, thus it's not supporting x86_64 extensions, or you try to use VirtualBox without using a x64 virtualization mode or you try to use `qemu-system-i386` which doesn't support x86_64 extensions too.
Either your machine (if you try to boot on bare metal) is very old, thus it's not supporting x86_64
extensions, or you try to use VirtualBox without using a x64 virtualization mode or you try to use
`qemu-system-i386` which doesn't support x86_64 extensions too.
### Boot fails with "Your computer does not support PAE. Halting!"
### "Your computer does not support PAE. Halting!"
- If booting on bare metal, your CPU is too old to boot Serenity.
- If you're using VirtualBox, you need to enable PAE/NX. Check the instructions [here.](VirtualBox.md)
- If you're using QEMU, the [CPU model configuration](https://qemu-project.gitlab.io/qemu/system/qemu-cpu-models.html) is not exposing PAE.

View File

@ -2,7 +2,7 @@
## Setup
First, make sure you have a working toolchain and can build and run SerenityOS. Go [here](https://github.com/SerenityOS/serenity/blob/master/Documentation/BuildInstructions.md) for instructions for setting that up.
First, make sure you have a working toolchain and can build and run SerenityOS. Go [here](BuildInstructions.md) for instructions for setting that up.
* Install [Qt Creator](https://www.qt.io/offline-installers). You don't need the entire Qt setup, just click 'Qt Creator' on the left side, and install that.
* Open Qt Creator, select `File -> New File or Project...`
@ -41,7 +41,7 @@ Qt Creator should be set up correctly now, go ahead and explore the project and
## Auto-Formatting
You can use `clang-format` to help you with the [style guide](https://github.com/SerenityOS/serenity/blob/master/Documentation/CodingStyle.md). Before you proceed, check that you're actually using clang-format version 11, as some OSes still ship clang-format version 9 or 10 by default.
You can use `clang-format` to help you with the [style guide](CodingStyle.md). Before you proceed, check that you're actually using clang-format version 11, as some OSes still ship clang-format version 9 or 10 by default.
- In QtCreator, go to "Help > About Plugins…"
- Find the `Beautifier (experimental)` row (for example, by typing `beau` into the search)

View File

@ -4,7 +4,7 @@
There are currently issues with running Serenity in VMware. Please refer to the [open issue](https://github.com/SerenityOS/serenity/issues/5716) for a list of currently known issues. Anything that doesn't currently work will be noted in this document.
## Creating the disk image
Before creating a disk image that will work in VMware, you will need to create a GRUB image as described in the [Serenity installation guide](https://github.com/SerenityOS/serenity/blob/master/Documentation/INSTALL.md). Please skip the final step of that section, as that is only relevant for putting the image onto a real drive. You **cannot** use the same disk image created for QEMU. Using that image will halt immediately with the message ``FATAL: No bootable medium found! System halted.``
Before creating a disk image that will work in VMware, you will need to create a GRUB image as described in the [Serenity installation guide](BareMetalInstallation.md). Please skip the final step of that section, as that is only relevant for putting the image onto a real drive. You **cannot** use the same disk image created for QEMU. Using that image will halt immediately with the message ``FATAL: No bootable medium found! System halted.``
The easiest way to convert the disk image is with QEMU:

View File

@ -4,7 +4,7 @@
There are currently issues with running Serenity in VirtualBox. Please refer to the [open issue](https://github.com/SerenityOS/serenity/issues/2927) for a list of currently known issues. Anything that doesn't currently work will be noted in this document.
## Creating the disk image
Before creating a disk image that will work in VirtualBox, you will need to create a GRUB image as described in the [Serenity installation guide](https://github.com/SerenityOS/serenity/blob/master/Documentation/INSTALL.md). Please skip the final step of that section, as that is only relevant for putting the image onto a real drive. You **cannot** use the same disk image created for QEMU. Using that image will halt immediately with the message ``FATAL: No bootable medium found! System halted.``
Before creating a disk image that will work in VirtualBox, you will need to create a GRUB image as described in the [Serenity installation guide](BareMetalInstallation.md). Please skip the final step of that section, as that is only relevant for putting the image onto a real drive. You **cannot** use the same disk image created for QEMU. Using that image will halt immediately with the message ``FATAL: No bootable medium found! System halted.``
There are a couple of ways to convert the disk image:

View File

@ -120,7 +120,8 @@ pick_gcc() {
if ! $GCC_CANDIDATE -dumpversion >/dev/null 2>&1; then
continue
fi
local VERSION="$($GCC_CANDIDATE -dumpversion)"
local VERSION=""
VERSION="$($GCC_CANDIDATE -dumpversion)"
local MAJOR_VERSION="${VERSION%%.*}"
if [ "$MAJOR_VERSION" -gt "$BEST_VERSION" ]; then
BEST_VERSION=$MAJOR_VERSION