419 Commits

Author SHA1 Message Date
Andrew Kelley
2f9264d8dc stage2: fix -Domit-stage2 regression
This flag is used when building stage1 to omit the stage2 backends from
the compiler to save memory on the CI server. It regressed with the
merging of e8813b296bc55a13b534bd9b2a03e1f6af366915 because Value
functions started calling into Sema functions.

The end goal for this build option is to eliminate it.
2022-03-23 13:24:55 -07:00
Andrew Kelley
593130ce0a stage2: lazy @alignOf
Add a `target` parameter to every function that deals with Type and
Value.
2022-03-22 15:45:58 -07:00
Jakub Konka
0376fd09bc macho: extend CodeSignature to accept entitlements
With this change, we can now bake in entitlements into the binary.
Additionally, I see this as the first step towards full code signature
support which includes baking in Apple issued certificates for
redistribution, etc.
2022-03-22 07:06:39 +01:00
Andrew Kelley
35d6ee08c4 stage2: default to LLVM backend
on targets for which self-hosted backends are not up to par.

See #89
2022-03-17 19:03:37 -07:00
Andrew Kelley
d4a0d5f959 Sema: implement @truncate for SIMD vectors 2022-03-15 15:09:48 -07:00
Andrew Kelley
55ba335e0f Sema: fix resolution of inferred error sets
Introduce `Module.ensureFuncBodyAnalyzed` and corresponding `Sema`
function. This mirrors `ensureDeclAnalyzed` except also waits until the
function body has been semantically analyzed, meaning that inferred
error sets will have been populated.

Resolving error sets can now emit a "unable to resolve inferred error
set" error instead of producing an incorrect error set type. Resolving
error sets now calls `ensureFuncBodyAnalyzed`. Closes #11046.

`coerceInMemoryAllowedErrorSets` now does a lot more work to avoid
resolving an inferred error set if possible. Same with
`wrapErrorUnionSet`.

Inferred error set types no longer check the `func` field to determine if
they are equal. That was incorrect because an inline or comptime function
call produces a unique error set which has the same `*Module.Fn` value for
this field. Instead we use the `*Module.Fn.InferredErrorSet` pointers to
test equality of inferred error sets.
2022-03-11 19:38:07 -07:00
Andrew Kelley
c6160fa3a5 LLVM: add compile unit to debug info
This commit also adds a bunch of bindings for debug info.
2022-03-08 14:58:53 -07:00
Andrew Kelley
88d1258e08 stage2: make -lgcc_s additionally link libunwind
Previously, Zig ignored -lgcc_s with a warning that this dependency is
redundant because it is satisfied by compiler-rt. However, sfackler
pointed out that it also provides exception handling functions. So if
Zig sees -lgcc_s on the linker line, it needs to fulfill this dependency
with libunwind.

I also made link_libc inferred to be on if libunwind is linked since
libunwind depends on libc.
2022-02-23 13:25:10 -07:00
xReveres
b2805666a7 stage1-wasm: implement shared memory 2022-02-23 08:57:20 +01:00
Andrew Kelley
4e1e5ab622 stage2: make AIR not reference ZIR for inline assembly
Instead it stores all the information it needs to into AIR.

