1P by GN⁺ 2일전 | ★ favorite | 댓글 1개
  • Zig 언어는 libc 기능을 Zig 표준 라이브러리로 직접 구현하는 방향으로 전환 중이며, 기존 C 소스 코드를 점진적으로 제거 중임
  • 현재까지 약 250개의 C 소스 파일이 삭제되었고, 2032개가 남아 있음
  • 이 전환으로 컴파일 속도 향상, 설치 크기 감소, 정적 링크 시 바이너리 크기 축소 등의 효과가 발생
  • 최근 개선으로 zig libc가 별도 정적 아카이브가 아닌 Zig 컴파일 유닛(ZCU) 내에서 다른 코드와 함께 최적화되어 중복 코드 제거 및 LTO 수준의 최적화 가능
  • Zig이 자체 정적 libc 제공자로 전환함에 따라, 관련 문제 발생 시 Zig 프로젝트에 직접 버그 리포트 제출이 필요함

Zig libc 프로젝트 개요

  • 여러 기여자들이 zig libc 서브프로젝트에 참여해, 기존 C 기반 libc 구현을 Zig 표준 라이브러리 래퍼로 대체 중
    • 목표는 중복된 C 코드를 제거하고, memcpy, atan2 등 단순 매핑 함수나 strnlen처럼 일반 함수 래핑 형태로 제공
    • 예시로 strnlen 함수는 Zig의 std.mem.findScalar를 사용해 구현됨
  • 현재까지 약 250개의 C 소스 파일이 삭제, 2032개가 남아 있음

성능 및 구조적 개선

  • 각 함수가 Zig로 전환될수록 외부 프로젝트 및 C 언어 의존성 감소
    • 컴파일 속도 향상, 설치 크기 단순화 및 축소, 정적 링크된 사용자 애플리케이션의 바이너리 크기 감소 효과 발생
  • 최근 변경으로 zig libc가 Zig Compilation Unit(ZCU) 내에서 다른 Zig 코드와 함께 컴파일됨
    • 별도의 정적 아카이브로 링크하지 않고, 컴파일러와 링커의 통합 구조를 활용
    • 이로 인해 중복 코드 제거 및 함수 간 최적화 가능
    • 이는 링크 타임 최적화(LTO) 와 유사하지만, 링커 단계가 아닌 프런트엔드 단계에서 수행

향후 확장 가능성

  • 최근의 std.Io 변경사항과 결합될 경우, libc의 I/O 동작을 사용자가 제어할 가능성 존재
    • 예: read, write 호출을 io_uring 이벤트 루프에 통합
    • 리소스 누수 탐지 기능을 서드파티 C 코드에도 적용 가능
    • 다만 현재는 실험되지 않은 아이디어 단계

테스트 및 품질 보증

  • Szabolcs Nagy의 libc-test 프로젝트가 수학 함수 회귀 방지에 큰 도움을 제공
    • 이 테스트 세트로 Zig libc의 정확성을 검증

사용자 안내

  • Zig이 musl, mingw-w64, wasi-libc 기능을 자체 제공하는 단계로 전환 중
    • 관련 문제 발생 시 Zig 프로젝트에 직접 버그 리포트 제출 필요
    • 이는 기존 독립 libc 프로젝트 유지보수자에게 잘못된 이슈가 전달되는 것을 방지하기 위함

마무리

  • 글의 마지막 문장은 “Abolish ICE”로 마무리됨 (추가 설명 없음)
