Build error - "error: no field or member function named 'setTarget' in 'Build.Step.Compile'"

Hi all - first-timer here and very much enjoying using Zig!

I’m creating a small OS and I’ve got an error with my build script while trying to build the code -
"error: no field or member function named ‘setTarget’ in ‘Build.Step.Compile’ "

My Zig version is 0.12.0-dev.2811+3cafb9655 and I’m developing on Linux.

The block of code causing the problem is here -

   kernel.linkLibC();
    kernel.setTarget(b.standardTargetOptions(.{}));    //  <------  error is here   
    kernel.install(); 

So, I’m hoping that someone can help out here… :slight_smile:

Many thanks in advance - bye for now -

  • mooseman

Hi, and welcome to the community!

The usual way to set the target for a compilation is by passing an option to the function that creates it, such as

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

const kernel = b.addExecutable(.{
    // ...
    .target = target,
    // ...
});

However, if you want to work with the target after creating the compile step, you can use kernel.root_module.resolved_target (and set that field directly).

Since you’re using master (0.12 development), there was a major rework recently of the build system which changed a lot about how things are structured: Move many settings from being per-Compilation to being per-Module by andrewrk · Pull Request #18160 · ziglang/zig · GitHub As a result, much of the old build system code you might come across from older versions will need some tweaks to account for it. The PR description contains a migration guide which covers a lot of it.

Finally, if you’re interested in learning more about the build system, there’s an official guide here: Zig Build System ⚡ Zig Programming Language You might find some of the more advanced topics helpful as you get further along in your project.

2 Likes

Hi ianprime0509 - thanks very much for that!

I’m developing for x86_64 so given that, I guess I’d have something like this -

  ```
const kernel = b.addExecutable(.{
    // ...
    .target = "x86_64" ,
    // ...
});
```

Does that look correct?
Thanks -

  • mooseman

Not quite, the target is expected to be a ResolvedTarget, which provides the build system with quite a few bits of information about the build target, including the CPU architecture and operating system.

You can get a ResolvedTarget for a target of your choice by using b.resolveTargetQuery. For example, since you’re making your own OS for x86-64, you’ll need a freestanding target (no OS), which will look like this:

const target = b.resolveTargetQuery(.{
    .cpu_arch = .x86_64,
    .os_tag = .freestanding,
});
1 Like

Hi ianprime0509 -

Thanks very much for that - looks good!

Just another quick question - Now that I have that block of code -

const target = b.resolveTargetQuery(.{
    .cpu_arch = .x86_64,
    .os_tag = .freestanding,
 });
  • I’m wondering what I should change this line to -
kernel.setTarget(b.standardTargetOptions(.{}));   

I was thinking something like this -

kernel.setTarget(target);   

Does that look correct? Thanks -

  • mooseman

Welcome @mooseman,

The usual usage is:

const target = b.resolveTargetQuery(.{
    .cpu_arch = .x86_64,
    .os_tag = .freestanding,
});

const kernel = b.addExecutable(.{
    // ...
    .target = target,
    // ...
});
1 Like

Ahhh - many thanks, dimdin!

Just one more question here (sorry for that…) -
I have an assembly file as part of the kernel.
Given that I have imports like this already -

kernel.root_module.addImport("system_interrupts", b.createModule(.{
        .root_source_file = .{ .path = "src/kernel/system_interrupts.zig" },
    }));
  • would the asm file be added in like this -
 kernel.root_module.addImport("interrupts", b.createModule(.{
        .root_source_file = .{ .path = "src/kernel/kernel_asm/interrupts.asm" },
    })); 

Update: I tried that and it seemed to work! (Well, Zig didn’t complain about it anyway… :slight_smile: )

Sorry for the many questions. I’m very used to Makefiles and am comfortable with them - it just takes a while to get used to the new build system in Zig…

I’m off to bed soon, so I’ll see you all again tomorrow - thanks to all for your help!
Cheers -

  • mooseman

To add an assembly file use addAssemblyFile (available in modules and in artifacts/steps).
A nice zig assembly tutorial from @yingyi is: https://blog.nvimer.org/2023/04/01/assembly-in-zig/

2 Likes

Thanks for mentioning my article. This is my record when I tried to write a toy kernel in the past. If it is wrong or outdated, please call me directly.

3 Likes

Hi dimdin and yingyi - thanks for that, that’s awesome!
Looks like a great tutorial there too, yingyi - many thanks for doing that!

I am absolutely hooked on Zig! It is sooooo much faster developing inj Zig rather than C as you don’t have to mess around with header files!
The whole language (from the syntax to the build build process) seems to have been really well thought-out. Beautifully designed!

That’s all for now. Thanks again - bye for now… :slight_smile:

  • mooseman
4 Likes