ziglang / zig

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

Cross compilation for x86_64-linux-gnu fails #21175

Open CashWasabi opened 2 months ago

CashWasabi commented 2 months ago

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

This is a mirror of a bug I reported in this repo: https://github.com/Not-Nik/raylib-zig https://github.com/Not-Nik/raylib-zig/issues/139

I was testing the generated project I get from executing:

./project_setup.sh demo

I've noticed that whenever I'm trying to cross compile for x86_64-linux-gnu I get the following stack trace:

zig build -Dtarget=x86_64-linux-gnu
install
└─ install demo
   └─ zig build-exe demo Debug x86_64-linux-gnu failure
error: error: unable to find dynamic system library 'GL' using strategy 'paths_first'. searched paths: none
error: unable to find dynamic system library 'X11' using strategy 'paths_first'. searched paths: none

error: the following command exited with error code 1:
/usr/bin/zig build-exe /home/mo/git/projects/demo/.zig-cache/o/c502fb93a46cdb616beac232c7104a1b/libraylib.a -ODebug -target x86_64-linux-gnu -mcpu baseline -I /home/mo/git/projects/demo/.zig-cache/o/a12fe0f75465fc2f91719bc59c04564f --dep raylib -Mroot=/home/mo/git/projects/demo/src/main.zig -ODebug -target x86_64-linux-gnu -mcpu baseline -Mraylib=/home/mo/.cache/zig/p/1220df9aa89d657f5dca24ab0ac3d187f7a992a4d27461fd9e76e934bf0670ca9a90/lib/raylib.zig -lGL -lX11 -lc --cache-dir /home/mo/git/projects/demo/.zig-cache --global-cache-dir /home/mo/.cache/zig --name demo --listen=- 
Build Summary: 3/6 steps succeeded; 1 failed (disable with --summary none)
install transitive failure
└─ install demo transitive failure
   └─ zig build-exe demo Debug x86_64-linux-gnu failure
error: the following build command failed with exit code 1:
/home/mo/git/projects/demo/.zig-cache/o/294fd65b2d3c872b8346030ac9f8b9d3/build /usr/bin/zig /home/mo/git/projects/demo /home/mo/git/projects/demo/.zig-cache /home/mo/.cache/zig --seed 0x2b72c6b9 -Z87cd8115588777d1 -Dtarget=x86_64-linux-gnu

Whenever I use the default compilation (which is still the same target as the explicit target I use above) it compiles fine.

It looks like this is somewhat of a known problem: https://github.com/ziglang/zig/issues/16733 https://github.com/ziglang/zig/issues/16733 https://github.com/ziglang/zig/issues/19275

I was wondering if this can be fixed somehow or if there's a workaround for this issue. I've been looking at this problem for 2 days now and I just can't get this to work.

Expected Behavior

The cross compilation should work the same as with the default compilation target.

der-teufel-programming commented 2 months ago

Are you sure you have x86_64-linux versions of GL and X11

CashWasabi commented 2 months ago

I am actually not sure what your questions means. I might not be familiar with having special versions of GL and X11. I would assume I have the specific version installed under /usr/lib and that they are then just x86_64-linux. uname -a output looks like this:

Linux archlinux 6.10.6-arch1-1 #1 SMP PREEMPT_DYNAMIC Mon, 19 Aug 2024 17:02:39 +0000 x86_64 GNU/Linux
xdBronch commented 2 months ago

when you specify a target, even if its technically the same as your native target, zig goes into a kind of cross compilation mode and system paths arent searched. if you want to cross compile a program like this you need to provide the libraries some other way or use possibly use some of the build systems System Integration Options shown in the help menu

CashWasabi commented 2 months ago

when you specify a target, even if its technically the same as your native target, zig goes into a kind of cross compilation mode and system paths arent searched. if you want to cross compile a program like this you need to provide the libraries some other way or use possibly use some of the build systems System Integration Options shown in the help menu

How would I integrate the dynamic libraries best in this case with System Integration Options? Sorry if this is obvious but I'm a bit lost right now.

xdBronch commented 2 months ago

ive never personally used these before so it might not be the best but i believe you could for example do zig build -Dtarget=... --search-prefix /usr

but generally this isnt the recommended solution, you should usually prefer using the package manager to fetch/build from source whatever libraries you need to make builds as reproducible as possible. the way i understand it the system integration options are mainly intended for e.g. linux package managers to build zig programs for distribution

CashWasabi commented 2 months ago

ive never personally used these before so it might not be the best but i believe you could for example do zig build -Dtarget=... --search-prefix /usr

but generally this isnt the recommended solution, you should usually prefer using the package manager to fetch/build from source whatever libraries you need to make builds as reproducible as possible. the way i understand it the system integration options are mainly intended for e.g. linux package managers to build zig programs for distribution

I tried that but this also didn't work. I got some linker errors after trying it out.

I guess I should also just be able to link the system libraries like normally?

exe.linkSystemLibrary("GL");
exe.linkSystemLibrary("X11");

This also doesn't detect anything though.

CashWasabi commented 2 months ago

If it helps this is the build.zig file:

const std = @import("std");
const rlz = @import("raylib-zig");

pub fn build(b: *std.Build) !void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const raylib_dep = b.dependency("raylib-zig", .{
        .target = target,
        .optimize = optimize,
    });

    const raylib = raylib_dep.module("raylib");
    const raylib_artifact = raylib_dep.artifact("raylib");

    //web exports are completely separate
    if (target.query.os_tag == .emscripten) {
        const exe_lib = rlz.emcc.compileForEmscripten(
            b,
            "demo",
            "src/main.zig",
            target,
            optimize,
        );

        exe_lib.linkLibrary(raylib_artifact);
        exe_lib.root_module.addImport("raylib", raylib);

        // Note that raylib itself is not actually added to the exe_lib output file, so it also needs to be linked with emscripten.
        const link_step = try rlz.emcc.linkWithEmscripten(b, &[_]*std.Build.Step.Compile{ exe_lib, raylib_artifact });

        b.getInstallStep().dependOn(&link_step.step);
        const run_step = try rlz.emcc.emscriptenRunStep(b);
        run_step.step.dependOn(&link_step.step);
        const run_option = b.step("run", "Run demo");
        run_option.dependOn(&run_step.step);
        return;
    }

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

    const target_os = exe.rootModuleTarget().os.tag;

    exe.linkLibrary(raylib_artifact);
    exe.root_module.addImport("raylib", raylib);

    const run_cmd = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run demo");
    run_step.dependOn(&run_cmd.step);

    b.installArtifact(exe);
}

The build.zig.zon looks like this:

.{
    .name = "demo",
    .version = "0.0.1",
    .dependencies = .{
        .@"raylib-zig" = .{
            .url = "https://github.com/Not-Nik/raylib-zig/archive/devel.tar.gz",
            .hash = "1220df9aa89d657f5dca24ab0ac3d187f7a992a4d27461fd9e76e934bf0670ca9a90",
        },
    },
    .paths = .{""},
}