Missing RPATH entries
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
I built a simple project with zig-0.13.0 and it could not find dynamic libraries. Same project in zig-0.11 could. The build.zig are equivalent (I can paste if needed, please ask).
This is zig-0.13.0:
readelf -d zig-out/bin/newsplane
Dynamic section at offset 0xdddf0 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libduckdb.so]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
...
vs zig-0.11.0
readelf -d ../newsplane_11/zig-out/bin/newsplane_11
Dynamic section at offset 0xaac38 contains 27 entries:
Tag Type Name/Value
0x000000000000001d (RUNPATH) Library runpath: [/gnu/store/gmka5za8fqzggaf6lw807w93na88md4y-profile/lib]
0x0000000000000001 (NEEDED) Shared library: [libduckdb.so]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
...
Expected Behavior
The RPATH should be correctly set up.
I do think the build.zig code, and maybe a link to the entire project would be relevant.
As it stands, I don't think anybody can reproduce this specific issue to verify or debug it.
FWIW I've seen RPATH come up in recent PRs, so maybe it's been fixed or the error will be different on master, but I do think the general mechanism is usable for people.
build.zig file of the zig-0.13.0 project
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "newsplane",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
exe.linkSystemLibrary("duckdb");
exe.linkLibC();
exe.linkLibCpp();
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_unit_tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_exe_unit_tests.step);
}
build.zig of the zig-0.11 project
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "newsplane_11",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
exe.linkSystemLibrary("duckdb");
exe.linkLibC();
exe.linkLibCpp();
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}
main.zig in both:
const std = @import("std");
const c = @cImport({
@cInclude("duckdb.h");
});
pub fn main() !void {
var db : c.duckdb_database = undefined;
if (c.duckdb_open(null, &db) == c.DuckDBError) {
// handle error
}
c.duckdb_close(&db);
}
This is enough to reproduce the problem.