I use CMake to create the DLL and SO file from my own C++ library, which I then call in my C# code via DLLImport. This has worked so far under Windows and under Linux (Docker). Now the library has been extended, which continues to work on Windows with the DLL. However, under Linux I now get the following error message when calling a DLL function:
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
Since it worked before under Linux I think it should find the library and therefore the dependencies are the problem. But now I don’t know how to proceed.
A colleague helped me with the analysis and I got the following information
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#
I’m using .NET 5.0 and the GCC-compiler
CMake-configuration
"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)
Dockerfile
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-part of docker-compose
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"
Advertisement
Answer
We have solved the problem. The reason was that the backend was running a different Linux distribution (Debian) than the Linux in which the DLL/SO was built (Ubuntu).
I changed the image in the dockerfile from …:5.0 to …:5.0-focal for 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