zls icon indicating copy to clipboard operation
zls copied to clipboard

Imports aren't identified if artifacts aren't created

Open akhildevelops opened this issue 1 year ago • 3 comments

Zig Version

0.13.0

ZLS Version

0.13.0

Client / Code Editor / Extensions

VSCode

Steps to Reproduce and Observed Behavior

For below build.zig,

const std = @import("std");

pub fn build(b: *std.Build) void {
    const postgres_module = b.dependency("pg", .{}).module("pg");
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addExecutable(.{ .name = "see_cleverly", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize });
    lib.root_module.addImport("pg", postgres_module);

    // b.installArtifact(lib); 
}

pg is not identified by zls

image

Below build.zig works

const std = @import("std");

pub fn build(b: *std.Build) void {
    const postgres_module = b.dependency("pg", .{}).module("pg");
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addExecutable(.{ .name = "see_cleverly", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize });
    lib.root_module.addImport("pg", postgres_module);

    b.installArtifact(lib);
}

image

Why would installartifact matter for zls to identify imported module ?

Below build.zig also doesn't work if I treat zig application as just a dependency to be imported by others

const std = @import("std");

pub fn build(b: *std.Build) void {
    const postgres_module = b.dependency("pg", .{}).module("pg");
    const module = b.addModule("see_cleverly", .{ .root_source_file = b.path("src/main.zig") });
    module.addImport("pg", postgres_module);
}

Expected Behavior

Imports should be recognized by zls

Relevant log output

No response

akhildevelops avatar Aug 22 '24 17:08 akhildevelops

I'm getting the same behavior. Is there any workarounds?

taylorh140 avatar Aug 22 '24 20:08 taylorh140

Workaround is to add add this in your build.zig b.installArtifact(lib);

akhildevelops avatar Aug 23 '24 01:08 akhildevelops

Why would installartifact matter for zls to identify imported module ?

Declaring a compile step with b.addExecutable on its own has no side-effects. Every step needs to be reachable from a top-level-step like install test check etc. Calling b.installArtifact is one possible approach because it declares the compile step as a dependency of the install step. A step that is not reachable from a top-level-step is the equivalent of an unused variable. You never actually compiling your src/main.zig so why should ZLS know about it?

This is working as intended. Even if ZLS would want to handle this, there is no way to figure out that you declared an unused step. If a tree falls in a forest and no one is around to hear it, does it make a sound?

Declaring a module with b.addModule, on the other hand, has side-effects because it makes the module accessible to other projects via b.dependency. That should be fixed.

Techatrix avatar Aug 25 '24 13:08 Techatrix

It seems still not work now.

I use zig 0.14.0, zls 0.14.0 with nixvim(actually is neovim) on macos. [build.zig.zon]:

    .dependencies = .{
        .pg = .{
            .url = "git+https://github.com/karlseguin/pg.zig?ref=master#693388ca7c29278ad6a5d1b27bd007be32ec2bc2",
            .hash = "pg-0.0.0-Wp_7gdX4BQCDJwuyYYOfvFmJyOtXRzgUpoGBTtTYDzFV",
        },
    },

that is generated by ❯ zig fetch --save git+https://github.com/karlseguin/pg.zig#master

[build.zig]:

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const pg = b.dependency("pg", .{
        .target = target,
        .optimize = optimize,
    }).module("pg");

    const exe = b.addExecutable(.{
        .name = "sqlc-demo",
        .root_source_file = b.path("src/demo.zig"),
        .target = target,
        .optimize = optimize,
    });
    exe.root_module.addImport("pg", pg);
    b.installArtifact(exe);

[main.zig]:

const std = @import("std");
const pg = @import("pg");

pub fn main() !void {

zls still cannot recognize pg, take it as 'unknown'.

i11010520 avatar Mar 17 '25 15:03 i11010520