Lobsters

Zig 0.17.0 Release Notes

Zig 0.17.0 출시 — 빌드 시스템 재구성과 증분 컴파일 개선

Zig 0.17.0은 5개월 동안 206명의 기여자가 만든 925개 커밋을 담은 릴리스입니다. 빌드 시스템을 재구성하고 Build Server Protocol을 도입했으며, x86_64 Linux 프로젝트에서 증분 컴파일을 활용할 수 있도록 ELF 링커를 개선했습니다.

AI 요약

Zig 0.17.0에는 5개월 동안 206명의 기여자가 만든 925개 커밋이 들어갔습니다. 이번 릴리스는 빌드 시스템 재구성, Build Server Protocol 도입, ELF 링커 개선을 중심으로 진행됐습니다. 언어 설계를 안정화하는 작업도 이어져 제안 약 25개를 채택하고 약 125개를 거부했습니다. 아직 결정되지 않은 제안은 Codeberg에 23개, 기존 GitHub 이슈 트래커에 61개 남아 있습니다.

빌드 시스템과 Build Server Protocol

zig build는 이제 빌드 스크립트를 실행하는 configurer와 빌드 그래프를 실행하는 maker를 별도 프로세스로 나눕니다. build.zig를 수정해도 maker 실행 파일을 다시 만들 필요가 없어지고, 빌드 설정을 컴팩트한 바이너리 형식으로 직렬화합니다. 설정이 같으면 configurer를 건너뛸 수 있도록 캐시를 관리하며, 캐시 적중 속도는 5~10% 빨라졌습니다. 캐시 적중이 실패한 이유를 설명하는 기능도 추가했습니다.

빌드 설정 과정에서 파일이나 디렉터리를 확인하는 동작은 캐시 결과에 영향을 줄 수 있습니다. dependOnFileContents, dependOnFileMetadata, dependOnDirectoryContents, dependOnDirectoryMetadata로 설정이 의존하는 대상을 명시할 수 있습니다. 실행 파일을 설정 단계에서 직접 찾는 findProgram은 설정 캐시를 무효화할 수 있으며, 실행 단계에서만 찾는 findProgramLazy는 캐시를 오염시키지 않습니다.

--listen=-을 지정하면 빌드 시스템이 Build Server Protocol을 제공해 외부 클라이언트가 빌드 그래프를 관찰하고 제어할 수 있습니다. IDE 같은 도구가 빌드 상태와 설정을 다루도록 마련한 인터페이스입니다. 프로세스 분리와 빌드 시스템 변경으로 Zig Language Server(ZLS)는 0.17.0에서 기존 기능을 사용할 수 없습니다. Zig 팀과 ZLS 팀은 프로토콜을 확장해 기존 기능을 복구하고 더 많은 기능을 제공하는 작업을 이어가고 있습니다.

패키지 관리 기능도 컴파일러에서 빌드 시스템으로 옮겼습니다. zig fetch, zig init, zig libc, 새 zig cache-cat 명령이 여기에 포함됩니다. 캐시 파일은 텍스트 대신 바이너리 형식을 사용해 크기를 약 25% 줄였습니다.

증분 컴파일과 링커

새 ELF 링커를 개선해 x86_64 Linux를 대상으로 하는 대다수 프로젝트에서 증분 컴파일을 사용할 수 있게 됐습니다. zig build -fincremental --watch를 실행하면 소스 변경을 감지해 증분 빌드를 수행합니다. 새 링커는 아직 기존 ELF 링커와 기능이 같지 않아 기본값은 아니지만, 이 사용 사례에서는 증분 컴파일을 지원합니다. 다음 릴리스에서는 기존 구현을 없애고 새 링커로 전환하는 방안을 목표로 합니다.

이번 릴리스에서 COFF 링커는 __dllimport, 생성자·소멸자 처리, /INCLUDE, /ALTERNATENAME, /MERGE, /DEFAULTLIB 인자 지원을 보강했습니다. SPIR-V 링커도 다시 작성해 증분 컴파일과 외부 .spv 오브젝트 파일 링크를 지원합니다. Zig 자체 WebAssembly 백엔드는 동작 테스트 2,054개 중 2,060개를 통과했지만, 디버그 정보 지원이 부족해 디버그 모드의 기본 백엔드로 쓰이지는 않습니다.

언어와 표준 라이브러리 변경

