#Fail to trigger build for raylib from my project while moving build to zig

1 messages · Page 1 of 1 (latest)

mighty kite
#

Hi, I am new here and to zig so feel free to point me to appropriate doc.
I am trying to use zig in an existing C project and looking at changing my current build system. I am using raylib at present and want to create a project root level build.zig which should then trigger raylib build.

//! Build script for the overall project

const std = @import("std");
const raylib = @import("extra/raylib/build.zig");

// This has been tested to work with zig 0.11.0 and zig 0.12.0-dev.2075+f5978181e
pub fn build(b: *std.Build) !void {
    try raylib.build(b);
}

This doesnt work and fails at the install stage where the raylib/src/build.zig uses relative path which doesnt work due to this setup. Any pointers to work around this wil be helpful.
The code in raylib/src/build.zig is as follows (for reference):

    lib.installHeader("src/raylib.h", "raylib.h");
    lib.installHeader("src/raymath.h", "raymath.h");
    lib.installHeader("src/rlgl.h", "rlgl.h");

The reason for failure is because when the zig build runs then it runs from base folder of my project, but raylib is inside a subfolder, but the raylib/src/build.zig assumes while installing (see above) that it is inside the raylib folder (which is not true).

>zig build
install
└─ install src\raymath.h to raymath.h failure
#

Fail to trigger build for raylib from my project while moving build to zig

fossil umbra
#

Which Zig version do you actually want to use?

mighty kite
#

0.12.0-dev.3291+17bad9f88

fossil umbra
#

You should create a build.zig.zon in your root dir with:

.{
    .name = "yourproject",
    .version = "0.0.0",
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src", // or whatever dirs you have
    },
    .dependencies = .{
        .raylib = .{
            .path = "extra/raylib",
        },
    },
}

and then do

const raylib = b.dependency("raylib", .{
    .target = target,
    .optimize = optimize,
}).artifact("raylib");
mighty kite
#

Let me try this out.

fossil umbra
#

you can import other build.zig files with @import("raylib"), but I don't see a reason to do that here

mighty kite
#

where do I get value of target?

fossil umbra
#

you can drop target to only support native builds and optimize to only support debug builds or support cross compiling to a target and optimization level specified on the command line with:

const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
mighty kite
#

appologies for asking basic questions, but I am still very early in learning zig.
I got the earlier build.zig from raylib, so when I updated with your suggestion then it looks like the following (which is probably incorrect since zig build fails).

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

    const raylib = b.dependency("raylib", .{
        .target = target,
        .optimize = optimize,
    }).artifact("raylib");
    try raylib.build(b);  // INCORRECT?
}

Error log

build.zig:38:15: error: no field or member function named 'build' in 'Build.Step.Compile'
    try raylib.build(b);
        ~~~~~~^~~~~~

Basically, I have a root folder with a couple of subfolder. Few of those are for library (assume common, math, etc) and then there are few for different apps (ultimately builds to binary, assume smartcalc, smartsearch, etc). I have raylib in extra/raylib which I want to use across apps.
I am trying to hack together a build system in zig so that I can then slowly move the C project to zig (incrementally).

#

cross platform is important for me, so I want to leverage zig as build system to generate binaries for different architectures.

fossil umbra
#

yeah delete that line

#

Adding it to .dependencies runs the build.zig for you in the correct directory

#

raylib is the library artifact that you can link your program to

mighty kite
#

If there is a sample project in c or c++ which uses zig as build system then I can read more on that to avoid asking basic questions.

fossil umbra
#

The template for a c(++) project would be:

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

    const raylib = b.dependency("raylib", .{
        .target = target,
        .optimize = optimize,
    }).artifact("raylib");

    const smartcalc_exe = b.addExecutable(.{
        .name = "smartcalc",
        .target = target,
        .optimize = optimize,
    });
    smartcalc_exe.linkLibC(); // For C only
    smartcalc_exe.root_module.linkLibrary(raylib);
    smartcalc_exe.root_Module.addIncludePath(.{ .path = "src/smartcalc" });
    smartcalc_exe.root_module.addCSourceFiles(.{
        .root = .{ .path = "src/smartcalc" },
        .files = &.{
            "main.c",
            "other.c",
        },
    });
    b.installArtifact(smartcalc_exe);

    const smartsearch_exe = b.addExecutable(.{
        .name = "smartsearch",
        .target = target,
        .optimize = optimize,
    });
    smartsearch_exe.linkLibCpp(); // For C and C++
    smartsearch_exe.root_module.linkLibrary(raylib);
    smartsearch_exe.root_module.addIncludePath(.{ .path = "src/smartsearch" });
    smartsearch_exe.root_module.addCSourceFiles(.{
        .root = .{ .path = "src/smartsearch" },
        .files = &.{
            "main.c",
            "other.c",
        },
    });
    b.installArtifact(smartsearch_exe);
}
mighty kite
#

wow! Thanks a lot. Let me try this one out.

#

We did not give include path info for raylib. Will linkLibrary(raylib) also take care of include folder of raylib?

fossil umbra
#

Honestly I'm not sure, but I'm hoping that works correctly.

mighty kite
#

trying this one out.

tawny rampart
#

raylib uses

lib.installHeader("src/raylib.h", "raylib.h");
lib.installHeader("src/raymath.h", "raymath.h");
lib.installHeader("src/rlgl.h", "rlgl.h");

