Skip to content

Commit f62a09d

Browse files
committed
Make macOS executables universal, for both x86_64 and arm64
This provides a rebuild of all macOS executables. For reproducibility, this was done entirely by `build_mac.sh`. I verified that different machines produce bit-for-bit identical output. A build machine running Xcode 16.2 16C5032a on macOS 15.2 24C101 was used. These tools should run on macOS 10.13 and later. This version was selected as it's the minimum macOS version that the xPack tools declare support for. A build of libusb is included, so that the provided `dfu-util` no longer has an external dependency. The universal structure was chosen for these tools to avoid changing paths, anywhere they may be relied on. If desired, `build_mac.sh` can also be used to produce single-architecture tools, even cross-compiling, depending on the value of the `ARCH` variable. The current released versions were selected: - libusb 1.0.27 - dfu-util 0.11 (including dfu-prefix and dfu-suffix) - hid-flash from STM32_HID_Bootloader 2.2.2 (this program erroneously reports its version as 2.2.1), with a patch from Serasidis/STM32_HID_Bootloader#68 (comment). - upload_reset from this repository at the HEAD of main Link: stm32duino/BoardManagerFiles#72 Signed-off-by: Mark Mentovai <[email protected]>
1 parent e87c95f commit f62a09d

File tree

7 files changed

+170
-0
lines changed

7 files changed

+170
-0
lines changed