closes #10784
2022-02-18 19:41:32 -07:00
Andrew Kelley
f20929bd8b stage2: fix crash using -femit-bin 2022-02-17 13:12:31 -07:00
Al Hoang
04f3d93017 haiku add missing cimport include for compilation 2022-02-14 15:24:53 +02:00
Andrew Kelley
5a00e24963 std.Progress: make the API infallible
by handling `error.TimerUnsupported`. In this case, only explicit calls
to refresh() will cause the progress line to be printed.
2022-02-08 17:26:55 -07:00
Cody Tapscott
5065830aa0 Avoid depending on child process execution when not supported by host OS
In accordance with the requesting issue (#10750):
- `zig test` skips any tests that it cannot spawn, returning success
- `zig run` and `zig build` exit with failure, reporting the command the cannot be run
- `zig clang`, `zig ar`, etc. already punt directly to the appropriate clang/lld main(), even before this change
- Native `libc` Detection is not supported

Additionally, `exec()` and related Builder functions error at run-time, reporting the command that cannot be run
2022-02-06 22:21:46 -07:00
Andrew Kelley
0e6d2184ca stage2: .stub files are yet another c++ source file extension
however .cu files are a superset of c++.
2022-01-27 13:39:28 -07:00
Andrew Kelley
f589a66062 stage2: make cuda file extensions a separate enum tag than c++
follow-up to 2f41bd3be438dae2a188cfae3295dc28f4e9d434.
2022-01-27 13:29:32 -07:00
Daniel Saier
2f41bd3be4 zig cc: Treat cu files as C++ source files
First step towards #10634.

Treating stub files as C++ allows to use zig c++ as a host
compiler for nvcc.

Treating cu files as C++ allow using zig c++ as a host compiler in
CMake. CMake calls the host compiler with -E on a cu file to identify
the compiler.

Using zig c++ to directly compile CUDA code is untested.
2022-01-27 19:23:55 +02:00
Andrew Kelley
40c9ce2caf zig cc: add --hash-style linker parameter
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-26 15:01:59 -07:00
Andrew Kelley
f0ddc7f7a2 translate-c: update for new function pointer semantics
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-25 22:04:01 -07:00
Andrew Kelley
a2abbeef90 stage2: rework a lot of stuff
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-24 21:53:57 -07:00
Kenta Iwasaki
5ae3e4e9bd lld: allow for entrypoint symbol name to be set
This commit enables for the entrypoint symbol to be set when linking ELF
or WebAssembly modules with lld using the Zig compiler.
2022-01-19 11:22:10 -07:00
Andrew Kelley
4d05f2ae5f remove zig_is_stage2 from @import("builtin")
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-17 21:55:49 -07:00
Jakub Konka
5cde5f947f Introduce LinkObject with must_link field 2022-01-13 20:02:11 +01:00
Jakub Konka
16c55b15cb zld: support -Wl,-force_load=archive_path flag
This actually enables using `zig cc` as a linker for `cargo test`
with `serde_derive`.
2022-01-13 20:02:11 +01:00
Jakub Konka
a615425b51 Merge branch 'linker-eport-symbols' of github.com:Luukdegram/zig into Luukdegram-linker-eport-symbols 2022-01-11 11:30:53 +01:00
Luuk de Gram
247b638ccf
Pass --allow-unknown-exports to wasmtime
Also skip exporting non-function symbols when we're building a WASI command using the stage2 llvm backend.
2022-01-07 18:35:08 +01:00
Meghan
c08b190c69
lint: duplicate import (#10519) 2022-01-07 00:06:06 -05:00
Luuk de Gram
6d951aff7e
wasm-linker: Only export symbols notated as such
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-06 20:19:47 +01:00
Andrew Kelley
1c24ef0d0b stage2: introduce std.builtin.CompilerBackend
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-04 18:12:45 -07:00
Andrew Kelley
d94303be2b stage2: introduce renameTmpIntoCache into the linker API
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-03 14:49:35 -07:00
Andrew Kelley
663ffa5a7a stage2: fix missing items from whole cache mode hash
Without this, Zig would re-use a compiler-rt built with stage2 when one
built by stage1 was needed.
2022-01-02 18:54:47 -07:00
Andrew Kelley
9dc25dd0b6 stage2: fix UAF of system_libs 2022-01-02 13:16:17 -07:00
Andrew Kelley
55243cfb31 stage2: fix implibs
Broken by the introduction of `CacheMode.whole`, they are now working
again by using the same mechanism as emitted binary files.
2022-01-02 13:16:17 -07:00
Andrew Kelley
013c286e43 stage2: fix memory leak in addNonIncrementalStuffToCacheManifest
I accidentally used errdefer instead of defer for the function-local
arena.
2022-01-02 13:16:17 -07:00
Andrew Kelley
73ba6bf30b stage2: fix memory leak of emit_bin.sub_path
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-02 13:16:17 -07:00
Andrew Kelley
208a6c7d6a stage2: fix not calling deinit() on whole_cache_manifest
Need to mark it as "needing cleanup" a bit earlier in the function.
2022-01-02 13:16:17 -07:00
Andrew Kelley
0ad2a99675 stage2: CacheMode.whole: trigger loading zig source files
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-02 13:16:17 -07:00
Andrew Kelley
d6c5602d46 stage2: fix CLI not populating output binary files
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-02 13:16:17 -07:00
Andrew Kelley
67e31807df stage2: CacheMode.whole fixes
* 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-02 13:16:17 -07:00
Andrew Kelley
e3bed8d81d stage2: introduce CacheMode
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
2022-01-02 13:16:17 -07:00
Andrew Kelley
6229d37dcf stage2: handle function dependency failures without crashing 2021-12-28 20:20:30 -07:00
Andrew Kelley
2cbeb85a96 stage2: error check for mixing --import-table and --export-table
is moved from the linker to the frontend. This is a follow-up from
4cb2f11693b1bf13770b8ad6a8b8a1e37101a516.
2021-12-21 18:21:42 -07:00
Luuk de Gram
4cb2f11693 wasm-linker: Implement the --export-table and --import-table flags.
This implements the flags for both the linker frontend as well as the self-hosted linker.

Closes #5790
2021-12-21 12:38:50 -08:00
Jakub Konka
a08137330c macho: handle -install_name option for dylibs/MachO
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-18 17:55:53 -08:00
Andrew Kelley
c9863c0a0c CLI: helpful error message when libc requested but not provided 2021-12-16 03:01:13 -07:00
Andrew Kelley
e977455f7c glibc: improve RISC-V support
* omit crti.o / crtn.o for this architecture
 * add missing entry.h header from upstream
2021-12-15 18:34:27 -07:00
Andrew Kelley
4d48948b52 glibc: pass -D__GLIBC_MINOR__=XX
instead of hard-coding it. This means that C code has accurate glibc
version information in the preprocessor.
2021-12-15 17:52:27 -07:00
Luuk de Gram
50201e1c30 wasm-linker: Allow specifying symbols to be exported
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-14 14:02:23 -08:00
Stephen Gutekanst
e563b166b2 Fix compilation cache updating bug leading to slow builds
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-14 13:56:35 -08:00
Andrew Kelley
274555be21 stage2: improve handling of the generated file builtin.zig
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-06 23:30:18 -08:00