Spurious recompilations for conditional imports

Apologies up-front for the absence of a minimal reproducible example! I am juggling a stack of yaks at the moment, and want to get the question out of my system before I forget, in case someone knows the answer immediately!

I have the following setup in my main.zig:

const module = if (condition) @import("./foo.zig") else @import("./bar.zig");

I noticed that my binary gets recompiled if I touch either foo.zig or bar.zig, regardless of which one is actually used.

I think this has to happen because AstGen is not lazy, so, if there are syntax errors in the unused files, the compilation should fail. And, hopefully, incremental compilation should make the rest of the build mostly no-op.

However, what concerns me is that I have some downstream build steps, that use my binary as a LazyPath. And those steps seem to get re-run as well, and that is a relatively bigger deal for me.

Is there some way I can make build.zig “see” that the executable isn’t actually changed if the inactive file is modified?

hoisting it into a module would do it

.imports = .{
    .{ .name = "mymodule", .module = if (condition) foo_mod else bar_mod }
},
1 Like

Yeah, the origin of the code is exactly me trying to avoid modules and build-system involvement, to have simple model where I have just one big pile of source code, where everything is importable via a relative path :smiley:

1 Like

Have you tried putting the imports in variables?

const a = @import("./foo.zig");
const b = @import("./bar.zig");
const module = if (condition) a else b;

yup, lazy evaluation only starts in semantic analysis since that is needed to truly know what is and is not used.

I think this is just a limitation of the non-incremental caching being less fine-grained, which should change as incremental develops more.

It could also be an unrelated caching bug…