zig-webui icon indicating copy to clipboard operation
zig-webui copied to clipboard

linux -> macos cross compilation question

Open happyalu opened this issue 6 months ago • 6 comments

Hi,

If I wanted to cross compile an app that uses zig-webui from linux to macos, and if I had the apple sdk somewhere on the linux host, could you please help me understand how to provide this path during the build? I tried setting --sysroot and --search-prefix but that didn't help. Not sure if those options are propagated to dependencies.

Thanks

happyalu avatar Jul 20 '25 07:07 happyalu

Update: If I modified webui/build.zig to add something like this, I can get the cross compilation to work (for webui at least). However, now I'm trying to look into how to propagate that from my_project -> zig-webui -> webui.

    const sdk_path = "sdk";
    exe.addSystemIncludePath(b.path(sdk_path ++ "/System/Library/Frameworks"));
    exe.addSystemIncludePath(b.path(sdk_path ++ "/usr/include"));
    exe.addFrameworkPath(b.path(sdk_path ++ "/System/Library/Frameworks"));

happyalu avatar Jul 21 '25 03:07 happyalu

I think I'll close this. Adding those things to the main binary seems to have worked; I switched to using local dependencies of webui and zig-webui, not sure if that solved it or not.

The trouble is far from over since the zig build is now segfaulting during the cross compilation; but this issue isn't the cause.

happyalu avatar Jul 21 '25 05:07 happyalu

Wow, man, can you provide a complete reproduction process?

I want to try it on m4

jinzhongjia avatar Jul 21 '25 09:07 jinzhongjia

// on a linux machine:

mkdir foo cd foo zig init zig fetch --save https://github.com/webui-dev/zig-webui/archive/7bac77b09511b612cb653a431da94dbeb4cfae6a.tar.gz

// copy examples/minimal/main.zig to src/main.zig

// add this to build.zig:

    const zig_webui = b.dependency("zig_webui", .{
        .target = target,
        .optimize = optimize,
        .enable_tls = false, // whether enable tls support
        .is_static = true, // whether static link
    });

    exe_mod.addImport("webui", zig_webui.module("webui"));

// on linux, this works: zig build

// cross compilation fails:

*❯ zig build -Dtarget=x86_64-macos
install
└─ install foo
   └─ zig build-exe foo Debug x86_64-macos
      └─ zig build-lib webui Debug x86_64-macos failure
error: error: unable to find framework 'Cocoa'. searched paths:  none
error: unable to find framework 'WebKit'. searched paths:  none

// download sdk from here: https://github.com/joseluisq/macosx-sdks/releases/download/15.5/MacOSX15.5.sdk.tar.xz

// unzip it to, say, /tmp/sdk/MacOSX15.5.sdk

// back to the project directory: ln -sf /tmp/sdk/MacOSX15.5.sdk sdk

// update build.zig as follows:

    if (target.result.isDarwinLibC()) {
        const sdk_path = "sdk";
        exe.addSystemIncludePath(b.path(sdk_path ++ "/System/Library/Frameworks"));
        exe.addSystemIncludePath(b.path(sdk_path ++ "/usr/include"));
        exe.addFrameworkPath(b.path(sdk_path ++ "/System/Library/Frameworks"));
    }

// cross compilation still doesn't work.

❯ zig build -Dtarget=x86_64-macos
install
└─ install foo
   └─ zig build-exe foo Debug x86_64-macos
      └─ zig build-lib webui Debug x86_64-macos failure
error: error: unable to find framework 'Cocoa'. searched paths:  none
error: unable to find framework 'WebKit'. searched paths:  none

// make a local copy of the deps. mkdir deps cd deps git clone [email protected]:webui-dev/zig-webui git clone [email protected]:webui-dev/webui

cd zig-webui // edit build.zig.json to use:

        .webui = .{
            .path = "../webui/",
            //.hash = "webui-2.5.0-beta.4-pxqD5bE4NwCVDCBguzzRmyOubiadAaVRNM0XMxqUv_GS",
            //.url = "https://github.com/webui-dev/webui/archive/e673cee5a26b4c475395ce8e2f5fb92608bf3574.tar.gz",
        },

