ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.64k stars 2.46k forks source link

Missing RPATH entries #20818

Open ekaitz-zarraga opened 1 month ago

ekaitz-zarraga commented 1 month ago

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.

rohlem commented 1 month ago

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.

ekaitz-zarraga commented 1 month ago

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.