diff options
| author | spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> | 2021-11-28 18:15:14 +0100 |
|---|---|---|
| committer | spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> | 2021-11-28 18:15:14 +0100 |
| commit | a75b3fa4b1a1b882c33f533645ddae75c09dd697 (patch) | |
| tree | 2b9bd90c0564b983a35971207116976425288da4 /doc | |
| parent | 6d9ceda63aefe8910e798b6b38a7783d00b855f1 (diff) | |
| download | psn00bsdk-a75b3fa4b1a1b882c33f533645ddae75c09dd697.tar.gz | |
Switch to mipsel-none-elf, move docs, add template presets
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/cmake_reference.md | 69 | ||||
| -rw-r--r-- | doc/dev notes.txt | 15 | ||||
| -rw-r--r-- | doc/installation.md | 155 | ||||
| -rw-r--r-- | doc/toolchain.md | 224 |
4 files changed, 434 insertions, 29 deletions
diff --git a/doc/cmake_reference.md b/doc/cmake_reference.md index 3b586ab..9e134d9 100644 --- a/doc/cmake_reference.md +++ b/doc/cmake_reference.md @@ -10,15 +10,44 @@ can be done on the command line (`-DCMAKE_TOOLCHAIN_FILE=...`), in `CMakeLists.txt` (before calling `project()`) or using a [preset](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html). -It's recommended to put this snippet in `CMakeLists.txt` to automatically set -the toolchain file according to the `PSN00BSDK_LIBS` environment variable: - -```cmake -if(NOT DEFINED CMAKE_TOOLCHAIN_FILE AND DEFINED ENV{PSN00BSDK_LIBS}) - set(CMAKE_TOOLCHAIN_FILE $ENV{PSN00BSDK_LIBS}/cmake/sdk.cmake) -endif() +It's suggested to have a default preset that sets `CMAKE_TOOLCHAIN_FILE` to +`$env{PSN00BSDK_LIBS}/cmake/sdk.cmake`, so the `PSN00BSDK_LIBS` environment +variable (used by former PSn00bSDK versions) is respected. Such a preset can be +created by placing a `CMakePresets.json` file in the project's root with the +following contents: + +```json +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "displayName": "Default configuration", + "description": "Use this preset to build the project using PSn00bSDK.", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "$env{PSN00BSDK_LIBS}/cmake/sdk.cmake", + "PSN00BSDK_TC": "", + "PSN00BSDK_TARGET": "mipsel-none-elf" + } + } + ] +} ``` +To avoid having to pass variables to CMake each time the project is built, a +second presets file named `CMakeUserPresets.json` can be created and populated +with hardcoded values in the `cacheVariables` section. This file can be kept +private (e.g. by adding it to `.gitignore`); CMake will automatically load +presets from it instead of `CMakePresets.json` if it exists. + See the [template](../template/CMakeLists.txt) for an example CMake script showing how to build a simple project. @@ -130,28 +159,24 @@ build script, from the CMake command line when configuring the project - `PSN00BSDK_TARGET` (`STRING`) The GCC toolchain's target triplet. PSn00bSDK assumes the toolchain targets - `mipsel-unknown-elf` by default, however this can be changed to e.g. use a - MIPS toolchain that was compiled for a slightly-different-but-equivalent - target. + `mipsel-none-elf` by default, however this can be changed to e.g. use a MIPS + toolchain that was compiled for a slightly-different-but-equivalent target. The following GCC target triplets have been confirmed to work with PSn00bSDK: - - `mipsel-unknown-elf` - `mipsel-none-elf` + - `mipsel-unknown-elf` + - ~~`mipsel-linux-gnu`~~ (has issues with linking) - `PSN00BSDK_TC` (`PATH`) - Path to the GCC toolchain's installation prefix/directory. By default this is - initialized to the value of the `PSN00BSDK_TC` environment variable (if set). - Note that modifying the environment variable after the project has been - configured will *NOT* update this cache entry unless the project's cache is - cleared manually. - - If not set, CMake will attempt to find the toolchain in the `PATH` - environment variable and store its path in this variable (so the search does - not have to be repeated). + Path to the GCC toolchain's installation prefix/directory. If not set, CMake + will attempt to find the toolchain in the `PATH` environment variable and + store its path in the project's variable cache (so the search does not have + to be repeated). It is recommended to add the toolchain's `bin` subfolder to + `PATH` rather than setting this variable. - **IMPORTANT**: if the toolchain's target is not `mipsel-unknown-elf`, + **IMPORTANT**: if the toolchain's target is not `mipsel-none-elf`, `PSN00BSDK_TARGET` must be set regardless of whether or not `PSN00BSDK_TC` is also set. @@ -204,4 +229,4 @@ the build script. LZP archives as part of the build pipeline. ----------------------------------------- -_Last updated on 2021-09-27 by spicyjpeg_ +_Last updated on 2021-11-24 by spicyjpeg_ diff --git a/doc/dev notes.txt b/doc/dev notes.txt index 3aa2db5..65a3976 100644 --- a/doc/dev notes.txt +++ b/doc/dev notes.txt @@ -109,13 +109,14 @@ your exception handler must do the following: controller- or interrupt-related function is being called. This is necessary (although ugly) as libpsn00b often calls such functions internally. -* For some reason mipsel-unknown-elf-nm (symbol map generator) insists on -outputting 64-bit addresses (with the top 32 bits set, e.g. FFFFFFFF80010000) -even when feeding it a regular 32-bit MIPS executable, while the standard x86 -nm tool that ships with most GCC packages prints the proper 32-bit address. -Unclear whether this is a bug, intended behavior or the result of some ancient -ELF ABI flag crap. DL_ParseSymbolMap() will ignore the top 32 bits, so this -should only bother you if you're implementing your own symbol map parser. +* For some reason mipsel-unknown-elf-nm and mipsel-none-elf-nm (symbol map +generators) insist on outputting 64-bit addresses (with the top 32 bits set, +e.g. FFFFFFFF80010000) even when feeding it a regular 32-bit MIPS executable, +while the standard x86 nm tool that ships with most GCC packages prints the +proper 32-bit address. Unclear whether this is a bug, intended behavior or the +result of some ancient ELF ABI flag crap. DL_ParseSymbolMap() will ignore the +top 32 bits, so this should only bother you if you're implementing your own +symbol map parser. * I haven't worked on psxspu but, for those willing to write some code, this is the formula to calculate SPU pitch values for playing musical notes ("^" is the diff --git a/doc/installation.md b/doc/installation.md new file mode 100644 index 0000000..576eb7a --- /dev/null +++ b/doc/installation.md @@ -0,0 +1,155 @@ + +# Getting started with PSn00bSDK + +## Building and installing + +The instructions below are for Windows and Linux. Building on macOS hasn't been +tested extensively yet, however it should work once the GCC toolchain is built +and installed properly. + +1. Install prerequisites and a host compiler toolchain. On Linux (most distros) + install the following packages from your distro's package manager: + + - `git` + - `build-essential`, `base-devel` or similar + - `make` or `ninja-build` + - `cmake` (3.20+ is required, download it from + [here](https://cmake.org/download) if your package manager only provides + older versions) + + On Windows you can obtain these dependencies by installing + [MSys2](https://www.msys2.org), opening the "MSys2 MSYS" shell and running: + + ```bash + pacman -Syu git mingw-w64-x86_64-make mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc + ``` + + If you are prompted to close the shell, you may have to reopen it afterwards + and rerun the command to finish installation. + **Do not use the MSys2 shell for the next steps**, use a regular command + prompt or PowerShell instead. + + Add these directories (replace `C:\msys64` if you installed MSys2 to a + different location) to the `PATH` environment variable using System + Properties: + + - `C:\msys64\mingw64\bin` + - `C:\msys64\usr\bin` + +2. Download a precompiled copy of the GCC toolchain for `mipsel-none-elf` from + the releases page and extract it into one of the directories listed in + step 3. If you want to build the toolchain yourself, see + [toolchain.md](toolchain.md). + + **NOTE**: PSn00bSDK is also compatible with toolchains that target + `mipsel-unknown-elf`. If you already have such a toolchain, you can use it + by passing `-DPSN00BSDK_TARGET=mipsel-unknown-elf` to CMake when configuring + the SDK (see step 5). + +3. If you chose a non-standard install location for the toolchain, add the + `bin` subfolder (inside the top-level toolchain directory) to the `PATH` + environment variable. This step is unnecessary if you installed/extracted + the toolchain into any of these directories: + + - `C:\Program Files\mipsel-none-elf` + - `C:\Program Files (x86)\mipsel-none-elf` + - `C:\mipsel-none-elf` + - `/usr/local/mipsel-none-elf` + - `/usr/mipsel-none-elf` + - `/opt/mipsel-none-elf` + +4. Clone the PSn00bSDK repo, then run the following command from the PSn00bSDK + repository to download additional dependencies: + + ```bash + git submodule update --init --recursive --remote + ``` + +5. Compile the libraries, tools and examples using CMake: + + ```bash + cmake --preset default . + cmake --build ./build + ``` + + If you want to install the SDK to a custom location rather than the default + one (`C:\Program Files\PSn00bSDK` or `/usr/local` depending on your OS), add + `--install-prefix <INSTALL_PATH>` to the first command. Add + `-DPSN00BSDK_TARGET=mipsel-none-elf` if your toolchain targets + `mipsel-none-elf` rather than `mipsel-unknown-elf`. + + **NOTE**: Ninja is used by default to build the SDK. If you can't get it to + work or don't have it installed, pass `-G "Unix Makefiles"` (or + `-G "MSYS Makefiles"` on Windows) to the first command to build using `make` + instead. + +6. Install the SDK to the path you chose (add `sudo` or run it from a command + prompt with admin privileges if necessary): + + ```bash + cmake --install ./build + ``` + + This will create and populate the following directories: + + - `<INSTALL_PATH>/bin` + - `<INSTALL_PATH>/lib/libpsn00b` + - `<INSTALL_PATH>/share/psn00bsdk` + +7. Set the `PSN00BSDK_LIBS` environment variable to point to the `lib/libpsn00b` + subfolder inside the install directory. You might also want to add the `bin` + folder to `PATH` if it's not listed already. + +Although not strictly required, you'll probably want to install a PS1 emulator +with debugging capabilities such as [no$psx](https://problemkaputt.de/psx.htm) +(Windows only), [DuckStation](https://github.com/stenzek/duckstation) or +[pcsx-redux](https://github.com/grumpycoders/pcsx-redux). +**Avoid ePSXe and anything based on MAME** as they are inaccurate. + +## Building installer packages + +CPack can be used to build NSIS-based installers, DEB/RPM packages and zipped +releases that include built SDK libraries, headers as well as the GCC toolchain. +Distributing prebuilt releases is however discouraged since PSn00bSDK is still +far from being feature-complete. + +1. Follow steps 1-4 above to set up the toolchain, then install + [NSIS](https://nsis.sourceforge.io/Download) on Windows or `dpkg` and `rpm` + on Linux. + +2. Run the following commands from the PSn00bSDK directory (pass the + appropriate options to the first command if necessary): + + ```bash + cmake --preset package . + cmake --build ./build -t package + ``` + + All built packages will be copied to the `build/packages` folder. + +## Creating a project + +1. Copy the contents of `<INSTALL_PATH>/share/psn00bsdk/template` (or the + `template` folder within the repo) to your new project's root directory. + +2. Configure and build the template by running: + + ```bash + cmake -S . -B ./build + cmake --build ./build + ``` + + If you did everything correctly there should be a `template.bin` CD image in + the `build` folder. Test it in an emulator to ensure it works. + +Note that, even though the template relies on the `PSN00BSDK_LIBS` environment +variable to locate the SDK by default, you can also specify the path directly +on the CMake command line by adding +`-DCMAKE_TOOLCHAIN_FILE=<INSTALL_PATH>/lib/libpsn00b/cmake/sdk.cmake` to the +CMake command line. + +The toolchain script defines a few CMake macros to create PS1 executables, DLLs +and CD images. See the [reference](doc/cmake_reference.md) for details. + +----------------------------------------- +_Last updated on 2021-11-19 by spicyjpeg_ diff --git a/doc/toolchain.md b/doc/toolchain.md new file mode 100644 index 0000000..8e28c24 --- /dev/null +++ b/doc/toolchain.md @@ -0,0 +1,224 @@ + +# Building the GCC toolchain + +If you wish to build the toolchain yourself, beware that this process can get +pretty tedious if your machine is not fairly recent. Ensure you have at least a +quad-core processor and 4 GB of free space before continuing. + +You'll need a Linux environment, even if you want to build a Windows toolchain +(as GCC is basically impossible to build under Windows but can be cross-compiled +via MinGW). Due to how the GCC build process works, you'll have to build a Linux +version of the toolchain first to be able to compile it for Windows. This +basically means you will have to build the whole toolchain twice if you want to +target Windows. + +These instructions are for Debian/Ubuntu, however it should be relatively easy +to follow them if you are using another distro. If you do not have access to a +Linux system already, consider spinning up a VM (a headless Debian or Ubuntu +Server install is recommended) or using WSL, whose setup is out of the scope of +this guide. + +## Choosing a GCC version + +PSn00bSDK *should* work with any GCC version. In most cases you'll want to get +the latest stable release of GCC and binutils. If for some reason you are having +problems you may try building one of the following versions, which have been +tested extensively: + +- ~~GCC 7.4.0 with binutils 2.31~~ (the linker fails to build PS1 DLLs) +- GCC **11.1.0** with binutils **2.36** +- GCC **11.2.0** with binutils **2.37** + +If you wish to pick an older GCC release but don't know which binutils version +it requires, see [here](https://wiki.osdev.org/Cross-Compiler_Successful_Builds) +for a compatibility table. + +## Downloading GCC + +1. Run the following commands to install a host toolchain and prerequisites + (adapt them for non-Debian distros if necessary): + + ```bash + sudo apt update + sudo apt install -y build-essential make wget + ``` + +2. Create an empty directory to store build artifacts in. You'll be able to + delete it once the toolchain is installed. + +3. Download the GCC and binutils source packages from + [here](https://ftpmirror.gnu.org/gnu) and unzip them into the folder you + created, or run the following commands to do the same (replace `<VERSION>` + with the versions you chose): + + ```bash + wget https://ftpmirror.gnu.org/gnu/binutils/binutils-<VERSION>.tar.xz + wget https://ftpmirror.gnu.org/gnu/gcc/gcc-<VERSION>/gcc-<VERSION>.tar.xz + tar xvf binutils-<VERSION>.tar.xz + tar xvf gcc-<VERSION>.tar.xz + rm -f *.tar.xz + ``` + +4. From the extracted GCC directory run the `download_prerequisites` script to + download additional dependencies: + + ```bash + cd gcc-<VERSION> + ./contrib/download_prerequisites + ``` + +## Building binutils + +1. Go back to the folder you made earlier and create a new subdirectory to build + binutils in (don't create it inside the extracted binutils source directory). + Call it `binutils-build` or whatever. + +2. Run the binutils configuration script from that folder: + + ```bash + ../binutils-<VERSION>/configure \ + --prefix=/usr/local/mipsel-none-elf --target=mipsel-none-elf \ + --disable-docs --disable-nls --with-float=soft + ``` + + Replace `<VERSION>` as usual. If you don't want to install the toolchain into + `/usr/local/mipsel-none-elf` you can change the `--prefix` option. + +3. Compile and install binutils (this will take a few minutes to finish): + + ```bash + make -j 4 + sudo make install-strip + ``` + + Increase `-j 4` to speed up the build if your machine or VM has more than 4 + CPU cores. + + **NOTE**: if the build fails with a "`uint` undeclared" or similar error, try + editing the source file that caused the error and pasting this line at the + beginning: + + ```c + typedef unsigned int uint; + ``` + + Rerun `make` to resume the build after saving the file. + +## Building GCC + +The process is mostly the same as binutils, just with different configuration +options. + +1. Go back to the main directory and create an empty `gcc-build` (or whatever) + subfolder. + +2. Run the GCC configuration script from there: + + ```bash + ../gcc-<VERSION>/configure \ + --prefix=/usr/local/mipsel-none-elf --target=mipsel-none-elf \ + --disable-docs --disable-nls --disable-libada --disable-libssp \ + --disable-libquadmath --disable-libstdc++-v3 --with-float=soft \ + --enable-languages=c,c++ --with-gnu-as --with-gnu-ld + ``` + + If you previously set a custom installation path, remember to set it here as + well (it must be the same). + +3. Compile and install GCC (will take a long time, usually around half an hour): + + ```bash + make -j 4 + sudo make install-strip + ``` + + Increase `-j 4` to speed up the build if your machine or VM has more than 4 + threads. + +4. Add the toolchain to the `PATH` environment variable. This is required to + rebuild the toolchain for Windows (see below), but it will also allow + PSn00bSDK to find the toolchain if you installed it in a custom location. + + Edit the `.bashrc` or `.bash_profile` file in your home directory and add + this line at the end (replace the path with the install location you chose + earlier, but keep the `/bin` at the end): + + ```bash + export PATH=$PATH:/usr/local/mipsel-none-elf/bin + ``` + + Restart the shell by closing and reopening the terminal window or SSH + connection afterwards. + +## Rebuilding for Windows + +At this point you should be able to build and install PSn00bSDK on your Linux +system. The instructions below are for building a second copy of the toolchain +that runs on Windows. + +1. Install the MinGW host toolchain: + + ```bash + sudo apt install -y g++-mingw-w64-x86-64 + ``` + +2. Create two new `binutils-win` and `gcc-win` folders in the directory you + extracted/built everything in. + +3. From the `binutils-win` directory, rerun the binutils configuration script + with the following options (do not change the installation path): + + ```bash + ../binutils-<VERSION>/configure \ + --build=x86_64-linux-gnu --host=x86_64-w64-mingw32 \ + --prefix=/tmp/mipsel-none-elf --target=mipsel-none-elf \ + --disable-docs --disable-nls --with-float=soft + ``` + + Then build binutils again: + + ```bash + make -j 4 + make install-strip + ``` + +4. Do the same for GCC from the `gcc-win` directory: + + ```bash + ../gcc-<VERSION>/configure \ + --build=x86_64-linux-gnu --host=x86_64-w64-mingw32 \ + --prefix=/tmp/mipsel-none-elf --target=mipsel-none-elf \ + --disable-docs --disable-nls --disable-libada --disable-libssp \ + --disable-libquadmath --disable-libstdc++-v3 --with-float=soft \ + --enable-languages=c,c++ --with-gnu-as --with-gnu-ld + ``` + + And build it as usual: + + ```bash + make -j 4 + make install-strip + ``` + +5. Copy the entire `/tmp/mipsel-none-elf` directory over to your Windows + machine using VM shared folders, a network share, `scp` or whichever method + you prefer. It's recommended to put the toolchain in + `C:\Program Files\mipsel-none-elf` or `C:\mipsel-none-elf`. + +6. If you want to keep the toolchain in another location and/or use it from the + command line, add the `bin` subdirectory inside `mipsel-none-elf` to the + `PATH` environment variable (as you did on Linux) using System Properties. + +## Note regarding C++ support + +C++ support in PSn00bSDK, besides compile-time features like `constexpr`, only +goes as far as basic classes, namespaces and the ability to dynamically create +and delete class objects at any point of the program. The required dependencies +(which are just wrappers around `malloc()` and `free()`) are supplied by `libc`. + +Standard C++ libraries are not implemented and likely never going to be +implemented due to bloat concerns that it may introduce. Besides, the official +SDK lacks full C++ support as well. + +----------------------------------------- +_Last updated on 2021-11-23 by spicyjpeg_ |
