authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-06 14:32:20-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-06 14:32:20-05:00
logd2602b442e7cdea2e74584f9529917d7a53625fd
tree656d2949eae12721fd33479ae49fc5bf0bd76e4d
parentb1775ca168e0bcfba6753346c5226881da49c6c4
signature Commit is signed but in an unrecognized format.

require running std lib tests coherently

this should actually improve CI times a bit too See the description at the top of std/os/startup.zig (deleted in this commit) for a more detailed understanding of what this commit does.

11 files changed, 65 insertions(+), 55 deletions(-)

CMakeLists.txt-1
......@@ -587,7 +587,6 @@ set(ZIG_STD_FILES
587587 "os/linux/vdso.zig"
588588 "os/linux/x86_64.zig"
589589 "os/path.zig"
590 "os/startup.zig"
591590 "os/time.zig"
592591 "os/uefi.zig"
593592 "os/windows/advapi32.zig"
src/codegen.cpp+13-5
......@@ -88,7 +88,7 @@ static const char *symbols_that_llvm_depends_on[] = {
8888};
8989
9090CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
91 Buf *zig_lib_dir)
91 Buf *zig_lib_dir, Buf *override_std_dir)
9292{
9393 CodeGen *g = allocate<CodeGen>(1);
9494
......@@ -96,8 +96,12 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
9696
9797 g->zig_lib_dir = zig_lib_dir;
9898
99 g->zig_std_dir = buf_alloc();
100 os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
99 if (override_std_dir == nullptr) {
100 g->zig_std_dir = buf_alloc();
101 os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
102 } else {
103 g->zig_std_dir = override_std_dir;
104 }
101105
102106 g->zig_c_headers_dir = buf_alloc();
103107 os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
......@@ -8356,8 +8360,12 @@ static void add_cache_pkg(CodeGen *g, CacheHash *ch, PackageTableEntry *pkg) {
83568360 if (!entry)
83578361 break;
83588362
8359 cache_buf(ch, entry->key);
8360 add_cache_pkg(g, ch, entry->value);
8363 // TODO: I think we need a more sophisticated detection of
8364 // packages we have already seen
8365 if (entry->value != pkg) {
8366 cache_buf(ch, entry->key);
8367 add_cache_pkg(g, ch, entry->value);
8368 }
83618369 }
83628370}
83638371
src/codegen.hpp+1-1
......@@ -15,7 +15,7 @@
1515#include <stdio.h>
1616
1717CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
18 Buf *zig_lib_dir);
18 Buf *zig_lib_dir, Buf *override_std_dir);
1919
2020void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
2121void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
src/link.cpp+1-1
......@@ -42,7 +42,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path)
4242 }
4343
4444 CodeGen *child_gen = codegen_create(full_path, child_target, child_out_type,
45 parent_gen->build_mode, parent_gen->zig_lib_dir);
45 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir);
4646
4747 child_gen->out_h_path = nullptr;
4848 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
src/main.cpp+9-3
......@@ -74,6 +74,7 @@ static int print_full_usage(const char *arg0) {
7474 " -dirafter [dir] same as -isystem but do it last\n"
7575 " -isystem [dir] add additional search path for other .h files\n"
7676 " -mllvm [arg] forward an arg to LLVM's option processing\n"
77 " --override-std-dir [arg] use an alternate Zig standard library\n"
7778 "\n"
7879 "Link Options:\n"
7980 " --dynamic-linker [path] set the path to ld.so\n"
......@@ -395,6 +396,7 @@ int main(int argc, char **argv) {
395396 bool system_linker_hack = false;
396397 TargetSubsystem subsystem = TargetSubsystemAuto;
397398 bool is_single_threaded = false;
399 Buf *override_std_dir = nullptr;
398400
399401 if (argc >= 2 && strcmp(argv[1], "build") == 0) {
400402 Buf zig_exe_path_buf = BUF_INIT;
......@@ -430,7 +432,8 @@ int main(int argc, char **argv) {
430432 Buf *build_runner_path = buf_alloc();
431433 os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path);
432434
433 CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir());
435 CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
436 override_std_dir);
434437 g->enable_time_report = timing_info;
435438 buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name);
436439 codegen_set_out_name(g, buf_create_from_str("build"));
......@@ -645,6 +648,8 @@ int main(int argc, char **argv) {
645648 clang_argv.append(argv[i]);
646649
647650 llvm_argv.append(argv[i]);
651 } else if (strcmp(arg, "--override-std-dir") == 0) {
652 override_std_dir = buf_create_from_str(argv[i]);
648653 } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
649654 lib_dirs.append(argv[i]);
650655 } else if (strcmp(arg, "--library") == 0) {
......@@ -819,7 +824,7 @@ int main(int argc, char **argv) {
819824
820825 switch (cmd) {
821826 case CmdBuiltin: {
822 CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir());
827 CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir(), override_std_dir);
823828 g->is_single_threaded = is_single_threaded;
824829 Buf *builtin_source = codegen_generate_builtin_source(g);
825830 if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
......@@ -878,7 +883,8 @@ int main(int argc, char **argv) {
878883 if (cmd == CmdRun && buf_out_name == nullptr) {
879884 buf_out_name = buf_create_from_str("run");
880885 }
881 CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir());
886 CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir(),
887 override_std_dir);
882888 g->subsystem = subsystem;
883889
884890 if (disable_pic) {
std/build.zig+10
......@@ -1686,6 +1686,7 @@ pub const TestStep = struct {
16861686 no_rosegment: bool,
16871687 output_path: ?[]const u8,
16881688 system_linker_hack: bool,
1689 override_std_dir: ?[]const u8,
16891690
16901691 pub fn init(builder: *Builder, root_src: []const u8) TestStep {
16911692 const step_name = builder.fmt("test {}", root_src);
......@@ -1707,6 +1708,7 @@ pub const TestStep = struct {
17071708 .no_rosegment = false,
17081709 .output_path = null,
17091710 .system_linker_hack = false,
1711 .override_std_dir = null,
17101712 };
17111713 }
17121714
......@@ -1737,6 +1739,10 @@ pub const TestStep = struct {
17371739 self.build_mode = mode;
17381740 }
17391741
1742 pub fn overrideStdDir(self: *TestStep, dir_path: []const u8) void {
1743 self.override_std_dir = dir_path;
1744 }
1745
17401746 pub fn setOutputPath(self: *TestStep, file_path: []const u8) void {
17411747 self.output_path = file_path;
17421748
......@@ -1914,6 +1920,10 @@ pub const TestStep = struct {
19141920 if (self.system_linker_hack) {
19151921 try zig_args.append("--system-linker-hack");
19161922 }
1923 if (self.override_std_dir) |dir| {
1924 try zig_args.append("--override-std-dir");
1925 try zig_args.append(builder.pathFromRoot(dir));
1926 }
19171927
19181928 try builder.spawnChild(zig_args.toSliceConst());
19191929 }
std/index.zig-1
......@@ -45,7 +45,6 @@ pub const unicode = @import("unicode.zig");
4545pub const zig = @import("zig/index.zig");
4646
4747pub const lazyInit = @import("lazy_init.zig").lazyInit;
48pub const startup = @import("os/startup.zig");
4948
5049test "std" {
5150 // run tests from these
std/os/index.zig+21-10
......@@ -8,8 +8,9 @@ const is_posix = switch (builtin.os) {
88};
99const os = @This();
1010
11// See the comment in startup.zig for why this does not use the `std` global above.
12const startup = @import("std").startup;
11comptime {
12 assert(@import("std") == std); // You have to run the std lib tests with --override-std-dir
13}
1314
1415test "std.os" {
1516 _ = @import("child_process.zig");
......@@ -670,11 +671,14 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
670671 }
671672}
672673
674pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null;
675pub var posix_environ_raw: [][*]u8 = undefined;
676
673677/// See std.elf for the constants.
674678pub fn linuxGetAuxVal(index: usize) usize {
675679 if (builtin.link_libc) {
676680 return usize(std.c.getauxval(index));
677 } else if (startup.linux_elf_aux_maybe) |auxv| {
681 } else if (linux_elf_aux_maybe) |auxv| {
678682 var i: usize = 0;
679683 while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
680684 if (auxv[i].a_type == index)
......@@ -734,7 +738,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
734738 try result.setMove(key, value);
735739 }
736740 } else {
737 for (startup.posix_environ_raw) |ptr| {
741 for (posix_environ_raw) |ptr| {
738742 var line_i: usize = 0;
739743 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
740744 const key = ptr[0..line_i];
......@@ -756,7 +760,7 @@ test "os.getEnvMap" {
756760
757761/// TODO make this go through libc when we have it
758762pub fn getEnvPosix(key: []const u8) ?[]const u8 {
759 for (startup.posix_environ_raw) |ptr| {
763 for (posix_environ_raw) |ptr| {
760764 var line_i: usize = 0;
761765 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
762766 const this_key = ptr[0..line_i];
......@@ -1937,14 +1941,14 @@ pub const ArgIteratorPosix = struct {
19371941 pub fn init() ArgIteratorPosix {
19381942 return ArgIteratorPosix{
19391943 .index = 0,
1940 .count = startup.posix_argv_raw.len,
1944 .count = raw.len,
19411945 };
19421946 }
19431947
19441948 pub fn next(self: *ArgIteratorPosix) ?[]const u8 {
19451949 if (self.index == self.count) return null;
19461950
1947 const s = startup.posix_argv_raw[self.index];
1951 const s = raw[self.index];
19481952 self.index += 1;
19491953 return cstr.toSlice(s);
19501954 }
......@@ -1955,6 +1959,10 @@ pub const ArgIteratorPosix = struct {
19551959 self.index += 1;
19561960 return true;
19571961 }
1962
1963 /// This is marked as public but actually it's only meant to be used
1964 /// internally by zig's startup code.
1965 pub var raw: [][*]u8 = undefined;
19581966};
19591967
19601968pub const ArgIteratorWindows = struct {
......@@ -3000,6 +3008,9 @@ pub const SpawnThreadError = error{
30003008 Unexpected,
30013009};
30023010
3011pub var linux_tls_phdr: ?*std.elf.Phdr = null;
3012pub var linux_tls_img_src: [*]const u8 = undefined; // defined if linux_tls_phdr is
3013
30033014/// caller must call wait on the returned thread
30043015/// fn startFn(@typeOf(context)) T
30053016/// where T is u8, noreturn, void, or !void
......@@ -3109,7 +3120,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
31093120 }
31103121 // Finally, the Thread Local Storage, if any.
31113122 if (!Thread.use_pthreads) {
3112 if (startup.linux_tls_phdr) |tls_phdr| {
3123 if (linux_tls_phdr) |tls_phdr| {
31133124 l = mem.alignForward(l, tls_phdr.p_align);
31143125 tls_start_offset = l;
31153126 l += tls_phdr.p_memsz;
......@@ -3153,8 +3164,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
31533164 posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID |
31543165 posix.CLONE_DETACHED;
31553166 var newtls: usize = undefined;
3156 if (startup.linux_tls_phdr) |tls_phdr| {
3157 @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), startup.linux_tls_img_src, tls_phdr.p_filesz);
3167 if (linux_tls_phdr) |tls_phdr| {
3168 @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), linux_tls_img_src, tls_phdr.p_filesz);
31583169 thread_ptr.data.tls_end_addr = mmap_addr + mmap_len;
31593170 newtls = @ptrToInt(&thread_ptr.data.tls_end_addr);
31603171 flags |= posix.CLONE_SETTLS;
std/os/startup.zig deleted-26
......@@ -1,26 +0,0 @@
1// This file contains global variables that are initialized on startup from
2// std/special/bootstrap.zig. There are a few things to be aware of here.
3//
4// First, when building an object or library, and no entry point is defined
5// (such as pub fn main), std/special/bootstrap.zig is not included in the
6// compilation. And so these global variables will remain set to the values
7// you see here.
8//
9// Second, when using `zig test` to test the standard library, note that
10// `zig test` is self-hosted. This means that it uses std/special/bootstrap.zig
11// and an @import("std") from the install directory, which is distinct from
12// the standard library files that we are directly testing with `zig test`.
13// This means that these global variables would not get set. So the workaround
14// here is that references to these globals from the standard library must
15// use `@import("std").startup` rather than
16// `@import("path/to/std/index.zig").startup` (and rather than the file path of
17// this file directly). We also put "std" as a reference to itself in the
18// standard library package so that this can work.
19
20const std = @import("../index.zig");
21
22pub var linux_tls_phdr: ?*std.elf.Phdr = null;
23pub var linux_tls_img_src: [*]const u8 = undefined; // defined when linux_tls_phdr is non-null
24pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null;
25pub var posix_environ_raw: [][*]u8 = undefined;
26pub var posix_argv_raw: [][*]u8 = undefined;
std/special/bootstrap.zig+7-7
......@@ -64,7 +64,7 @@ fn posixCallMainAndExit() noreturn {
6464 if (builtin.os == builtin.Os.linux) {
6565 // Scan auxiliary vector.
6666 const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1);
67 std.startup.linux_elf_aux_maybe = auxv;
67 std.os.linux_elf_aux_maybe = auxv;
6868 var i: usize = 0;
6969 var at_phdr: usize = 0;
7070 var at_phnum: usize = 0;
......@@ -87,8 +87,8 @@ fn posixCallMainAndExit() noreturn {
8787// This is marked inline because for some reason LLVM in release mode fails to inline it,
8888// and we want fewer call frames in stack traces.
8989inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 {
90 std.startup.posix_argv_raw = argv[0..argc];
91 std.startup.posix_environ_raw = envp;
90 std.os.ArgIteratorPosix.raw = argv[0..argc];
91 std.os.posix_environ_raw = envp;
9292 return callMain();
9393}
9494
......@@ -145,15 +145,15 @@ fn linuxInitializeThreadLocalStorage(at_phdr: usize, at_phnum: usize, at_phent:
145145 // TODO look for PT_DYNAMIC when we have https://github.com/ziglang/zig/issues/1917
146146 switch (phdr.p_type) {
147147 std.elf.PT_PHDR => base = at_phdr - phdr.p_vaddr,
148 std.elf.PT_TLS => std.startup.linux_tls_phdr = phdr,
148 std.elf.PT_TLS => std.os.linux_tls_phdr = phdr,
149149 else => continue,
150150 }
151151 }
152 const tls_phdr = std.startup.linux_tls_phdr orelse return;
153 std.startup.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr);
152 const tls_phdr = std.os.linux_tls_phdr orelse return;
153 std.os.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr);
154154 assert(main_thread_tls_bytes.len >= tls_phdr.p_memsz); // not enough preallocated Thread Local Storage
155155 assert(main_thread_tls_align >= tls_phdr.p_align); // preallocated Thread Local Storage not aligned enough
156 @memcpy(&main_thread_tls_bytes, std.startup.linux_tls_img_src, tls_phdr.p_filesz);
156 @memcpy(&main_thread_tls_bytes, std.os.linux_tls_img_src, tls_phdr.p_filesz);
157157 tls_end_addr = @ptrToInt(&main_thread_tls_bytes) + tls_phdr.p_memsz;
158158 linuxSetThreadArea(@ptrToInt(&tls_end_addr));
159159}
test/tests.zig+3
......@@ -194,6 +194,9 @@ pub fn addPkgTests(b: *build.Builder, test_filter: ?[]const u8, root_src: []cons
194194 if (link_libc) {
195195 these_tests.linkSystemLibrary("c");
196196 }
197 if (mem.eql(u8, name, "std")) {
198 these_tests.overrideStdDir("std");
199 }
197200 step.dependOn(&these_tests.step);
198201 }
199202 }