diff --git a/platforms/FreeBSD/Readme.md b/platforms/FreeBSD/Readme.md new file mode 100644 index 00000000..bb3f4b8e --- /dev/null +++ b/platforms/FreeBSD/Readme.md @@ -0,0 +1,45 @@ +# FreeBSD Swift Package Builder Script + +## Description + +This shell script automates the creation of FreeBSD packages (.pkg files) for Swift programming language toolchains. It takes a compiled Swift toolchain directory as input and produces a properly structured FreeBSD package that can be installed using the `pkg` package manager. + +## Summary + +The script is specifically designed for FreeBSD systems and requires a properly structured Swift toolchain with a `usr/` subdirectory containing the Swift binaries and libraries. + +The script performs the following key operations: + +- Validation: Ensures the current platform is FreeBSD and validates command-line arguments +- Directory Setup: Creates temporary staging areas for package files and metadata +- Toolchain Processing: Copies the Swift toolchain to the appropriate directory structure (`/usr/local/swift`) +- Symlink Creation: Creates symbolic links in `/usr/local/bin` for `swift` and `swiftc` commands +- Package Manifest Generation: Creates a FreeBSD package manifest with metadata including version, description, and maintainer information +- File List Generation: Builds a complete list of files and symlinks to include in the package +- Package Creation: Uses FreeBSD's `pkg create` command to build the final package with Zstandard compression +- Cleanup: Removes temporary staging directories + +The resulting package installs Swift to `/usr/local/swift` with convenient symlinks in `/usr/local/bin`, making Swift commands available in the standard path. + +## Usage Examples + +### Basic Usage + +``` +# Package a Swift 6.2 toolchain +./makePackage /home/user/swift-6.2-RELEASE-freebsd /usr/local/packages/swift-6.2.pkg +``` + +### Complete Workflow Example + +``` +# 1. Create the package +./makePackage ./swift-6.2-RELEASE-freebsd ./swift-6.2.pkg + +# 2. Install the package (as root) +pkg install ./swift-6.2.pkg + +# 3. Verify installation +swift --version +swiftc --help +``` diff --git a/platforms/FreeBSD/makePackage b/platforms/FreeBSD/makePackage new file mode 100755 index 00000000..f4203eac --- /dev/null +++ b/platforms/FreeBSD/makePackage @@ -0,0 +1,115 @@ +#!/bin/sh -e +# +# Builds a FreeBSD package out of a toolchain. +# Usage: makePackage /path/to/toolchain /path/to/final/package + +# Validate the command line arguments. +if [ "$#" -ne 2 ]; then + echo "Usage: $0 /path/to/toolchain /path/to/final/package" >/dev/stderr + exit 1 +fi + +# Create some variables for ease of use. +PLATFORM="$(uname)" +CURRENT_DIRECTORY="$(pwd)" +TOOLCHAIN_PATH="$1" +PACKAGE_PATH="$2" +PACKAGE_STAGING="$(mktemp -d)" +METADATA_STAGING="$(mktemp -d)" +SWIFT_TOOLCHAIN_HOME="$PACKAGE_STAGING/usr/local/swift" + +# Check the platform and exit if we aren't running on FreeBSD. +if [ ! "$PLATFORM" = "FreeBSD" ]; then + echo "Platform $PLATFORM is not supported" >/dev/stderr + exit 1 +fi + +# Create necessary directories on disk. +mkdir -p "$METADATA_STAGING" +mkdir -p "$PACKAGE_STAGING/usr/local/bin" +echo "Staging Swift package files in $PACKAGE_STAGING..." + +# Check the path that we were provided. We want to ensure that the +# path that we were given is the root of the produced toolchain. +# In other words, directly below the directory that we were passed +# should be another directory named `usr`. +if [ ! -d "$TOOLCHAIN_PATH/usr" ]; then + echo "error: Directory provided was not the root directory of a toolchain" >/dev/stderr + exit 1 +fi + +# Stage the package files, dropping the initial usr/ directory +# that is at the root of the provided toolchain from the path +# but keeping everything after it. +# So, the directory structure relative to the root of the staging +# area will be +# - ./usr/local/swift/bin +# - ./usr/local/swift/lib +# and so on. +mkdir -p "$SWIFT_TOOLCHAIN_HOME" +cp -R "$TOOLCHAIN_PATH/usr/" "$SWIFT_TOOLCHAIN_HOME" +echo "Copied toolchain into $SWIFT_TOOLCHAIN_HOME." + +# Because the Swift toolchain will be installed to /usr/local/swift, +# we need to create symlinks to the actual Swift binaries. This is +# because users expect the installed binaries to be in the path at +# /usr/local/bin. +echo "Creating symlinks to Swift tools..." +echo "Entering $PACKAGE_STAGING/usr/local/bin" +cd "$PACKAGE_STAGING/usr/local/bin" +ln -s "../swift/bin/swift" "swift" +ln -s "../swift/bin/swiftc" "swiftc" +echo "Returning to $CURRENT_DIRECTORY" + +# Once the symlink structure has been created, then we must generate +# the list of files to store in the package. To do so, we iterate over +# the staging area, and generate the list of files. These paths need +# to be relative to ./usr/local since that is the prefix that we indicate +# below in the manifest file. +# +# When the package is created using `pkg create`, pkg will handle the +# process of generating the file hashes, etc. for everything here. +echo "Generate package list..." +cd "$PACKAGE_STAGING/usr/local" +find "." -type l > "$METADATA_STAGING/pkg-plist" +find "." -type f >> "$METADATA_STAGING/pkg-plist" +cd "$CURRENT_DIRECTORY" + +SWIFT_VERSION="$("$SWIFT_TOOLCHAIN_HOME/bin/swift" --version | grep -Eo 'version [0-9.]+' | sed 's/version //')" +echo "Swift version being packaged is $SWIFT_VERSION" + +# Create the manifest file. All fields below are required. pkg_create(3) +# will add additional fields as part of generating the package. +echo "Generating manifest..." +cat > "$METADATA_STAGING/manifest" <