zig icon indicating copy to clipboard operation
zig copied to clipboard

cross-compile to RPi + linking third party libraries generate executable with invalid runtime paths

Open marrony opened this issue 1 year ago • 0 comments

Zig Version

0.12.0-dev.1849+bb0f7d55e

Steps to Reproduce and Observed Behavior

I have a project where I need to cross-compile to RPi using a 3rd party library that I don't have access to the source code only the shared object (libEDSDK.so). The project compiles fine but it generate invalid runtime paths in the executable.

$ readelf -d zig-shared-obj

Dynamic section at offset 0xa2cf4 contains 26 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [/Users/marrony/Development/zig-shared-obj/lib/libEDSDK.so]
 0x00000001 (NEEDED)                     Shared library: [libpthread.so.0]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld-linux-armhf.so.3]
 ....

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const default_target = std.zig.CrossTarget.parse(.{
        .arch_os_abi = "arm-linux-gnueabihf",
    }) catch @panic("unknown target");

    const target = b.standardTargetOptions(.{
        .default_target = default_target,
    });

    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "zig-shared-obj",
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    exe.addLibraryPath(.{ .path = "lib" });
    exe.addIncludePath(.{ .path = "include" });
    exe.defineCMacro("TARGET_OS_LINUX", null);
    exe.linkLibC();

    // how to properly link lib/libEDSDK.so ?
    exe.linkSystemLibrary("EDSDK");

    b.installArtifact(exe);
}

src/main.zig

const std = @import("std");

const c = @cImport({
    @cInclude("stdbool.h");
    @cInclude("EDSDK.h");
});

pub fn main() void {
    if (c.EdsInitializeSDK() != c.EDS_ERR_OK) {
        std.debug.print("Error initializing the library\n", .{});
    }

    std.debug.print("Hello World\n", .{});

    if (c.EdsTerminateSDK() != c.EDS_ERR_OK) {
        std.debug.print("Error terminating the library\n", .{});
    }
}

Here is a reproducible example: https://github.com/marrony/zig-shared-obj

Related issues?

  • https://github.com/ziglang/zig/issues/15849
  • https://github.com/ziglang/zig/issues/17373

Expected Behavior

I expect the final executable to not have fullpath of the linked shared objects.

marrony avatar Dec 26 '23 05:12 marrony