-
Notifications
You must be signed in to change notification settings - Fork 8
/
build_macOS.sh
executable file
·193 lines (164 loc) · 5.62 KB
/
build_macOS.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/bin/bash
# ---------------------------------------------------------------------
# This file executes the build command for the macOS Application bundle
# ---------------------------------------------------------------------
PYTHON_VERSION=3.11.4
SRC_DIR=src
# Call getopt to validate the provided input.
VENV_DIR=build_env.$$
VERBOSE=false
MAKE_DISK=false
KEEP_VENV=false
SETUP_ENVIRONMENT=false
while getopts "hvdesp" OPTION; do
case "$OPTION" in
h) echo "Options:"
echo "\t-h Print help (this)"
echo "\t-v Verbose output"
echo "\t-e Keep Python virtual environment (don't delete)"
echo "\t-s Setup dev environment"
echo "\t-d Make disk image (.dmg)"
exit 0
;;
v) VERBOSE=true
;;
d) MAKE_DISK=true
;;
e) KEEP_VENV=true
;;
s) SETUP_ENVIRONMENT=true
;;
*) echo "Incorrect option provided"
exit 1
;;
esac
done
# Prints the provided error message and then exits with an error code
function fail {
CODE="${1:-1}"
MESSAGE="${2:-Unknown error}"
echo ""
echo -e "\033[31;1;4m*** ERROR: $MESSAGE ***\033[0m"
echo ""
exit $CODE
}
# Exits with error code/message if the previous command failed
function check_failure {
CODE="$?"
MESSAGE="$1"
[[ $CODE == 0 ]] || fail "$CODE" "$MESSAGE"
}
if [ "$SETUP_ENVIRONMENT" = true ]; then
# Install HomeBrew (only if you don't have it)
which -s brew
if [[ $? != 0 ]] ; then
# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
check_failure "Failed to install homebrew"
fi
# Install Dependencies
brew install inkscape
brew install --build-from-source libusb
check_failure "Failed to install libusb"
# Link Homebrew lib so pyusb can find libusb
ln -s /opt/homebrew/lib ~/lib
# Tcl/Tk
brew install --build-from-source tcl-tk
check_failure "Failed to install tcl-tk"
# Install python environments...
brew install --build-from-source pyenv
check_failure "Failed to install pyenv"
eval "$(pyenv init -)"
# Install Python with pyenv and set it as the default Python
pyenv uninstall -f ${PYTHON_VERSION}
# https://github.com/pyenv/pyenv/issues/94
# Not needed anymore with python 3.11.4
# env PATH="$(brew --prefix tcl-tk)/bin:$PATH" \
# LDFLAGS="-L$(brew --prefix tcl-tk)/lib" \
# CPPFLAGS="-I$(brew --prefix tcl-tk)/include" \
# PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
# PYTHON_CONFIGURE_OPTS="--enable-framework --with-tcltk-includes='-I$(brew --prefix tcl-tk)/include' --with-tcltk-libs='-L$(brew --prefix tcl-tk)/lib -ltcl8.6 -ltk8.6'"
pyenv install ${PYTHON_VERSION}
check_failure "Failed to install Python ${PYTHON_VERSION}"
# Select Python to use
pyenv local ${PYTHON_VERSION} && pyenv rehash
check_failure "Failed to setup Python ${PYTHON_VERSION}"
fi
echo "Validate environment..."
OS=$(uname)
if [ "${OS}" != "Darwin" ]; then
fail "Um... this build script is for macOS."
fi
# Use the specific python version from pyenv so we don't get hung up on the
# system python or a user's own custom environment.
PYTHON=$(command -v python3)
PY_VER=$($PYTHON --version 2>&1 | awk '{ print $2 }')
[[ ${PY_VER} == "${PYTHON_VERSION}" ]] || fail 1 "Packaging REQUIRES Python ${PYTHON_VERSION}. Please rerun with -s to setup build environment"
# Clean up any previous build work
echo "Remove old builds..."
rm -rf ./build ./dist *.pyc ./__pycache__
# Set up and activate virtual environment for dependencies
echo "Setup Python Virtual Environment..."
python3 -m venv "${VENV_DIR}"
check_failure "Failed to initialize python venv"
source "./${VENV_DIR}/bin/activate"
check_failure "Failed to activate python venv"
# Unset our python variable now that we are running inside of the virtualenv
# and can just use `python` directly
PYTHON=
# Install requirements
echo "Install Dependencies..."
python3 -m pip install --upgrade pip
pip3 install -r ${SRC_DIR}/requirements.txt
check_failure "Failed to install python requirements"
echo "Build macOS Application Bundle..."
# Create .spec file if it doesn't exist
SPEC_NAME=k40_whisperer.spec
SPEC_FILE=${SRC_DIR}/${SPEC_NAME}
if [ ! -f "$SPEC_FILE" ]; then
echo "$SPEC_FILE does not exist. Creating a basic one..."
pyi-makespec --onefile -w \
--add-data right.png:. \
--add-data left.png:. \
--add-data up.png:. \
--add-data down.png:. \
--add-data UL.png:. \
--add-data UR.png:. \
--add-data LR.png:. \
--add-data LL.png:. \
--add-data CC.png:. \
-n 'K40 Whisperer' \
-i emblem.icns \
--osx-bundle-identifier com.scorchworks.k40_whisperer \
--specpath ${SRC_DIR} \
--name ${SPEC_NAME}
k40_whisperer.py
fi
# Get version from main source file.
VERSION=$(grep "^version " ${SRC_DIR}/k40_whisperer.py | grep -Eo "[\.0-9]+")
python3 -OO -m PyInstaller -y --clean ${SPEC_FILE}
check_failure "Failed to package k40_whisperer bundle"
# Remove temporary binary
rm -rf dist/k40_whisperer
echo "Copy support files to dist..."
cp ${SRC_DIR}/{k40_whisperer_test.svg,Change_Log.txt,gpl-3.0.txt,README.md} dist
# Clean up the build directory when we are done.
echo "Clean up build artifacts..."
rm -rf build
# Remove virtual environment
if [ "$KEEP_VENV" = false ]; then
echo "Remove Python virtual environment..."
deactivate
rm -rf "${VENV_DIR}"
fi
# Buid a new disk image
if [ "$MAKE_DISK" = true ]; then
echo "Build macOS Disk Image..."
VOLNAME="K40 Whisperer ${VERSION}"
VOLFILE="K40-Whisperer-${VERSION}.dmg"
# Remove the old disk image if it exists
[ ! -e ${VOLFILE} ] || rm ${VOLFILE}
hdiutil create -fs 'Case-sensitive APFS' -volname "${VOLNAME}" -srcfolder ./dist ./dist/${VOLFILE}
check_failure "Failed to build k40_whisperer dmg"
fi
echo "Done."