且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

即使在PATH中也找不到Docker Alpine可执行二进制文件

更新时间:2023-08-22 16:44:34

在Alpine Linux上,未找到 错误是动态链接失败的典型症状.musl的 ldd 链接程序确实是一个相当令人困惑的错误.

On Alpine Linux, the not found error is a typical symptom of dynamic link failure. It is indeed a rather confusing error by musl's ldd linker.

世界上大多数Linux软件都与GNU libc库(libc) glibc 链接.提供标准的C库和POSIX API).大多数Linux发行版均基于glibc.OTOH,Alpine Linux 基于 musl libc 库,这是一个最小的实现,严格的 POSIX合规.例如,基于glibc发行版构建的可执行文件取决于/lib/x86_64-linux-gnu/libc.so.6 ,而Alpine则不可用(除非它们是静态链接的).

Most of the world Linux software is linked against glibc, the GNU libc library (libc provides the standard C library and POSIX API). Most Linux distributions are based on glibc. OTOH, Alpine Linux is based on the musl libc library, which is a minimal implementation and strictly POSIX compliant. Executables built on glibc distributions depend on /lib/x86_64-linux-gnu/libc.so.6, for example, which is not available on Alpine (unless, they are statically linked).

除了这种依赖关系外,需要特别注意的是,尽管musl试图在某种程度上保持glibc兼容性,但远非完全兼容,而且针对glibc构建的复杂软件也无法与musl-libc一起使用.将/lib/ld-musl-x86_64.so.1 符号链接到glibc路径不太可能.

Except for this dependency, it's important to note that while musl attempts to maintain glibc compatibility to some extent, it is far from being fully compatible, and complex software that's built against glibc won't work with musl-libc, so simply symlinking /lib/ld-musl-x86_64.so.1 to the glibc path isn't likely going to work.

通常,有几种方法可以在Alpine上运行glibc二进制文件:

Generally, there are several ways for running glibc binaries on Alpine:

  1. 安装 libc6兼容性软件包: apk添加libc6-compat .
    该软件包提供了一个轻量级的glibc兼容性层.对于简单的应用程序,这可能就足够了.

  1. Install the libc6 compatibility package: apk add libc6-compat.
    This package provides a light weight glibc compatibility layer. For simple applications, this may be sufficient.

在Alpine上安装适当的glibc,以提供所有glibc方法和功能.有适用于Alpine的glibc构建,应按以下过程安装(示例):

Install proper glibc on Alpine, for providing all glibc methods and functionalities. There are glibc builds available for Alpine, which should be installed in the following procedure (example):

# Source: https://github.com/anapsix/docker-alpine-java

ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
ENV GLIBC_VERSION=2.30-r0

RUN set -ex && \
    apk --update add libstdc++ curl ca-certificates && \
    for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
        do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
    apk add --allow-untrusted /tmp/*.apk && \
    rm -v /tmp/*.apk && \
    /usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib

  1. 使用静态链接的可执行文件.静态可执行文件不带有动态依赖关系,可以在任何Linux上运行.

  1. Use statically linked executables. Static executables don't carry dynamic dependencies and could run on any Linux.

或者,该软件可以从Alpine上的源代码构建.

Alternatively, the software may be built from source on Alpine.

对于LibreDWG,让我们首先验证问题:

For LibreDWG, let's first verify the issue:

/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin
/usr/local/bin # ldd ./dwg2dxf
    /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
    libredwg.so.0 => /usr/local/lib/libredwg.so.0 (0x7fd3744db000)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
Error relocating /usr/local/lib/libredwg.so.0: __strcat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __snprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __memcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __stpcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __printf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __fprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strncat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __sprintf_chk: symbol not found
Error relocating ./dwg2dxf: __snprintf_chk: symbol not found
Error relocating ./dwg2dxf: __printf_chk: symbol not found
Error relocating ./dwg2dxf: __fprintf_chk: symbol not found

您会看到 dwg2dxf 取决于多个glibc符号.现在,让我们按照选项2来安装glibc:

You can see that dwg2dxf depends on several glibc symbols. Now, let's follow option 2 for installing glibc:

/usr/src/app # cd /usr/local/bin
/usr/local/bin # ls
dwg2SVG     dwg2dxf     dwgadd      dwgbmp      dwgfilter   dwggrep     dwglayers   dwgread     dwgrewrite  dwgwrite    dxf2dwg     dxfwrite
/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin # export GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc && \
> export GLIBC_VERSION=2.30-r0 && \
> apk --update add libstdc++ curl ca-certificates && \
> for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
>    do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
> apk add --allow-untrusted /tmp/*.apk && \
> rm -v /tmp/*.apk && \
> /usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
(1/1) Installing curl (7.74.0-r1)
Executing busybox-1.32.1-r3.trigger
OK: 629 MiB in 126 packages
(1/2) Installing glibc (2.30-r0)
(2/2) Installing glibc-bin (2.30-r0)
Executing glibc-bin-2.30-r0.trigger
/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link
OK: 640 MiB in 128 packages
removed '/tmp/glibc-2.30-r0.apk'
removed '/tmp/glibc-bin-2.30-r0.apk'
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link

/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link

中提琴:

/usr/local/bin # ./dwg2dxf

Usage: dwg2dxf [-v[N]] [--as rNNNN] [-m|--minimal] [-b|--binary] DWGFILES...