68 Commits

Author SHA1 Message Date
Andrew Kelley
749f10af49 std.ArrayList: make unmanaged the default 2025-08-11 15:52:49 -07:00
mlugg
422e8d476c
build runner: fix FTBFS on targets without --watch implementation
This was a regression in #24588.

I have verified that this patch works by confirming that with the
downstream patches SerenityOS apply to the Zig source tree (sans the one
working around this regression), I can build the build runner for
SerenityOS.

Resolves: #24682
2025-08-04 09:47:56 +01:00
mlugg
abf1795337 std.Build.Watch: add macOS implementation based on FSEventStream
Resolves: #21905
2025-08-02 05:13:13 +01:00
mlugg
dcc3e6e1dd build system: replace fuzzing UI with build UI, add time report
This commit replaces the "fuzzer" UI, previously accessed with the
`--fuzz` and `--port` flags, with a more interesting web UI which allows
more interactions with the Zig build system. Most notably, it allows
accessing the data emitted by a new "time report" system, which allows
users to see which parts of Zig programs take the longest to compile.

The option to expose the web UI is `--webui`. By default, it will listen
on `[::1]` on a random port, but any IPv6 or IPv4 address can be
specified with e.g. `--webui=[::1]:8000` or `--webui=127.0.0.1:8000`.
The options `--fuzz` and `--time-report` both imply `--webui` if not
given. Currently, `--webui` is incompatible with `--watch`; specifying
both will cause `zig build` to exit with a fatal error.

When the web UI is enabled, the build runner spawns the web server as
soon as the configure phase completes. The frontend code consists of one
HTML file, one JavaScript file, two CSS files, and a few Zig source
files which are built into a WASM blob on-demand -- this is all very
similar to the old fuzzer UI. Also inherited from the fuzzer UI is that
the build system communicates with web clients over a WebSocket
connection.

When the build finishes, if `--webui` was passed (i.e. if the web server
is running), the build runner does not terminate; it continues running
to serve web requests, allowing interactive control of the build system.

In the web interface is an overall "status" indicating whether a build
is currently running, and also a list of all steps in this build. There
are visual indicators (colors and spinners) for in-progress, succeeded,
and failed steps. There is a "Rebuild" button which will cause the build
system to reset the state of every step (note that this does not affect
caching) and evaluate the step graph again.

If `--time-report` is passed to `zig build`, a new section of the
interface becomes visible, which associates every build step with a
"time report". For most steps, this is just a simple "time taken" value.
However, for `Compile` steps, the compiler communicates with the build
system to provide it with much more interesting information: time taken
for various pipeline phases, with a per-declaration and per-file
breakdown, sorted by slowest declarations/files first. This feature is
still in its early stages: the data can be a little tricky to
understand, and there is no way to, for instance, sort by different
properties, or filter to certain files. However, it has already given us
some interesting statistics, and can be useful for spotting, for
instance, particularly complex and slow compile-time logic.
Additionally, if a compilation uses LLVM, its time report includes the
"LLVM pass timing" information, which was previously accessible with the
(now removed) `-ftime-report` compiler flag.

To make time reports more useful, ZIR and compilation caches are ignored
by the Zig compiler when they are enabled -- in other words, `Compile`
steps *always* run, even if their result should be cached. This means
that the flag can be used to analyze a project's compile time without
having to repeatedly clear cache directory, for instance. However, when
using `-fincremental`, updates other than the first will only show you
the statistics for what changed on that particular update. Notably, this
gives us a fairly nice way to see exactly which declarations were
re-analyzed by an incremental update.

If `--fuzz` is passed to `zig build`, another section of the web
interface becomes visible, this time exposing the fuzzer. This is quite
similar to the fuzzer UI this commit replaces, with only a few cosmetic
tweaks. The interface is closer than before to supporting multiple fuzz
steps at a time (in line with the overall strategy for this build UI,
the goal will be for all of the fuzz steps to be accessible in the same
interface), but still doesn't actually support it. The fuzzer UI looks
quite different under the hood: as a result, various bugs are fixed,
although other bugs remain. For instance, viewing the source code of any
file other than the root of the main module is completely broken (as on
master) due to some bogus file-to-module assignment logic in the fuzzer
UI.