build_mac.sh

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
5+
[ -z "${ARCH+x}" ] && ARCH=universal
6+
7+
case "${ARCH}" in
8+
arm64)
9+
# Build for arm64, either as a same-architecture or cross-architecture
10+
# build.
11+
CONFIGURE_HOST_ARG="--host=aarch64-apple-darwin"
12+
CC_ARCH_ARG="-arch ${ARCH}"
13+
14+
# Don't collide with macosx, which has traditionally been used for x86_64
15+
# code.
16+
ARCH_DIR=mac-arm64
17+
;;
18+
universal)
19+
# Build for x86_64 and arm64 simultaneously, putting the results into
20+
# "universal" or "fat" binaries.
21+
CONFIGURE_HOST_ARG=
22+
CC_ARCH_ARG="-arch x86_64 -arch arm64"
23+
24+
# It's fine to put universal code into macosx, traditionally used for x86_64
25+
# code, because it will contain x86_64 code and will run without trouble on
26+
# x86_64 systems. Using the same directory for universal files means that
27+
# these tools will remain at a stable path across a transition between
28+
# x86_64 and arm64.
29+
ARCH_DIR=macosx
30+
;;
31+
x86_64)
32+
# Build for x86_64, either as a same-architecture or cross-architecture
33+
# build.
34+
CONFIGURE_HOST_ARG="--host=${ARCH}-apple-darwin"
35+
CC_ARCH_ARG="-arch ${ARCH}"
36+
37+
ARCH_DIR=macosx
38+
;;
39+
*)
40+
# Build for some other ${ARCH}, either as a same-architecture or
41+
# cross-architecture build.
42+
CONFIGURE_HOST_ARG="--host=${ARCH}-apple-darwin"
43+
CC_ARCH_ARG="-arch ${ARCH}"
44+
45+
ARCH_DIR="mac-${ARCH}"
46+
;;
47+
esac
48+
49+
if [ -z "${MIN_OS_VERSION+x}" ]; then
50+
case "${ARCH}" in
51+
arm64)
52+
# macOS 11 was the first to support arm64.
53+
MIN_OS_VERSION=11.0
54+
;;
55+
universal | x86_64)
56+
# Although this could be set lower, the xPack tools declare support for
57+
# macOS 10.13, so it's unlikely that anyone would be using anything older.
58+
#
59+
# In a universal build, the toolchain will use this value for the x86_64
60+
# build, but will automatically increase the minimum to 11.0 for the arm64
61+
# build, because that was the first OS version to support arm64.
62+
MIN_OS_VERSION=10.13
63+
;;
64+
esac
65+
fi
66+
if [ -n "${MIN_OS_VERSION+x}" ]; then
67+
CC_MIN_OS_VERSION_ARG="-mmacosx-version-min=${MIN_OS_VERSION}"
68+
fi
69+
70+
MAKE_J_ARG="-j$(sysctl -n hw.ncpu)"
71+
BASE_CFLAGS="-Os -flto"
72+
BASE_LDFLAGS="-dead_strip"
73+
74+
LIBUSB_VERSION=1.0.27
75+
DFU_UTIL_VERSION=0.11
76+
STM32_HID_BOOTLOADER_VERSION=2.2.2
77+
78+
set -x
79+
80+
(
81+
cd "$(dirname "${0}")/.."
82+
83+
# dfu-util depends on libusb, which isn't part of the operating system.
84+
# Provide a build of libusb to satisfy that dependency.
85+
[ ! -d libusb ] && git clone https://github.com/libusb/libusb.git
86+
cd libusb
87+
git checkout "v${LIBUSB_VERSION}"
88+
# git clean -fdx
89+
# git checkout -- .
90+
sh bootstrap.sh
91+
CC="clang ${CC_ARCH_ARG} ${CC_MIN_OS_VERSION_ARG}" \
92+
CFLAGS="${BASE_CFLAGS}" \
93+
LDFLAGS="${BASE_LDFLAGS} -Wl,-source_version,${LIBUSB_VERSION}" \
94+
sh configure ${CONFIGURE_HOST_ARG}
95+
make clean
96+
make ${MAKE_J_ARG}
97+
98+
# Rewrite the LC_ID_DYLIB in libusb-1.0.0.dylib so that other modules that
99+
# link against it will expect to find it in the same directory that they are
100+
# located in (@loader_path). Later, libusb-1.0.0.dylib will be copied to the
101+
# same directory as dfu-util and the other executables that rely on it.
102+
install_name_tool \
103+
-id @loader_path/libusb-1.0.0.dylib \
104+
libusb/.libs/libusb-1.0.0.dylib
105+
106+
cd ..
107+
108+
[ ! -d dfu-util ] && git clone git://git.code.sf.net/p/dfu-util/dfu-util
109+
cd dfu-util
110+
git checkout "v${DFU_UTIL_VERSION}"
111+
# git clean -fdx
112+
# git checkout -- .
113+
sh autogen.sh
114+
CC="clang ${CC_ARCH_ARG} ${CC_MIN_OS_VERSION_ARG}" \
115+
CFLAGS="${BASE_CFLAGS} -fvisibility=hidden" \
116+
LDFLAGS="${BASE_LDFLAGS} -Wl,-source_version,${DFU_UTIL_VERSION}" \
117+
USB_CFLAGS="-I$(pwd)/../libusb/libusb" \
118+
USB_LIBS="-L$(pwd)/../libusb/libusb/.libs -lusb-1.0.0" \
119+
sh configure ${CONFIGURE_HOST_ARG}
120+
make clean
121+
make ${MAKE_J_ARG}
122+
cd ..
123+
124+
[ ! -d STM32_HID_Bootloader ] &&
125+
git clone https://github.com/Serasidis/STM32_HID_Bootloader.git
126+
cd STM32_HID_Bootloader
127+
git checkout "${STM32_HID_BOOTLOADER_VERSION}"
128+
# git clean -fdx
129+
# git checkout -- .
130+
git checkout -- cli/main.c
131+
132+
# Isolate and apply the patch from
133+
# https://github.com/Serasidis/STM32_HID_Bootloader/issues/68#issuecomment-2009105851
134+
curl --silent \
135+
https://api.github.com/repos/Serasidis/STM32_HID_Bootloader/issues/comments/2009105851 |
136+
jq --raw-output .body |
137+
sed -e 's/\r//g' -e '1,/^```/d' -e '/^```$/,$d' |
138+
patch cli/main.c
139+
140+
make -C cli clean
141+
make -C cli ${MAKE_J_ARG} \
142+
CC="clang ${CC_ARCH_ARG} ${CC_MIN_OS_VERSION_ARG}" \
143+
CFLAGS="${BASE_CFLAGS} -fvisibility=hidden -Wall -Werror -c" \
144+
LDFLAGS="${BASE_LDFLAGS} -Wl,-source_version,${STM32_HID_BOOTLOADER_VERSION}"
145+
cd ..
146+
)
147+
148+
mkdir -p "${ARCH_DIR}"
149+
150+
cp ../libusb/libusb/.libs/libusb-1.0.0.dylib \
151+
../dfu-util/src/dfu-prefix \
152+
../dfu-util/src/dfu-suffix \
153+
../dfu-util/src/dfu-util \
154+
../STM32_HID_Bootloader/cli/hid-flash \
155+
"${ARCH_DIR}/"
156+
chmod -x "${ARCH_DIR}/libusb-1.0.0.dylib"
157+
158+
# It would be nice to include -Wl,-source_version here, but that's tricky to do
159+
# for code that's in this repository, and probably won't be tagged with a
160+
# version until after this tool is built.
161+
clang \
162+
${CC_ARCH_ARG} \
163+
${CC_MIN_OS_VERSION_ARG} \
164+
${BASE_CFLAGS} \
165+
-fvisibility=hidden \
166+
${BASE_LDFLAGS} \
167+
-Wall \
168+
-Werror \
169+
-o "${ARCH_DIR}/upload_reset" \
170+
src/upload_reset/unix/upload_reset.c

macosx/dfu-prefix

63 KB
Binary file not shown.

macosx/dfu-suffix

63 KB
Binary file not shown.

macosx/dfu-util

98.4 KB
Binary file not shown.

macosx/hid-flash

54.5 KB
Binary file not shown.

macosx/libusb-1.0.0.dylib

242 KB
Binary file not shown.

macosx/upload_reset

56.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)