@bitCast의 정의가 바뀌었습니다. 이제 값의 메모리 배치가 아니라 논리적 비트 표현을 다른 타입으로 해석합니다. 배열과 벡터는 첫 원소부터 각 원소의 논리적 비트 표현을 이어 붙이며, 동작은 대상 엔디안에 영향을 받지 않습니다. 배열이나 벡터를 포함한 기존 캐스트는 컴파일 오류 없이 결과가 달라질 수 있으므로 업그레이드할 때 확인해야 합니다. extern struct나 extern union을 대상으로 한 캐스트는 허용되지 않습니다. 메모리 표현을 재해석하려던 코드는 @ptrCast나 extern union을 사용해야 합니다.

열거형 변환에는 @intFromEnum, @enumFromInt를 대체하는 @backingInt, @fromBackingInt가 추가됐습니다. 기존 배열 반복 초기화 문법 a ** b는 제거돼 @splat으로 바꿔야 합니다. 정수 나눗셈 결과를 양의 무한대 방향으로 올림하는 @divCeil도 추가됐습니다. @cImport는 제거됐고, C 헤더 번역은 별도 패키지인 ZSF translate-c를 사용하도록 안내합니다. 문법 파일과 실제 파서의 불일치를 줄이기 위해 문법에서 파서를 생성하고 기존 파서와 퍼징 테스트로 비교하는 방법도 도입했습니다.

새 @SpirvType 내장 기능은 Zig 타입 체계에 대응하는 타입이 없던 SPIR-V 이미지, 샘플러, 런타임 배열 등을 표현합니다. SPIR-V를 대상으로 하지 않을 때 사용하면 컴파일 오류가 납니다. 표준 라이브러리에는 스레드 안전 할당자와 공유 잠금 API가 들어갔으며, DebugAllocator와 Check는 사용 중단 예정입니다. std.zon.parse는 인자 구조체를 받고 arena에 결과를 할당하도록 바뀌었습니다. 표준 라이브러리와 빌드 API의 이름 변경·사용 중단 항목도 많아 업그레이드 안내를 확인해야 합니다.

플랫폼 지원과 도구

새 릴리스는 여러 아키텍처와 운영체제 지원을 추가하거나 테스트 범위를 넓혔습니다. loongarch32-linux, sparc64-linux, aarch64-openbsd 지원이 추가됐고, aarch64-freebsd와 aarch64-netbsd CI 검사는 pull request에서도 실행됩니다. 일부 새 대상은 C 백엔드나 실험적인 LLVM 백엔드에서만 사용할 수 있습니다. PowerPC의 long double ABI를 IEEE 형식으로 명시하면서 glibc가 double-double 형식만 지원하는 powerpc-linux-gnueabi[hf] 지원은 제거됐습니다.

Zig는 LLVM 22.1.8로 업그레이드했으며, zig cc와 zig c++도 Clang 22.1.8을 기반으로 합니다. 새 zig objdump는 COFF와 다른 바이너리 형식의 헤더, 심볼, 재배치 정보를 출력합니다. 스냅샷 테스트에서 주소나 크기처럼 결과를 흔들 수 있는 값을 가리는 기능도 제공합니다. 릴리스 주기 동안 버그 보고 329건을 닫았으며, x86_64 Linux의 증분 컴파일을 비롯한 개선에도 불구하고 알려진 회귀와 컴파일 오류가 남아 있다고 릴리스 노트는 밝힙니다.

Lobsters 반응

  • @kneeawn — 앞으로 진행될 Build Server Protocol과 ZLS 작업이 정말 기대됩니다. 초기 작업은 좋아 보이고, 빌드 서버가 무엇을 해야 하는지 표준이 생기면 커뮤니티가 한 방향으로 모이는 데 도움이 되길 바랍니다. LSP는 제게 큰 도움이 됐고, 이와 같은 표준이 더 생기면 좋겠습니다. Microsoft 색채가 조금 덜한 표준이면 더 좋겠지만, 일단 받아들이겠습니다. 이 프로토콜에 대해 알고는 있었지만 Java 생태계 밖으로 퍼지지는 않은 것 같습니다.
  • @baer — 오늘 퍼저 코드를 작성하다가 자체 제작 디버그 백엔드가 퍼저 테스트를 컴파일하지 못해 답답했습니다. 몇 시간만 기다렸어야 했습니다.
    • @andrewrk — 퍼징에는 Safe 최적화 모드가 더 낫습니다. 단언을 켠 상태에서 검사를 최대한 빠르게 실행해야 유전 알고리즘이 흥미로운 입력을 더 많이 찾습니다.
    • @baer — 말이 됩니다. 저도 그렇게 해봤지만 코드가 어디서 실패했는지 단서를 얻지 못했고, 참조 위치가 전부 표준 라이브러리 내부를 가리켰습니다. 제가 설정해야 할 무언가를 놓쳤을 수도 있습니다.

원문: Zig / 번역·요약: Trawling