Skip to content

Commit fbdcea1

Browse files
committed
build_mp.sh --icon: our executables can wear our own icon
The windows port hardcodes ports/windows/micropython.rc to ../../logo/vector-logo-2.ico, and the Makefile compiles it to micropython.res and links that into $(PROG) whatever the program is named - so every windows binary this script builds has been wearing MicroPython's logo, including micropython-vst3's sidecar. --icon PATH (env twin MP_ICON) rewrites that one line for the build. Deliberately not a patch and deliberately no stored copy of the resource script: the original is stashed and the EXIT trap already installed for the mailbox overlays puts it back. Restored by copy, so the restored file is newer than the .res built from ours and the next build without --icon rebuilds back to the port's own logo. The icon is per-invocation, never sticky - this checkout is shared. Refuses rather than ignores: a non-windows port (an ELF binary has nowhere to carry one), a path that is not there, and a file whose header is not 00 00 01 00 - a .png renamed .ico is the mistake everyone makes once, and windres reports it as a parse error minutes into a build. All three refusals were exercised, and the checkout was checked clean afterwards; micropython-vst3 is the first consumer.
1 parent 7ea72e6 commit fbdcea1

1 file changed

Lines changed: 68 additions & 1 deletion

File tree

build_mp.sh

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
#
44
# Usage:
55
# ./build_mp.sh [--port PORT] [--board BOARD] [--variant VARIANT] [--debug]
6+
# [--icon PATH]
67
#
78
# Environment: WORKSPACE_DIR, MP_DIR, IDF_DIR, EMSDK_DIR, PORT, BOARD, VARIANT,
89
# OS_DUPTERM, OS_DUPTERM_SLOTS, MP_BUILD_DEBUG, MP_AUTOSIZE,
910
# MP_OVERLAY_SKIP (patch numbers excluded from the mailbox
1011
# overlays, e.g. "0001 0003"), MP_MAKE_EXTRA (extra VAR=VALUE
11-
# words appended to the make command line)
12+
# words appended to the make command line), MP_ICON (same as
13+
# --icon: the .ico the windows port's executable wears)
1214
#
1315
# USER_C_MODULES and FROZEN_MANIFEST are always cleared at startup so a prior
1416
# shell export cannot stick across port/board/variant builds. They then default
@@ -39,9 +41,24 @@
3941
set -euo pipefail
4042

4143
APPLIED_MP_PATCHES=()
44+
# Set by apply_micropython_icon: where the port's own micropython.rc was put
45+
# while ours stood in its place.
46+
MP_ICON_RC_BACKUP=""
4247

4348
restore_micropython_overlay() {
4449
local index
50+
# The icon first: it is a plain file copy and cannot fail the way a patch
51+
# reversal can, so doing it here means a patch that will not reverse still
52+
# leaves the resource script as MicroPython wrote it.
53+
if [[ -n "$MP_ICON_RC_BACKUP" && -f "$MP_ICON_RC_BACKUP" ]]; then
54+
# Copied back rather than moved-with-timestamp on purpose: the restored
55+
# file is NEWER than the .res built from ours, so the next build without
56+
# --icon rebuilds the resource and the port's own logo returns. The icon
57+
# is per-invocation, never sticky - this checkout is shared.
58+
cp "$MP_ICON_RC_BACKUP" "$MP_DIR/ports/windows/micropython.rc"
59+
rm -f "$MP_ICON_RC_BACKUP"
60+
MP_ICON_RC_BACKUP=""
61+
fi
4562
for ((index=${#APPLIED_MP_PATCHES[@]}-1; index>=0; index--)); do
4663
git -C "$MP_DIR" apply --reverse "${APPLIED_MP_PATCHES[index]}" || {
4764
echo "error: failed to remove MicroPython overlay ${APPLIED_MP_PATCHES[index]}" >&2
@@ -93,18 +110,22 @@ while [[ $# -gt 0 ]]; do
93110
--board) BOARD="$2"; shift 2 ;;
94111
--variant) VARIANT="$2"; shift 2 ;;
95112
--debug) MP_BUILD_DEBUG=1; shift ;;
113+
--icon) MP_ICON="$2"; shift 2 ;;
96114
--no-os-dupterm) OS_DUPTERM=0; OS_DUPTERM_EXPLICIT=1; shift ;;
97115
--os-dupterm) OS_DUPTERM=1; OS_DUPTERM_EXPLICIT=1; shift ;;
98116
-h|--help)
99117
cat <<EOF
100118
Usage: $0 [--port PORT] [--board BOARD] [--variant VARIANT] [--debug]
119+
[--icon PATH]
101120
102121
Build MicroPython with user C modules from the cmods workspace.
103122
104123
Options:
105124
--port PORT MicroPython port (e.g. unix, esp32, rp2)
106125
--board BOARD Board name for board-based ports
107126
--variant VARIANT Board variant (board ports) or build variant (unix, etc.)
127+
--icon PATH windows: .ico the built executable wears, in place of
128+
the port's own logo. Restored after the build.
108129
--debug esp32: UART REPL + USB Serial/JTAG debug console
109130
(ESP32_GENERIC_S3/SPIRAM_OCT → SPIRAM_OCT_DEBUG).
110131
USB jack = IDF secondary console / ESP_LOG; UART jack = REPL.
@@ -120,6 +141,7 @@ Environment:
120141
file for the selected port/board/variant (read by manifest-micropython.py)
121142
PORT, BOARD, VARIANT Same as the corresponding options
122143
MP_BUILD_DEBUG Same as --debug when set to 1/true/yes/on
144+
MP_ICON Same as --icon (windows only)
123145
OS_DUPTERM Enable os.dupterm on unix/webassembly (default: 1); windows default: 0
124146
OS_DUPTERM_SLOTS dupterm slot count for desktop ports (default: 1)
125147
SDL2_DEV Unpacked SDL2 MinGW development ZIP root (windows; required when displayif usdl2 links)
@@ -542,6 +564,50 @@ ensure_host_mpy_cross() {
542564
make -C "$MP_DIR/mpy-cross" USER_C_MODULES= FROZEN_MANIFEST=
543565
}
544566