Implementation notes:

* The `lib/build-web/` directory holds the client side of the web UI.

* The general server logic is in `std.Build.WebServer`.

* Fuzzing-specific logic is in `std.Build.Fuzz`.

* `std.Build.abi` is the new home of `std.Build.Fuzz.abi`, since it now
  relates to the build system web UI in general.

* The build runner now has an **actual** general-purpose allocator,
  because thanks to `--watch` and `--webui`, the process can be
  arbitrarily long-lived. The gpa is `std.heap.DebugAllocator`, but the
  arena remains backed by `std.heap.page_allocator` for efficiency. I
  fixed several crashes caused by conflation of `gpa` and `arena` in the
  build runner and `std.Build`, but there may still be some I have
  missed.

* The I/O logic in `std.Build.WebServer` is pretty gnarly; there are a
  *lot* of threads involved. I anticipate this situation improving
  significantly once the `std.Io` interface (with concurrency support)
  is introduced.
2025-08-01 23:48:21 +01:00
Andrew Kelley
b22b9ebfe0 std.Progress: introduce Status 2025-07-25 17:33:11 -07:00
Andrew Kelley
5df52ca0a2 build runner: print newline before summary 2025-07-21 12:32:37 -07:00
Andrew Kelley
1a998886c8
Merge pull request #24329 from ziglang/writergate
Deprecates all existing std.io readers and writers in favor of the newly
provided std.io.Reader and std.io.Writer which are non-generic and have the
buffer above the vtable - in other words the buffer is in the interface, not
the implementation. This means that although Reader and Writer are no longer
generic, they are still transparent to optimization; all of the interface
functions have a concrete hot path operating on the buffer, and only make
vtable calls when the buffer is full.
2025-07-10 12:04:27 +02:00
triallax
5b4b033236 build runner: fix --verbose-llvm-bc= not properly accepting value
closes #21001
2025-07-10 11:04:29 +02:00
Andrew Kelley
87a7568a44 build runner: restore missing newline 2025-07-07 22:43:52 -07:00
Andrew Kelley
cce32bd1d5 fix build runner 2025-07-07 22:43:52 -07:00
Andrew Kelley
0e37ff0d59 std.fmt: breaking API changes
added adapter to AnyWriter and GenericWriter to help bridge the gap
between old and new API

make std.testing.expectFmt work at compile-time

std.fmt no longer has a dependency on std.unicode. Formatted printing
was never properly unicode-aware. Now it no longer pretends to be.

Breakage/deprecations:
* std.fs.File.reader -> std.fs.File.deprecatedReader
* std.fs.File.writer -> std.fs.File.deprecatedWriter
* std.io.GenericReader -> std.io.Reader
* std.io.GenericWriter -> std.io.Writer
* std.io.AnyReader -> std.io.Reader
* std.io.AnyWriter -> std.io.Writer
* std.fmt.format -> std.fmt.deprecatedFormat
* std.fmt.fmtSliceEscapeLower -> std.ascii.hexEscape
* std.fmt.fmtSliceEscapeUpper -> std.ascii.hexEscape
* std.fmt.fmtSliceHexLower -> {x}
* std.fmt.fmtSliceHexUpper -> {X}
* std.fmt.fmtIntSizeDec -> {B}
* std.fmt.fmtIntSizeBin -> {Bi}
* std.fmt.fmtDuration -> {D}
* std.fmt.fmtDurationSigned -> {D}
* {} -> {f} when there is a format method
* format method signature
  - anytype -> *std.io.Writer
  - inferred error set -> error{WriteFailed}
  - options -> (deleted)
* std.fmt.Formatted
  - now takes context type explicitly
  - no fmt string
2025-07-07 22:43:51 -07:00
Andrew Kelley
0b3f0124dc std.io: move getStdIn, getStdOut, getStdErr functions to fs.File
preparing to rearrange std.io namespace into an interface

how to upgrade:

