Manual in README.md in the main branch
This commit is contained in:
@@ -1,3 +1,437 @@
|
||||
# racket-audio-native-libs
|
||||
|
||||
Packages with native libraries to be used with racket-audio.
|
||||
Native library distribution repository for `racket-audio`.
|
||||
|
||||
This repository contains the platform-specific native libraries used by
|
||||
`racket-audio`. It uses one Git branch per published Racket package.
|
||||
|
||||
The `main` branch contains the build and maintenance files. The other branches
|
||||
contain the actual Racket packages that are registered in the Racket Package
|
||||
Index.
|
||||
|
||||
## Branch structure
|
||||
|
||||
The repository uses the following branches:
|
||||
|
||||
```text
|
||||
main
|
||||
native-libs
|
||||
x86_64-win32
|
||||
x86_64-linux
|
||||
aarch64-linux
|
||||
aarch64-macosx
|
||||
```
|
||||
|
||||
Their purpose is:
|
||||
|
||||
```text
|
||||
main
|
||||
Build scripts, documentation and maintenance files.
|
||||
|
||||
native-libs
|
||||
Meta-package: racket-audio-native-libs.
|
||||
Selects the correct platform package.
|
||||
|
||||
x86_64-win32
|
||||
Native libraries for 64-bit Windows.
|
||||
|
||||
x86_64-linux
|
||||
Native libraries for 64-bit Intel/AMD Linux.
|
||||
|
||||
aarch64-linux
|
||||
Native libraries for 64-bit ARM Linux, for example a 64-bit Raspberry Pi.
|
||||
|
||||
aarch64-macosx
|
||||
Native libraries for Apple Silicon macOS, for example an M1 Mac.
|
||||
```
|
||||
|
||||
Each platform branch is a separate Racket package.
|
||||
|
||||
## Package names
|
||||
|
||||
The intended Racket package names are:
|
||||
|
||||
```text
|
||||
racket-audio-native-libs
|
||||
racket-audio-x86_64-win32
|
||||
racket-audio-x86_64-linux
|
||||
racket-audio-aarch64-linux
|
||||
racket-audio-aarch64-macosx
|
||||
```
|
||||
|
||||
`racket-audio` itself should depend on:
|
||||
|
||||
```text
|
||||
racket-audio-native-libs
|
||||
```
|
||||
|
||||
The `racket-audio-native-libs` package then selects the correct platform
|
||||
package.
|
||||
|
||||
This keeps the Racket code in `racket-audio` independent of the operating
|
||||
system and architecture.
|
||||
|
||||
## Native package layout
|
||||
|
||||
A platform branch contains the native libraries directly in the root of the
|
||||
branch, together with `info.rkt`.
|
||||
|
||||
For example, the `x86_64-win32` branch may look like:
|
||||
|
||||
```text
|
||||
info.rkt
|
||||
portaudio.dll
|
||||
libsndfile-1.dll
|
||||
libmpg123-0.dll
|
||||
...
|
||||
```
|
||||
|
||||
The exact DLL names depend on the libraries used by `racket-audio`.
|
||||
|
||||
The corresponding `info.rkt` uses `copy-foreign-libs`:
|
||||
|
||||
```racket
|
||||
#lang info
|
||||
|
||||
(define collection 'multi)
|
||||
|
||||
(define version "0.1.0")
|
||||
|
||||
(define pkg-desc
|
||||
"native libraries for \"racket-audio\" on \"x86_64-win32\"")
|
||||
|
||||
(define pkg-authors
|
||||
'(hans))
|
||||
|
||||
(define install-platform
|
||||
"win32\\x86_64")
|
||||
|
||||
(define copy-foreign-libs
|
||||
'("portaudio.dll"
|
||||
"libsndfile-1.dll"))
|
||||
|
||||
(define deps
|
||||
'("base"))
|
||||
```
|
||||
|
||||
Every native library that must be installed with the package must be listed in
|
||||
`copy-foreign-libs`.
|
||||
|
||||
This also includes DLLs, shared objects or dylibs that are runtime dependencies
|
||||
of the primary audio libraries.
|
||||
|
||||
During package setup, Racket copies these files to a location that can be found
|
||||
by `ffi-lib`.
|
||||
|
||||
## Meta-package
|
||||
|
||||
The `native-libs` branch contains the package:
|
||||
|
||||
```text
|
||||
racket-audio-native-libs
|
||||
```
|
||||
|
||||
It contains no native libraries itself.
|
||||
|
||||
Its `info.rkt` selects the correct package based on the current Racket
|
||||
platform.
|
||||
|
||||
Conceptually:
|
||||
|
||||
```text
|
||||
racket-audio
|
||||
|
|
||||
+-- racket-audio-native-libs
|
||||
|
|
||||
+-- racket-audio-x86_64-win32
|
||||
+-- racket-audio-x86_64-linux
|
||||
+-- racket-audio-aarch64-linux
|
||||
+-- racket-audio-aarch64-macosx
|
||||
```
|
||||
|
||||
Only the package matching the current platform is installed.
|
||||
|
||||
## Use from racket-audio
|
||||
|
||||
The `racket-audio` package should declare `racket-audio-native-libs` as a
|
||||
dependency in its `info.rkt`.
|
||||
|
||||
For example:
|
||||
|
||||
```racket
|
||||
(define deps
|
||||
'("base"
|
||||
"racket-audio-native-libs"))
|
||||
```
|
||||
|
||||
The FFI code should preferably load libraries by their logical name instead of
|
||||
using machine-specific absolute paths.
|
||||
|
||||
For example:
|
||||
|
||||
```racket
|
||||
(ffi-lib "portaudio")
|
||||
```
|
||||
|
||||
rather than:
|
||||
|
||||
```racket
|
||||
(ffi-lib "C:\\some\\local\\directory\\portaudio.dll")
|
||||
```
|
||||
|
||||
The native package is responsible for installing the actual library for the
|
||||
current platform.
|
||||
|
||||
## Development workflow
|
||||
|
||||
Development and package preparation take place on `main`.
|
||||
|
||||
The platform branches should contain only the files required for the published
|
||||
Racket package.
|
||||
|
||||
A typical Windows workflow is:
|
||||
|
||||
```text
|
||||
main
|
||||
|
|
||||
| prepare/test Windows DLL package
|
||||
v
|
||||
x86_64-win32
|
||||
|
|
||||
| commit + push
|
||||
v
|
||||
Racket Package Index
|
||||
```
|
||||
|
||||
The same approach can later be used for Linux, Raspberry Pi and macOS.
|
||||
|
||||
## Adding or updating a Windows package
|
||||
|
||||
Start on `main`:
|
||||
|
||||
```bash
|
||||
git switch main
|
||||
git pull
|
||||
```
|
||||
|
||||
Prepare or collect the required 64-bit Windows DLL files.
|
||||
|
||||
Before publishing, verify that all runtime dependencies are included.
|
||||
|
||||
Then switch to the platform branch:
|
||||
|
||||
```bash
|
||||
git switch x86_64-win32
|
||||
```
|
||||
|
||||
Update:
|
||||
|
||||
```text
|
||||
info.rkt
|
||||
*.dll
|
||||
```
|
||||
|
||||
Make sure `copy-foreign-libs` contains every DLL that belongs to the package.
|
||||
|
||||
Commit and push:
|
||||
|
||||
```bash
|
||||
git add info.rkt *.dll
|
||||
git commit -m "Update Windows native libraries"
|
||||
git push
|
||||
```
|
||||
|
||||
## Adding or updating Linux x86_64
|
||||
|
||||
Use:
|
||||
|
||||
```bash
|
||||
git switch x86_64-linux
|
||||
```
|
||||
|
||||
The branch will normally contain:
|
||||
|
||||
```text
|
||||
info.rkt
|
||||
*.so
|
||||
*.so.*
|
||||
```
|
||||
|
||||
Include all shared libraries required at runtime.
|
||||
|
||||
After testing:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Update Linux x86_64 native libraries"
|
||||
git push
|
||||
```
|
||||
|
||||
## Adding or updating Raspberry Pi / Linux ARM64
|
||||
|
||||
For a Raspberry Pi running a 64-bit operating system and 64-bit Racket, use:
|
||||
|
||||
```bash
|
||||
git switch aarch64-linux
|
||||
```
|
||||
|
||||
This package is intended for:
|
||||
|
||||
```text
|
||||
aarch64-linux
|
||||
```
|
||||
|
||||
Build the libraries natively on the Raspberry Pi where practical.
|
||||
|
||||
After testing:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Update Linux ARM64 native libraries"
|
||||
git push
|
||||
```
|
||||
|
||||
## Adding or updating Apple Silicon macOS
|
||||
|
||||
For an Apple Silicon Mac, such as an M1 Mac, use:
|
||||
|
||||
```bash
|
||||
git switch aarch64-macosx
|
||||
```
|
||||
|
||||
The branch normally contains:
|
||||
|
||||
```text
|
||||
info.rkt
|
||||
*.dylib
|
||||
```
|
||||
|
||||
Build and test the libraries on the Apple Silicon target machine.
|
||||
|
||||
After testing:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Update Apple Silicon native libraries"
|
||||
git push
|
||||
```
|
||||
|
||||
## Testing a platform package locally
|
||||
|
||||
Before registering or updating a package in the Racket Package Index, install
|
||||
the platform branch locally and verify that `racket-audio` can load and use the
|
||||
libraries.
|
||||
|
||||
For example, from a checkout of the platform branch:
|
||||
|
||||
```bash
|
||||
raco pkg install --auto .
|
||||
```
|
||||
|
||||
After changing an already installed package, use the normal Racket package
|
||||
update/reinstall workflow as appropriate.
|
||||
|
||||
The important test is that the existing FFI code can load the libraries without
|
||||
using local absolute paths.
|
||||
|
||||
## Racket Package Index
|
||||
|
||||
Each published branch is registered as a separate Racket package.
|
||||
|
||||
The source URL can point directly to the corresponding Git branch.
|
||||
|
||||
Conceptually:
|
||||
|
||||
```text
|
||||
racket-audio-native-libs
|
||||
<repository-url>#native-libs
|
||||
|
||||
racket-audio-x86_64-win32
|
||||
<repository-url>#x86_64-win32
|
||||
|
||||
racket-audio-x86_64-linux
|
||||
<repository-url>#x86_64-linux
|
||||
|
||||
racket-audio-aarch64-linux
|
||||
<repository-url>#aarch64-linux
|
||||
|
||||
racket-audio-aarch64-macosx
|
||||
<repository-url>#aarch64-macosx
|
||||
```
|
||||
|
||||
The Racket Package Index therefore does not need a separate manually uploaded
|
||||
ZIP file. The Git branch itself is the package source.
|
||||
|
||||
## Initial branch publication
|
||||
|
||||
If the branches exist locally but not yet on `origin`, publish them with:
|
||||
|
||||
```bash
|
||||
git push -u origin native-libs
|
||||
git push -u origin x86_64-win32
|
||||
git push -u origin x86_64-linux
|
||||
git push -u origin aarch64-linux
|
||||
git push -u origin aarch64-macosx
|
||||
```
|
||||
|
||||
After that, a normal:
|
||||
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
is sufficient when working on a branch that has its upstream configured.
|
||||
|
||||
## Build automation
|
||||
|
||||
The first goal is to make the packaging work reliably using already available
|
||||
native libraries.
|
||||
|
||||
After that, `main` can grow into a build orchestrator using Racket itself.
|
||||
|
||||
The intended direction is:
|
||||
|
||||
```text
|
||||
Windows machine
|
||||
-> build x86_64-win32
|
||||
|
||||
Linux x86_64 machine
|
||||
-> build x86_64-linux
|
||||
|
||||
Raspberry Pi 64-bit
|
||||
-> build aarch64-linux
|
||||
|
||||
Apple Silicon Mac
|
||||
-> build aarch64-macosx
|
||||
```
|
||||
|
||||
The build orchestration can use `racket-makefile`, the Racket `git` module and,
|
||||
for remote targets, SSH or another small remote-execution layer.
|
||||
|
||||
The native libraries should preferably be built on the target architecture
|
||||
instead of cross-compiled, unless there is a good reason to do otherwise.
|
||||
|
||||
## Versioning
|
||||
|
||||
The version in each platform package should correspond to the native library
|
||||
set delivered by that branch.
|
||||
|
||||
When changing the packaged native libraries, update the package version where
|
||||
appropriate and keep the meta-package dependency versions compatible.
|
||||
|
||||
## Licenses
|
||||
|
||||
Native libraries may have licenses that differ from the license of the Racket
|
||||
wrapper.
|
||||
|
||||
Before publishing a new library or version, verify:
|
||||
|
||||
```text
|
||||
- the upstream license;
|
||||
- whether binary redistribution is permitted;
|
||||
- whether license or copyright files must be included;
|
||||
- whether additional runtime libraries have separate license requirements.
|
||||
```
|
||||
|
||||
Do not assume that the license of `racket-audio` automatically covers the
|
||||
native binaries.
|
||||
|
||||
Reference in New Issue
Block a user