Replacement for --pkg-begin ... --pkg-end command-line options

–pkg-begin <name> <path> Make pkg available to import and push current pkg
–pkg-end Pop current pkg

online docs for older versions of zig build-* described these options, used to specify an @import name and a root.zig

what’s equivalent in the latest zig-build-* tools??? short of using a build.zig file, i effectively have a “pre-computed” list of {, } which i’d like to pass to the tools…

--mod [name]:[deps]:[src] Make a module available for dependency under the given name.
see: New-Module-CLI in 0.11.0 release notes


(Assuming 0.12.0 master.)

Relevant excerpt from zig build-exe --help:

Global Compile Options:
  --dep [[import=]name]     Add an entry to the next module's import table
  -M[name][=src]            Create a module based on the current per-module settings.
                            The first module is the main module.
                            "std" can be configured by omitting src
                            After a -M argument, per-module settings are reset.

Per-Module Compile Options:
  -target [name]            <arch><sub>-<os>-<abi> see the targets command
  -O [mode]                 Choose what to optimize for
  (... omitted for brevity ...)

Per-Module Link Options:
  -l[lib], --library [lib]       Link against system library (only if actually used)
  (... omitted for brevity ...)

The per-module options you specify apply to the next module defined with an -M option (--dep is also per-module option), which completes the defininition of that module and “pops” it off the stack. Some per-module options will be inherited by dependencies; for example, if you specify -OReleaseSafe for the main module (the first -M module) but not for dependencies, they will also compiled under the ReleaseSafe optimize mode.

In practice an invocation will look something like zig build-exe -target x86_64-windows-gnu -OReleaseSafe --dep foo --dep bar -Mroot=main.zig -Mfoo=foo.zig -Mbar=bar.zig.

1 Like

my initial sandbox experiment worked, though i have a few follow-up questions…

in my use-case, i have a universe of modules with logical, globally-unique names (call them modA, modB, etc for now)… in practice, there will be ~100 of these…

within an given modX.zig, i’ll @import other modules from the universe using their logical names…

the dependence grapgh between these individual modules is in general quite complex – though it is acyclic… can i simply state my root module depends on ALL of the modX modules??? and would individual modules still be able to @import one another???

also, when i tried a simple experiment with just a single modA, i was able to say something like this in my main.zig:

const modA = @import("modA");

    _ =; 

my program built/ran just fine, though for whatever reason the zig extension for VS Code wasn’t able to figure out the type of modA… features like intellisense and even some syntax-highlighting didn’t work as expected…

when i originally imported modA as a relative path under src/ everything worked fine in VS Code…


No, you need to explicitly define the dependencies of each module, you can’t automatically depend on them all. For projects of this size with several dozen modules you’d probably be better off using the Zig build system than compiling via the command line.

When compiling via the command line ZLS won’t know where modules are coming from (because it doesn’t know the exact command you will invoke), so it can’t provide completions for any modules other than the root. If you want ZLS to find and provide completions for dependencies you need to use the build system.

Declare the modules in build.zig, even if you don’t use it for building, zig language server can use to discover the modules.

pub fn build(b: *std.Build) void {
    const mod_X = b.addModule("modX", .{
        .root_source_file = .{ .path = "src/modX.zig" },
    const mod_R = b.addModule("modR", .{
        .root_source_file = .{ .path = "src/modR.zig" },
        .imports = &.{
            .{ .name = "modX", .module = mod_X },

hmmm… let me try to restate what i’m REALLY trying to do – which is to “zigify” a legacy build model i’ve used to target resource-constrained bare-metal MCUs with ~32K of memory…

since my final executable programs are not very big, my legacy build model ultimately produced a single main.c file – which was then compiled by any number of C compilers (including LLVM)… since the “whole program” was contained in a single source file, i had no need for LTO…

upstream from main.c, the program comprises 100+ logical “units” which each have a globally unique name and will “import” one another in some hierarchic (acyclic) manner… the globally unique name of each unit is generally of the form libA/ModX – suggesting that these units are further organized into “libraries”…

still coming up to speed on zig, i could certainly place my entire universe of “units” and “libraries” under my src folder – at which point they could @import one another using relative paths of the form ../../libA/ModX.zig… imposing a uniform two-level directory structure under src is not unreasonable for my use-case…

to improve readability (if nothing else), i was hoping to say something like @import("libA/ModX")… since @import requires a string LITERAL, i can’t even programmatically map logical names to physical paths at comptime

i suppose i could generate some well-known .zig file that imports ALL such units in my universe, and then exposes these under more compact names derived from their physical path… what i don’t know is how “lazy” the zig compiler is about processing @import calls…

what if the 100+ units used in my program was drawn from a universe of 1000s… would they all be eagerly ingested by the compiler??? said another way, i could have 1000s of .zig files under my src folder – but my program will only directly/indirectly @import just 100 of these…

not sure whether this makes any sense, or whether i should look at the problem differently…

according to this it appears that @import is indeed lazy…

other suggestions in that thread are now making a little more sense to me as well…

bottom line – it does appear that i can create my own little “universe” under my src folder…