std.io.getStdIn() -> std.fs.File.stdin()
std.io.getStdOut() -> std.fs.File.stdout()
std.io.getStdErr() -> std.fs.File.stderr()
2025-07-07 22:43:51 -07:00
Elaine Gibson
2e5b3b5c7c build runner: disable fuzz in single-threaded builds 2025-06-05 13:45:52 +01:00
Elaine Gibson
2cfa0f567d std.Build.Watch: not supported on haiku 2025-06-05 13:45:47 +01:00
Alex Rønne Petersen
87f8f47ba5
std.Build: Demote errors for exceeding max_rss to warnings.
We have no control over memory usage on arbitrary systems in the wild. But we
would still like to get the warnings so we can adjust the values based on
observations in the official ZSF CI.

Closes #23254.
Closes #23638.
2025-06-02 20:55:01 +02:00
mlugg
aeed5f9ebd
compiler: introduce incremental debug server
In a compiler built with debug extensions, pass `--debug-incremental` to
spawn the "incremental debug server". This is a TCP server exposing a
REPL which allows querying a bunch of compiler state, some of which is
stored only when that flag is passed. Eventually, this will probably
move into `std.zig.Server`/`std.zig.Client`, but this is easier to work
with right now. The easiest way to interact with the server is `telnet`.
2025-05-25 04:43:43 +01:00
mlugg
46d7e808dc
build runner: don't incorrectly omit reference traces
It's incorrect to ever set `include_reference_trace` here, because the
compiler has already given or not given reference traces depending on
the `-freference-trace` option propagated to the compiler process by
`std.Build.Step.Compile`.

Perhaps in future we could make the compiler always return the reference
trace when communicating over the compiler protocol; that'd be more
versatile than the current behavior, because the build runner could, for
instance, show a reference trace on-demand without having to even invoke
the compiler. That seems really useful, since the reference trace is
*often* unnecessary noise, but *sometimes* essential. However, we don't
live in that world right now, so passing the option here doesn't make
sense.

Resolves: #23415
2025-05-16 13:40:52 +01:00
Alex Rønne Petersen
35f30558ad
std.Build: Rename --glibc-runtimes to --libc-runtimes and enable it for musl. 2025-05-06 01:52:47 +02:00
Andrew Kelley
4e700fdf8e
Merge pull request #22516 from Jan200101/PR/build_id_option
std.Build: add build-id option
2025-04-11 16:37:46 -04:00
Jan200101
1a5dcff8e4
std.Build: update build-id flag description
it now denotes:
- all supported styles
- what a given style outputs
- what formats a given style supports
2025-04-05 22:11:07 +02:00
GalaxyShard
b5a5260546 std.Build: implement addEmbedPath for adding C #embed search directories 2025-03-27 09:47:42 +01:00
Eric Joldasov
27c1f2b3a0 zig build: allow to choose "lazy mode" for fetching process
`--fetch` flag now has additional optional parameter, which specifies
how lazy dependencies should be fetched:
 * `needed` — lazy dependencies are fetched only if they are required
   for current build configuration to work. Default and works same
   as old `--fetch` flag.
 * `all` — lazy dependencies are always fetched. If `--system` flag
   is used after that, it's guaranteed that **any** build configuration
   will not require additional download of dependencies during build.
   Helpful for distro packagers and CI systems:
   https://www.github.com/ziglang/zig/issues/14597#issuecomment-1426827495

If none is passed, behaviour is same as if `needed` was passed.

Signed-off-by: Eric Joldasov <bratishkaerik@landless-city.net>
2025-03-26 19:00:33 +01:00
Jan200101
013a228960 std.Build: add build-id option 2025-03-07 10:59:02 +01:00
Andrew Kelley
6b6c1b1b0e Revert "Merge pull request #22898 from kristoff-it/deprecated-proposal"
This reverts commit dea72d15da4fba909dc3ccb2e9dc5286372ac023, reversing
changes made to ab381933c87bcc744058d25a876cfdc0d23fc674.

The changeset does not work as advertised and does not have sufficient
test coverage.

Reopens #22822
2025-02-28 01:37:10 -08:00
Andrew Kelley
dea72d15da
Merge pull request #22898 from kristoff-it/deprecated-proposal
Implement `@deprecated`
2025-02-27 01:31:09 -05:00
Brad Olson
c031b62b83 compiler.build_runner: only build Fuzz on 64-bit platforms 2025-02-26 19:16:05 -05:00
Andrew Kelley
c5aa680c88 don't inherit allowed deprecation from parent modules
Inheriting allow-deprecation from parent modules doesn't make too much
sense, so instead make them default to disallow unless otherwise
specified. This allows build system to avoid redundant
`-fno-allow-deprecated` args.