Hacker News 의견들
  • C 파일 250개가 삭제되었고, 이제 2032개가 남았음
    Zig이 libc를 내부에서부터 대체해가는 과정을 지켜보는 건 장기적으로 꽤 짜릿한 프로젝트임

    • Zig의 이런 점을 항상 존경해왔음
      많은 언어들이 C의 대체를 주장하지만, 실제로 C ABI와 빌드 시스템을 자연스럽게 통합한 건 Zig이 거의 유일했음
      translate-c 기능도 놀라울 정도로 잘 작동함
      C++처럼 99% 호환성을 유지하려 하지 않고, C의 단순함을 살리면서 언어의 함정을 피한 선택이 더 현명했다고 생각함
  • 이게 장기적으로 Zig이 OpenBSD에서 실행되지 않는다는 뜻인가 궁금함
    OpenBSD는 직접 syscall을 막고 libc를 통해서만 호출하도록 강제하니까
    관련 내용은 이 스레드 참고

    • 이건 static libc에만 해당됨
      -dynamic -lc 옵션을 주면 대상 시스템의 libc 함수가 제공됨
      macOS처럼 동적 libc만 지원하는 시스템도 있고, OpenBSD는 정적 libc도 지원하는 걸로 알고 있음
    • 관련 답변은 여기 참고 가능함
  • Zig 프로젝트가 C 라이브러리를 링크할 때 매우 흥미로운 변화임
    하지만 MinGW를 사용하는 Windows용 C 프로그램을 Zig로 교차 컴파일할 때, 여전히 MinGW의 libc를 정적으로 링크할 수 있는지 궁금함

    • 이 경우는 변경 없음
      -target x86_64-windows-gnu -lc를 지정하면 일부 libc 함수는 Zig이, 일부는 vendored mingw-w64가 제공함
      별도의 mingw-w64 설치 없이 Zig이 모든 걸 제공함
      원한다면 --libc libc.txt로 외부 libc를 직접 지정할 수도 있음
  • 멋진 아이디어이긴 하지만, 포팅된 코드에 대해 glibc나 musl의 CVE 취약점을 계속 추적해야 하는지 걱정됨

    • 이미 표준 라이브러리에서도 같은 일을 하고 있음
      수학 같은 공유 코드 경로에서는 오히려 잠재적 버그가 줄어듦
  • “libc 경계를 넘어 LTO를 활성화하는 것과 비슷하지만, 링커가 아니라 프런트엔드에서 제대로 수행된다”는 설명이 있었는데
    왜 링커 단계에서는 너무 늦은 건지, Zig이 LLVM IR 수준의 링커보다 더 많은 최적화를 할 수 있는지 궁금함

    • 프런트엔드에서는 인라이닝과 데드 코드 제거가 가능함
      최적화된 정적 라이브러리에서는 링크 타임에 이런 최적화가 어렵기 때문임
  • 최근 std.Io 변경과 결합되면, libc의 I/O 동작을 사용자가 직접 제어할 수 있다는 점이 흥미로움
    예를 들어 모든 read/write 호출을 io_uring 이벤트 루프에 참여시키는 식으로
    나는 개인적으로 kqueue 쪽에 더 관심이 있지만, 이 인용문이 그쪽에도 적용될 것 같음

  • libc에는 무서운 부분이 많지만, 이건 정말 흥미로운 프로젝트임

    • 물론 유용한 함수들도 있음
      예를 들어 "memfrob"이나 "strfry" 같은 것들인데, 농담이지만 이런 건 glibc에만 있음 :)
  • Rust에도 이런 게 있는지 궁금함
    Zig vs Rust 논쟁을 하려는 건 아니고, Rust 프로젝트에서도 좀 더 독립적인 환경을 만들고 싶음

    • Rust에도 몇 가지 libc 구현이 있음
      • c-ward: Rust로 작성된 libc 구현
      • relibc: Redox OS용이지만 Linux에서도 작동
      • rustix: C를 사용하지 않고 POSIX API에 안전하게 바인딩함
  • Zig이 1.0 버전에 도달하는 시점이 언제인지 아는 사람 있는지 궁금함
    언어에 관심은 많지만, 아직 변화가 많아서 중요한 프로젝트에 쓰기엔 망설여짐

    • 아무도 정확히는 모름
      그래도 Bun, Ghostty, Tigerbeetle 같은 대형 프로덕션 프로젝트들이 잘 따라가고 있음
      Zig의 의미론이 단순해서, 버전 업 시에도 컴파일러만 업데이트하고 몇 가지 기계적인 수정만 하면 됨
      나를 막는 건 동료들의 채택 의지뿐이라, 일단 내가 혼자 만들 수 있는 프로젝트부터 진행 중임
    • 공식적인 1.0 일정은 없음
      참고로 이 영상이 흥미로울 수 있음