From f9a48e26ef27fbbcef6737a5480a8269d688717d Mon Sep 17 00:00:00 2001 From: Hans Dijkema Date: Tue, 11 Aug 2026 13:25:41 +0200 Subject: [PATCH] Manual in README.md in the main branch --- README.md | 436 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 435 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b49fd1..b51c23e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,437 @@ # racket-audio-native-libs -Packages with native libraries to be used with racket-audio. \ No newline at end of file +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 + #native-libs + +racket-audio-x86_64-win32 + #x86_64-win32 + +racket-audio-x86_64-linux + #x86_64-linux + +racket-audio-aarch64-linux + #aarch64-linux + +racket-audio-aarch64-macosx + #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.