Docs/Tools

Cross compiling

Build for another OS or CPU.

On this page

--target builds an executable for another operating system or CPU. No extra toolchain is needed: the linker and the system libraries for each target ship with Valk.

Choose a target#

Terminal
valk build src -o app --target win-x64
Target Platform
linux-x64 Linux on x86-64
linux-arm64 Linux on 64-bit ARM, such as a Raspberry Pi or AWS Graviton
macos-x64 macOS on Intel
macos-arm64 macOS on Apple silicon
win-x64 Windows on x86-64

A Windows target adds .exe to the output name, so the command above writes app.exe. Copy the executable to a machine of that platform to run it.

Check code for every platform#

A lint compiles without linking, so it works for any target without setup:

Terminal
valk build src --lint --target macos-arm64

Run it for each target you support to catch code that only compiles on one platform.

Write platform-specific code#

OS (linux, macos or win) and ARCH (x64 or arm64) describe the target being built, not the build machine.

Valk
fn config_dir() String {
    #if OS == "win"
    return "C:/ProgramData/app"
    #elif OS == "macos"
    return "/Library/Application Support/app"
    #else
    return "/etc/app"
    #end
}

fn main() {
    println(config_dir())
}

A branch that is not selected is never compiled, so it may call functions that exist on one platform only. See Compile-time code.

Add OpenSSL for the target#

valk.net, valk.http and valk.crypto, and packages built on them, link OpenSSL. A Valk release ships it for its own platform only, so cross compiling such a program stops with a message naming the package to add:

Terminal
vman install github.com/valk-lang/openssl-win-x64 --libs

There is one package per target: openssl-linux-x64, openssl-linux-arm64, openssl-macos-x64, openssl-macos-arm64 and openssl-win-x64. A dependency's compiled libraries are linked only when its valk.json entry has "libs": true, which --libs writes for you:

JSON
{
    "dependencies": {
        "openssl_win_x64": {
            "src": "github.com/valk-lang/openssl-win-x64",
            "version": "3.5.x",
            "libs": true
        }
    }
}

A C library named with -l or a link declaration must be built for the target. Put it in libs/<target>/ next to valk.json, for example libs/win-x64/foo.lib, or pass its directory with -L. Only a build for the machine itself also searches the system's library directories. See C interop.

--static links the C runtime and the libraries into the executable, so a Linux build runs on machines that lack them.