4

First of all I would like to give some background information to avoid the XY Problem.

I am trying to compile a c++ program using makefiles and g++. I also have to build any dependencies statically into the program, but not the 'system libraries' (libz.so, libdl.so, libstdc++.so, libm.so, libpthread.so, libc.so and libgcc.so).

To achieve this I specify -static as linker flag, then all dependencies that have to be statically linked and then I use the -Wl, -Bdynamic option, that should tell the linker to link every library, after this option, to be linked in dynamically including the 'system libraries' because they get linked last.(please correct me if I am wrong.)

LDFLAGS += -Lpath/to/dependencies

# These libs should be linked statically
LDFLAGS += -static
LDFLAGS += -llib1
LDFLAGS += -llib2
LDFLAGS += -llib3

# Libs after this should be linked dynamically.
LDFLAGS += -Wl, -Bdynamic
LDFLAGS += -lz         # If i dont specify these three libraries (z, pthread, dl) 
LDFLAGS += -lpthread   # I get undefined reference errors 
LDFLAGS += -ldl

When I call make, the program compiles and links just fine, but when I try to execute it I get the error: bash: ./program: No such file or directory. But the file DOES exist.

When I remove the -static flag from the linker, the program can be excecuted just fine, but the dependencies are linked dynamically, which is not what I want :(.

So when I call file on the program, that was made with the -static flag, I get this:

program: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), dynamically linked, interpreter /usr/lib/libc.so.1, for GNU/Linux 4.9.0, not stripped

The problem seems to be that the interpreter is set to /usr/lib/libc.so.1 and not to /lib/ld-linux.so.2 as it should usually be. At least it is, when I compile without the -static option.

What I found out is that the 'interpreter' is in reality the shared library loader and from what I read, I now assume that the bash tells me it can not find the program because the library loader is just wrong (Even though I don't quite understand the details of this).

So basically my question is: Why does the library loader get set to libc.so when I specify the -static option to the linker and how can I tell the linker to use the correct library loader when -static is specified?

mario.b
  • 165
  • 1
  • 12
  • Found a workaround as described here: https://stackoverflow.com/questions/6578484/telling-gcc-directly-to-link-a-library-statically. By using -l:liblibname.a. This worked aswell as the solution from n.m. – mario.b Aug 11 '17 at 13:09

1 Answers1

7

Your error is mixing -static and -Bdynamic as both compiler and linker flags. Don't do that. If you use -Wl, gcc just blindly pass these flags to the linker, but if you don't, it rearranges the entire link line. (check what it does with gcc -v).

The mix creates an inconsistent and erroneous link command. I have no idea why gcc doesn't at least warn about that, but it doesn't, and silently sets the dynamic loader to a non-existent file.

You want to use -Wl,-Bstatic and -Wl,-Bdynamic consistently throughout. Not -Bstatic and -Bdynamic, as gcc logic is different from that of ld.

This will create a correct dynamically linked executable with some static libs linked in.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243