librespot/COMPILING.md

147 lines
6.5 KiB
Markdown
Raw Normal View History

# Compiling
## Setup
In order to compile librespot, you will first need to set up a suitable Rust build environment, with the necessary dependencies installed. You will need to have a C compiler, Rust, and the development libraries for the audio backend(s) you want installed. These instructions will walk you through setting up a simple build environment.
### Install Rust
2021-07-09 19:02:48 +00:00
The easiest, and recommended way to get Rust is to use [rustup](https://rustup.rs). Once thats installed, Rust's standard tools should be set up and ready to use.
#### Additional Rust tools - `rustfmt`
2021-07-09 19:02:48 +00:00
To ensure a consistent codebase, we utilise [`rustfmt`](https://github.com/rust-lang/rustfmt) and [`clippy`](https://github.com/rust-lang/rust-clippy), which are installed by default with `rustup` these days, else they can be installed manually with:
```bash
rustup component add rustfmt
2021-07-09 19:02:48 +00:00
rustup component add clippy
```
Using `cargo fmt` and `cargo clippy` is not optional, as our CI checks against this repo's rules.
### General dependencies
2022-07-28 17:06:38 +00:00
Along with Rust, you will also require a C compiler.
On Debian/Ubuntu, install with:
```shell
sudo apt-get install build-essential
```
On Fedora systems, install with:
```shell
2022-07-28 17:06:38 +00:00
sudo dnf install gcc
```
### Audio library dependencies
2022-07-28 17:06:38 +00:00
Depending on the chosen backend, specific development libraries are required.
2019-11-12 12:51:34 +00:00
*_Note this is an non-exhaustive list, open a PR to add to it!_*
| Audio backend | Debian/Ubuntu | Fedora | macOS |
|--------------------|------------------------------|-----------------------------------|-------------|
|Rodio (default) | `libasound2-dev` | `alsa-lib-devel` | |
|ALSA | `libasound2-dev, pkg-config` | `alsa-lib-devel` | |
2021-07-09 19:02:48 +00:00
|GStreamer | `gstreamer1.0-plugins-base libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-good libgstreamer-plugins-good1.0-dev` | `gstreamer1 gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugins-good` | `gstreamer gst-devtools gst-plugins-base gst-plugins-good` |
|PortAudio | `portaudio19-dev` | `portaudio-devel` | `portaudio` |
|PulseAudio | `libpulse-dev` | `pulseaudio-libs-devel` | |
2021-07-09 19:02:48 +00:00
|JACK | `libjack-dev` | `jack-audio-connection-kit-devel` | `jack` |
|JACK over Rodio | `libjack-dev` | `jack-audio-connection-kit-devel` | `jack` |
|SDL | `libsdl2-dev` | `SDL2-devel` | `sdl2` |
|Pipe & subprocess | - | - | - |
2019-11-12 12:51:34 +00:00
###### For example, to build an ALSA based backend, you would need to run the following to install the required dependencies:
On Debian/Ubuntu:
```shell
sudo apt-get install libasound2-dev pkg-config
```
On Fedora systems:
```shell
sudo dnf install alsa-lib-devel
```
Discovery: Refactor and add Avahi DBus backend (#1347) * discovery: use opaque error type for DnsSdError This helps to decouple discovery and core by not leaking implementation details of the zeroconf backend into Error conversion impls in core. * discovery: map all MDNS/DNS-SD errors to DiscoveryError::DnsSdError previously, libmdns errors would use a generic conversion from std::io::Error to core::Error * discovery: use an opaque type for the handle to the DNS-SD service * discovery: make features additive i.e. add with-libmdns instead of using not(with-dns-sd). The logic is such that enabling with-dns-sd in addition to the default with-libmdns will still end up using dns-sd, as before. If only with-libmdns is enabled, that will be the default. If none of the features is enabled, attempting to build a `Discovery` will yield an error. * discovery: add --zeroconf-backend CLI flag * discovery: Add minimal Avahi zeroconf backend * bump MSRV to 1.75 required by zbus >= 4 * discovery: ensure that server and dns-sd backend shutdown gracefully Previously, on drop the the shutdown_tx/close_tx, it wasn't guaranteed the corresponding tasks would continue to be polled until they actually completed their shutdown. Since dns_sd::Service is not Send and non-async, and because libmdns is non-async, put them on their own threads. * discovery: use a shared channel for server and zeroconf status messages * discovery: add Avahi reconnection logic This deals gracefully with the case where the Avahi daemon is restarted or not running initially. * discovery: allow running when compiled without zeroconf backend... ...but exit with an error if there's no way to authenticate * better error messages for invalid options with no short flag
2024-10-26 14:45:02 +00:00
### Zeroconf library dependencies
Depending on the chosen backend, specific development libraries are required.
*_Note this is an non-exhaustive list, open a PR to add to it!_*
| Zeroconf backend | Debian/Ubuntu | Fedora | macOS |
|--------------------|------------------------------|-----------------------------------|-------------|
|avahi | | | |
|dns_sd | `libavahi-compat-libdnssd-dev pkg-config` | `avahi-compat-libdns_sd-devel` | |
|libmdns (default) | | | |
### Getting the Source
The recommended method is to first fork the repo, so that you have a copy that you have read/write access to. After that, its a simple case of cloning your fork.
```bash
git clone git@github.com:YOUR_USERNAME/librespot.git
```
## Compiling & Running
Once your build environment is setup, compiling the code is pretty simple.
### Compiling
2019-11-12 12:51:34 +00:00
To build a ```debug``` build with the default backend, from the project root run:
```bash
cargo build
```
And for ```release```:
```bash
cargo build --release
```
2019-11-12 12:51:34 +00:00
You will most likely want to build debug builds when developing, as they compile faster, and more verbose, and as the name suggests, are for the purposes of debugging. When submitting a bug report, it is recommended to use a debug build to capture stack traces.
There are also a number of compiler feature flags that you can add, in the event that you want to have certain additional features also compiled. The list of these is available on the [wiki](https://github.com/librespot-org/librespot/wiki/Compiling#addition-features).
By default, librespot compiles with the ```rodio-backend``` and ```with-libmdns``` features. To compile without default features, you can run with:
```bash
cargo build --no-default-features
```
Note that this will also disable zeroconf discovery backends for Spotify Connect. For normal use cases, select at least one audio and discovery backend.
For example, to build with the ALSA audio and libmdns discovery backend:
2019-11-12 12:51:34 +00:00
```bash
cargo build --no-default-features --features "alsa-backend with-libmdns"
2019-11-12 12:51:34 +00:00
```
#### Cross Compiling for Raspberry Pi
To cross compile for Raspberry pi, get the arm-unknown-gnueabihf target for Rust:
```bash
rustup target add armv7-unknown-linux-gnueabi
```
You need to manually add a linker, which can be installed with apt:
```bash
sudo apt install gcc-arm-linux-gnueabihf
```
The target must be specified to cargo along with the linker.
This can be done via `.cargo/config.toml`, or via command line:
```bash
RUSTFLAGS="-C linker=arm-linux-gnueabihf-gcc" cargo build --no-default-features --target armv7-unknown-linux-gnueabihf
```
Note that this does not work with armv6 (found e.g. in Raspberry Pi 1 and Zero). Previously, you could use the linker in https://github.com/raspberrypi/tools, but this is now too old and will give an error when compiling Librespot (since `3e85d77bfb3520e16c35bb7db3912c76e8cc90d7`). More info: https://github.com/japaric/rust-cross/issues/42
### Running
Assuming you just compiled a ```debug``` build, you can run librespot with the following command:
```bash
2021-07-09 19:02:48 +00:00
./target/debug/librespot
```
There are various runtime options, documented in the wiki, and visible by running librespot with the ```-h``` argument.
2021-07-09 19:02:48 +00:00
Note that debug builds may cause buffer underruns and choppy audio when dithering is enabled (which it is by default). You can disable dithering with ```--dither none```.