which afaik is why you dont have to add the include path. but there is LazyPath.dependency if you did need to. ie
exe.root_module.addIncludePath(.{ .dependency = .{ .dependency = raylib_dep, .sub_path = “src” } })

fossil umbra
#

I mean there's no src/include

tawny rampart
#

youre very right 😅

fossil umbra
#

but yeah, exe.root_module.addIncludePath(raylib_dep.path("src")); is the backup

tawny rampart
#

oh thats a lot easier to type lol

#

forgot about path

mighty kite
#

raylib is not happy with this setup.

Error:

>zig build
install
└─ install tools
   └─ zig build-exe tools Debug native
      └─ install ..\raygui\src\raygui.h to raygui.h failure
error: unable to update file from 'I:\arcadegames\extra\raygui\src\raygui.h' to 'I:\arcadegames\zig-cache\i\a67d3531234196dedd73541f1284ce1b\include\raygui.h': FileNotFound
install
└─ install tools
   └─ zig build-exe tools Debug native
      └─ zig build-lib raylib Debug native 1 errors
I:\arcadegames\zig-cache\o\abf9e8e63f51541ffc703ad35e651014\raygui.c:2:10: error: 'raygui.h' file not found
#include "raygui.h"
         ^~~~~~~~~~~

My build.zig which has one app for now included to keep things simple:

const std = @import("std");
const builtin = @import("builtin");

// This has been tested to work with zig 0.12.0-dev.3291+17bad9f88
pub fn build(b: *std.Build) !void {

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

    const raylib = b.dependency("raylib", .{
        .target = target,
        .optimize = optimize,
        .raygui = true
    }).artifact("raylib");

    const tools_exe = b.addExecutable(.{
        .name = "tools",
        .target = target,
        .optimize = optimize,
    });
    tools_exe.linkLibCpp(); // For C and C++
    tools_exe.root_module.linkLibrary(raylib);
    tools_exe.root_module.addIncludePath(.{ .path = "tools" });
    tools_exe.root_module.addCSourceFiles(.{
        .root = .{ .path = "tools" },
        .files = &.{
            "tools_main.c",
        },
    });
    b.installArtifact(tools_exe);
}

My build.zig.zon. Do I need to add all folders eventually which needs to be built? I have added tools for now.

.{
    .name = "smart",
    .version = "0.1.0",
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "tools", // or whatever dirs you have
    },
    .dependencies = .{
        .raylib = .{
            .path = "extra/raylib",
        },
    },
}
fossil umbra
#

Does extra/raygui exist?

mighty kite
#

yes

fossil umbra
#

well specifically I:\arcadegames\extra\raygui\src\raygui.h

mighty kite
#
I:.
├───extra
│   └───raylib
│       ├───.github
│
├───tools
└───zig-cache
    ├───h
fossil umbra
#

that's raylib not raygui

#

it sounds like you tried enabling raygui without adding raygui to extra

mighty kite
#

oops! It looks like I enabled raygui in options.

#

wow! It worked when I disabled raygui in options.

    const raylib = b.dependency("raylib", .{
        .target = target,
        .optimize = optimize,
        .raygui = false  // disabled
    }).artifact("raylib");
#

zig build is simply amazing. All that I get in zig-out is bin folder and rest in cache

Thanks @fossil umbra 🤗

#

Do I need to add all the folders which have binary app or generating libs in build.zig.zon?

#
.{
    .name = "smart",
    .version = "0.1.0",
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "tools", // I am taking about THIS. Is this required?
    },
    .dependencies = .{
        .raylib = .{
            .path = "extra/raylib",
        },
    },
}
fossil umbra
#

build.zig.zon defines a package, you should include every file/dir that should be a part of the package

mighty kite
#

Thanks

mighty kite
#

My build.zig worked when I use exe, but when I have lib which must be created from C sources then it complains about not finding 'windows.h' although I have in my code

#ifdef _WIN32

#include <windows.h>
// ...
#else
// ...
#endif

Errors:

      +- zig build-exe tictactoe Debug native
         +- zig build-lib utils Debug native 1 errors
I:\arcadegames\common\utils\src\cpuinfo.c:27:10: error: 'windows.h' file not found
error: the following command failed with 1 compilation errors:
D:\zig\zig.exe build-lib I:\arcadegames\common\utils\src\cpuinfo.c -ODebug -Mroot --cache-dir I:\arcadegames\zig-cache --global-cache-dir D:\Local\zig --name utils -static --listen=- 
Build Summary: 6/23 steps succeeded; 1 failed (disable with --summary none)

The build.zig is somewhat similar to

    const lib = b.addStaticLibrary(.{
        .name = "utils",
        .target = target,
        .optimize = optimize,
    });
    lib .addCSourceFile(.{ .file = .{ .path = path }, .flags = &.{} });

    const exe = b.addExecutable(.{
        .name = "tictactoe",
        .target = target,
        .optimize = optimize,
    });
    exe.linkLibC();
    exe.linkLibrary(lib );
    // ...

I am building lib with C sources from some subfolders, so that internally it creates a static lib but not install it. It will be used for linking final app.

#

update: Problem solved.

I was missing lib.linkLibC(); and when I added that then it worked 🙂