(AI의 도움을 받아 작성한 답변입니다. 해당 주제에 대해 더 많은 의견을 남겨주시는 것을 환영합니다!)
Linux에서 OpenCvSharp 네이티브 라이브러리 의존성 문제에 대하여
겪고 계신 문제의 핵심은, OpenCvSharp4.runtime.ubuntu.22.04-x64 NuGet 패키지가 포함하는 네이티브 바이너리(libOpenCvSharpExtern.so)가 특정 버전의 시스템 라이브러리(libtesseract, libtiff, libpng 등)에 링크되어 빌드되어 있다는 점입니다. 배포 대상 Linux 환경의 라이브러리 버전이 패키지 빌드 시점과 다르면 DllNotFoundException이나 링커 오류가 발생합니다.
몇 가지 접근 방법을 정리해 드립니다.
1. Docker 컨테이너로 런타임 환경 고정
가장 확실한 방법입니다. ubuntu:22.04 기반 이미지 위에서 필요한 네이티브 패키지를 설치하고 앱을 실행하면, NuGet 런타임 패키지가 기대하는 라이브러리 버전과 정확히 일치시킬 수 있습니다.
FROM mcr.microsoft.com/dotnet/runtime:8.0-jammy
RUN apt-get update && apt-get install -y --no-install-recommends \
libgdiplus \
libtesseract-dev \
libtiff-dev \
libpng-dev \
libjpeg-dev \
libopencv-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY publish/ .
ENTRYPOINT ["dotnet", "YourApp.dll"]
Avalonia UI 앱이라 GUI가 필요하신 상황이겠지만, X11 포워딩이나 Wayland 소켓 마운트로 컨테이너 안에서도 GUI 실행이 가능합니다. 다만 이 방식이 배포 환경에 맞지 않는다면 아래 방법들을 고려해 보십시오.
2. 시스템 OpenCV를 직접 빌드하고 P/Invoke 경로 지정
NuGet 런타임 패키지에 의존하지 않고, 대상 Linux 환경에서 OpenCV와 OpenCvSharp의 네이티브 래퍼를 직접 빌드하는 방법입니다.
-
OpenCvSharp4와 OpenCvSharp4.Extensions NuGet 패키지만 설치하고, runtime 패키지는 제거합니다.
-
대상 환경에서 libopencv-dev를 설치하거나 OpenCV를 소스 빌드합니다.
-
OpenCvSharp GitHub 저장소의 네이티브 소스(OpenCvSharpExtern)를 CMake로 빌드하여 libOpenCvSharpExtern.so를 직접 생성합니다.
-
빌드된 .so 파일을 앱의 출력 디렉터리에 배치하거나 LD_LIBRARY_PATH로 경로를 지정합니다.
이렇게 하면 시스템에 설치된 라이브러리 버전과 네이티브 래퍼가 동일한 환경에서 빌드되므로 버전 불일치가 원천적으로 해소됩니다. 빌드 과정이 추가되지만 가장 깔끔한 해결책입니다.
3. 조건부 RuntimeIdentifier로 패키지 분기
Windows와 Linux 모두 지원해야 한다면, 프로젝트 파일에서 RID 기반 조건부 참조를 설정할 수 있습니다.
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'win-x64'">
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.*" />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
<!-- runtime 패키지 제거, 직접 빌드한 .so를 번들 -->
<None Include="native/linux-x64/libOpenCvSharpExtern.so"
CopyToOutputDirectory="PreserveNewest" Link="libOpenCvSharpExtern.so" />
</ItemGroup>
이렇게 하면 dotnet publish -r linux-x64시에는 직접 빌드한 네이티브 바이너리가, Windows에서는 NuGet 런타임 패키지가 사용됩니다.
4. Emgu CV 고려
OpenCvSharp 외에 Emgu CV라는 대안도 있습니다. Emgu CV는 자체적으로 네이티브 바이너리를 NuGet 패키지에 포함하는 방식이 좀 더 성숙되어 있고, Linux 런타임 지원도 비교적 안정적입니다. 다만 상용 라이선스(듀얼 라이선스)인 점은 확인이 필요합니다. 프로젝트 초기 단계라면 검토해 볼 만합니다.
요약하면, NuGet 런타임 패키지만으로 Linux에서 "just works"를 기대하기 어려운 것이 현재 OpenCvSharp 생태계의 현실입니다. 실무적으로는 Docker로 런타임 환경을 고정하거나, 네이티브 래퍼를 대상 환경에서 직접 빌드하는 두 가지가 가장 많이 쓰이는 방법입니다.
추가로 궁금하신 점이 있으시면 이어서 질문해 주세요.