Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem finding c headers #2

Open
wiiggee1 opened this issue Feb 9, 2025 · 0 comments
Open

Problem finding c headers #2

wiiggee1 opened this issue Feb 9, 2025 · 0 comments

Comments

@wiiggee1
Copy link

wiiggee1 commented Feb 9, 2025

Hi, I am writing my Master Thesis and trying to setup Zig with esp idf. Write now I am facing the problem of not finding certain c headers such as freertos. My build.zig looks like this.

const std = @import("std");

// Although this function looks imperative, note that its job is to
// declaratively construct a build graph that will be executed by an external
// runner.
pub fn build(b: *std.Build) !void {
    // Standard target options allows the person running `zig build` to choose
    // what target to build for. Here we do not override the defaults, which
    // means any target is allowed, and the default is native. Other options
    // for restricting supported target set are available.
    const esp32s3_target = std.Target.Query{
        .cpu_arch = .xtensa,
        .cpu_model = .{ .explicit = &std.Target.xtensa.cpu.esp32s3 },
        .os_tag = .freestanding,
        .abi = .none,
    };

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

    // Ensure that Zig can find the necessary ESP-IDF header files.
    // const home_directory = std.process.getEnvVarOwned(b.allocator, "HOME") catch "";
    const esp_idf_path = std.process.getEnvVarOwned(b.allocator, "IDF_PATH") catch "";
    std.debug.print("esp_idf_path: {s}\n", .{esp_idf_path});

    //Here goes a static library to be linked with c / c++ app.
    const esp_idf_lib = b.addStaticLibrary(.{
        .name = "zig_main",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
        .link_libc = true,
    });

    if (!std.mem.eql(u8, esp_idf_path, "")) {
        esp_idf_lib.linkLibC();
        try searched_idf_include(b, esp_idf_lib, esp_idf_path);
        //try searched_idf_libs(b, esp_idf_lib);
        //try add_c_includes(b, esp_idf_lib);
    }

    b.installArtifact(esp_idf_lib);

    esp_idf_lib.setLinkerScript(b.path("linker.ld"));

    const link = b.addSystemCommand(&[_][]const u8{
        "xtensa-esp32-elf-gcc",
        "-T",
        "linker.ld",
        "-o",
        "esp32_s3_app",
        "main.o",
    });

    link.step.dependOn(&esp_idf_lib.step);

    const link_step = b.step("link", "Linking the ELF binary from the .o (object) files.");
    link_step.dependOn(&link.step);

    // This *creates* a Run step in the build graph, to be executed when another
    // step is evaluated that depends on it. The next line below will establish
    // such a dependency.
    //const run_cmd = b.addRunArtifact(exe);

    // By making the run step depend on the install step, it will be run from the
    // installation directory rather than directly from within the cache directory.
    // This is not necessary, however, if the application depends on other installed
    // files, this ensures they will be present and in the expected location.
    //run_cmd.step.dependOn(b.getInstallStep());

    // This allows the user to pass arguments to the application in the build
    // command itself, like this: `zig build run -- arg1 arg2 etc`
    // if (b.args) |args| {
    //     run_cmd.addArgs(args);
    // }

    // This creates a build step. It will be visible in the `zig build --help` menu,
    // and can be selected like this: `zig build run`
    // This will evaluate the `run` step rather than the default, which is "install".
    // const run_step = b.step("run", "Run the app");
    // run_step.dependOn(&run_cmd.step);

    // Creates a step for unit testing. This only builds the test executable
    // but does not run it.
    // const lib_unit_tests = b.addTest(.{
    //     .root_source_file = b.path("src/root.zig"),
    //     .target = target,
    //     .optimize = optimize,
    // });

    //const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);

    // const exe_unit_tests = b.addTest(.{
    //     .root_source_file = b.path("src/main.zig"),
    //     .target = target,
    //     .optimize = optimize,
    // });

    // const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);

    // Similar to creating the run step earlier, this exposes a `test` step to
    // the `zig build --help` menu, providing a way for the user to request
    // running the unit tests.
    // const test_step = b.step("test", "Run unit tests");
    //test_step.dependOn(&run_lib_unit_tests.step);
    // test_step.dependOn(&run_exe_unit_tests.step);
}

