Skip to content

Commit 7c18174

Browse files
authored
Use (patched) staticx for Aarch64 exe builds (#355)
1 parent 992a30a commit 7c18174

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

exe-requirements.txt

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,11 @@ pyinstaller==4.0; platform.machine == "x86_64"
33
# aarch64 requires a later version due to the use of a newer centos version.
44
# see https://github.com/pyinstaller/pyinstaller/issues/5540
55
pyinstaller==4.10; platform.machine == "aarch64"
6-
staticx==0.12.1
6+
# for aarch64 we build a slightly patched version
7+
# I tried upgrading to 0.13.6 but it crashes when the botoloader is run as non-root :/
8+
# I got this error in gdb:
9+
# (gdb) run
10+
# Starting program: /path/to/build/x86_64/gprofiler
11+
# During startup program terminated with signal SIGSEGV, Segmentation fault.
12+
# staying with 0.12.1 for the mean time...
13+
staticx==0.12.1; platform.machine == "x86_64"

pyi.Dockerfile

+12-2
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,24 @@ RUN pyinstaller pyinstaller.spec \
204204
&& test -f build/pyinstaller/warn-pyinstaller.txt \
205205
&& if grep 'gprofiler\.' build/pyinstaller/warn-pyinstaller.txt ; then echo 'PyInstaller failed to pack gProfiler code! See lines above. Make sure to check for SyntaxError as this is often the reason.'; exit 1; fi;
206206

207+
# for aarch64 - build a patched version of staticx 0.13.6. we remove calls to getpwnam and getgrnam, for these end up doing dlopen()s which
208+
# crash the staticx bootloader. we don't need them anyway (all files in our staticx tar are uid 0 and we don't need the names translation)
209+
COPY scripts/staticx_patch.diff staticx_patch.diff
210+
RUN if [ $(uname -m) = "aarch64" ]; then \
211+
git clone -b v0.13.6 https://github.com/JonathonReinhart/staticx.git && \
212+
cd staticx && \
213+
git reset --hard 819d8eafecbaab3646f70dfb1e3e19f6bbc017f8 && \
214+
git apply ../staticx_patch.diff && \
215+
python3 -m pip install . ; \
216+
fi
217+
207218
COPY ./scripts/list_needed_libs.sh ./scripts/list_needed_libs.sh
208219
# staticx packs dynamically linked app with all of their dependencies, it tries to figure out which dynamic libraries are need for its execution
209220
# in some cases, when the application is lazily loading some DSOs, staticx doesn't handle it.
210221
# we use list_needed_libs.sh to list the dynamic dependencies of *all* of our resources,
211222
# and make staticx pack them as well.
212223
# using scl here to get the proper LD_LIBRARY_PATH set
213-
# TODO: use staticx for aarch64 as well; currently it doesn't generate correct binaries when run over Docker emulation.
214-
RUN if [ $(uname -m) != "aarch64" ]; then source scl_source enable devtoolset-8 llvm-toolset-7 && libs=$(./scripts/list_needed_libs.sh) && staticx $libs dist/gprofiler dist/gprofiler; fi
224+
RUN if [ $(uname -m) != "aarch64" ]; then source scl_source enable devtoolset-8 llvm-toolset-7 ; fi; libs=$(./scripts/list_needed_libs.sh) && staticx $libs dist/gprofiler dist/gprofiler
215225

216226
FROM scratch AS export-stage
217227

scripts/list_needed_libs.sh

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
12
#!/usr/bin/env bash
23
#
34
# Copyright (c) Granulate. All rights reserved.
45
# Licensed under the AGPL3 License. See LICENSE.md in the project root for license information.
56
#
6-
set -e
7+
set -euo pipefail
78

89
# this file lists all dynamic dependenices of executables in gprofiler/resources.
910
# we use it to let staticx know which libraries it should pack inside.
@@ -40,7 +41,11 @@ for f in $BINS ; do
4041
fi
4142
done
4243

44+
printed=
4345
for l in $libs ; do
44-
>&2 echo "found needed lib: $l"
45-
echo -n " -l $l"
46+
if ! echo "$printed" | grep -q "$l"; then
47+
>&2 echo "found needed lib: $l"
48+
echo -n " -l $l"
49+
printed="$printed $l"
50+
fi
4651
done

scripts/staticx_patch.diff

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
diff --git a/libtar/decode.c b/libtar/decode.c
2+
index b34b1d9..d221c3a 100644
3+
--- a/libtar/decode.c
4+
+++ b/libtar/decode.c
5+
@@ -44,11 +44,6 @@ uid_t
6+
th_get_uid(const TAR *t)
7+
{
8+
int uid;
9+
- struct passwd *pw;
10+
-
11+
- pw = getpwnam(t->th_buf.uname);
12+
- if (pw != NULL)
13+
- return pw->pw_uid;
14+
15+
/* if the password entry doesn't exist */
16+
sscanf(t->th_buf.uid, "%o", &uid);
17+
@@ -60,11 +55,6 @@ gid_t
18+
th_get_gid(const TAR *t)
19+
{
20+
int gid;
21+
- struct group *gr;
22+
-
23+
- gr = getgrnam(t->th_buf.gname);
24+
- if (gr != NULL)
25+
- return gr->gr_gid;
26+
27+
/* if the group entry doesn't exist */
28+
sscanf(t->th_buf.gid, "%o", &gid);

0 commit comments

Comments
 (0)