Link

Names the native library an extern function is imported from, and optionally the exported symbol to bind to. The operating system loader resolves the library by name at run time.

Syntax

#Link("Kernel32.dll")
extern func Beep(freq: uint32, duration: uint32) -> bool32;

The library is a plain name — vulkan.so, vulkan.dylib, vulkan.dll — without a path. The argument may be a string literal or a compile-time string constant.

Binding a Different Symbol Name

By default the exported symbol matches the Rux declaration name. A second argument binds to a differently named export, so the Rux name can follow local conventions:

#Link("libm.so", "sqrt")
extern func SquareRoot(x: float64) -> float64;   // calls C's sqrt

Applying to an extern Block

The one-argument form may annotate an entire extern block, applying the library to every function inside it:

#Link("Kernel32.dll")
extern {
    func GetStdHandle(handle: uint32) -> *opaque;
    func WriteFile(
        handle: *opaque,
        buffer: *opaque,
        numberOfBytesToWrite: uint32,
        numberOfBytesWritten: *var uint32,
        overlapped: *Overlapped,
    ) -> bool32;
}

Compatibility Spellings

#Library("name") and #Symbol("name") set the library and symbol separately. They are retained for compatibility and cannot be combined with #Link — prefer #Link, which expresses both in one attribute.

Selecting a Library per Platform

Because a library name differs across systems, guard the declarations with conditional compilation:

import Core::{ #target };

when #target.os == .Windows {
    #Link("Kernel32.dll")
    extern func GetTickCount64() -> uint64;
} else when #target.os == .Linux {
    #Link("librt.so")
    extern func clock_gettime(clockid: int32, tp: *opaque) -> int32;
}

See Also