567+
# --icon / MP_ICON: give the built executable our own icon instead of the
568+
# port's. ports/windows/micropython.rc is a single line naming an .ico, and the
569+
# windows Makefile compiles it to micropython.res and links that into $(PROG)
570+
# whatever the program is named - so rewriting that one line is the entire
571+
# mechanism. Deliberately not a patch and deliberately no stored copy of the
572+
# resource script: the original is stashed and the EXIT trap puts it back, the
573+
# same transactional shape the mailbox overlays use.
574+
apply_micropython_icon() {
575+
[[ -n "${MP_ICON:-}" ]] || return 0
576+
577+
if [[ "$PORT" != windows ]]; then
578+
echo "error: --icon is only meaningful for --port windows - an ELF binary" >&2
579+
echo " has nowhere to carry one. Port requested: $PORT" >&2
580+
return 1
581+
fi
582+
583+
local icon
584+
icon=$(realpath -e -- "$MP_ICON" 2>/dev/null) || {
585+
echo "error: --icon: no such file: $MP_ICON" >&2
586+
return 1
587+
}
588+
# Checked here because windres reports a bad file as a parse error minutes
589+
# into the build, and a .png renamed .ico is the mistake everyone makes
590+
# once. An ICONDIR opens 00 00 01 00: reserved, then resource type 1.
591+
local magic
592+
magic=$(od -An -tx1 -N4 -- "$icon" | tr -d ' \n')
593+
if [[ "$magic" != "00000100" ]]; then
594+
echo "error: --icon: not a Windows .ico (header reads $magic): $icon" >&2
595+
return 1
596+
fi
597+
598+
local rc="$MP_DIR/ports/windows/micropython.rc"
599+
[[ -f "$rc" ]] || {
600+
echo "error: --icon: the windows port has no micropython.rc at $rc" >&2
601+
return 1
602+
}
603+
604+
MP_ICON_RC_BACKUP=$(mktemp)
605+
cp "$rc" "$MP_ICON_RC_BACKUP"
606+
printf 'app ICON "%s"\n' "$icon" > "$rc"
607+
echo "Icon: $icon"
608+
echo " ports/windows/micropython.rc rewritten for this build; restored on exit"
609+
}
610+
545611
apply_micropython_cmods_patches() {
546612
# Apply mailbox patches whose names contain micropython-<PORT> as temporary
547613
# working-tree overlays. No matches means there is nothing to do.
@@ -1013,6 +1079,7 @@ echo " FROZEN_MANIFEST_UPSTREAM=$FROZEN_MANIFEST_UPSTREAM"
10131079
ensure_windows_cross_compile
10141080
ensure_windows_sdl2_env
10151081
apply_micropython_cmods_patches
1082+
apply_micropython_icon
10161083

10171084
print_rerun_hint
10181085
print_make_commands

0 commit comments

Comments
 (0)