distribution packaging
This commit is contained in:
parent
e6fa62f35d
commit
a7ada7d65b
6 changed files with 1015 additions and 80 deletions
354
tools/package.sh
Executable file
354
tools/package.sh
Executable file
|
|
@ -0,0 +1,354 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# McRogueFace Distribution Packager
|
||||
#
|
||||
# Creates clean distribution packages for Windows and Linux
|
||||
# Supports light (minimal stdlib) and full (complete stdlib) variants
|
||||
#
|
||||
# Usage:
|
||||
# ./tools/package.sh windows light # Windows light build
|
||||
# ./tools/package.sh windows full # Windows full build
|
||||
# ./tools/package.sh linux light # Linux light build
|
||||
# ./tools/package.sh linux full # Linux full build
|
||||
# ./tools/package.sh all # All variants
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
DIST_DIR="$PROJECT_ROOT/dist"
|
||||
|
||||
# Version from git or default
|
||||
VERSION=$(cd "$PROJECT_ROOT" && git describe --tags --always 2>/dev/null || echo "dev")
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Files and directories to exclude from distribution
|
||||
EXCLUDE_PATTERNS=(
|
||||
"CMakeFiles"
|
||||
"CMakeCache.txt"
|
||||
"cmake_install.cmake"
|
||||
"Makefile"
|
||||
"*.o"
|
||||
"*.obj"
|
||||
".git"
|
||||
".gitignore"
|
||||
"__pycache__"
|
||||
"*.pyc"
|
||||
"*.pyo"
|
||||
)
|
||||
|
||||
# Platform-specific excludes
|
||||
WINDOWS_EXCLUDES=(
|
||||
"*.so"
|
||||
"*.so.*"
|
||||
"lib.linux-*"
|
||||
)
|
||||
|
||||
LINUX_EXCLUDES=(
|
||||
"*.dll"
|
||||
"*.exe"
|
||||
"*.pdb"
|
||||
)
|
||||
|
||||
check_build_exists() {
|
||||
local platform=$1
|
||||
local build_dir
|
||||
|
||||
if [ "$platform" = "windows" ]; then
|
||||
build_dir="$PROJECT_ROOT/build-windows"
|
||||
if [ ! -f "$build_dir/mcrogueface.exe" ]; then
|
||||
log_error "Windows build not found. Run 'make windows' first."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
build_dir="$PROJECT_ROOT/build"
|
||||
if [ ! -f "$build_dir/mcrogueface" ]; then
|
||||
log_error "Linux build not found. Run 'make' first."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
create_stdlib_zip() {
|
||||
local platform=$1
|
||||
local preset=$2
|
||||
local output_dir=$3
|
||||
|
||||
log_info "Creating stdlib zip: platform=$platform preset=$preset"
|
||||
|
||||
# Use Python 3 to run our stdlib packager
|
||||
python3 "$SCRIPT_DIR/package_stdlib.py" \
|
||||
--platform "$platform" \
|
||||
--preset "$preset" \
|
||||
--output "$output_dir"
|
||||
}
|
||||
|
||||
package_windows() {
|
||||
local preset=$1
|
||||
local build_dir="$PROJECT_ROOT/build-windows"
|
||||
local package_name="McRogueFace-${VERSION}-Windows-${preset}"
|
||||
local package_dir="$DIST_DIR/$package_name"
|
||||
|
||||
log_info "Packaging Windows ($preset): $package_name"
|
||||
|
||||
# Check build exists
|
||||
check_build_exists windows || return 1
|
||||
|
||||
# Clean and create package directory
|
||||
rm -rf "$package_dir"
|
||||
mkdir -p "$package_dir"
|
||||
|
||||
# Copy executable
|
||||
cp "$build_dir/mcrogueface.exe" "$package_dir/"
|
||||
|
||||
# Copy DLLs (excluding build artifacts)
|
||||
for dll in "$build_dir"/*.dll; do
|
||||
[ -f "$dll" ] && cp "$dll" "$package_dir/"
|
||||
done
|
||||
|
||||
# Copy assets
|
||||
if [ -d "$build_dir/assets" ]; then
|
||||
cp -r "$build_dir/assets" "$package_dir/"
|
||||
fi
|
||||
|
||||
# Copy scripts
|
||||
if [ -d "$build_dir/scripts" ]; then
|
||||
cp -r "$build_dir/scripts" "$package_dir/"
|
||||
fi
|
||||
|
||||
# Copy Python stdlib directory structure (same as Linux)
|
||||
# Python home is set to <exe>/lib/Python, so stdlib must be there
|
||||
mkdir -p "$package_dir/lib/Python"
|
||||
|
||||
# Copy the Lib directory from build (matches Linux structure)
|
||||
if [ -d "$build_dir/lib/Python/Lib" ]; then
|
||||
log_info "Copying Python stdlib (preset: $preset)"
|
||||
cp -r "$build_dir/lib/Python/Lib" "$package_dir/lib/Python/"
|
||||
|
||||
# Remove test directories and other excludes to save space
|
||||
rm -rf "$package_dir/lib/Python/Lib/test"
|
||||
rm -rf "$package_dir/lib/Python/Lib/tests"
|
||||
rm -rf "$package_dir/lib/Python/Lib/idlelib"
|
||||
rm -rf "$package_dir/lib/Python/Lib/tkinter"
|
||||
rm -rf "$package_dir/lib/Python/Lib/turtledemo"
|
||||
rm -rf "$package_dir/lib/Python/Lib/pydoc_data"
|
||||
rm -rf "$package_dir/lib/Python/Lib/lib2to3"
|
||||
rm -rf "$package_dir/lib/Python/Lib/ensurepip"
|
||||
rm -rf "$package_dir/lib/Python/Lib/_pyrepl"
|
||||
find "$package_dir/lib/Python/Lib" -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
|
||||
find "$package_dir/lib/Python/Lib" -name "*.pyc" -delete 2>/dev/null || true
|
||||
find "$package_dir/lib/Python/Lib" -name "test_*.py" -delete 2>/dev/null || true
|
||||
find "$package_dir/lib/Python/Lib" -name "*_test.py" -delete 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Also copy python314.zip for backwards compatibility (some deployments use it)
|
||||
if [ -f "$build_dir/python314.zip" ]; then
|
||||
cp "$build_dir/python314.zip" "$package_dir/"
|
||||
fi
|
||||
|
||||
# Create the distribution archive
|
||||
log_info "Creating archive: ${package_name}.zip"
|
||||
(cd "$DIST_DIR" && zip -r "${package_name}.zip" "$package_name")
|
||||
|
||||
# Report size
|
||||
local size=$(du -h "$DIST_DIR/${package_name}.zip" | cut -f1)
|
||||
log_info "Created: $DIST_DIR/${package_name}.zip ($size)"
|
||||
|
||||
# Cleanup uncompressed directory
|
||||
rm -rf "$package_dir"
|
||||
}
|
||||
|
||||
package_linux() {
|
||||
local preset=$1
|
||||
local build_dir="$PROJECT_ROOT/build"
|
||||
local package_name="McRogueFace-${VERSION}-Linux-${preset}"
|
||||
local package_dir="$DIST_DIR/$package_name"
|
||||
|
||||
log_info "Packaging Linux ($preset): $package_name"
|
||||
|
||||
# Check build exists
|
||||
check_build_exists linux || return 1
|
||||
|
||||
# Clean and create package directory
|
||||
rm -rf "$package_dir"
|
||||
mkdir -p "$package_dir"
|
||||
mkdir -p "$package_dir/lib"
|
||||
|
||||
# Copy executable
|
||||
cp "$build_dir/mcrogueface" "$package_dir/"
|
||||
|
||||
# Copy shared libraries from __lib (not from build dir which has artifacts)
|
||||
if [ -d "$PROJECT_ROOT/__lib" ]; then
|
||||
# Copy only essential runtime libraries (not test modules)
|
||||
# Core libraries: libpython, libsfml-*, libtcod
|
||||
for lib in libpython3.14.so.1.0 libsfml-graphics.so.2.6.1 libsfml-window.so.2.6.1 \
|
||||
libsfml-system.so.2.6.1 libsfml-audio.so.2.6.1 libtcod.so; do
|
||||
[ -f "$PROJECT_ROOT/__lib/$lib" ] && cp "$PROJECT_ROOT/__lib/$lib" "$package_dir/lib/"
|
||||
done
|
||||
|
||||
# Create necessary symlinks
|
||||
(cd "$package_dir/lib" && \
|
||||
ln -sf libpython3.14.so.1.0 libpython3.14.so && \
|
||||
ln -sf libsfml-graphics.so.2.6.1 libsfml-graphics.so.2.6 && \
|
||||
ln -sf libsfml-graphics.so.2.6.1 libsfml-graphics.so && \
|
||||
ln -sf libsfml-window.so.2.6.1 libsfml-window.so.2.6 && \
|
||||
ln -sf libsfml-window.so.2.6.1 libsfml-window.so && \
|
||||
ln -sf libsfml-system.so.2.6.1 libsfml-system.so.2.6 && \
|
||||
ln -sf libsfml-system.so.2.6.1 libsfml-system.so && \
|
||||
ln -sf libsfml-audio.so.2.6.1 libsfml-audio.so.2.6 && \
|
||||
ln -sf libsfml-audio.so.2.6.1 libsfml-audio.so)
|
||||
|
||||
# Copy Python extension modules to correct location (excluding test modules)
|
||||
# Must match structure: lib/Python/lib.linux-x86_64-3.14/
|
||||
local pylib_dir="$PROJECT_ROOT/__lib/Python/lib.linux-x86_64-3.14"
|
||||
if [ -d "$pylib_dir" ]; then
|
||||
mkdir -p "$package_dir/lib/Python/lib.linux-x86_64-3.14"
|
||||
for so in "$pylib_dir"/*.so; do
|
||||
local basename=$(basename "$so")
|
||||
# Skip test modules
|
||||
case "$basename" in
|
||||
*test*|xxlimited*|_ctypes_test*|_xxtestfuzz*)
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
cp "$so" "$package_dir/lib/Python/lib.linux-x86_64-3.14/"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Copy assets
|
||||
if [ -d "$build_dir/assets" ]; then
|
||||
cp -r "$build_dir/assets" "$package_dir/"
|
||||
fi
|
||||
|
||||
# Copy scripts
|
||||
if [ -d "$build_dir/scripts" ]; then
|
||||
cp -r "$build_dir/scripts" "$package_dir/"
|
||||
fi
|
||||
|
||||
# Copy Python stdlib directory
|
||||
# Python home is set to <exe>/lib/Python, stdlib must be in lib/Python/Lib/
|
||||
mkdir -p "$package_dir/lib/Python"
|
||||
|
||||
# Copy the Lib directory from __lib/Python/Lib (filtered by preset)
|
||||
if [ -d "$PROJECT_ROOT/__lib/Python/Lib" ]; then
|
||||
log_info "Copying Python stdlib (preset: $preset)"
|
||||
|
||||
# For now, copy entire Lib - filtering happens via package_stdlib.py for zip
|
||||
# TODO: Implement directory-based filtering for light preset
|
||||
cp -r "$PROJECT_ROOT/__lib/Python/Lib" "$package_dir/lib/Python/"
|
||||
|
||||
# Remove test directories and other excludes to save space
|
||||
rm -rf "$package_dir/lib/Python/Lib/test"
|
||||
rm -rf "$package_dir/lib/Python/Lib/tests"
|
||||
rm -rf "$package_dir/lib/Python/Lib/idlelib"
|
||||
rm -rf "$package_dir/lib/Python/Lib/tkinter"
|
||||
rm -rf "$package_dir/lib/Python/Lib/turtledemo"
|
||||
rm -rf "$package_dir/lib/Python/Lib/pydoc_data"
|
||||
rm -rf "$package_dir/lib/Python/Lib/lib2to3"
|
||||
rm -rf "$package_dir/lib/Python/Lib/ensurepip"
|
||||
rm -rf "$package_dir/lib/Python/Lib/_pyrepl"
|
||||
find "$package_dir/lib/Python/Lib" -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
|
||||
find "$package_dir/lib/Python/Lib" -name "*.pyc" -delete 2>/dev/null || true
|
||||
find "$package_dir/lib/Python/Lib" -name "test_*.py" -delete 2>/dev/null || true
|
||||
find "$package_dir/lib/Python/Lib" -name "*_test.py" -delete 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Create run script
|
||||
cat > "$package_dir/run.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
export LD_LIBRARY_PATH="$SCRIPT_DIR/lib:$LD_LIBRARY_PATH"
|
||||
exec "$SCRIPT_DIR/mcrogueface" "$@"
|
||||
EOF
|
||||
chmod +x "$package_dir/run.sh"
|
||||
|
||||
# Create the distribution archive
|
||||
log_info "Creating archive: ${package_name}.tar.gz"
|
||||
(cd "$DIST_DIR" && tar -czf "${package_name}.tar.gz" "$package_name")
|
||||
|
||||
# Report size
|
||||
local size=$(du -h "$DIST_DIR/${package_name}.tar.gz" | cut -f1)
|
||||
log_info "Created: $DIST_DIR/${package_name}.tar.gz ($size)"
|
||||
|
||||
# Cleanup uncompressed directory
|
||||
rm -rf "$package_dir"
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
echo "McRogueFace Distribution Packager"
|
||||
echo ""
|
||||
echo "Usage: $0 <platform> <preset>"
|
||||
echo ""
|
||||
echo "Platforms:"
|
||||
echo " windows - Windows build (requires 'make windows' first)"
|
||||
echo " linux - Linux build (requires 'make' first)"
|
||||
echo " all - Build all variants"
|
||||
echo ""
|
||||
echo "Presets:"
|
||||
echo " light - Minimal stdlib (~2-3 MB)"
|
||||
echo " full - Complete stdlib (~8-10 MB)"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 windows light # Small Windows package"
|
||||
echo " $0 linux full # Full Linux package"
|
||||
echo " $0 all # All platform/preset combinations"
|
||||
}
|
||||
|
||||
main() {
|
||||
local platform=${1:-}
|
||||
local preset=${2:-full}
|
||||
|
||||
# Create dist directory
|
||||
mkdir -p "$DIST_DIR"
|
||||
|
||||
case "$platform" in
|
||||
windows)
|
||||
package_windows "$preset"
|
||||
;;
|
||||
linux)
|
||||
package_linux "$preset"
|
||||
;;
|
||||
all)
|
||||
log_info "Building all distribution variants..."
|
||||
package_windows light || true
|
||||
package_windows full || true
|
||||
package_linux light || true
|
||||
package_linux full || true
|
||||
log_info "All packages created in $DIST_DIR"
|
||||
ls -lh "$DIST_DIR"/*.zip "$DIST_DIR"/*.tar.gz 2>/dev/null || true
|
||||
;;
|
||||
-h|--help|"")
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown platform: $platform"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Loading…
Add table
Add a link
Reference in a new issue