跨多个环境动态链接 Boost



所以我正在尝试为二进制文件设置一个运行 docker 环境。 我正在尝试使运行 docker 映像尽可能小。 二进制依赖于提升,并使用 cmake 构建

克马克

cmake_minimum_required(VERSION 3.15)
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_ALL_DYN_LINK)
set(Boost_NO_BOOST_CMAKE ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.70.0 REQUIRED COMPONENTS locale exception serialization system timer regex
thread program_options chrono filesystem iostreams)
include_directories(${Boost_INCLUDE_DIRS} SYSTEM)

提升取自源码压缩包,并构建为相当新的。 我使用我的本地机器构建(它可以执行二进制文件没有问题(。 然后,我构建了一个 docker 映像,我还在其中从源代码安装/构建 boost,并将二进制文件从本地计算机复制到 docker 中。

当我在 docker 中执行时,我在运行二进制文件时缺少符号。

在 Docker 内部 - 二进制运行

root@200f0fb753fc:/opt/bin# ./run_bin
./run_bin: symbol lookup error: ./run_bin: undefined symbol: _ZN5boost9iostreams4zlib6finishE

我可以看到它可以很好地找到正确的共享对象文件

内部码头工人 - ldd

root@200f0fb753fc:/opt/bin# ldd ./run_bin
linux-vdso.so.1 (0x00007ffd54576000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd02fb46000)
libssl.so.1.1 => /usr/lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007fd02f8b9000)
libcrypto.so.1.1 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007fd02f3ee000)
libboost_regex.so.1.70.0 => /usr/lib/libboost_regex.so.1.70.0 (0x00007fd02f131000)
libboost_thread.so.1.70.0 => /usr/lib/libboost_thread.so.1.70.0 (0x00007fd02ef0d000)
libboost_filesystem.so.1.70.0 => /usr/lib/libboost_filesystem.so.1.70.0 (0x00007fd02ecf1000)
libboost_iostreams.so.1.70.0 => /usr/lib/libboost_iostreams.so.1.70.0 (0x00007fd02eae2000)
libboost_date_time.so.1.70.0 => /usr/lib/libboost_date_time.so.1.70.0 (0x00007fd02e8d0000)
libaerospike.so => /usr/lib/libaerospike.so (0x00007fd02e61c000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd02e293000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd02e07b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd02dc8a000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd0304dc000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd02da86000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd02d6e8000)

root@200f0fb753fc:/opt/bin# find / -name "libboost_iostreams.so.1.70.0"
/usr/lib/libboost_iostreams.so.1.70.0

是否可以在 cmake 上设置一个选项以允许在另一个环境中运行它?

还是我试图做的事情从根本上是错误的?

我知道在小型 docker 映像中构建二进制文件的最简单解决方案是使用带有 alpine 容器的多阶段构建Dockerfile

使用multi-stage build您的Dockerfile可以使用二进制文件在一个(大的"臃肿"(映像中使用cmake和二进制文件所依赖的任何库来构建二进制文件,然后只需将可执行文件及其所需的任何文件复制到干净(小(alpine映像中。例如:

Dockerfile

FROM alpine:3.10 AS build
# Load build packages
RUN apk --update add --no-cache 
build-base 
cmake 
boost boost-dev
# The cmake boost variables
ENV BOOST_INCLUDEDIR /usr/include
ENV BOOST_LIBRARYDIR /usr/lib
WORKDIR /opt
COPY . <project-name>
WORKDIR /opt/<project-name>
RUN mkdir build 
&& cd build 
&& cmake 
-DBOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} 
-DBOOST_LIBRARYDIR=${BOOST_LIBRARYDIR} 
-DCMAKE_BUILD_TYPE=Release 
..
&& make
# Create a clean alpine image for the binary
FROM alpine:3.10
# Copy the binary into the clean alpine image
COPY --from=build /opt/<project-name>/build/<binary-name> /bin/<binary-name>
# Copy the required library files into the clean alpine image
COPY --from=build /usr/lib/<library-names>.* /usr/lib/
# Run binary on entry
ENTRYPOINT ["/bin/<binary-name>"]

构建命令

docker build . -t <image-name>:<ver>

Docker 创建两个映像:它构建二进制文件的大型映像和仅包含二进制文件及其依赖项的较小(标记(映像。

注意:alpine:3.10apkboost1.69.0 库中安装。
您可能需要在第一个映像中生成所需的特定版本的boost,并将相关的.so文件复制到第二个映像。

最新更新