.NET Native AOT를 정적 라이브러리(.lib 또는 .a) 형태로 빌드할 때 한 애플리케이션 내에 단 하나의 닷넷 정적 라이브러리만 링킹할 수 있는 이유는 기술적인 심볼 충돌런타임 구조 때문입니다.

구체적인 이유는 다음과 같습니다.

  • 독립적인 런타임 사본 포함: .NET Native AOT로 생성된 각 정적 라이브러리는 내부에 가비지 컬렉터(GC), AppDomain, 그리고 필수적인 런타임 심볼들의 독립적인 사본을 각각 포함하고 있습니다.
  • 심볼 충돌(Symbol Collision): 여러 개의 닷넷 정적 라이브러리를 하나의 실행 파일로 합치려고(Linking) 하면, 각 라이브러리가 개별적으로 가지고 있는 내부 런타임 심볼들이 서로 겹치게 되어 충돌이 발생합니다.
  • 단일 런타임 원칙: Native AOT 배포 모델은 **"하나의 프로세스(앱) 내에는 오직 하나의 런타임 인스턴스만 존재해야 한다"**는 설계 원칙을 따릅니다. 정적 라이브러리 방식은 이 원칙을 위배하는 구조가 되기 쉽습니다.
  • 다이아몬드 의존성 문제: 여러 라이브러리가 동일한 런타임의 독립적인 복사본을 각각 포함하여 심볼이 충돌하는 이 현상을 **'다이아몬드 의존성 문제'**라고 부릅니다. 이는 닷넷뿐만 아니라 Go나 Rust와 같은 현대적인 언어에서도 정적 링크 시 발생하는 전형적인 문제입니다.

따라서 여러 개의 닷넷 기능을 독립적인 모듈로 만들어 사용해야 한다면, 정적 라이브러리보다는 심볼 충돌을 피할 수 있는 동적 라이브러리(Windows의 .dll, Linux의 .so 등) 형식을 사용하는 것이 해결책이 될 수 있습니다.

이 상황은 마치 한 배에 두 명의 선장(런타임/GC)이 탈 수 없는 것과 같습니다. 각각의 정적 라이브러리가 배를 조종하는 자신만의 선장을 데리고 오기 때문에, 이를 하나로 묶으려 하면 배의 지휘권(심볼)이 충돌하여 배가 제대로 항해할 수 없게 되는 원리입니다.

Posted by gurupia
,