patchelf
patchelf copied to clipboard
How to build a static patchelf binary?
I am trying to make a static build of patchelf that does not need any shared libraries.
#############################################
# Download and extract minimal Alpine system
#############################################
wget http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.2-x86_64.tar.gz
mkdir -p ./miniroot
cd ./miniroot
tar xf ../alpine-minirootfs-3.10.2-x86_64.tar.gz
cd -
#############################################
# Prepare chroot
#############################################
sudo mount -o bind /dev miniroot/dev
sudo mount -t proc none miniroot/proc
sudo mount -t sysfs none miniroot/sys
sudo cp -p /etc/resolv.conf miniroot/etc/
sudo chroot miniroot /bin/sh <<\EOF
#############################################
# Now inside chroot
#############################################
# Install build dependencies
apk update
apk add alpine-sdk bash util-linux wget autoconf gettext automake
# Build
wget https://github.com/NixOS/patchelf/archive/0.9.tar.gz # 0.10 cripples my files, puts XXXXX inside
tar xf *.tar.gz
cd patchelf-*/
./bootstrap.sh
./configure --prefix=/usr
make -j$(nproc)
sudo make install
#############################################
# Exit chroot and clean up
#############################################
exit
EOF
sudo umount miniroot/proc miniroot/sys miniroot/dev
I can compile patchelf using this procedure, but it is not linked statically. How can I achieve that?
I think you would just say:
./configure --prefix=/usr
make -j$(nproc) LDFLAGS=-static
I then see:
me@server:~/src/patchelf$ ldd src/patchelf
not a dynamic executable
Strange, this is what I get when I do this:
/patchelf-0.9 # ldd src/patchelf
/lib/ld-musl-x86_64.so.1 (0x7f6eedd01000)
/patchelf-0.9 # file src/patchelf
src/patchelf: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped
I can't reproduce it, but I am also am not using the same build environment. I'm operating under Ubuntu 18.04 with the distro-provided autoconf, make, gcc, etc. In case it's useful, here's everything I see:
me@server:~/src/patchelf$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
me@server:~/src/patchelf$ ./bootstrap.sh
...
...
me@server:~/src/patchelf$ make -j4 LDFLAGS=-static
...
...
me@server:~/src/patchelf$ ldd src/patchelf
not a dynamic executable
It could be that the make in your environment isn't passing LDFLAGS. Maybe try setting that in the environment or adding it to the Makefile explicitly? These are just some ideas which may be completely off-base.
Indeed, on Ubuntu it works :+1:
Thank you very, very much!
wget https://github.com/NixOS/patchelf/archive/0.9.tar.gz # 0.10 cripples my files, puts XXXXX inside
tar xf *.tar.gz
cd patchelf-*/
sudo apt install autoconf
./bootstrap.sh
./configure --prefix=/usr
make -j$(nproc) LDFLAGS=-static
ldd src/patchelf
Edit: But I need to use Alpine Linux and musl libc.
I just tested what rsanden recommended and it works here on my very old slackware system.
I am setting up a base (host) system with many statically compiled programs, including busybox and patchelf, to make it simpler to fix any problems that arise at a later time (in particular glibc is quite annoying ... I'd wish it would be simpler to use musl here).
It shouldn't be hard with Nix to use musl.
@domenkozar I tried nix-shell -p pkgsCross.musl64.patchelf. It builds, but when I run file $(which patchelf) in it, I get ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /nix/store/0c7c96gikmzv87i7lv3vq5s1cmfjd6zf-glibc-2.31-74/lib/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped
Was anyone ever able to produce a static build of patchelf with musl libc on Alpine Linux?
I believe you might need to pass CFLAGS=-no-pie