Iperf: Configuration does not generate statically linked executable

Created on 14 Aug 2017  ·  12Comments  ·  Source: esnet/iperf

Context

  • Version of iperf3:
    3.2

  • Hardware:
    x86_64

  • Operating system (and distribution, if any):
    Cross-compiling for ARM under Ubuntu

Bug Report

  • Expected Behavior
    Builds a statically linked executable

  • Actual Behavior
    Builds an executable with dynamically linked libraries

doru@doru-N551JK:~/Desktop/iperf$ file output/bin/iperf3
output/bin/iperf3: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=6d84258ed9cbe40710234da5f5b1cf8244d4a365, not stripped

  • Steps to Reproduce
    clone the master branch

apply this patch: https://github.com/esnet/iperf/pull/631/commits/423a2ec12bf969cb3df93a34f50330837bc6d707

configure

./configure --without-openssl --host=arm-none-linux-gnueabi CC=arm-linux-gnueabi-gcc LD=arm-linux-gnueabi-ld CXX=arm-linux-gnueabi-g++ CFLAGS=-static CXXFLAGS=-static --enable-static --disable-shared --prefix=/home/doru/Desktop/iperf3/output

  • Possible Solution

If I build iperf2 (not iperf3) using the steps above, it results a statically linked executable:
doru@doru-N551JK:~/Desktop/iperf-2.0.5/output/bin$ file iperf
iperf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=631918d87fb90840809bb5e5aa5b3d613bf1a775, not stripped

The configuration must be revised.

bug

Most helpful comment

Perhaps a better workaround is to set LDFLAGS=--static when running configure. Note the extra minus.
For example:

configure "LDFLAGS=--static" --disable-shared 

This builds a static executable however the following warning is produced:

warning: Using 'getaddrinfo' in statically linked applications requires at runtime the 
shared libraries from the glibc version used for linking

All 12 comments

I confirm this is a problem (tested on CentOS 7 and FreeBSD 11, both native compiling and not necessary to cross-build to another platform), but I don't yet know why. We don't test this configure feature very often but I _thought_ I'd seen it working at one point in the past. I notice that for some reason we never do a LT_INIT in configure.ac but it's not clear to me whether this is a factor or not.

Note that iperf2 and iperf3 are completely separate programs with different build infrastructures.

Also, I'm guessing this really does have something to do with libtool, which is not really my specialty, so if anyone has libtool skills, help would be greatly appreciated.

OK. I revisited this a little bit on some CentOS 7 VMs. I relearned that --enable-static --disable-shared just means that the shared libraries won't get built (in this case libiperf.so). CFLAGS=-static tries to do static linking, but it requires that the static C library in the libc-static RPM be installed. Also SCTP support can break the build on this platform, because as far as I can tell there are no lksctp-* packages in CentOS 7 that include static libraries (dynamic libraries only).

All this means that I'm also having trouble actually building a statically linked iperf3 executable, but it's not due to anything in iperf3.

This is indeed an issue with libtool that has been discussed for over 5 years now. See CRITICAL: libtool makes static linking impossible.

I do not know what is the best way to fix it in iperf. For the moment I could suggest only a workaround.

To build iperf3 statically after running configure replace
in src/Makefile on lines 155-157

iperf3_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(iperf3_CFLAGS) $(CFLAGS) \
        $(iperf3_LDFLAGS) $(LDFLAGS) -o $@

with

iperf3_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) -all-static $(iperf3_CFLAGS) $(CFLAGS) \
        $(iperf3_LDFLAGS) $(LDFLAGS) -o $@

That is insert -all-static straight after $(CCLD).

The problem is that libtool treats -static option given to the compiler as its own MODE-ARG and removes it from the compiler command line.

Perhaps a better workaround is to set LDFLAGS=--static when running configure. Note the extra minus.
For example:

configure "LDFLAGS=--static" --disable-shared 

This builds a static executable however the following warning is produced:

warning: Using 'getaddrinfo' in statically linked applications requires at runtime the 
shared libraries from the glibc version used for linking

@d1mach: Thanks for the info and workaround...that's quite interesting!

That workaround worked fine for me compiling natively on CentOS 7 (x86_64). I had to have a machine with glibc-static installed, but not any of the lksctp-* stuff. Also I didn't build with OpenSSL (the test VM I was using didn't have openssl-devel).

I am not sure how this would work in a cross-compiling environment...@doru91 do you think this workaround might help you?

The solution is fine by me.

Thanks a lot!

I probably need to write this up for the FAQ...I'd wager you're not the only person who wants / needs to build a static executable. Optimistically keeping this issue open to remind me to do this.

Added FAQ entry in 835ec5f, closing. Thanks all for the info and discussion!

@d1mach thanks you so much. I have a big problem with issue. Your answer work well for me.

@d1mach Here's a thank you from the future. That "--static" trick is one I scoured the internet for a fix for, not completely understanding what was wrong. This solved it, and will come in handy in the future. Much appreciated.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

travis1230 picture travis1230  ·  4Comments

KevinJosephMorin picture KevinJosephMorin  ·  5Comments

Surendraknatarajan picture Surendraknatarajan  ·  9Comments

Febbe picture Febbe  ·  4Comments

bbordereau picture bbordereau  ·  10Comments