aboutsummaryrefslogtreecommitdiff
path: root/src/Compilation.zig
AgeCommit message (Collapse)Author
2022-01-26zig cc: add --hash-style linker parameterAndrew Kelley
This is only relevant for ELF files. I also fixed a bug where passing a zig source file to `zig cc` would incorrectly punt to clang because it thought there were no positional arguments.
2022-01-25translate-c: update for new function pointer semanticsAndrew Kelley
After #10656, function pointers are represented with e.g. `*const fn()void` rather than `fn()void`. This commit adds code to translate-c to emit different code depending on whether the output zig source code is intended to be compiled with stage1 or stage2. Ideally we will have stage1 and stage2 support the exact same Zig language, but for now they diverge because I would rather focus on finishing and shipping stage2 than implementing the features in stage1.
2022-01-24stage2: rework a lot of stuffAndrew Kelley
AstGen: * rename the known_has_bits flag to known_non_opv to make it better reflect what it actually means. * add a known_comptime_only flag. * make the flags take advantage of identifiers of primitives and the fact that zig has no shadowing. * correct the known_non_opv flag for function bodies. Sema: * Rename `hasCodeGenBits` to `hasRuntimeBits` to better reflect what it does. - This function got a bit more complicated in this commit because of the duality of function bodies: on one hand they have runtime bits, but on the other hand they require being comptime known. * WipAnonDecl now takes a LazySrcDecl parameter and performs the type resolutions that it needs during finish(). * Implement comptime `@ptrToInt`. Codegen: * Improved handling of lowering decl_ref; make it work for comptime-known ptr-to-int values. - This same change had to be made many different times; perhaps we should look into merging the implementations of `genTypedValue` across x86, arm, aarch64, and riscv.
2022-01-19lld: allow for entrypoint symbol name to be setKenta Iwasaki
This commit enables for the entrypoint symbol to be set when linking ELF or WebAssembly modules with lld using the Zig compiler.
2022-01-17remove `zig_is_stage2` from `@import("builtin")`Andrew Kelley
Instead use the standarized option for communicating the zig compiler backend at comptime, which is `zig_backend`. This was introduced in commit 1c24ef0d0b09a12a1fe98056f2fc04de78a82df3.
2022-01-13Introduce LinkObject with must_link fieldJakub Konka
2022-01-13zld: support -Wl,-force_load=archive_path flagJakub Konka
This actually enables using `zig cc` as a linker for `cargo test` with `serde_derive`.
2022-01-11Merge branch 'linker-eport-symbols' of github.com:Luukdegram/zig into ↵Jakub Konka
Luukdegram-linker-eport-symbols
2022-01-07Pass `--allow-unknown-exports` to wasmtimeLuuk de Gram
Also skip exporting non-function symbols when we're building a WASI command using the stage2 llvm backend.
2022-01-07lint: duplicate import (#10519)Meghan
2022-01-06wasm-linker: Only export symbols notated as suchLuuk de Gram
This exposes a function from stage2 to stage1 to append symbols to automatically export them. This happends under the following conditions: - Target is wasm - User has not provided --export/--rdynamic flags themselves.
2022-01-04stage2: introduce std.builtin.CompilerBackendAndrew Kelley
This allows Zig code to perform conditional compilation based on a tag by which a Zig compiler implementation identifies itself. See the doc comment in this commit for more details.
2022-01-03stage2: introduce renameTmpIntoCache into the linker APIAndrew Kelley
Doc comments reproduced here: This function is called by the frontend before flush(). It communicates that `options.bin_file.emit` directory needs to be renamed from `[zig-cache]/tmp/[random]` to `[zig-cache]/o/[digest]`. The frontend would like to simply perform a file system rename, however, some linker backends care about the file paths of the objects they are linking. So this function call tells linker backends to rename the paths of object files to observe the new directory path. Linker backends which do not have this requirement can fall back to the simple implementation at the bottom of this function. This function is only called when CacheMode is `whole`. This solves stack trace regressions on Windows and macOS because the linker backends do not observe object file paths until flush().
2022-01-02stage2: fix missing items from whole cache mode hashAndrew Kelley
Without this, Zig would re-use a compiler-rt built with stage2 when one built by stage1 was needed.
2022-01-02stage2: fix UAF of system_libsAndrew Kelley
2022-01-02stage2: fix implibsAndrew Kelley
Broken by the introduction of `CacheMode.whole`, they are now working again by using the same mechanism as emitted binary files.
2022-01-02stage2: fix memory leak in addNonIncrementalStuffToCacheManifestAndrew Kelley
I accidentally used errdefer instead of defer for the function-local arena.
2022-01-02stage2: fix memory leak of emit_bin.sub_pathAndrew Kelley
Instead of juggling GPA-allocated sub_path (and ultimately dropping the ball, in this analogy), `Compilation.create` allocates an already-exactly-correct size `sub_path` that has the digest unpopulated. This is then overwritten in place as necessary and used as the `emit_bin.sub_path` value, and no allocations/frees are performed for this file path.
2022-01-02stage2: fix not calling deinit() on whole_cache_manifestAndrew Kelley
Need to mark it as "needing cleanup" a bit earlier in the function.
2022-01-02stage2: CacheMode.whole: trigger loading zig source filesAndrew Kelley
Previously the code asserted source files were already loaded, but this is not the case when cached ZIR is loaded. Now it will trigger .zig source code to be loaded for the purposes of hashing the source for `CacheMode.whole`. This additionally refactors stat_size, stat_inode, and stat_mtime fields into using the `Cache.File.Stat` struct.
2022-01-02stage2: fix CLI not populating output binary filesAndrew Kelley
This fixes a regression in this branch that can be reproduced with the following steps: 1. `zig build-exe hello.zig` 2. delete the "hello" binary 3. `zig build-exe hello.zig` 4. observe that the "hello" binary is missing This happened because it was a cache hit, but nothing got copied to the output directory. This commit sets CacheMode to incremental - even for stage1 - when the CLI requests `disable_lld_caching` (this option should be renamed), resulting in the main Compilation to be repeated (uncached) for stage1, populating the binary into the cwd as expected. For stage2 the result is even better: the incremental compilation system will look for build artifacts to incrementally compile, and start fresh if not found.
2022-01-02stage2: CacheMode.whole fixesAndrew Kelley
* Logic to check whether a bin file is not emitted is more complicated in between `Compilation.create` and `Compilation.update`. Fixed the logic that decides whether to build compiler-rt and other support artifacts. * Basically, one cannot inspect the value of `comp.bin_file.emit` until after update() is called - fixed another instance of this happening in the CLI. * In the CLI, `runOrTest` is updated to properly use the result value of `comp.bin_file.options.emit` rather than guessing whether the output binary is. * Don't assume that the emit output has no directory components in sub_path. In other words, don't assume that the emit directory is the final directory; there may be sub-directories.
2022-01-02stage2: introduce CacheModeAndrew Kelley
The two CacheMode values are `whole` and `incremental`. `incremental` is what we had before; `whole` is new. Whole cache mode uses everything as inputs to the cache hash; and when a hit occurs it skips everything including linking. This is ideal for when source files change rarely and for backends that do not have good incremental compilation support, for example compiler-rt or libc compiled with LLVM with optimizations on. This is the main motivation for the additional mode, so that we can have LLVM-optimized compiler-rt/libc builds, without waiting for the LLVM backend every single time Zig is invoked. Incremental cache mode hashes only the input file path and a few target options, intentionally relying on collisions to locate already-existing build artifacts which can then be incrementally updated. The bespoke logic for caching stage1 backend build artifacts is removed since we now have a global caching mechanism for when we want to cache the entire compilation, *including* linking. Previously we had to get "creative" with libs.txt and a special byte in the hash id to communicate flags, so that when the cached artifacts were re-linked, we had this information from stage1 even though we didn't actually run it. Now that `CacheMode.whole` includes linking, this extra information does not need to be preserved for cache hits. So although this changeset introduces complexity, it also removes complexity. The main trickiness here comes from the inherent differences between the two modes: `incremental` wants a directory immediately to operate on, while `whole` doesn't know the output directory until the compilation is complete. This commit deals with this problem mostly inside `update()`, where, on a cache miss, it replaces `zig_cache_artifact_directory` with a temporary directory, and then renames it into place once the compilation is complete. Items remaining before this branch can be merged: * [ ] make sure these things make it into the cache manifest: - @import files - @embedFile files - we already add dep files from c but make sure the main .c files make it in there too, not just the included files * [ ] double check that the emit paths of other things besides the binary are working correctly. * [ ] test `-fno-emit-bin` + `-fstage1` * [ ] test `-femit-bin=foo` + `-fstage1` * [ ] implib emit directory copies bin_file_emit directory in create() and needs to be adjusted to be overridden as well. * [ ] make sure emit-h is handled correctly in the cache hash * [ ] Cache: detect duplicate files added to the manifest Some preliminary performance measurements of wall clock time and peak RSS used: stage1 behavior (1077 tests), llvm backend, release build: * cold global cache: 4.6s, 1.1 GiB * warm global cache: 3.4s, 980 MiB stage2 master branch behavior (575 tests), llvm backend, release build: * cold global cache: 0.62s, 191 MiB * warm global cache: 0.40s, 128 MiB stage2 this branch behavior (575 tests), llvm backend, release build: * cold global cache: 0.62s, 179 MiB * warm global cache: 0.27s, 90 MiB
2021-12-28stage2: handle function dependency failures without crashingAndrew Kelley
2021-12-21stage2: error check for mixing --import-table and --export-tableAndrew Kelley
is moved from the linker to the frontend. This is a follow-up from 4cb2f11693b1bf13770b8ad6a8b8a1e37101a516.
2021-12-21wasm-linker: Implement the --export-table and --import-table flags.Luuk de Gram
This implements the flags for both the linker frontend as well as the self-hosted linker. Closes #5790
2021-12-18macho: handle -install_name option for dylibs/MachOJakub Konka
The status quo for the `build.zig` build system is preserved in the sense that, if the user does not explicitly override `dylib.setInstallName(...);` in their build script, the default of `@rpath/libname.dylib` applies. However, should they want to override the default behaviour, they can either: 1) unset it with ```dylib.setIntallName(null);``` 2) set it to an explicit string with ```dylib.setInstallName("somename.dylib");``` When it comes to the command line however, the default is not to use `@rpath` for the install name when creating a dylib. The user will now be required to explicitly specify the `@rpath` as part of the desired install name should they choose so like so: 1) with `build-lib` ``` zig build-lib -dynamic foo.zig -install_name @rpath/libfoo.dylib ``` 2) with `cc` ``` zig cc -shared foo.c -o libfoo.dylib -Wl,"-install_name=@rpath/libfoo.dylib" ```
2021-12-16CLI: helpful error message when libc requested but not providedAndrew Kelley
2021-12-15glibc: improve RISC-V supportAndrew Kelley
* omit crti.o / crtn.o for this architecture * add missing entry.h header from upstream
2021-12-15glibc: pass -D__GLIBC_MINOR__=XXAndrew Kelley
instead of hard-coding it. This means that C code has accurate glibc version information in the preprocessor.
2021-12-14wasm-linker: Allow specifying symbols to be exportedLuuk de Gram
Notating a symbol to be exported in code will only tell the linker where to find this symbol, so other object files can find it. However, this does not mean said symbol will also be exported to the host environment. Currently, we 'fix' this by force exporting every single symbol that is visible. This creates bigger binaries and means host environments have access to symbols that they perhaps shouldn't have. Now, users can tell Zig which symbols are to be exported, meaning all other symbols that are not specified will not be exported. Another change is we now support `-rdynamic` in the wasm linker as well, meaning all symbols will be put in the dynamic symbol table. This is the same behavior as with ELF. This means there's a 3rd strategy users will have to build their wasm binary.
2021-12-14Fix compilation cache updating bug leading to slow buildsStephen Gutekanst
While investigating slow build times with [a large project](https://github.com/hexops/mach/issues/124), I found that the compiler was reading from disk nearly every C source file in my project when rebuilding despite no changes having been made. This accounted for several seconds of time (approx. 20-30% of running `zig build` without any changes to the sources.) The cause of this was that comparisons of file mtimes would _always_ fail (the mtime of the file on disk was always newer than that stored in the cache manifest), and so the cache logic would always fall back to byte-for-byte file content comparisons with what is on disk vs. in the cache-reading every C source file in my project from disk during each rebuild. Because file contents were the same, a cache hit occurred, and _despite the mtime being different the cache manifest would not be updated._ One can reproduce this by building a Zig project so the cache is populated, and then changing mtimes of their C source files to be newer than what is in the cache (without altering file contents.) The fix is rather simple: we should always write the updated cache manifest regardless of whether or not a cache hit occurred (a cache hit doesn't indicate if a manifest is dirty) Luckily, `writeManifest` already contains logic to determine if a manifest is dirty and becomes no-op if no change to the manifest file is necessary-so we merely need to ensure it is invoked. Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
2021-12-06stage2: improve handling of the generated file builtin.zigAndrew Kelley
All Zig code is eligible to `@import("builtin")` which is mapped to a generated file, build.zig, based on the target and other settings. Zig invocations which share the same target settings will generate the same builtin.zig file and thus the path to builtin.zig is in a shared cache folder, and different projects can sometimes use the same file. Before this commit, this led to race conditions where multiple invocations of `zig` would race to write this file. If one process wanted to *read* the file while the other process *wrote* the file, the reading process could observe a truncated or partially written builtin.zig file. This commit makes the following improvements: - limitations: - avoid clobbering the inode, mtime in the hot path - avoid creating a partially written file - builtin.zig needs to be on disk for debug info / stack trace purposes - don't mark the task as complete until the file is finished being populated (possibly by an external process) - strategy: - create the `@import("builtin")` `Module.File` during the AstGen work, based on generating the contents in memory rather than loading from disk. - write builtin.zig in a separate task that doesn't have to complete until the end of the AstGen work queue so that it can be done in parallel with everything else. - when writing the file, first stat the file path. If it exists, we are done. - otherwise, write the file to a temp file in the same directory and atomically rename it into place (clobbering the inode, mtime in the cold path). - summary: - all limitations respected - hot path: one stat() syscall that happens in a worker thread This required adding a missing function to the standard library: `std.fs.Dir.statFile`. In this commit, it does open() and then fstat() which is two syscalls. It should be improved in a future commit to only make one. Fixes #9439.
2021-12-03stage2: use Target.Abi instead of introducing Target.TargetAbiAndrew Kelley
This branch introduced std.Target.TargetAbi when we already had std.Target.Abi which was, unsurprisingly, already suited for this task. Also pull out the -mabi= cc flag addition to the common area instead of duplicating it for assembly and c files.
2021-12-03turn off LTO by default for RISCV even in Release modevole-dev
2021-12-03default mabi based on RISC-V extensions and -mabi build optionvole-dev
The target abi can also be set in build.zig via LibExeObjStep.target_abi The value passed in is checked that it is a valid value in std.Target.TargetAbi The target abi is also validated against the target cpu
2021-11-30Merge pull request #10055 from leecannon/allocator_refactorAndrew Kelley
Allocgate
2021-11-30CLI: introduce -fsingle-threaded/-fno-single-threadedAndrew Kelley
Previously there was only `--single-threaded`. This flag now matches other boolean flags, instead of only being able to opt in to single-threaded builds, you can now force multi-threaded builds. Currently this only has the possibility to emit an error message, but it is a better user experience to understand why one cannot choose to enable threads in some cases. This is breaking change to the CLI. Related: #10143
2021-11-30allocgate: renamed getAllocator function to allocatorLee Cannon
2021-11-30allocgate: stage 1 and 2 buildingLee Cannon
2021-11-30allocgate: std Allocator interface refactorLee Cannon
2021-11-29add clang_argv to stage1 cache hashAndrew Kelley
closes #9304
2021-11-29update libc linux headers to v5.16-rc3Andrew Kelley
* Add missing Linux headers. Closes #9837 * Update existing headers to latest Linux. * Consolidate headers that are the same for multiple Zig target CPU architectures. For example, Linux has only an x86 directory for both x86_64 and x86 CPU architectures. Now Zig only ships an x86 directory for Linux headers, and will emit the proper corresponding -isystem flags. * tools/update-linux-headers.zig is now available for upgrading to newer Linux headers, and the update process is now documented on the wiki.
2021-11-28Merge pull request #10223 from g-w1/print-mirJakub Konka
stage2: initial implementation of print_mir
2021-11-27initial implementation of print_mirJacob G-W
2021-11-26macos: detect SDK path and version, then pass to the linkerJakub Konka
Since we are already detecting the path to the native SDK, if available, also fetch SDK's version and route that to the linker. The linker can then use it to correctly populate LC_BUILD_VERSION load command.
2021-11-26macos: always use Zig shipped libc headers when no native SDKJakub Konka
If Zig didn't detect native SDK, always use shipped libc headers when targeting macOS.
2021-11-25stage2: better error message when copying artifacts failsAndrew Kelley
2021-11-25Skip detecting native libc dirs on darwinJakub Konka
This is handled before by detecting and adding SDK path which is a centralised point for the native libc installation on darwin.
2021-11-25Autofetch macOS SDK if native target on macOS onlyJakub Konka
This means that I am purposefully regressing linking iOS and related which will require manual specification of the sysroot path, etc.