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