Zig Programming Language

repository·master·Indexed 12 days ago

https://github.com/ziglang/zig

A general-purpose programming language and toolchain designed for robustness, optimality, and maintainability. It features explicit memory management, no hidden control flow, and a powerful build system. The toolchain includes support for linking against glibc (v2.17+ for standard builds, v2.2.5+ for zig cc), the resinator resource compiler for .rc files, and the translate-c utility for converting C source to Zig.

Tokens
11.2K
Snippets
34
Records
58
Agent score
93%

What's inside Zig

  1. Create a build.zig.zon manifest

    master
    The build.zig.zon file is the manifest for build.zig scripts. It contains metadata specifically pertaining to the build process and package identity. It must be located in the build root (the directory containing build.zig).
  2. Link against the GNU C Library (glibc)

    master

    By default, Zig binaries do not depend on any external C library. To link a binary against glibc, use the -lc flag. The specific C library used is determined by the target ABI: gnu selects glibc, while musl selects the musl C library.

    zig build-exe main.zig -lc
  3. Specify a glibc version via target ABI

    master

    You can target a specific glibc version to ensure compatibility with older systems. This is done by appending the version number to the -target flag. For example, using gnu.2.19 will create a dependency on glibc v2.19 or later. Use zig env to check your current default target and version.

    zig build-exe main.zig -lc -target native-native-gnu.2.19
  4. Define dependencies in build.zig.zon

    master

    Dependencies in the dependencies struct must be defined using either a url and hash OR a path. The url and path fields are mutually exclusive.

    Remote Dependencies

    When using a url, you must provide a hash (multihash format). The hash is the source of truth; the url is simply a mirror. If you update a url, you must delete the old hash to avoid mismatch errors.

    Local Dependencies

    When using path, the package is located in a directory relative to the build root. In this case, the hash is not computed and is irrelevant.

    Lazy Fetching

    Set lazy = true to declare a dependency as lazily fetched. The package will only be fetched if it is actually used by the build process.

  5. Resinator CLI: Input and Output Formats

    master

    The resinator compiler supports several input and output formats. Formats are typically inferred from file extensions, but can be explicitly specified.

    Supported Formats

    • .rc: Resource script format.
    • .res: Intermediate resource format.
    • .rcpp: Preprocessed resource format.
    • .obj or .o: COFF object format.

    Format Inference Rules

    • Input Format: Inferred from the input filename extension.
    • Output Format:
      • If an output filename is provided, it is inferred from that extension (e.g., .obj or .o results in .coff).
      • If no output filename is provided, it is inferred from the input filename (e.g., .res input results in .coff output).
      • If the input is .res, the output defaults to .coff.
      • If the output format is set to .rcpp, the compiler automatically enables preprocess = .only mode.

    Supported Transformations

    Not all format combinations are valid. The following transformations are supported:

    • From .rc: Can convert to .res, .coff, or .rcpp.
    • From .res: Can convert to .coff only.
    • From .rcpp: Can convert to .res or .coff (cannot convert .rcpp to .rcpp).
  6. Log TLS secrets for debugging

    master

    You can enable SSL key logging by providing an SslKeyLog pointer in the Options.ssl_key_log field. This allows external tools to decrypt the captured traffic. The writer field in SslKeyLog is used during the handshake to record the necessary secrets.

    const key_log = SslKeyLog{
        .client_key_seq = 0,
        .server_key_seq = 0,
        .client_random = undefined, // Populated during init
        .writer = my_file_writer,
    };
    
    const client = try tls.Client.init(input, output, .{ 
        .ssl_key_log = &key_log, 
        // ... other options
    });
  7. Manage connections with ConnectionPool

    master

    The Client uses a ConnectionPool to reuse open connections. The pool is a Least-Recently-Used (LRU) cache.

    Core Functionality:

    • findConnection(pool, criteria): Searches the pool for an available connection matching the provided Criteria (host, port, and protocol). Returns null if no match is found. This is thread-safe.
    • release(pool, connection, io): Returns a connection to the pool. If the connection is marked as closing or the pool is at its free_size limit, the connection is destroyed instead. This is thread-safe.
    • resize(pool, allocator, new_size): Adjusts the pool capacity. If shrinking, idle connections are closed until the new size is reached. This is thread-safe.
    • deinit(pool, io): Frees the pool and closes all connections. Warning: All future operations on the pool will deadlock after this call.
  8. Resinator CLI: Define and Undefine Symbols

    master

    You can manage preprocessor symbols using the /d (define) and /u (undefine) flags.

    • Define a symbol: Use /d<name> or /d<name>=<value>. If a name is repeated, the last definition takes precedence.
    • Undefine a symbol: Use /u<name>. Once a symbol is undefined, subsequent definitions of that same symbol are ignored.
    • Precedence: Undefine operations always take precedence over define operations if they appear later in the command line.

    Note: Symbol names must be valid C identifiers (e.g., no leading digits, only alphanumeric characters and underscores).

    # Example usage
    # Define 'FOO' as '1'
    /dFOO foo.rc
    
    # Define 'BAR' as 'baz'
    /dBAR=baz foo.rc
    
    # Undefine 'FOO'
    /uFOO foo.rc
    
    # Undefine takes precedence over define
    /dFOO /uFOO foo.rc
  9. Configure the std.http.Client

    master

    The std.http.Client is used to make HTTP(S) requests. It manages a connection pool and handles TLS.

    Key Configuration Fields:

    • allocator: A thread-safe Allocator used for all client allocations.
    • io: An Io instance used for opening TCP connections.
    • ca_bundle: A std.crypto.Certificate.Bundle used for TLS certificate verification. If std.options.http_disable_tls is true, this is ignored.
    • tls_buffer_size: The size of the TLS buffer. Defaults to std.crypto.tls.Client.min_buffer_len unless TLS is disabled.
    • ssl_key_log: An optional pointer to an SslKeyLog stream. If provided, SSL secrets are logged here, allowing traffic to be decrypted by other processes.
    • now: An optional Io.Timestamp. If null, the client will scan the system for root certificates during the next HTTPS request.
    • read_buffer_size: The size allocated for each connection's reader buffer (default: 8192).
    • write_buffer_size: The size allocated for each connection's writer buffer (default: 1024).
    • http_proxy / https_proxy: Optional pointers to Proxy objects to route traffic through a third party.
  10. Handle WebSocket upgrades

    master

    To support WebSockets, first check if an upgrade is requested using upgradeRequested. If it returns a .websocket variant, use respondWebSocket to complete the handshake. This returns a WebSocket object for bidirectional communication.

    const upgrade = std.http.Server.upgradeRequested(&request);
    if (upgrade == .websocket) {
        const ws_options = std.http.Server.WebSocketOptions{
            .key = upgrade.websocket.?,
            .reason = "Switching Protocols",
        };
        var ws = try request.respondWebSocket(ws_options);
        // Use ws to read/write messages
    }
  11. Cipher Suite availability and performance

    master

    The available cipher_suites are determined by whether the system has hardware support for AES.

    If crypto.core.aes.has_hardware_support is true, the priority order is:

    1. AEGIS_128L_SHA256
    2. AEGIS_256_SHA512
    3. AES_128_GCM_SHA256
    4. ECDHE_RSA_WITH_AES_128_GCM_SHA256
    5. AES_256_GCM_SHA384
    6. ECDHE_RSA_WITH_AES_256_GCM_SHA384
    7. CHACHA20_POLY1305_SHA256
    8. ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

    If hardware support is absent, CHACHA20_POLY1305_SHA256 and its ECDHE variant are prioritized for better software performance.