zig icon indicating copy to clipboard operation
zig copied to clipboard

Possible option file caching issue

Open voroskoi opened this issue 1 year ago • 1 comments

Zig Version

0.12.0-dev.3667+77abd3a96

Steps to Reproduce and Observed Behavior

  1. Create a zig module which has one option called foo.
  2. Use createModule() and make the options available for importing.
  3. Now create an other module which also has an option called foo and no other options.
  4. Also use the second package's options in this new module.
  5. Try to build it.

You will see some similar error message: zig-cache/c/b1eb6d44884b0101056eb8b005a5056c/options.zig:1:1: error: file exists in multiple modules zig-cache/c/b1eb6d44884b0101056eb8b005a5056c/options.zig:1:1: note: root of module build_options zig-cache/c/b1eb6d44884b0101056eb8b005a5056c/options.zig:1:1: note: root of module build_options0

If You add some other options to any of the packages the error goes away. I think the cache system merges the to options.zig because their content is the same.

I think when You have a module (A) with some options and You build upon that and want to expose those options via Your new module (B) without adding any further options You will always encounter this error, but the use-case seems to be quite common for me.

Expected Behavior

I think that option files created with std.Build.createOptions() should not be cached to avoid this issue, or maybe I am just using the build system wrong.

voroskoi avatar Apr 18 '24 21:04 voroskoi

Repro build.zig:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const wf = b.addWriteFiles();

    const exe = b.addExecutable(.{
        .name = "main",
        .root_source_file = wf.add("main.zig",
            \\pub const mod1 = @import("mod1");
            \\pub const mod2 = @import("mod2");
            \\pub fn main() void {
            \\    _ = mod1;
            \\    _ = mod2;
            \\}
        ),
        .target = b.resolveTargetQuery(.{}),
    });

    const options1 = b.addOptions();
    options1.addOption([]const u8, "foo", "foo");
    const mod1 = b.createModule(.{
        .root_source_file = wf.add("mod1.zig",
            \\pub const options = @import("build_options");
        ),
    });
    mod1.addOptions("build_options", options1);
    exe.root_module.addImport("mod1", mod1);

    const options2 = b.addOptions();
    options2.addOption([]const u8, "foo", "foo");
    const mod2 = b.createModule(.{
        .root_source_file = wf.add("mod2.zig",
            \\pub const options = @import("build_options");
        ),
    });
    mod2.addOptions("build_options", options2);
    exe.root_module.addImport("mod2", mod2);

    b.installArtifact(exe);
}

It's an interesting problem. I suspect you could also run into this if you had two Step.Run that both ran the same command and produced the same output source files. Maybe generated and deduplicated files should be excluded from the "file exists in multiple modules" check?

castholm avatar Apr 18 '24 22:04 castholm