esp32-zig-starter
esp32-zig-starter copied to clipboard
Problem finding c headers
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.
VS
and :
This is what I get trying to compile: