리눅스에서 Avalonia UI 기본 프로젝트 오류

Visual Studio 2022에 Avalonia 확장을 설치하고 Avalonia C# Project를 생성했습니다.
추가 코딩을 아무것도 하지 않고 기본으로 생성된 프로젝트를 win-x64로 publish하여 windows에서 실행하면 정상적으로 실행이됩니다.
그러나 linux-x64로 publish하여 Linux에서 실행하니 다음과 같은 오류가 발생합니다.

jd@raspberry:~/Desktop/av $ ./AvaloniaApplication1.Desktop 
Unhandled exception. System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception.
 ---> System.DllNotFoundException: Unable to load shared library 'libSkiaSharp' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable: 
libfontconfig.so.1: cannot open shared object file: No such file or directory
libSkiaSharp.so: cannot open shared object file: No such file or directory
/home/jd/Desktop/av/liblibSkiaSharp.so: cannot open shared object file: No such file or directory
/home/jd/Desktop/av/libSkiaSharp: cannot open shared object file: No such file or directory
/home/jd/Desktop/av/liblibSkiaSharp: cannot open shared object file: No such file or directory

   at SkiaSharp.SkiaApi.sk_colortype_get_default_8888()
   at SkiaSharp.SKImageInfo..cctor()
   --- End of inner exception stack trace ---
   at Avalonia.Skia.PlatformRenderInterface..ctor(Nullable`1 maxResourceBytes) in /_/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs:line 25
   at Avalonia.Skia.SkiaPlatform.Initialize(SkiaOptions options) in /_/src/Skia/Avalonia.Skia/SkiaPlatform.cs:line 20
   at Avalonia.SkiaApplicationExtensions.<>c.<UseSkia>b__0_0() in /_/src/Skia/Avalonia.Skia/SkiaApplicationExtensions.cs:line 19
   at Avalonia.AppBuilder.SetupUnsafe() in /_/src/Avalonia.Controls/AppBuilder.cs:line 314
   at Avalonia.AppBuilder.Setup() in /_/src/Avalonia.Controls/AppBuilder.cs:line 303
   at Avalonia.AppBuilder.SetupWithLifetime(IApplicationLifetime lifetime) in /_/src/Avalonia.Controls/AppBuilder.cs:line 187
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 219
   at AvaloniaApplication1.Desktop.Program.Main(String[] args) in D:\03.Test\AvaloniaUITest\ForQnA\AvaloniaApplication1.Desktop\Program.cs:line 13
Stopped

Linux에서 C#으로 UI작업이 필요해서 AvaloniaUI를 사용해보려고 하는데 시작부터 안되니 조금 황당합니다.
어떻게 해결해야 하는지 또는 제가 무엇을 잘못했는지 도움 부탁드립니다.
참고로 아래는 저의 Linux 환경입니다.

jd@raspberry:~ $ sudo hostnamectl
   Static hostname: raspberry
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 15599edde58640e29d161a13ab23d8c2
           Boot ID: 705e7b34f0154571af8ea1789940c91f
    Virtualization: vmware
  Operating System: Debian GNU/Linux 11 (bullseye)
            Kernel: Linux 5.10.0-15-amd64
      Architecture: x86-64

대상 머신에 프로젝트를 배포하실때 Publish를 통해 배포를 하셨나요?

image

일반적인 경우 위와 같이 Publish를 통해 배포를 하면 Target rumtime에 대한 Dependency가 있는 라이브러리가 함께 포함됩니다.
그런데 로그에서 SkiaSharp관련 라이브러리가 배포되지 않은 것으로 나타납니다.
Target runtime이 linux-arm64인지 한번 확인해 보세요.

1개의 좋아요

답변 감사드립니다.

image
위와 같이 publish 하여 실행하니 질문과 같은 오류가 발생하였습니다.

@al6uiz 님이 알려주신것처럼 아래와 같이 publish 하니 다른 오류가 발생합니다.
image

jd@raspberry:~/Desktop/av $ ./AvaloniaApplication1.Desktop 
aarch64-binfmt-P: Could not open '/lib/ld-linux-aarch64.so.1': No such file or directory

아! 호스트 이름이 raspberry이고 OS가 Debian이라 타겟 플랫폼이 arm64 베이스의 Raspberry Pi OS인줄 알았네요.

jd@raspberry:~ $ sudo hostnamectl
   Static hostname: raspberry
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 15599edde58640e29d161a13ab23d8c2
           Boot ID: 705e7b34f0154571af8ea1789940c91f
    Virtualization: vmware
  Operating System: Debian GNU/Linux 11 (bullseye)
            Kernel: Linux 5.10.0-15-amd64
      Architecture: x86-64

Architecture가 x86-64이면 linux-x64가 맞는 것 같습니다.

처음 질문에 있는 libSkiaSharp.so 파일은 보통 배포 폴더의 runtimes\linux-x64\native 폴더 안에 위치합니다.
해당 파일이 있는지 확인해보십시오.

(추가)
libSkiaSharp.so에 Dependency가 있는 libfontconfig1 패키지를 수동으로 한번 설치해 보십시오.

publish 폴더에는 libSkiaSharp.so 파일이 있습니다.
그러나 libfontconfig.so.1 파일은 없습니다.
sudo apt-get install -y libfontconfig1을 실행하면 이미 설치되어 있다고 메시지가 나옵니다.

OS는 VM에 Debian Bullseye with Raspberry Pi Desktop을 설치했습니다.

관련된 오류를 재현할수 있는 환경은 아니라 정확하지는 않지만

관련 오류로 검색하셔서 패키지를 설치해보시겠어요?

OS는 linux-x64 환경이 맞는것 같습니다.
linux-arm64로 publish하면 ld-linux-aarch64.so.1 관련 오류가 발생하며, ld-linux-aarch64.so.1관련 패키지를 설치하면 설치중에 의존성 문제로 설치가 실패합니다.

우선 의존성 관련 패키지를 모두 설치했습니다.
패키지를 amd64로 설치하니까 의존성 오류가 해결되더군요.

그런데 다른 오류가 발생했습니다.

jd@raspberry:~/Desktop $ ./AvaloniaApplication1.Desktop 
Unhandled exception. System.InvalidOperationException: Default font family name can't be null or empty.
   at Avalonia.Media.FontManager..ctor(IFontManagerImpl platformImpl) in /_/src/Avalonia.Base/Media/FontManager.cs:line 37
   at Avalonia.Media.FontManager.get_Current() in /_/src/Avalonia.Base/Media/FontManager.cs:line 59
   at Avalonia.AppBuilder.<>c__DisplayClass62_0.<ConfigureFonts>b__0(AppBuilder appBuilder) in /_/src/Avalonia.Controls/AppBuilder.cs:line 269
   at Avalonia.AppBuilder.SetupUnsafe() in /_/src/Avalonia.Controls/AppBuilder.cs:line 322
   at Avalonia.AppBuilder.Setup() in /_/src/Avalonia.Controls/AppBuilder.cs:line 303
   at Avalonia.AppBuilder.SetupWithLifetime(IApplicationLifetime lifetime) in /_/src/Avalonia.Controls/AppBuilder.cs:line 187
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 219
   at AvaloniaApplication1.Desktop.Program.Main(String[] args) in D:\AvaloniaApplication1\AvaloniaApplication1.Desktop\Program.cs:line 13
Stopped

Default Font가 설치되어 있지 않아서 오류가 발생하는 것 같은데…
Avalonia UI에서는 어느 Font를 Default로 사용하나요?
어떤 Font를 설치해야 오류가 해결될까요?
그리고, Default Font가 설치되어 있지 않으면 다른 대체 Font로 사용하도록 하려면 프로그램의 어느부분을 수정해야 하는지요?

Avalonia 버전이 어떻게 되어요?

일단은 버전과 상관없이 리눅스 로케일을 영어권으로 하면 실행이 되실꺼에요.

한글일 경우 대체 폰트를 직접 적용해야 했던 것으로 기억합니다.

Avalonia UI 버전은 11.0.0 입니다.
리눅스 로케일을 영어로 변경하니 정상적으로 실행되었습니다.
한글을 사용하기 위해서는 어떻게 폰트 설정을 해야 하는지 알 수 있을까요?

var options = new FontManagerOptions();
if (Environment.OSVersion.Platform== PlatformID.Unix)
{
    options.DefaultFamilyName = "NamumGothic";
}
return AppBuilder.Configure<App>().UsePlatformDetect().With(options);

저는 영문 로캘 리눅스에서만 사용해왔어서 해당 문제가 발생하지 않았는데요, 위와 같이 Main() 함수의 AppBuilder 부분에 With()함수를 이용해 FontManagerOptions.DefaultFamilyName 속성을 지정해주니 한글 로캘에서도 정상 동작하는 것 같습니다.

관련 답변 링크 System.InvalidOperationException: Default font family name can't be null or empty · Issue #4427 · AvaloniaUI/Avalonia · GitHub

2개의 좋아요

프로젝트에 Assets 폴더 하위에 Fonts 폴더를 만들고 ttf 파일들을 추가했습니다.
프로젝트 파일에는 다음과 같이 추가했습니다.

<ItemGroup>
	<AvaloniaResource Include="Assets\**" />
</ItemGroup>

Program.cs에 다음과 같이 추가했습니다.

return AppBuilder.Configure<App>()
		.UsePlatformDetect()
		.LogToTrace()
		.With(new FontManagerOptions
		{
			DefaultFamilyName = "avares://AvaloniaApplication1.Desktop/Assets/Fonts#NotoSansKR",
			FontFallbacks = new[]
			{
				new FontFallback
				{
					FontFamily = new Avalonia.Media.FontFamily("avares://AvaloniaApplication1.Desktop/Assets/Fonts#NotoSansKR")
				}
			}
		});

위와 같이 수정했는데… 프로그램 실행 중 오류가 발생합니다. 폰트를 찾지 못하는것 같은데요.

아래는 제가 참고한 사이트입니다. 어느 부분이 잘못되었을까요?
AvaloniaUI.QuickGuides
[preview6] Default font family name can’t be null or empty #11084
System.InvalidOperationException: Default font family name can’t be null or empty #4427

1개의 좋아요

일단 어셈블리 리소스로 ttf폰트를 로드하는 것 보다 그냥 시스템상의 한국어 폰트 이름을 먼저 넣어보시죠.
저는 GNOME 기준 시스템 메뉴의 ‘글꼴’ 메뉴에서 나타나는 폰트 이름을 그대로 넣었습니다.

image

한글 폰트가 뭔지 잘 모르시겠다면 그냥 나눔고딕으로 설치하셔도 될 듯 합니다.

apt-get install fonts-nanum

1개의 좋아요

아래와 같이 수정하여 해결했습니다.

return AppBuilder.Configure<App>()
		.UsePlatformDetect()
		.LogToTrace()
		.With(new FontManagerOptions
		{
			DefaultFamilyName = "avares://AvaloniaApplication1.Desktop/Assets/Fonts#Noto Sans KR",
			FontFallbacks = new[]
			{
				new FontFallback
				{
					FontFamily = new Avalonia.Media.FontFamily("avares://AvaloniaApplication1.Desktop/Assets/Fonts#Noto Sans KR")
				}
			}
		});

그동안 도움 주신 @al6uiz@dimohy 님. 너무 감사드립니다.

5개의 좋아요