Linker Error — Como Resolver em Zig
O Que Este Erro Significa
Erros de linker em Zig ocorrem na etapa final da compilação, quando o linker tenta combinar o código objeto compilado com bibliotecas externas para gerar o executável ou biblioteca final. O linker precisa resolver todos os símbolos (funções, variáveis) referenciados pelo código — se algum símbolo não é encontrado ou há conflito, o processo falha.
Mensagens típicas:
error: undefined symbol: funcao_externa
error: library not found: -lssl
error: relocation overflow
Estes erros são mais comuns ao usar interoperabilidade com C (@cImport), bibliotecas externas ou cross-compilation.
Causas Comuns
1. Biblioteca C Não Instalada
const c = @cImport({
@cInclude("openssl/ssl.h");
});
// ERRO DE LINKER: library not found: -lssl
2. Símbolo Externo Não Definido
// Declaração de função externa que não existe
extern fn funcao_que_nao_existe() void;
pub fn main() void {
funcao_que_nao_existe(); // ERRO: undefined symbol
}
3. Falta Vincular Biblioteca no build.zig
// build.zig — SEM linkagem da biblioteca
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Falta: exe.linkSystemLibrary("ssl");
4. Biblioteca Estática Não Encontrada
$ zig build
# error: unable to find library: -lminha_lib
# library search paths: /usr/lib, /usr/local/lib
5. Conflito de Símbolos Duplicados
// Dois módulos exportam a mesma função
export fn processar() void {} // Módulo A
export fn processar() void {} // Módulo B
// ERRO: duplicate symbol: processar
Como Corrigir
Solucao 1: Instalar Bibliotecas de Desenvolvimento
# Ubuntu/Debian
$ sudo apt install libssl-dev libz-dev
# Fedora/RHEL
$ sudo dnf install openssl-devel zlib-devel
# macOS
$ brew install openssl zlib
# Após instalar, rebuild
$ zig build
Solucao 2: Vincular Biblioteca no build.zig
// build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Vincular bibliotecas do sistema
exe.linkSystemLibrary("ssl");
exe.linkSystemLibrary("crypto");
exe.linkSystemLibrary("z");
// Vincular libc (necessário para muitas bibliotecas C)
exe.linkLibC();
b.installArtifact(exe);
}
Solucao 3: Adicionar Caminhos de Busca de Bibliotecas
// build.zig
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Adicionar caminhos de busca
exe.addLibraryPath(.{ .cwd_relative = "/usr/local/lib" });
exe.addIncludePath(.{ .cwd_relative = "/usr/local/include" });
exe.linkSystemLibrary("minha_lib");
exe.linkLibC();
Solucao 4: Vincular Biblioteca Estática Diretamente
// build.zig
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Vincular arquivo .a ou .lib diretamente
exe.addObjectFile(.{ .cwd_relative = "libs/libminha_lib.a" });
exe.linkLibC();
Solucao 5: Compilar Código C junto com Zig
// build.zig
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Compilar arquivo C como parte do projeto
exe.addCSourceFile(.{
.file = b.path("src/utils.c"),
.flags = &.{ "-Wall", "-O2" },
});
exe.linkLibC();
Solucao 6: Cross-Compilation com Bibliotecas Bundled
// build.zig — para cross-compilation
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Use bibliotecas que Zig traz embutidas
exe.linkLibC(); // libc do target
// Zig inclui implementações de muitas bibliotecas comuns
Diagnóstico
Verificar Bibliotecas Disponíveis
# Linux — listar bibliotecas instaladas
$ ldconfig -p | grep ssl
# macOS
$ brew list openssl --prefix
# Verificar se pkg-config encontra a biblioteca
$ pkg-config --libs openssl
Ver Símbolos em uma Biblioteca
# Listar símbolos de uma biblioteca estática
$ nm /usr/lib/libssl.a | grep SSL_connect
# Listar símbolos de uma biblioteca compartilhada
$ nm -D /usr/lib/libssl.so | grep SSL_connect
Verbose Mode do Linker
# Zig com output verbose do linker
$ zig build -verbose
Cross-Compilation e Linker
Ao compilar para outro sistema, o linker precisa das bibliotecas do alvo:
// build.zig — cross-compilation
const target = b.resolveTargetQuery(.{
.cpu_arch = .x86_64,
.os_tag = .linux,
.abi = .musl, // musl é estático — evita problemas de linking
});
const exe = b.addExecutable(.{
.name = "meu-projeto",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// musl libc é bundled com Zig — funciona em cross-compilation
exe.linkLibC();
Erros Relacionados
- build.zig not found — Arquivo de build não encontrado
- @cImport failed — Falha ao importar cabeçalho C
- Target not supported — Alvo não suportado
- Dependency fetch failed — Falha ao buscar dependência