Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use staticx for Aarch64 exe builds #355

Merged
merged 10 commits into from
May 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion exe-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@ pyinstaller==4.0; platform.machine == "x86_64"
# aarch64 requires a later version due to the use of a newer centos version.
# see https://github.com/pyinstaller/pyinstaller/issues/5540
pyinstaller==4.10; platform.machine == "aarch64"
staticx==0.12.1
# for aarch64 we build a slightly patched version
# I tried upgrading to 0.13.6 but it crashes when the botoloader is run as non-root :/
# I got this error in gdb:
# (gdb) run
# Starting program: /path/to/build/x86_64/gprofiler
# During startup program terminated with signal SIGSEGV, Segmentation fault.
# staying with 0.12.1 for the mean time...
staticx==0.12.1; platform.machine == "x86_64"
14 changes: 12 additions & 2 deletions pyi.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,24 @@ RUN pyinstaller pyinstaller.spec \
&& test -f build/pyinstaller/warn-pyinstaller.txt \
&& 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;

# 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
# 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)
COPY scripts/staticx_patch.diff staticx_patch.diff
RUN if [ $(uname -m) = "aarch64" ]; then \
git clone -b v0.13.6 https://github.com/JonathonReinhart/staticx.git && \
cd staticx && \
git reset --hard 819d8eafecbaab3646f70dfb1e3e19f6bbc017f8 && \
git apply ../staticx_patch.diff && \
python3 -m pip install . ; \
fi

COPY ./scripts/list_needed_libs.sh ./scripts/list_needed_libs.sh
# staticx packs dynamically linked app with all of their dependencies, it tries to figure out which dynamic libraries are need for its execution
# in some cases, when the application is lazily loading some DSOs, staticx doesn't handle it.
# we use list_needed_libs.sh to list the dynamic dependencies of *all* of our resources,
# and make staticx pack them as well.
# using scl here to get the proper LD_LIBRARY_PATH set
# TODO: use staticx for aarch64 as well; currently it doesn't generate correct binaries when run over Docker emulation.
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
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

FROM scratch AS export-stage

Expand Down
11 changes: 8 additions & 3 deletions scripts/list_needed_libs.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

#!/usr/bin/env bash
#
# Copyright (c) Granulate. All rights reserved.
# Licensed under the AGPL3 License. See LICENSE.md in the project root for license information.
#
set -e
set -euo pipefail

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

printed=
for l in $libs ; do
>&2 echo "found needed lib: $l"
echo -n " -l $l"
if ! echo "$printed" | grep -q "$l"; then
>&2 echo "found needed lib: $l"
echo -n " -l $l"
printed="$printed $l"
fi
done
28 changes: 28 additions & 0 deletions scripts/staticx_patch.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
diff --git a/libtar/decode.c b/libtar/decode.c
index b34b1d9..d221c3a 100644
--- a/libtar/decode.c
+++ b/libtar/decode.c
@@ -44,11 +44,6 @@ uid_t
th_get_uid(const TAR *t)
{
int uid;
- struct passwd *pw;
-
- pw = getpwnam(t->th_buf.uname);
- if (pw != NULL)
- return pw->pw_uid;

/* if the password entry doesn't exist */
sscanf(t->th_buf.uid, "%o", &uid);
@@ -60,11 +55,6 @@ gid_t
th_get_gid(const TAR *t)
{
int gid;
- struct group *gr;
-
- gr = getgrnam(t->th_buf.gname);
- if (gr != NULL)
- return gr->gr_gid;

/* if the group entry doesn't exist */
sscanf(t->th_buf.gid, "%o", &gid);
Jongy marked this conversation as resolved.
Show resolved Hide resolved