Zig Libc
(ziglang.org)- 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를 사용해 구현됨
- 목표는 중복된 C 코드를 제거하고,
- 현재까지 약 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의 이런 점을 항상 존경해왔음
-
이게 장기적으로 Zig이 OpenBSD에서 실행되지 않는다는 뜻인가 궁금함
OpenBSD는 직접 syscall을 막고 libc를 통해서만 호출하도록 강제하니까
관련 내용은 이 스레드 참고- 이건 static libc에만 해당됨
-dynamic -lc옵션을 주면 대상 시스템의 libc 함수가 제공됨
macOS처럼 동적 libc만 지원하는 시스템도 있고, OpenBSD는 정적 libc도 지원하는 걸로 알고 있음 - 관련 답변은 여기 참고 가능함
- 이건 static 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 프로젝트에서도 좀 더 독립적인 환경을 만들고 싶음 -
Zig이 1.0 버전에 도달하는 시점이 언제인지 아는 사람 있는지 궁금함
언어에 관심은 많지만, 아직 변화가 많아서 중요한 프로젝트에 쓰기엔 망설여짐- 아무도 정확히는 모름
그래도 Bun, Ghostty, Tigerbeetle 같은 대형 프로덕션 프로젝트들이 잘 따라가고 있음
Zig의 의미론이 단순해서, 버전 업 시에도 컴파일러만 업데이트하고 몇 가지 기계적인 수정만 하면 됨
나를 막는 건 동료들의 채택 의지뿐이라, 일단 내가 혼자 만들 수 있는 프로젝트부터 진행 중임 - 공식적인 1.0 일정은 없음
참고로 이 영상이 흥미로울 수 있음
- 아무도 정확히는 모름