静态链接 libc

Jon*_*rin 2 cmake libc

我正在尝试使用 CMake 3.15 制作静态可执行文件。我正在 Alpine Linux 上构建(因此使用 musl),目前,我的可执行文件的 ldd 输出是:

# ldd my_executable
    /lib/ld-musl-x86_64.so.1 (0x7fc6f7977000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7fc6f65b3000)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fc6f7977000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7fc6f659f000)
Run Code Online (Sandbox Code Playgroud)

我可以设置target_link_options(my_executable PRIVATE -static-libgcc -static-libstdc++),并且它们静态链接:

# ldd my_executable
    /lib/ld-musl-x86_64.so.1 (0x7fc6f7977000)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fc6f7977000)
Run Code Online (Sandbox Code Playgroud)

但我无法让 musl 静态链接。我尝试过(使用干净的构建,以确保配置步骤从零开始):

  1. 添加-statictarget_link_options上面。
  2. set(CMAKE_EXE_LINKER_FLAGS "-static")在致电之前add_executable(my_executable ...)
  3. 添加-statictarget_link_libraries(my_executable lib1 lib2 -static)

当我在模式下运行 CMake 时VERBOSE=1,它​​总是以以下方式结束链接命令:

... -Wl,-Bdynamic -ldl -lrt -lm -lpthread
Run Code Online (Sandbox Code Playgroud)

我相信这是我的问题:我想摆脱它-Bdynamic。我缺少什么?这是-Bdynamic来自我的依赖项之一吗?我将它们全部从源代码构建为静态 ( .a) 库,那么它们如何动态链接 libc?或者我需要-static在构建它们时对它们进行全部修补以添加它们吗?

Jon*_*rin 5

As hinted by KamilCuk's comment, the answer here seems to have the solution. Still, I'm not doing exactly the same, therefore I'll keep this answer, too.

For the target executable that I want statically linked:

add_executable(my_executable main.cpp)
Run Code Online (Sandbox Code Playgroud)

I had to set the following properties/options:

set_target_properties(my_executable PROPERTIES LINK_SEARCH_START_STATIC ON)
set_target_properties(my_executable PROPERTIES LINK_SEARCH_END_STATIC ON)

target_link_options(my_executable PRIVATE -static-libgcc -static-libstdc++ -static)
Run Code Online (Sandbox Code Playgroud)

Some notes:

  • LINK_SEARCH_*_STATIC were useful to remove -Bdynamic from the linking command.
  • I never managed to remove -ldl from the linking command, but it seems like dl did not get link eventually (presumably because it is not used).
  • ldd was not enough to verify that my_executable is statically linked. readelf -l my_executable showed that it does not have an INTERP header, and there is currently no such thing as a dynamic binary without it (using musl).
  • It turns out that checking whether a binary is statically linked or not is not so straightforward :-).