pub fn add_c_includes(b: *std.Build, lib: *std.Build.Step.Compile) !void {
    //const home_directory = std.process.getEnvVarOwned(b.allocator, "HOME") catch "";
    const esp_idf_path = std.process.getEnvVarOwned(b.allocator, "IDF_PATH") catch "/home/wiiggee1/esp-idf/";
    const esp_components = std.fmt.allocPrint(b.allocator, "{s}/components", .{esp_idf_path}) catch @panic("Out of Memory");

    var comp_dir = std.fs.openDirAbsolute(esp_components, .{ .iterate = true }) catch @panic("Failed to open dir!");
    std.debug.print("component iterator buffer: {s}\n", .{comp_dir.iterate().buf});

    var dir_it = comp_dir.iterate();
    while (dir_it.next()) |dir| {
        const comp = dir orelse break;
        const comp_name: []const u8 = comp.name;
        //const esp_comp_lib = std.fmt.allocPrint(b.allocator, "lib{s}", .{comp_name}) catch @panic("Out of Memory");

        const esp_comp = std.fmt.allocPrint(b.allocator, "{s}/{s}/include/", .{ esp_components, comp_name }) catch @panic("Out of Memory");

        // const esp_comp_src = std.fmt.allocPrint(b.allocator, "{s}/{s}/", .{ esp_components, comp_name }) catch @panic("Out of Memory");

        if (comp.kind != .directory) {
            continue;
        }
        // std.debug.print("kind: {any}\n", .{comp.kind});
        //std.debug.print("esp_component name: {s}\n", .{comp_name});
        //std.debug.print("esp_comp path: {s}\n", .{esp_comp});
        //esp_idf_lib.addSystemIncludePath(.{ .cwd_relative = esp_comp });
        lib.addIncludePath(.{ .cwd_relative = esp_comp });
    } else |err| {
        std.debug.print("Got error: {s}", .{@errorName(err)});
        return;
    }
    comp_dir.close();

    lib.linkLibC();
}

pub fn searched_idf_include(b: *std.Build, lib: *std.Build.Step.Compile, idf_path: []const u8) !void {
    const comp = b.pathJoin(&.{ idf_path, "components" });
    var dir = try std.fs.cwd().openDir(comp, .{
        .iterate = true,
    });
    defer dir.close();
    var walker = try dir.walk(b.allocator);
    defer walker.deinit();

    while (try walker.next()) |entry| {
        _ = std.fs.path.extension(entry.basename);
        if (entry.kind == .directory) {
            if (std.mem.indexOf(u8, entry.path, "/include") != null) {
                const include_directory = b.pathJoin(&.{ comp, std.fs.path.dirname(b.dupe(entry.path)).? });
                std.debug.print("Adding include path: {s}\n", .{include_directory});
                lib.addSystemIncludePath(.{ .cwd_relative = include_directory });
            }
        }

        // const include_file = inline for (&.{".h"}) |e| {
        //     //std.debug.print("ext == e: ; {s} == {s}, break true", .{ ext, e });
        //     if (std.mem.eql(u8, ext, e))
        //         break true;
        // } else false;
        // //###############################
        // if (include_file) {
        //     const include_dir = b.pathJoin(&.{ comp, std.fs.path.dirname(b.dupe(entry.path)).? });
        //     //std.debug.print("component include dir: {s}\n", .{include_dir});
        //     //_ = lib.out_filename;
        //     // lib.addSystemIncludePath(.{ .cwd_relative = include_dir });
        //     lib.addIncludePath(.{ .cwd_relative = include_dir });
        // }
    }
}

pub fn searched_idf_libs(b: *std.Build, lib: *std.Build.Step.Compile) !void {
    var dir = try std.fs.cwd().openDir("../build", .{
        .iterate = true,
    });
    defer dir.close();
    var walker = try dir.walk(b.allocator);
    defer walker.deinit();

    while (try walker.next()) |entry| {
        const ext = std.fs.path.extension(entry.basename);
        const lib_ext = inline for (&.{".obj"}) |e| {
            if (std.mem.eql(u8, ext, e))
                break true;
        } else false;
        if (lib_ext) {
            const src_path = std.fs.path.dirname(@src().file) orelse b.pathResolve(&.{".."});
            const cwd_path = b.pathJoin(&.{ src_path, "build", b.dupe(entry.path) });
            const lib_file: std.Build.LazyPath = .{ .cwd_relative = cwd_path };
            lib.addObjectFile(lib_file);
        }
    }
}

Do you have any tips / suggestions?

To clarify things. It doesn't seem to find some header files.

Image

VS

Image

and :

Image

This is what I get trying to compile:

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant