patchelf icon indicating copy to clipboard operation
patchelf copied to clipboard

How to build a static patchelf binary?

Open probonopd opened this issue 5 years ago • 9 comments

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?

probonopd avatar Dec 08 '19 10:12 probonopd

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

rsanden avatar Jan 06 '20 18:01 rsanden

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

probonopd avatar Jan 06 '20 18:01 probonopd

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.

rsanden avatar Jan 11 '20 05:01 rsanden

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.

probonopd avatar Jan 16 '20 21:01 probonopd

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).

rubyFeedback avatar May 29 '20 05:05 rubyFeedback

It shouldn't be hard with Nix to use musl.

domenkozar avatar May 29 '20 12:05 domenkozar

@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

piegamesde avatar May 29 '21 14:05 piegamesde

Was anyone ever able to produce a static build of patchelf with musl libc on Alpine Linux?

probonopd avatar May 02 '22 06:05 probonopd

I believe you might need to pass CFLAGS=-no-pie

Tachi107 avatar May 02 '22 08:05 Tachi107