Zig

From Gentoo Wiki
Jump to:navigation Jump to:search

Zig is a general-purpose programming language and toolchain for maintaining robust, optimal and reusable software. Zig aims to replace C as the better language and can use or export C functions without FFI[1] and compile code in C and C++, using libclang.[2] Upstream also works on their own C compiler[3] so that these functions will be available without libclang.

Installation

Prerequisites

Warning
Compiling Zig 0.10.1 requires up to 9.6 GiB of RAM.[4]

Zig supports at least Linux kernel 3.16+.[5] If building from source, it must be built with same compiler as LLVM/Clang, or the user will get in trouble (see relevant section in Troubleshooting below).

USE flags

USE flags for dev-lang/zig A robust, optimal, and maintainable programming language

+llvm Build with LLVM backend and extensions enabled.
doc Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally
test Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently)
verify-sig Verify upstream signatures on distfiles

USE flags for dev-lang/zig-bin A robust, optimal, and maintainable programming language

doc Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally
verify-sig Verify upstream signatures on distfiles

Emerge

Note
Replace "dev-lang/zig" with "dev-lang/zig-bin" if you want to use binary package (if available for your architecture).

Packages are currently not stabilized on any arch and keyworded as testing on a small subset of arches, so the user need to accept testing (~arch, replace with the system's arch) keyword for the latter:

root #echo "dev-lang/zig ~arch" >> /etc/portage/package.accept_keywords

Then emerge the package:

root #emerge --ask dev-lang/zig

Configuration

ZIG_MCPU and ZIG_TARGET

To adjust for which target and CPU dev-lang/zig will be built for, there are variables ZIG_MCPU and ZIG_TARGET (that will be passed as -target and -mcpu arguments to zig:

FILE /etc/portage/make.conf/zigExamples of ZIG_MCPU and ZIG_TARGET
# By default ZIG_MCPU and ZIG_TARGET equal to "native"
# In case of cross-compilation ZIG_MCPU equals to "baseline"
# and ZIG_TARGET is converted from CTARGET or CHOST
# In most cases user don't have to set custom values, except when "native" or convertion doesn't work
#
# ZIG_TARGET has this required sections: <arch>-<os>-<abi>
ZIG_TARGET="x86_64-linux-gnu" # For computer running AMD64 on Linux kernel with glibc
# And optional ones: min_ver...max_version of OS and ABI/libc version
ZIG_TARGET="x86_64-linux.6.1.12...6.1.12-gnu.2.36" # For Linux kernel 6.1.12 and glibc 2.36
#
# ZIG_MCPU has required section of architecture's name
ZIG_MCPU="znver2" # For processors from Zen 2 family
# And optional section for features on this architecture
# ("+" means it has and "-" means it hasn't this feature)
ZIG_MCPU="x86_64+x87-sse" # For processors on AMD64 architecture, with added support for X87 but without SSE2 instructions

Setting a default slot

The eselect command can be used to manipulate a /usr/bin/zig symlink.

user $eselect zig help
Manage Zig versions
Usage: eselect zig <action> <options>
Standard actions:
  help                      Display help text
  usage                     Display usage information
  version                   Display version information
Extra actions:
  list                      List available Zig versions
  set <target>              Set active Zig version
    target                    Target name or number (from 'list' action)
  show                      Show current Zig version
  update                    Automatically update the zig symlink
    ifunset                   Do not override currently set version
user $eselect zig list
Available Zig versions:
  [1]   zig-0.10.1 *
  [2]   zig-9999
  [3]   zig-bin-0.10.1

Environment variables

Note
Unfortunately, there is no way to set other args (such as target or release/optimize mode) with environment variables, so the user needs to specify them in args.

Command args have higher precedence over the following environment variables:

  • ZIG_GLOBAL_CACHE_DIR - path to the directory where things that are shared between different compilations are cached
  • ZIG_LOCAL_CACHE_DIR - path to the directory where the current compilation is cached, by default next to build.zig
  • ZIG_LIB_DIR - path to Zig standard library

Usage

General usage

Warning
Many programs and libraries written in Zig leverages comptime possibilities of the language. More info is available in language reference, in short: during compilation Zig can run arbitrary code in the source files (build.zig, standard library, project itself etc.), so please be cautious.
user $zig --help

Most commands grouped together, like ast-check to translate-c, have the same command options.

In the second group, it is highly recommended to use -fstrip to reduce the executable size except for debugging purposes.

Build modes

Zig has 4 "build modes" (or "optimize modes" in recent versions):

Feature Debug (default) ReleaseFast ReleaseSafe ReleaseSmall
Compilation speed Fast Slow Slow Slow
Safety checks at runtime Enabled Disabled Enabled Disabled
Optimizations Disabled Optimized for speed Optimized for speed Optimized for size
Reproducible Not guaranteed Yes Yes Yes
Equivalent in C

(interop. or compiling)[6]

-D_DEBUG -O0 -DNDEBUG -O2 -O2 -D_FORTIFY_SOURCE=2 -DNDEBUG -Os
Note
Safety checks at runtime can be overridden per-scope/block by setting @setRuntimeSafety. Safety cheks at compile-time are always enabled.

LSP support

Unofficial language server is available as dev-zig/zls in GURU repository. For installing follow this guide to enable GURU repository, accept testing branch for this package and run:

root #emerge --ask dev-zig/zls::guru

Text editors support

See this list of tools from upstream. Currently none of them are packaged.

Freestanding

User might want to take a look at posts Using Zig to build a bare metal RISCV32 binary and Build an IoT App with Zig and LoRaWAN.

Troubleshooting

"undefined reference to ..." during emerging

The most possible reason is that the LLVM and Clang packages were built with other C++ compiler than Zig. Ensure that the user set the same compiler and emerge again.

warning: Encountered error: UnexpectedEndOfFile, falling back to default ABI and dynamic linker.

Zig compiler relies on the presence of /usr/bin/env for choosing libc when targeting host machine. It checks whether /usr/bin/env contains actual ELF file or is a symlink/shebang to another executable, and retries this operation recursively until found. Then, it tries to extract information about libc from this ELF file. If this message occurs, it means that Zig failed to detect it properly, and will choose default libc and ABI instead (e.g. musl on Linux). The workaround is by using the following args to the command:

user $zig build -Dtarget=<target>

Or:

user $zig build-exe -target <target>

Where target is the desired target, such as native-native-gnu or native-native-musl. For more information about target format see ZIG_MCPU and ZIG_TARGET section.

Removal

Unmerge

root #emerge --ask --depclean --verbose dev-lang/zig

See also

  • Clang — a C/C++/Objective-C/C++, CUDA, and RenderScript language front-end for the LLVM project
  • Rust — a general-purpose, multi-paradigm, compiled, programming language.
  • Go — an open source, statically typed, compiled programming language

External resources

  • Official list of the community spaces
  • Official list of community projects and awesome-zig list
  • Ziglings — learn Zig by fixing tiny broken programs, inspired by Rustlings
  • Differences between zig cc and clang

References