This makes the generated CLIs smaller, and makes zig1.wasm update not
needed.

Also represented `is_root` differently (moved to field of graph).
2025-02-26 14:41:33 -05:00
Loris Cro
ba7cd8121d @deprecated: add build system support 2025-02-26 14:41:33 -05:00
Meghan Denny
9142482372
std.ArrayList: popOrNull() -> pop() [v2] (#22720) 2025-02-10 04:21:31 +00:00
Guillaume Wenzek
3348478fc3
Make -freference-trace work without colors
Currently -freference-trace only works when running from a terminal.
This is annoying if you're running in another environment or if you redirect the output.
But -freference-trace also works fine without the color, so change how the build runner is interpreting this option.
2025-01-30 13:02:06 +01:00
mlugg
0bb93ca053
std.Build: simplify module dependency handling
At the expense of a slight special case in the build runner, we can make
the handling of dependencies between modules a little shorter and much
easier to follow.

When module and step graphs are being constructed during the "configure"
phase, we do not set up step dependencies triggered by modules. Instead,
after the configure phase, the build runner traverses the whole
step/module graph, starting from the root top-level steps, and
configures all step dependencies implied by modules. The "make" phase
then proceeds as normal. Also, the old `Module.dependencyIterator` logic
is replaced by two separate iterables. `Module.getGraph` takes the root
module of a compilation, and returns all modules in its graph; while
`Step.Compile.getCompileDependencies` takes a `*Step.Compile` and
returns all `*Step.Compile` it depends on, recursively, possibly
excluding dynamic libraries. The old `Module.dependencyIterator`
combined these two functions into one unintuitive iterator; they are now
separated, which in particular helps readability at the usage sites
which only need one or the other.
2024-12-18 01:47:51 +05:00
mlugg
3e9810266b
compiler: add some missing consts
The previous commit exposed some missing `const` qualifiers in a few
places. These mutable slices could have been used to store invalid
values into memory!
2024-12-16 14:53:54 +00:00
Andrew Kelley
7a46ba73ce implement --watch for kqueue
it doesn't detect and remove no longer watched things yet

it also isn't aware of any file names reported by kqueue. I'm unsure if
that functionality exists.
2024-10-24 16:24:56 -07:00
Andrew Kelley
4706ec81d4 introduce a CLI flag to enable .so scripts; default off
The compiler defaults this value to off so that users whose system
shared libraries are all ELF files don't have to pay the cost of
checking every file to find out if it is a text file instead.

When a GNU ld script is encountered, the error message instructs users
about the CLI flag that will immediately solve their problem.
2024-10-23 16:27:38 -07:00
Linus Groh
8588964972 Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
Andrew Kelley
2a651eab45 build runner: --fuzz not yet supported on Windows 2024-08-07 00:48:32 -07:00
Andrew Kelley
e0ffac4e3c introduce a web interface for fuzzing
* new .zig-cache subdirectory: 'v'
  - stores coverage information with filename of hash of PCs that want
    coverage. This hash is a hex encoding of the 64-bit coverage ID.
* build runner
  * fixed bug in file system inputs when a compile step has an
    overridden zig_lib_dir field set.
  * set some std lib options optimized for the build runner
    - no side channel mitigations
    - no Transport Layer Security
    - no crypto fork safety
  * add a --port CLI arg for choosing the port the fuzzing web interface
    listens on. it defaults to choosing a random open port.
  * introduce a web server, and serve a basic single page application
    - shares wasm code with autodocs
    - assets are created live on request, for convenient development
      experience. main.wasm is properly cached if nothing changes.
    - sources.tar comes from file system inputs (introduced with the
      `--watch` feature)
  * receives coverage ID from test runner and sends it on a thread-safe
    queue to the WebServer.
* test runner
  - takes a zig cache directory argument now, for where to put coverage
    information.
  - sends coverage ID to parent process
* fuzzer
  - puts its logs (in debug mode) in .zig-cache/tmp/libfuzzer.log
  - computes coverage_id and makes it available with
    `fuzzer_coverage_id` exported function.
  - the memory-mapped coverage file is now namespaced by the coverage id
    in hex encoding, in `.zig-cache/v`
* tokenizer
  - add a fuzz test to check that several properties are upheld
2024-08-07 00:48:32 -07:00
Jarrod Meyer
2de0e2eca3 Watch.zig: add initial windows implementation 2024-07-27 11:32:43 -04:00
Andrew Kelley
a3c74aca99 add --debug-rt CLI arg to the compiler + bonus edits
The flag makes compiler_rt and libfuzzer be in debug mode.

Also:
* fuzzer: override debug logs and disable debug logs for frequently
  called functions
* std.Build.Fuzz: fix bug of rerunning the old unit test binary
* report errors from rebuilding the unit tests better
* link.Elf: additionally add tsan lib and fuzzer lib to the hash
2024-07-25 18:52:21 -07:00
Andrew Kelley
bce3b1efb0 build runner sends a start_fuzzing message to test runner 2024-07-25 18:52:21 -07:00
Andrew Kelley
711ed56ce3 build runner: extract logic to std.Build.Fuzz 2024-07-25 18:52:21 -07:00
Andrew Kelley
047640383e add --fuzz CLI argument to zig build
This flag makes the build runner rebuild unit tests after the pipeline
finishes, if it finds any unit tests.

I did not make this integrate with file system watching yet.

The test runner is updated to detect which tests are fuzz tests.

Run step is updated to track which test indexes are fuzz tests.
2024-07-25 18:52:20 -07:00
Andrew Kelley
33c7984183 add std.testing.random_seed
closes #17609
2024-07-23 11:43:12 -07:00
Andrew Kelley
445bd7a06f build runner: update watch caption to include subprocesses 2024-07-14 22:27:51 -07:00
Andrew Kelley
716b128a24 frontend: add -fincremental, -fno-incremental flag
Remove --debug-incremental

This flag is also added to the build system. Importantly, this tells
Compile step whether or not to keep the compiler running between
rebuilds. It defaults off because it is currently crashing
zirUpdateRefs.
2024-07-14 21:18:09 -07:00
Andrew Kelley
abf8955951 make zig compiler processes live across rebuilds
Changes the `make` function signature to take an options struct, which
additionally includes `watch: bool`. I intentionally am not exposing
this information to configure phase logic.

Also adds global zig cache to the compiler cache prefixes.

Closes #20600
2024-07-14 19:51:16 -07:00
Andrew Kelley
5efcc2e9e7 build runner: refactor fs watch logic for OS abstraction
Makes the build runner compile successfully for non-linux targets;
printing an error if you ask for --watch rather than making build
scripts fail to compile.
2024-07-12 14:20:20 -07:00
Andrew Kelley
a3c20dffae integrate Compile steps with file watching
Updates the build runner to unconditionally require a zig lib directory
parameter. This parameter is needed in order to correctly understand
file system inputs from zig compiler subprocesses, since they will refer
to "the zig lib directory", and the build runner needs to place file
system watches on directories in there.

The build runner's fanotify file watching implementation now accounts
for when two or more Cache.Path instances compare unequal but ultimately
refer to the same directory in the file system.

Breaking change: std.Build no longer has a zig_lib_dir field. Instead,
there is the Graph zig_lib_directory field, and individual Compile steps
can still have their zig lib directories overridden. I think this is
unlikely to break anyone's build in practice.

The compiler now sends a "file_system_inputs" message to the build
runner which shares the full set of files that were added to the cache
system with the build system, so that the build runner can watch
properly and redo the Compile step. This is implemented for whole cache
mode but not yet for incremental cache mode.
2024-07-12 00:14:08 -07:00
Andrew Kelley
b6ed833083 build runner: ignore ENOENT of fanotify_mark REMOVE
This happens when deleting watched directories and is harmless.
2024-07-12 00:14:08 -07:00
Andrew Kelley
2ebf021061 build runner: don't pass a dirfd + null to fanotify_mark
Otherwise it reports EBADF.
2024-07-12 00:14:08 -07:00