1
Fork 0

Compare commits

...

2 Commits

Author SHA1 Message Date
Motiejus Jakštys 90867df2b7 update README 2 months ago
Motiejus Jakštys 3ba59fcb78 launcher: formatting 2 months ago
  1. 38
      README.md
  2. 106
      toolchain/launcher.zig

@ -297,20 +297,6 @@ unlikely to implement them any time soon, but patches implementing those will
be accepted. See [Questions & Contributions](#questions-amp-contributions) on
how to contribute.
## Sharing of libc shims/libc++.a
Zig does not always share `libc++.a` and the glibc shims. We have observed
to be caused for 2 reasons:
- For some commands Go `chdir`s to `/tmp/`. This causes `ZIG_LIB_DIR` to be
absolute, which blows the cache key to find the right `libc++.a` (because Zig
thinks we are using a different lib dir to compile libc++). This is currently
worked around in `toolchain/defs.bzl` by overfitting to Go and returning
early from that particular invocation.
- Sometimes Bazel's sandbox messes up Zig's cache keys. If one runs without the
sandbox (`--spawn_strategy=standalone`), the cache hit rate and thus the
build time are much better.
## Zig cache location
Currently zig cache is in `$HOME`, so `bazel clean --expunge` does not clear
@ -376,6 +362,8 @@ Feel free to track [Universal headers][universal-headers] project for a fix.
- [rules/go #2894 Per-arch_target linker flags](https://github.com/bazelbuild/rules_go/issues/2894) (CLOSED, thanks mjonaitis)
- [golang/go #46644 cmd/link: with CC=zig: SIGSERV when cross-compiling to darwin/amd64](https://github.com/golang/go/issues/46644) (CLOSED, thanks kubkon)
... and more.
# Host Environments
This repository is used on the following (host) platforms:
@ -410,8 +398,9 @@ $ docker run -e CC=/usr/bin/false -ti --rm -v "$PWD:/x" -w /x debian:bullseye-sl
# apt update
# apt install --no-install-recommends -y direnv git shellcheck ca-certificates
# eval "$(direnv hook bash)" && direnv allow
# ./ci/test
# ./ci/lint
# ./ci/launcher
# ./ci/test
```
Some of the tests rely on `qemu-aarch64` to run arm64 binaries and wine for
@ -423,8 +412,7 @@ $ docker run -e CC=/usr/bin/false -ti --rm -v "$PWD:/x" -w /x debian:bullseye-sl
# dpkg --add-architecture arm64 && apt update
# apt install --no-install-recommends -y direnv git shellcheck ca-certificates libc6:arm64 qemu-user-static wine64
# eval "$(direnv hook bash)" && direnv allow
# ./ci/test
# ./ci/lint
<... run the ci/ commands as above>
```
# Questions & Contributions
@ -457,8 +445,8 @@ interests when reading patches or mailing lists.
- Committer: Laurynas Lubys. Bazel expert with regards to tests, transitions
and overall structure. Rewrote bazel-zig-cc to cater for platforms when libc
platforms were added.
- Committer: Ken Micklas. Ken is leading hermetic toolchain effort at Uber, of
which bazel-zig-cc is a part of.
- Committer: Ken Micklas. Ken was leading hermetic toolchain effort at Uber
throughout 2022, of which bazel-zig-cc is a part of.
- Maintainer for Windows: Fabian Hahn. If you make a change that breaks
Windows, Fabian will find you. Please don't break Windows, so Fabian doesn't
have to look for you. Instead, send him your patches first.
@ -469,6 +457,12 @@ You may find contact information of the individuals in the commit logs.
This section lists notable uses or mentions of bazel-zig-cc.
- 2023-01-24 [bazel-zig-cc v1.0.0][bazel-zig-cc-v1]: releasing bazel-zig-cc and
admitting that bazel-zig-cc is used in production to compile all of Uber's
[Go Monorepo][go-monorepo].
- 2022-11-18 [BazelCon 2022: Making Uber's hermetic C++
toolchain][bazelcon2022]: Laurynas Lubys presents the story of how this
repository came into being and how it was used (as of the conference).
- 2022-05-23 [How Zig is used at Uber (youtube)][yt-how-zig-is-used-at-uber]:
Yours Truly (the author) talks about how bazel-zig-cc came to existence and
how it's used at Uber in Milan Zig Meetup.
@ -477,9 +471,6 @@ This section lists notable uses or mentions of bazel-zig-cc.
author $250 for bazel-zig-cc.
- 2022-01-13 [bazel-zig-cc building Envoy][zig-cc-envoy].
If you'd like your blog post, company or a project added here, do not hesitate
and send a patch.
# Thanks
Many thanks to Adam Bouhenguel and his [bazel-zig-cc][ajbouh], the parent of
@ -504,3 +495,6 @@ the issues promptly.
[google-award]: https://opensource.googleblog.com/2022/03/Announcing-First-Group-of-Google-Open-Source-Peer-Bonus-Winners-in-2022.html
[go-gc-sections]: https://go-review.googlesource.com/c/go/+/407814
[universal-headers]: https://github.com/ziglang/universal-headers
[bazel-zig-cc-v1]: https://lists.sr.ht/~motiejus/bazel-zig-cc/%3CCAFVMu-rYbf_jDTT4p%3DCS2KV1asdS5Ovo5AyuCwgv2AXr8OOP0g%40mail.gmail.com%3E
[go-monorepo]: https://www.uber.com/blog/go-monorepo-bazel/
[bazelcon2022]: https://www.youtube.com/watch?v=a1jXzx3884g

@ -113,28 +113,20 @@ pub fn main() u8 {
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
var argv_it = process.argsWithAllocator(arena) catch |err| {
std.debug.print("error parsing args: {s}\n", .{@errorName(err)});
return 1;
};
var argv_it = process.argsWithAllocator(arena) catch |err|
return fatal("error parsing args: {s}\n", .{@errorName(err)});
const action = parseArgs(arena, fs.cwd(), &argv_it) catch |err| {
std.debug.print("error: {s}\n", .{@errorName(err)});
return 1;
};
const action = parseArgs(arena, fs.cwd(), &argv_it) catch |err|
return fatal("error: {s}\n", .{@errorName(err)});
switch (action) {
.early_ok => return 0,
.early_err => |msg| {
std.io.getStdErr().writeAll(msg) catch {};
return 1;
},
.early_err => |msg| return fatal(msg),
.exec => |params| {
if (builtin.os.tag == .windows) {
return spawnWindows(arena, params);
} else {
if (builtin.os.tag == .windows)
return spawnWindows(arena, params)
else
return execUnix(arena, params);
}
},
}
}
@ -142,20 +134,15 @@ pub fn main() u8 {
fn spawnWindows(arena: mem.Allocator, params: ExecParams) u8 {
var proc = ChildProcess.init(params.args.items, arena);
proc.env_map = &params.env;
const ret = proc.spawnAndWait() catch |err| {
std.debug.print(
"error spawning {s}: {s}\n",
.{ params.args.items[0], @errorName(err) },
);
return 1;
};
const ret = proc.spawnAndWait() catch |err|
return fatal(
"error spawning {s}: {s}\n",
.{ params.args.items[0], @errorName(err) },
);
switch (ret) {
.Exited => |code| return code,
else => |other| {
std.debug.print("abnormal exit: {any}\n", .{other});
return 1;
},
else => |other| return fatal("abnormal exit: {any}\n", .{other}),
}
}
@ -178,7 +165,7 @@ fn parseArgs(
argv_it: anytype,
) error{OutOfMemory}!ParseResults {
const arg0 = argv_it.next() orelse
return fatal(arena, "error: argv[0] cannot be null", .{});
return parseFatal(arena, "error: argv[0] cannot be null", .{});
const zig_tool = blk: {
const b = fs.path.basename(arg0);
@ -191,9 +178,10 @@ fn parseArgs(
const maybe_target = getTarget(arg0) catch |err| switch (err) {
error.BadParent => {
const fmt_args = .{ .zig_tool = zig_tool, .exe = EXE };
if (mem.eql(u8, zig_tool, "c++")) {
return fatal(arena, usage_cpp, fmt_args);
} else return fatal(arena, usage_other, fmt_args);
if (mem.eql(u8, zig_tool, "c++"))
return parseFatal(arena, usage_cpp, fmt_args)
else
return parseFatal(arena, usage_other, fmt_args);
},
else => |e| return e,
};
@ -220,13 +208,9 @@ fn parseArgs(
&[_][]const u8{ root, "zig" ++ EXE },
);
var env = process.getEnvMap(arena) catch |err| {
return fatal(
arena,
"error getting process environment: {s}",
.{@errorName(err)},
);
};
var env = process.getEnvMap(arena) catch |err|
return parseFatal(arena, "error getting env: {s}", .{@errorName(err)});
try env.put("ZIG_LIB_DIR", zig_lib_dir);
try env.put("ZIG_LOCAL_CACHE_DIR", CACHE_DIR);
try env.put("ZIG_GLOBAL_CACHE_DIR", CACHE_DIR);
@ -246,7 +230,7 @@ fn parseArgs(
return ParseResults{ .exec = .{ .args = args, .env = env } };
}
fn fatal(
fn parseFatal(
arena: mem.Allocator,
comptime fmt: []const u8,
args: anytype,
@ -255,6 +239,11 @@ fn fatal(
return ParseResults{ .early_err = msg };
}
pub fn fatal(comptime fmt: []const u8, args: anytype) u8 {
fmt.debug.print(fmt, args);
return 1;
}
// Golang probing for a particular linker flag causes many unneeded stubs to be
// built, e.g. glibc, musl, libc++. The hackery can probably be deleted after
// Go 1.20 is released. In particular,
@ -278,28 +267,25 @@ fn getTarget(self_exe: []const u8) error{BadParent}!?[]const u8 {
// strings `is.it.x86_64?-stallinux,macos-`; we are trying to aid users
// that run things from the wrong directory, not trying to punish the ones
// having fun.
{
var it = mem.split(u8, triple, "-");
if (it.next()) |arch| {
if (mem.indexOf(u8, "aarch64,x86_64", arch) == null)
return error.BadParent;
} else return error.BadParent;
if (it.next()) |got_os| {
if (mem.indexOf(u8, "linux,macos,windows", got_os) == null)
return error.BadParent;
} else return error.BadParent;
// ABI triple is too much of a moving target
if (it.next() == null) return error.BadParent;
// but the target needs to have 3 dashes.
if (it.next() != null) return error.BadParent;
}
var it = mem.split(u8, triple, "-");
const arch = it.next() orelse return error.BadParent;
if (mem.indexOf(u8, "aarch64,x86_64", arch) == null)
return error.BadParent;
const got_os = it.next() orelse return error.BadParent;
if (mem.indexOf(u8, "linux,macos,windows", got_os) == null)
return error.BadParent;
// ABI triple is too much of a moving target
if (it.next() == null) return error.BadParent;
// but the target needs to have 3 dashes.
if (it.next() != null) return error.BadParent;
if (mem.eql(u8, "c++" ++ EXE, fs.path.basename(self_exe))) {
return triple;
} else return null;
if (mem.eql(u8, "c++" ++ EXE, fs.path.basename(self_exe)))
return triple
else
return null;
}
fn comptimeSplit(comptime str: []const u8) [countWords(str)][]const u8 {

Loading…
Cancel
Save