dosbox-staging/scripts/create-package.sh
2023-12-11 03:18:41 -06:00

318 lines
11 KiB
Bash
Executable file

#!/bin/sh
set -e
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2020-2022 Sherman Perry and the DOSBox Staging Team
usage()
{
printf "%s\n" "\
Usage: -p <platform> [-h -c <commit> -b <branch> -r <repo> -v <version> -f] BUILD_DIR PACKAGE_DIR
Where:
-h : Show this help message
-p : Build platform. Can be one of linux, macos, msys2, msvc
-c : Git commit
-b : Git branch
-r : Git repository
-v : DOSBox Staging version
-f : Force creation if PACKAGE_DIR is not empty
BUILD_DIR : Meson build directory
PACKAGE_DIR : Package directory
Note: On macos, '-v' must be set. On msvc, the environment variable VC_REDIST_DIR must be set."
}
create_parent_dir()
{
path=$1
dir=$(dirname "$path")
if [ "$dir" != "." ]; then
case $platform in
msvc) mkdir -p "$dir" ;;
macos) install -d "${dir}/"
esac
fi
}
install_file()
{
src=$1
dest=$2
case $platform in
linux|msys2) install -DT -m 644 "$src" "$dest" ;;
msvc) create_parent_dir "$dest" && cp "$src" "$dest" ;;
macos) create_parent_dir "$dest" && install -m 644 "$src" "$dest" ;;
esac
}
install_doc()
{
# Install common documentation files
case $platform in
linux)
install_file docs/README.template "${pkg_dir}/README"
install_file LICENSE "${pkg_dir}/LICENSE"
install_file README "${pkg_dir}/doc/manual.txt"
install_file docs/dosbox.1 "${pkg_dir}/man/dosbox.1"
install_file licenses/BSD-2-Clause.txt "${pkg_dir}/doc/licenses/BSD-2-Clause.txt"
install_file licenses/BSD-3-Clause.txt "${pkg_dir}/doc/licenses/BSD-3-Clause.txt"
install_file licenses/GPL-2.0.txt "${pkg_dir}/doc/licenses/GPL-2.0.txt"
install_file licenses/LGPL-2.1.txt "${pkg_dir}/doc/licenses/LGPL-2.1.txt"
install_file licenses/MIT.txt "${pkg_dir}/doc/licenses/MIT.txt"
install_file licenses/Zlib.txt "${pkg_dir}/doc/licenses/Zlib.txt"
readme_tmpl="${pkg_dir}/README"
;;
macos)
install_file docs/README.template "${macos_content_dir}/SharedSupport/README"
install_file LICENSE "${macos_content_dir}/SharedSupport/LICENSE"
install_file README "${macos_content_dir}/SharedSupport/manual.txt"
install_file docs/README.video "${macos_content_dir}/SharedSupport/video.txt"
install_file licenses/BSD-2-Clause.txt "${macos_content_dir}/doc/licenses/BSD-2-Clause.txt"
install_file licenses/BSD-3-Clause.txt "${macos_content_dir}/doc/licenses/BSD-3-Clause.txt"
install_file licenses/GPL-2.0.txt "${macos_content_dir}/doc/licenses/GPL-2.0.txt"
install_file licenses/LGPL-2.1.txt "${macos_content_dir}/doc/licenses/LGPL-2.1.txt"
install_file licenses/MIT.txt "${macos_content_dir}/doc/licenses/MIT.txt"
install_file licenses/Zlib.txt "${macos_content_dir}/doc/licenses/Zlib.txt"
readme_tmpl="${macos_content_dir}/SharedSupport/README"
;;
msys2|msvc)
install_file docs/README.template "${pkg_dir}/README.txt"
install_file LICENSE "${pkg_dir}/LICENSE.txt"
install_file docs/README.video "${pkg_dir}/doc/video.txt"
install_file README "${pkg_dir}/doc/manual.txt"
install_file licenses/BSD-2-Clause.txt "${pkg_dir}/doc/licenses/BSD-2-Clause.txt"
install_file licenses/BSD-3-Clause.txt "${pkg_dir}/doc/licenses/BSD-3-Clause.txt"
install_file licenses/GPL-2.0.txt "${pkg_dir}/doc/licenses/GPL-2.0.txt"
install_file licenses/LGPL-2.1.txt "${pkg_dir}/doc/licenses/LGPL-2.1.txt"
install_file licenses/MIT.txt "${pkg_dir}/doc/licenses/MIT.txt"
install_file licenses/Zlib.txt "${pkg_dir}/doc/licenses/Zlib.txt"
readme_tmpl="${pkg_dir}/README.txt"
;;
esac
# Fill template variables in README.template
if [[ "$git_branch" == "refs/tags/"* ]] && [[ "$git_branch" != *"-"* ]]; then
version_tag=`echo $git_branch | awk '{print substr($0,11);exit}'`
package_information="release $version_tag"
elif [[ "$git_branch" == "release/"* ]]; then
version_tag=`git describe --tags | cut -f1 -d"-"`
package_information="release $version_tag"
elif [ -n "$git_branch" ] && [ -n "$git_commit" ]; then
package_information="a development branch named $git_branch with commit $git_commit"
else
package_information="a development branch"
fi
if [ -n "$package_information" ]; then
sed -i -e "s|%PACKAGE_INFORMATION%|$package_information|" "$readme_tmpl"
fi
if [ -n "$git_repo" ]; then
sed -i -e "s|%GITHUB_REPO%|$git_repo|" "$readme_tmpl"
fi
}
install_resources()
{
case "$platform" in
"macos")
local src_dir=${build_dir}/../Resources
local dest_dir=${macos_content_dir}/Resources
;;
*)
local src_dir=${build_dir}/resources
local dest_dir=${pkg_dir}/resources
;;
esac
find $src_dir -type f |
while IFS= read -r src; do
install_file "$src" "$dest_dir/${src#*$src_dir/}"
done
}
pkg_linux()
{
# Print shared object dependencies
# ldd crashes with a malloc error on the s390x platform, so always pass
ldd "${build_dir}/dosbox" || true
install -DT "${build_dir}/dosbox" "${pkg_dir}/dosbox"
install -DT contrib/linux/dosbox-staging.desktop "${pkg_dir}/desktop/dosbox-staging.desktop"
install -DT contrib/linux/install-icons.sh "${pkg_dir}/install-icons.sh"
DESTDIR="$(realpath "$pkg_dir")" make -C contrib/icons/ install datadir=
}
pkg_macos()
{
# Note, this script assumes macos builds have x86_64 and arm64 subdirectories
# Print shared object dependencies
for arch in x86_64 arm64; do
echo "Checking shared object dependencies for $arch:"
otool -L "${build_dir}/dosbox-$arch/dosbox"
python3 scripts/verify-macos-dylibs.py "${build_dir}/dosbox-$arch/dosbox"
echo ""
done
# Create universal binary from both architectures
mkdir dosbox-universal
lipo dosbox-x86_64/dosbox dosbox-arm64/dosbox -create -output dosbox-universal/dosbox
install -d "${macos_content_dir}/MacOS/"
install dosbox-universal/dosbox "${macos_content_dir}/MacOS/"
install_file contrib/macos/Info.plist.template "${macos_content_dir}/Info.plist"
install_file contrib/macos/PkgInfo "${macos_content_dir}/PkgInfo"
install_file contrib/icons/macos/dosbox-staging.icns "${macos_content_dir}/Resources/"
sed -i -e "s|%VERSION%|${dbox_version}|" "${macos_content_dir}/Info.plist"
# Install start commands
start_command="Start DOSBox Staging.command"
start_logging_command="Start DOSBox Staging (logging).command"
install -m 755 "contrib/macos/${start_command}" "${macos_dist_dir}/${start_command}"
install -m 755 "contrib/macos/${start_logging_command}" "${macos_dist_dir}/${start_logging_command}"
# Hide command extensions in Finder
file_attr="00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
xattr -x -w com.apple.FinderInfo "$file_attr" "${macos_dist_dir}/${start_command}"
xattr -x -w com.apple.FinderInfo "$file_attr" "${macos_dist_dir}/${start_logging_command}"
# Set up visual appearance of the root folder of the DMG image
install_file contrib/macos/background/background.tiff "${macos_dist_dir}/.hidden/background.tiff"
install_file contrib/macos/DS_Store "${macos_dist_dir}/.DS_Store"
}
pkg_msys2()
{
install -DT "${build_dir}/dosbox.exe" "${pkg_dir}/dosbox.exe"
# Discover and copy required dll files
ntldd -R "${pkg_dir}/dosbox.exe" \
| sed -e 's/^[[:blank:]]*//g' \
| cut -d ' ' -f 3 \
| grep -E -i '(mingw|clang)(32|64)' \
| sed -e 's|\\|/|g' \
| xargs cp --target-directory="${pkg_dir}/"
}
pkg_msvc()
{
# Get the release dir name from $build_dir
release_dir=$(basename -- "$(dirname -- "${build_dir}")")/$(basename -- "${build_dir}")
# Copy binary
cp "${build_dir}/dosbox.exe" "${pkg_dir}/dosbox.exe"
# Copy dll files
cp "${build_dir}"/*.dll "${pkg_dir}/"
cp "src/libs/zmbv/${release_dir}"/*.dll "${pkg_dir}/"
# Copy MSVC C++ redistributable files
cp docs/vc_redist.txt "${pkg_dir}/doc/vc_redist.txt"
cp "$VC_REDIST_DIR"/*.dll "${pkg_dir}/"
}
# Get GitHub CI environment variables if available. The CLI options
# '-c', '-b', '-r' will override these if set.
if [ -n "${GITHUB_REPOSITORY:-}" ]; then
git_commit=`echo ${GITHUB_SHA} | awk '{print substr($0,1,9);exit}'`
git_branch=${GITHUB_REF#refs/heads/}
git_repo=${GITHUB_REPOSITORY}
else
git_commit=$(git rev-parse --short HEAD || echo '')
git_branch=$(git rev-parse --abbrev-ref HEAD || echo '')
git_repo=$(basename "$(git rev-parse --show-toplevel)" || echo '')
fi
print_usage="false"
while getopts 'p:c:b:r:v:hf' c
do
case $c in
h) print_usage="true" ;;
f) force_pkg="true" ;;
p) platform=$OPTARG ;;
c) git_commit=$OPTARG ;;
b) git_branch=$OPTARG ;;
r) git_repo=$OPTARG ;;
v) dbox_version=$OPTARG ;;
*) true ;; # keep shellcheck happy
esac
done
shift "$((OPTIND - 1))"
build_dir=$1
pkg_dir=$2
if [ "$print_usage" = "true" ]; then
usage
exit 0
fi
p=$platform
case $p in
linux|macos|msys2|msvc) true ;;
*) platform="unsupported" ;;
esac
if [ "$platform" = "unsupported" ]; then
echo "Platform not set or unsupported"
usage
exit 1
fi
if [ ! -d "$build_dir" ]; then
echo "Build directory not set, or does not exist"
usage
exit 1
fi
if [ -z "$pkg_dir" ]; then
echo "Package directory not set"
usage
exit 1
fi
if [ "$platform" = "macos" ]; then
if [ -z "$dbox_version" ]; then
echo "DOSBox Staging version required on macOS"
usage
exit 1
fi
macos_dist_dir="${pkg_dir}/dist"
macos_content_dir="${macos_dist_dir}/DOSBox Staging.app/Contents"
fi
if [ "$platform" = "msvc" ] && [ -z "$VC_REDIST_DIR" ]; then
echo "VC_REDIST_DIR environment variable not set"
usage
exit 1
fi
if [ -f "$pkg_dir" ]; then
echo "PACKAGE_DIR must not be a file"
usage
exit 1
fi
mkdir -p "$pkg_dir"
if [ -z "$(find "${pkg_dir}" -maxdepth 0 -empty)" ] && [ "$force_pkg" != "true" ]; then
echo "PACKAGE_DIR must be empty. Use '-f' to force creation anyway"
usage
exit 1
fi
set -x
install_doc
install_resources
case $platform in
linux) pkg_linux ;;
macos) pkg_macos ;;
msys2) pkg_msys2 ;;
msvc) pkg_msvc ;;
*) echo "Oops."; usage; exit 1 ;;
esac