mirror of
https://github.com/token2/fido2-manage.git
synced 2026-04-09 10:45:39 +00:00
for DMG files for MacOS distribution
helper scripts to produce DMG files for MacOS distribution
This commit is contained in:
128
build_macos.sh
Normal file
128
build_macos.sh
Normal file
@@ -0,0 +1,128 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
# --- Configuration ---
|
||||
APP_NAME="fido2-manage"
|
||||
CLI_EXECUTABLE_NAME="fido2-token2"
|
||||
FINAL_APP_NAME="${APP_NAME}.app"
|
||||
DMG_NAME="${APP_NAME}.dmg"
|
||||
VOL_NAME="FIDO2 Manager"
|
||||
BUILD_DIR="build"
|
||||
DIST_DIR="dist"
|
||||
STAGING_DIR="${BUILD_DIR}/staging" # A clean directory for our portable binaries
|
||||
|
||||
# --- Helper Functions ---
|
||||
info() {
|
||||
echo "[INFO] $1"
|
||||
}
|
||||
|
||||
fatal() {
|
||||
echo "[FATAL] $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_command() {
|
||||
if ! command -v "$1" &> /dev/null; then
|
||||
fatal "'$1' is not installed. Please install it first for the build environment."
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Build Steps ---
|
||||
|
||||
# 1. Prerequisite Checks for the Build Machine
|
||||
info "Checking build machine prerequisites..."
|
||||
check_command "cmake"
|
||||
check_command "hdiutil"
|
||||
check_command "otool"
|
||||
check_command "install_name_tool"
|
||||
if ! command -v "brew" &> /dev/null; then
|
||||
fatal "Homebrew is not installed. It is required to fetch build dependencies."
|
||||
fi
|
||||
dependencies=("pkg-config" "openssl@3" "libcbor" "zlib" "python-tk")
|
||||
info "Checking Homebrew dependencies..."
|
||||
for dep in "${dependencies[@]}"; do
|
||||
if ! brew list "$dep" &>/dev/null; then
|
||||
info "Dependency '$dep' not found. Installing with Homebrew..."
|
||||
brew install "$dep" || fatal "Failed to install '$dep'."
|
||||
fi
|
||||
done
|
||||
PYTHON_EXEC="/opt/homebrew/bin/python3"
|
||||
|
||||
# 2. Setup Python environment and install PyInstaller
|
||||
info "Setting up Python virtual environment and installing PyInstaller..."
|
||||
if [ -d ".venv" ]; then rm -rf ".venv"; fi
|
||||
"$PYTHON_EXEC" -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
# Let pip choose the latest compatible version of PyInstaller
|
||||
pip install pyinstaller
|
||||
deactivate
|
||||
|
||||
# 3. Build the C++ binary
|
||||
info "Building the C++ binary: ${CLI_EXECUTABLE_NAME}..."
|
||||
# Clean up old build artifacts to ensure a fresh build
|
||||
if [ -d "$BUILD_DIR" ]; then rm -rf "$BUILD_DIR"; fi
|
||||
if [ -d "$DIST_DIR" ]; then rm -rf "$DIST_DIR"; fi
|
||||
if [ -f "${APP_NAME}.spec" ]; then rm -f "${APP_NAME}.spec"; fi
|
||||
|
||||
mkdir -p "$STAGING_DIR"
|
||||
cmake -S . -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="arm64"
|
||||
cmake --build "$BUILD_DIR" --config Release
|
||||
CLI_BINARY_PATH="${BUILD_DIR}/tools/${CLI_EXECUTABLE_NAME}"
|
||||
if [ ! -f "$CLI_BINARY_PATH" ]; then
|
||||
fatal "Build failed. C++ Executable not found."
|
||||
fi
|
||||
|
||||
# 4. Make the C++ binary and its dependencies portable
|
||||
info "Making the C++ binary and its libraries portable..."
|
||||
if [ ! -f "./bundle_libs.sh" ]; then
|
||||
fatal "./bundle_libs.sh not found. Please create it first."
|
||||
fi
|
||||
chmod +x ./bundle_libs.sh
|
||||
# The bundle_libs script copies the binary and its dylib dependencies into the staging folder
|
||||
# and corrects their internal linkage paths.
|
||||
./bundle_libs.sh "$STAGING_DIR" "$CLI_BINARY_PATH"
|
||||
|
||||
# 4.1 Fix library version compatibility issues
|
||||
info "Fixing library version compatibility..."
|
||||
cd "$STAGING_DIR"
|
||||
# Create symlink for libcbor version compatibility
|
||||
if [ -f "libcbor.0.12.dylib" ] && [ ! -f "libcbor.0.11.dylib" ]; then
|
||||
ln -sf libcbor.0.12.dylib libcbor.0.11.dylib
|
||||
fi
|
||||
cd ..
|
||||
|
||||
# 4.2 Fix library linking (this must be done on macOS)
|
||||
info "Fixing library linking..."
|
||||
if [ ! -f "./fix_macos_linking.sh" ]; then
|
||||
fatal "./fix_macos_linking.sh not found. Please run this script to create it."
|
||||
fi
|
||||
chmod +x ./fix_macos_linking.sh
|
||||
./fix_macos_linking.sh
|
||||
|
||||
info "Portable binary and libraries are in ${STAGING_DIR}. Verifying linkage..."
|
||||
# This check is for you to confirm it worked. All paths should start with @rpath or be system paths.
|
||||
otool -L "${STAGING_DIR}/${CLI_EXECUTABLE_NAME}"
|
||||
|
||||
# 5. Create the standalone macOS app using PyInstaller
|
||||
info "Creating the standalone .app bundle with PyInstaller..."
|
||||
source .venv/bin/activate
|
||||
# Bundle the Python script and include the entire staging directory as data.
|
||||
# PyInstaller will place the contents of the staging directory in the root of the app bundle.
|
||||
pyinstaller --name "$APP_NAME" \
|
||||
--windowed \
|
||||
--noconsole \
|
||||
--add-data "${STAGING_DIR}/*:." \
|
||||
gui-mac.py
|
||||
deactivate
|
||||
|
||||
# 6. Package the final .app into a .dmg
|
||||
info "Packaging into ${DMG_NAME}..."
|
||||
APP_BUNDLE_PATH="${DIST_DIR}/${FINAL_APP_NAME}"
|
||||
FINAL_DMG_PATH="${DIST_DIR}/${DMG_NAME}"
|
||||
|
||||
if [ -f "$FINAL_DMG_PATH" ]; then rm -f "$FINAL_DMG_PATH"; fi
|
||||
|
||||
hdiutil create -fs HFS+ -srcfolder "$APP_BUNDLE_PATH" -volname "$VOL_NAME" "$FINAL_DMG_PATH"
|
||||
|
||||
info "Process complete! The final distributable file is: ${FINAL_DMG_PATH}"
|
||||
Reference in New Issue
Block a user