Real cross compilation with sysroot doesn't work

Hi,

On the MacOSX I want to do test cross-compilation of the very simple project where program should print on the screen gstreamer version.

This program is working on OSX but I can’t cross-compile it to the target aarch64-linux-gnu.

I have sysroot folder with all libraries and headers (it is working correctly with Make).

app.zig:

const std = @import("std");

const c = @cImport({
    @cInclude("gst/gst.h");
});

pub fn main() !void {
    std.debug.print("hello world \n", .{});
    var argc: c_int = 0;
    var argv: [*c][*c]u8 = null;
    c.gst_init(&argc, &argv);

    var major: c.uint = 0;
    var minor: c.uint = 0;
    var micro: c.uint = 0;
    var nano: c.uint = 0;
    c.gst_version(&major, &minor, &micro, &nano);

    if (nano == 1) {
        std.debug.print("Gstreamer Development Release: {d}.{d}.{d}.{d}\n", .{ major, minor, micro, nano });
    } else {
        std.debug.print("Gstreamer Development Release: {d}.{d}.{d}\n", .{ major, minor, micro });
    }
}

build.zig ← this idea is the main target of my interest of ZIG

const std = @import("std");

pub fn build(b: *std.Build) void {
    
    const exe = b.addExecutable(.{
        .name = "gst_version",
        .root_source_file = .{ .path = "app.zig" },
        //.target = b.host,
        .target = b.resolveTargetQuery(.{
            .cpu_arch = .aarch64,
            .os_tag = .linux,
            .abi = .gnu,
        }),
    });

    exe.addLibraryPath(.{ .path = "./usr/lib/aarch64-linux-gnu" });
    exe.addIncludePath(.{ .path = "/usr/include" });
    exe.addIncludePath(.{ .path = "/usr/include/gstreamer-1.0" });
    exe.linkSystemLibrary("gstreamer-1.0");
    //exe.linkSystemLibrary("gstreamer");
    exe.linkLibC();

    b.installArtifact(exe);
}
zig build --summary all --sysroot sysroot

And I got:

app.zig:3:11: error: C import failed
const c = @cImport({
          ^~~~~~~~
referenced by:
    main: app.zig:11:5
    callMain: /opt/homebrew/Cellar/zig/0.12.0/lib/zig/std/start.zig:511:32
    remaining reference traces hidden; use '-freference-trace' to see all reference traces
/Users/user/cross-cpp/zig-cache/o/ce1bb7180e1e4ac4e765f24ddfaa1a73/cimport.h:1:10: error: 'gst/gst.h' file not found
#include <gst/gst.h>

In many places I see that people correctly can cross compile but the programs are very simple without sysroot of the target.

I really want to make this real, because … cmake… I want this zig build.

Best regards and thanks for help.

Hello @sidhion Welcome to ziggit :slight_smile:

If it is possible to compile gstreamer using zig cc (zig cc is clang);
zig can compile and link to some versions of glibc on any supported target.

I am using zig to cross compile from linux targeting other mac, linux and windows platforms. But I have never used a sysroot for that.
Since zig compiler cannot find the include files, try to use the --search-prefix flag; documented as “Add a path to look for binaries, libraries, headers”.

But did you compile for target and specific libs that are not default in system for example rabbitmq/gstreamer? Sysroot is nice if it works, because I can use same path for example standard /usr/include for many target with different sysroots.

For example. I have Jetson Nano and there are /usr/include and /usr/lib. I then copy this to location in build host and define parent folder as sysroot. Next I set in CMake that sysroot for compilation is /path/to/sysroot. I don’t need to change any paths to point to this path only what I need is to set sysroot.

I am trying to point to includes and libs .so without success. I can’t use zig build? Because I want to replace CMake with this brilliant zig build system.

Edit:
I got progress this is working:

zig build-exe app.zig -target aarch64-linux-gnu -lc -I./sysroot/usr/include/gstreamer-1.0 -I./sysroot/usr/include/glib-2.0 -I./sysroot/usr/lib/aarch64-linux-gnu/glib-2.0/include -Lsysroot/usr/lib/aarch64-linux-gnu -lgstreamer-1.0

How move this to zig build? not build-exe?

Currently done:

    exe.addIncludePath(.{ .cwd_relative = "sysroot/usr/include/gstreamer-1.0" });

Only sad that I need to specify this and sysroot doesn’t resolve this.