Linux Docker 中的 CMake Lib 缺少依赖项
CMake Lib in Linux Docker missing dependencies
我使用 CMake 从我自己的 C++ 库创建 DLL 和 SO 文件,然后我通过 DLLImport 在我的 C# 代码中调用它们。到目前为止,这在 Windows 和 Linux (Docker) 下有效。现在库已经扩展,它继续使用 DLL 在 Windows 上工作。但是,在 Linux 下,我现在在调用 DLL 函数时收到以下错误消息:
Unable to load shared library 'CustomLib' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libCustomLib: cannot open shared object file: No such file or directory
因为它之前在 Linux 下工作,我认为它应该找到库,因此依赖项是问题所在。但现在我不知道如何进行。
同事帮我分析了一下,得到以下信息
root@f266455d4988:/app# LD_DEBUG=all /app/libCustomLib.so
Segmentation fault
root@f266455d4988:/app# ldd ./libCustomLib.so
linux-vdso.so.1 (0x00007ffc9d983000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f05720a5000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f057208b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0571eca000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0571d47000)
/lib64/ld-linux-x86-64.so.2 (0x00007f05722d8000)
root@f266455d4988:/app#
我正在使用 .NET 5.0 和 GCC 编译器
CMake 配置
"name": "Linux-GCC-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"cmakeExecutable": "cmake",
"remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "linux_x64" ],
"remoteMachineName": "${defaultRemoteMachineName}",
"remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src",
"remoteBuildRoot": "$HOME/${projectDirName}/${name}",
"remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}",
"remoteCopySources": true,
"rsyncCommandArgs": "-t --delete --delete-excluded",
"remoteCopyBuildOutput": false,
"remoteCopySourcesMethod": "rsync",
"addressSanitizerRuntimeFlags": "detect_leaks=0"
CMakeLists.txt
cmake_minimum_required (VERSION 3.8)
include_directories(${CMAKE_SOURCE_DIR}/CustomLib/xyz)
include_directories(${CMAKE_SOURCE_DIR}/CustomLib/xxx)
link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
file(GLOB headers *.h)
file(GLOB headers *.hpp)
add_library (CustomLib SHARED CustomLib.cpp
...
${headers})
add_executable (CustomLibExe CustomLib.cpp
${headers})
target_compile_features(CustomLib PUBLIC cxx_std_17)
target_compile_features(CustomLibExe PUBLIC cxx_std_17)
target_compile_options (CustomLib PUBLIC -fexceptions)
target_compile_options (CustomLibExe PUBLIC -fexceptions)
Docker文件
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["testAPI/testAPI.csproj", "testAPI/"]
RUN dotnet restore "testAPI/testAPI.csproj"
COPY . .
WORKDIR "/src/testAPI"
RUN dotnet build "testAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "testAPI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "testAPI.dll"]
api-docker的一部分-撰写
test_api:
image: ${DOCKER_REGISTRY-}testapi
container_name: testapi
build:
context: .
dockerfile: testAPI/Dockerfile
networks:
- test_network
depends_on:
- test_sql
environment:
LD_LIBRARY_PATH: "/app"
#LD_LIBRARY_PATH: "/lib/x86_64-linux-gnu"
ports:
- "5000:80"
我们已经解决了这个问题。原因是后端 运行 与构建 DLL/SO 的 Linux 不同 Linux 发行版 (Debian) (Ubuntu)。
我将 dockerfile 中的图像从 ...:5.0 更改为 ...:5.0-focal Ubuntu。
FROM mcr.microsoft.com/dotnet/aspnet:5.0-focal AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS build
WORKDIR /src
我使用 CMake 从我自己的 C++ 库创建 DLL 和 SO 文件,然后我通过 DLLImport 在我的 C# 代码中调用它们。到目前为止,这在 Windows 和 Linux (Docker) 下有效。现在库已经扩展,它继续使用 DLL 在 Windows 上工作。但是,在 Linux 下,我现在在调用 DLL 函数时收到以下错误消息:
Unable to load shared library 'CustomLib' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libCustomLib: cannot open shared object file: No such file or directory
因为它之前在 Linux 下工作,我认为它应该找到库,因此依赖项是问题所在。但现在我不知道如何进行。
同事帮我分析了一下,得到以下信息
root@f266455d4988:/app# LD_DEBUG=all /app/libCustomLib.so
Segmentation fault
root@f266455d4988:/app# ldd ./libCustomLib.so
linux-vdso.so.1 (0x00007ffc9d983000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f05720a5000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f057208b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0571eca000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0571d47000)
/lib64/ld-linux-x86-64.so.2 (0x00007f05722d8000)
root@f266455d4988:/app#
我正在使用 .NET 5.0 和 GCC 编译器
CMake 配置
"name": "Linux-GCC-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"cmakeExecutable": "cmake",
"remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "linux_x64" ],
"remoteMachineName": "${defaultRemoteMachineName}",
"remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src",
"remoteBuildRoot": "$HOME/${projectDirName}/${name}",
"remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}",
"remoteCopySources": true,
"rsyncCommandArgs": "-t --delete --delete-excluded",
"remoteCopyBuildOutput": false,
"remoteCopySourcesMethod": "rsync",
"addressSanitizerRuntimeFlags": "detect_leaks=0"
CMakeLists.txt
cmake_minimum_required (VERSION 3.8)
include_directories(${CMAKE_SOURCE_DIR}/CustomLib/xyz)
include_directories(${CMAKE_SOURCE_DIR}/CustomLib/xxx)
link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
file(GLOB headers *.h)
file(GLOB headers *.hpp)
add_library (CustomLib SHARED CustomLib.cpp
...
${headers})
add_executable (CustomLibExe CustomLib.cpp
${headers})
target_compile_features(CustomLib PUBLIC cxx_std_17)
target_compile_features(CustomLibExe PUBLIC cxx_std_17)
target_compile_options (CustomLib PUBLIC -fexceptions)
target_compile_options (CustomLibExe PUBLIC -fexceptions)
Docker文件
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["testAPI/testAPI.csproj", "testAPI/"]
RUN dotnet restore "testAPI/testAPI.csproj"
COPY . .
WORKDIR "/src/testAPI"
RUN dotnet build "testAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "testAPI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "testAPI.dll"]
api-docker的一部分-撰写
test_api:
image: ${DOCKER_REGISTRY-}testapi
container_name: testapi
build:
context: .
dockerfile: testAPI/Dockerfile
networks:
- test_network
depends_on:
- test_sql
environment:
LD_LIBRARY_PATH: "/app"
#LD_LIBRARY_PATH: "/lib/x86_64-linux-gnu"
ports:
- "5000:80"
我们已经解决了这个问题。原因是后端 运行 与构建 DLL/SO 的 Linux 不同 Linux 发行版 (Debian) (Ubuntu)。
我将 dockerfile 中的图像从 ...:5.0 更改为 ...:5.0-focal Ubuntu。
FROM mcr.microsoft.com/dotnet/aspnet:5.0-focal AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS build
WORKDIR /src