Skip to content

Commit 2d7c55c

Browse files
Add installation packaging script for FreeBSD
Swift should be distributed to FreeBSD users as a .pkg file which can be installed using pkg, the system package manager. This allows for a better user experience because it handles installing all of the required dependencies as well as placing the compiler in the user's PATH. To create a FreeBSD package, we should have a script that automates the process of creating one. This commit adds such a script. It is designed to be invoked by the CI system, but can also be invoked by an end user.
1 parent 49821e7 commit 2d7c55c

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

platforms/FreeBSD/makePackage

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/bin/sh -e
2+
#
3+
# Builds a FreeBSD package out of a toolchain.
4+
# Usage: makePackage /path/to/toolchain /path/to/final/package
5+
6+
# Validate the command line arguments.
7+
if [ "$#" -ne 2 ]; then
8+
echo "Usage: $0 /path/to/toolchain /path/to/final/package" >/dev/stderr
9+
exit 1
10+
fi
11+
12+
# Create some variables for ease of use.
13+
PLATFORM="$(uname)"
14+
CURRENT_DIRECTORY="$(pwd)"
15+
TOOLCHAIN_PATH="$1"
16+
PACKAGE_PATH="$2"
17+
PACKAGE_STAGING="$(mktemp -d)"
18+
METADATA_STAGING="$(mktemp -d)"
19+
SWIFT_TOOLCHAIN_HOME="$PACKAGE_STAGING/usr/local/swift"
20+
21+
# Check the platform and exit if we aren't running on FreeBSD.
22+
if [ ! "$PLATFORM" = "FreeBSD" ]; then
23+
echo "Platform $PLATFORM is not supported" >/dev/stderr
24+
exit 1
25+
fi
26+
27+
# Create necessary directories on disk.
28+
mkdir -p "$METADATA_STAGING"
29+
mkdir -p "$PACKAGE_STAGING/usr/local/bin"
30+
echo "Staging Swift package files in $PACKAGE_STAGING..."
31+
32+
# Check the path that we were provided. We want to ensure that the
33+
# path that we were given is the root of the produced toolchain.
34+
# In other words, directly below the directory that we were passed
35+
# should be another directory named `usr`.
36+
if [ ! -d "$TOOLCHAIN_PATH/usr" ]; then
37+
echo "error: Directory provided was not the root directory of a toolchain" >/dev/stderr
38+
exit 1
39+
fi
40+
41+
# Stage the package files, dropping the initial usr/ directory
42+
# that is at the root of the provided toolchain from the path
43+
# but keeping everything after it.
44+
# So, the directory structure relative to the root of the staging
45+
# area will be
46+
# - ./usr/local/swift/bin
47+
# - ./usr/local/swift/lib
48+
# and so on.
49+
mkdir -p "$SWIFT_TOOLCHAIN_HOME"
50+
cp -R "$TOOLCHAIN_PATH/usr/" "$SWIFT_TOOLCHAIN_HOME"
51+
echo "Copied toolchain into $SWIFT_TOOLCHAIN_HOME."
52+
53+
# Because the Swift toolchain will be installed to /usr/local/swift,
54+
# we need to create symlinks to the actual Swift binaries. This is
55+
# because users expect the installed binaries to be in the path at
56+
# /usr/local/bin.
57+
echo "Creating symlinks to Swift tools..."
58+
echo "Entering $PACKAGE_STAGING/usr/local/bin"
59+
cd "$PACKAGE_STAGING/usr/local/bin"
60+
ln -s "../swift/bin/swift" "swift"
61+
ln -s "../swift/bin/swiftc" "swiftc"
62+
echo "Returning to $CURRENT_DIRECTORY"
63+
64+
# Once the symlink structure has been created, then we must generate
65+
# the list of files to store in the package. To do so, we iterate over
66+
# the staging area, and generate the list of files. These paths need
67+
# to be relative to ./usr/local since that is the prefix that we indicate
68+
# below in the manifest file.
69+
#
70+
# When the package is created using `pkg create`, pkg will handle the
71+
# process of generating the file hashes, etc. for everything here.
72+
echo "Generate package list..."
73+
cd "$PACKAGE_STAGING/usr/local"
74+
find "." -type l > "$METADATA_STAGING/pkg-plist"
75+
find "." -type f >> "$METADATA_STAGING/pkg-plist"
76+
cd "$CURRENT_DIRECTORY"
77+
78+
SWIFT_VERSION="$("$SWIFT_TOOLCHAIN_HOME/bin/swift" --version | grep -Eo 'version [0-9.]+' | sed 's/version //')"
79+
echo "Swift version being packaged is $SWIFT_VERSION"
80+
81+
# Create the manifest file. All fields below are required. pkg_create(3)
82+
# will add additional fields as part of generating the package.
83+
echo "Generating manifest..."
84+
cat > "$METADATA_STAGING/manifest" <<EOF
85+
{
86+
"name": "swift",
87+
"version": "$SWIFT_VERSION",
88+
"desc": "The Swift programming language",
89+
"arch": "$(uname -m)",
90+
"prefix": "/usr/local",
91+
"origin": "",
92+
"comment": "",
93+
"maintainer": "Apple Inc.",
94+
"www": "https://www.swift.org"
95+
}
96+
EOF
97+
98+
# Log where we wrote the metadata files.
99+
echo "Wrote manifest file to $METADATA_STAGING/manifest"
100+
echo "Wrote package file list to $METADATA_STAGING/pkg-plist"
101+
102+
# Generate the package. FreeBSD will helpful determine the required
103+
# dependencies for us based on the shared libraries that the binaries
104+
# in the toolchain require. We should call `pkg update` beforehand to
105+
# ensure this package database of dependencies is updated, just for
106+
# good measure.
107+
echo "Building package..."
108+
PACKAGE_FILE_NAME="$METADATA_STAGING/swift-$SWIFT_VERSION.pkg"
109+
mkdir -p "$(dirname $PACKAGE_PATH)"
110+
pkg update
111+
pkg create -f tzst -M "$METADATA_STAGING/manifest" -r "$PACKAGE_STAGING" -p "$METADATA_STAGING/pkg-plist" -o "$METADATA_STAGING"
112+
mv "$PACKAGE_FILE_NAME" "$PACKAGE_PATH"
113+
114+
# Cleanup.
115+
rm -rf "$PACKAGE_STAGING" "$METADATA_STAGING"

0 commit comments

Comments
 (0)