cd ../.. // edit build.zig.json to use

        .zig_webui = .{
            .path = "./deps/zig-webui/",
            //.url = "https://github.com/webui-dev/zig-webui/archive/7bac77b09511b612cb653a431da94dbeb4cfae6a.tar.gz",
            //.hash = "zig_webui-2.5.0-beta.4-M4z7zclVAQDqPWXDSPZqTLauq-75FEfI0Sa644Fhk_hS",
        },

// cross compilation still fails.

// edit deps/webui/build.zig to have the following:

    if (target.result.isDarwinLibC()) {
        const sdk_path = "sdk";
        webui.addSystemIncludePath(b.path(sdk_path ++ "/System/Library/Frameworks"));
        webui.addSystemIncludePath(b.path(sdk_path ++ "/usr/include"));
        webui.addFrameworkPath(b.path(sdk_path ++ "/System/Library/Frameworks"));
    }

// also needs an sdk link:

ln -sf /tmp/sdk/MacOSX15.5.sdk deps/webui/sdk

// zig build now finds the frameworks, but segfaults. I wasn't able to figure out why it segfaults.

❯ zig build -Dtarget=x86_64-macos
install
└─ install foo
   └─ zig build-exe foo Debug x86_64-macos failure
error: the following command terminated unexpectedly:
/nix/store/55609r49jmh9kzdbcxclx2f5cq9ifk31-zig-0.14.1/bin/zig build-exe ..... 

Build Summary: 5/8 steps succeeded; 1 failed
install transitive failure
└─ install foo transitive failure
   └─ zig build-exe foo Debug x86_64-macos failure

Maybe this is wishful on my part that it might work. It would be really cool, but maybe it's difficult. It does work for windows :)

happyalu avatar Jul 21 '25 10:07 happyalu

Thank you @happyalu for reporting this 👍 We will look into this soon

AlbertShown avatar Jul 21 '25 15:07 AlbertShown

I think I got this to work.

Add this to build.zig.zon as a dependency:

        .macos_sdk = .{
            .url = "https://github.com/joseluisq/macosx-sdks/releases/download/15.5/MacOSX15.5.sdk.tar.xz",
            .hash = "N-V-__8AAEg0c2TYnl45ERm8qt0B6b-Rretjyf62AnCDkFMl",
            .lazy = true,
        },

Assuming that we have, in the build.zig :

    const zig_webui_enableTLS = false;
    const zig_webui_isStatic = true;

     const zig_webui = b.dependency("zig_webui", .{
         .target = target,
         .optimize = optimize,
        .enable_tls = zig_webui_enableTLS,
        .is_static = zig_webui_isStatic,
    });

We can add this to the build.zig:

    if (target.result.os.tag == .macos) {
        const maybe_macos_sdk = b.lazyDependency("macos_sdk", .{});
        if (maybe_macos_sdk) |macos_sdk| {
            const macos_sdk_path = macos_sdk.path("");

            const webui_c_lib = zig_webui.builder.dependency("webui", .{
                .target = target,
                .optimize = optimize,
                .dynamic = !zig_webui_isStatic,
                .@"enable-tls" = zig_webui_enableTLS,
                .@"enable-webui-log" = zig_webui_enableTLS,
                .verbose = .err,
            }).artifact("webui");
            webui_c_lib.addSystemFrameworkPath(macos_sdk_path.path(b, "System/Library/Frameworks"));
            webui_c_lib.addSystemIncludePath(macos_sdk_path.path(b, "usr/include"));
            webui_c_lib.addLibraryPath(macos_sdk_path.path(b, "usr/lib"));

            exe.addSystemFrameworkPath(macos_sdk_path.path(b, "System/Library/Frameworks"));
            exe.addSystemIncludePath(macos_sdk_path.path(b, "usr/include"));
            exe.addLibraryPath(macos_sdk_path.path(b, "usr/lib"));
        }
    }

zig build now works with -Dtarget=aarch64-macos or -Dtarget=x86_64-macos even from linux.

It would be nice if the build.zig of zig_webui could expose the "artifact" of webui directly, because if the parameters passed for webui_c_lib don't match here exactly with what zig-webui's build.zig uses, then this doesn't work.

happyalu avatar Jul 29 '25 10:07 happyalu

Hey, have we done more tests?

If this is useful, we can merge this to zig-webui ?

jinzhongjia avatar Nov 24 '25 12:11 jinzhongjia