Skip to content

Commit

Permalink
Merge pull request #1215 from ziglang/self-hosted-first-test
Browse files Browse the repository at this point in the history
self-hosted: first passing test
  • Loading branch information
andrewrk committed Jul 11, 2018
2 parents 8fba0a6 + 8197a14 commit c620a1f
Show file tree
Hide file tree
Showing 11 changed files with 420 additions and 107 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -431,6 +431,7 @@ set(ZIG_CPP_SOURCES
set(ZIG_STD_FILES
"array_list.zig"
"atomic/index.zig"
"atomic/int.zig"
"atomic/queue_mpmc.zig"
"atomic/queue_mpsc.zig"
"atomic/stack.zig"
Expand Down
152 changes: 89 additions & 63 deletions build.zig
Expand Up @@ -35,70 +35,27 @@ pub fn build(b: *Builder) !void {
"BUILD_INFO",
});
var index: usize = 0;
const cmake_binary_dir = nextValue(&index, build_info);
const cxx_compiler = nextValue(&index, build_info);
const llvm_config_exe = nextValue(&index, build_info);
const lld_include_dir = nextValue(&index, build_info);
const lld_libraries = nextValue(&index, build_info);
const std_files = nextValue(&index, build_info);
const c_header_files = nextValue(&index, build_info);
const dia_guids_lib = nextValue(&index, build_info);
var ctx = Context{
.cmake_binary_dir = nextValue(&index, build_info),
.cxx_compiler = nextValue(&index, build_info),
.llvm_config_exe = nextValue(&index, build_info),
.lld_include_dir = nextValue(&index, build_info),
.lld_libraries = nextValue(&index, build_info),
.std_files = nextValue(&index, build_info),
.c_header_files = nextValue(&index, build_info),
.dia_guids_lib = nextValue(&index, build_info),
.llvm = undefined,
};
ctx.llvm = try findLLVM(b, ctx.llvm_config_exe);

const llvm = findLLVM(b, llvm_config_exe) catch unreachable;
var test_stage2 = b.addTest("src-self-hosted/test.zig");
test_stage2.setBuildMode(builtin.Mode.Debug);

var exe = b.addExecutable("zig", "src-self-hosted/main.zig");
exe.setBuildMode(mode);

// This is for finding /lib/libz.a on alpine linux.
// TODO turn this into -Dextra-lib-path=/lib option
exe.addLibPath("/lib");

exe.addIncludeDir("src");
exe.addIncludeDir(cmake_binary_dir);
addCppLib(b, exe, cmake_binary_dir, "zig_cpp");
if (lld_include_dir.len != 0) {
exe.addIncludeDir(lld_include_dir);
var it = mem.split(lld_libraries, ";");
while (it.next()) |lib| {
exe.addObjectFile(lib);
}
} else {
addCppLib(b, exe, cmake_binary_dir, "embedded_lld_wasm");
addCppLib(b, exe, cmake_binary_dir, "embedded_lld_elf");
addCppLib(b, exe, cmake_binary_dir, "embedded_lld_coff");
addCppLib(b, exe, cmake_binary_dir, "embedded_lld_lib");
}
dependOnLib(exe, llvm);

if (exe.target.getOs() == builtin.Os.linux) {
const libstdcxx_path_padded = try b.exec([][]const u8{
cxx_compiler,
"-print-file-name=libstdc++.a",
});
const libstdcxx_path = mem.split(libstdcxx_path_padded, "\r\n").next().?;
if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) {
warn(
\\Unable to determine path to libstdc++.a
\\On Fedora, install libstdc++-static and try again.
\\
);
return error.RequiredLibraryNotFound;
}
exe.addObjectFile(libstdcxx_path);

exe.linkSystemLibrary("pthread");
} else if (exe.target.isDarwin()) {
exe.linkSystemLibrary("c++");
}

if (dia_guids_lib.len != 0) {
exe.addObjectFile(dia_guids_lib);
}

if (exe.target.getOs() != builtin.Os.windows) {
exe.linkSystemLibrary("xml2");
}
exe.linkSystemLibrary("c");
try configureStage2(b, test_stage2, ctx);
try configureStage2(b, exe, ctx);

b.default_step.dependOn(&exe.step);

Expand All @@ -110,12 +67,16 @@ pub fn build(b: *Builder) !void {
exe.setVerboseLink(verbose_link_exe);

b.installArtifact(exe);
installStdLib(b, std_files);
installCHeaders(b, c_header_files);
installStdLib(b, ctx.std_files);
installCHeaders(b, ctx.c_header_files);

const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
const with_lldb = b.option(bool, "with-lldb", "Run tests in LLDB to get a backtrace if one fails") orelse false;

const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
test_stage2_step.dependOn(&test_stage2.step);
test_step.dependOn(test_stage2_step);

test_step.dependOn(docs_step);

test_step.dependOn(tests.addPkgTests(b, test_filter, "test/behavior.zig", "behavior", "Run the behavior tests", with_lldb));
Expand All @@ -133,7 +94,7 @@ pub fn build(b: *Builder) !void {
test_step.dependOn(tests.addGenHTests(b, test_filter));
}

fn dependOnLib(lib_exe_obj: *std.build.LibExeObjStep, dep: *const LibraryDep) void {
fn dependOnLib(lib_exe_obj: var, dep: *const LibraryDep) void {
for (dep.libdirs.toSliceConst()) |lib_dir| {
lib_exe_obj.addLibPath(lib_dir);
}
Expand All @@ -148,7 +109,7 @@ fn dependOnLib(lib_exe_obj: *std.build.LibExeObjStep, dep: *const LibraryDep) vo
}
}

fn addCppLib(b: *Builder, lib_exe_obj: *std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void {
fn addCppLib(b: *Builder, lib_exe_obj: var, cmake_binary_dir: []const u8, lib_name: []const u8) void {
const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp", b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
}
Expand Down Expand Up @@ -254,3 +215,68 @@ fn nextValue(index: *usize, build_info: []const u8) []const u8 {
}
}
}

fn configureStage2(b: *Builder, exe: var, ctx: Context) !void {
// This is for finding /lib/libz.a on alpine linux.
// TODO turn this into -Dextra-lib-path=/lib option
exe.addLibPath("/lib");

exe.addIncludeDir("src");
exe.addIncludeDir(ctx.cmake_binary_dir);
addCppLib(b, exe, ctx.cmake_binary_dir, "zig_cpp");
if (ctx.lld_include_dir.len != 0) {
exe.addIncludeDir(ctx.lld_include_dir);
var it = mem.split(ctx.lld_libraries, ";");
while (it.next()) |lib| {
exe.addObjectFile(lib);
}
} else {
addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_wasm");
addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_elf");
addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_coff");
addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_lib");
}
dependOnLib(exe, ctx.llvm);

if (exe.target.getOs() == builtin.Os.linux) {
const libstdcxx_path_padded = try b.exec([][]const u8{
ctx.cxx_compiler,
"-print-file-name=libstdc++.a",
});
const libstdcxx_path = mem.split(libstdcxx_path_padded, "\r\n").next().?;
if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) {
warn(
\\Unable to determine path to libstdc++.a
\\On Fedora, install libstdc++-static and try again.
\\
);
return error.RequiredLibraryNotFound;
}
exe.addObjectFile(libstdcxx_path);

exe.linkSystemLibrary("pthread");
} else if (exe.target.isDarwin()) {
exe.linkSystemLibrary("c++");
}

if (ctx.dia_guids_lib.len != 0) {
exe.addObjectFile(ctx.dia_guids_lib);
}

if (exe.target.getOs() != builtin.Os.windows) {
exe.linkSystemLibrary("xml2");
}
exe.linkSystemLibrary("c");
}

const Context = struct {
cmake_binary_dir: []const u8,
cxx_compiler: []const u8,
llvm_config_exe: []const u8,
lld_include_dir: []const u8,
lld_libraries: []const u8,
std_files: []const u8,
c_header_files: []const u8,
dia_guids_lib: []const u8,
llvm: LibraryDep,
};
18 changes: 12 additions & 6 deletions src-self-hosted/errmsg.zig
Expand Up @@ -11,11 +11,15 @@ pub const Color = enum {
On,
};

pub const Span = struct {
first: ast.TokenIndex,
last: ast.TokenIndex,
};

pub const Msg = struct {
path: []const u8,
text: []u8,
first_token: TokenIndex,
last_token: TokenIndex,
span: Span,
tree: *ast.Tree,
};

Expand All @@ -39,17 +43,19 @@ pub fn createFromParseError(
.tree = tree,
.path = path,
.text = text_buf.toOwnedSlice(),
.first_token = loc_token,
.last_token = loc_token,
.span = Span{
.first = loc_token,
.last = loc_token,
},
});
errdefer allocator.destroy(msg);

return msg;
}

pub fn printToStream(stream: var, msg: *const Msg, color_on: bool) !void {
const first_token = msg.tree.tokens.at(msg.first_token);
const last_token = msg.tree.tokens.at(msg.last_token);
const first_token = msg.tree.tokens.at(msg.span.first);
const last_token = msg.tree.tokens.at(msg.span.last);
const start_loc = msg.tree.tokenLocationPtr(0, first_token);
const end_loc = msg.tree.tokenLocationPtr(first_token.end, last_token);
if (!color_on) {
Expand Down
5 changes: 5 additions & 0 deletions src-self-hosted/introspect.zig
Expand Up @@ -53,3 +53,8 @@ pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {
return error.ZigLibDirNotFound;
};
}

/// Caller must free result
pub fn resolveZigCacheDir(allocator: *mem.Allocator) ![]u8 {
return std.mem.dupe(allocator, u8, "zig-cache");
}
36 changes: 18 additions & 18 deletions src-self-hosted/main.zig
Expand Up @@ -481,29 +481,29 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
module.link_out_file = flags.single("out-file");

try module.build();
const process_build_events_handle = try async<loop.allocator> processBuildEvents(module, true);
const process_build_events_handle = try async<loop.allocator> processBuildEvents(module, color);
defer cancel process_build_events_handle;
loop.run();
}

async fn processBuildEvents(module: *Module, watch: bool) void {
while (watch) {
// TODO directly awaiting async should guarantee memory allocation elision
const build_event = await (async module.events.get() catch unreachable);
async fn processBuildEvents(module: *Module, color: errmsg.Color) void {
// TODO directly awaiting async should guarantee memory allocation elision
const build_event = await (async module.events.get() catch unreachable);

switch (build_event) {
Module.Event.Ok => {
std.debug.warn("Build succeeded\n");
return;
},
Module.Event.Error => |err| {
std.debug.warn("build failed: {}\n", @errorName(err));
@panic("TODO error return trace");
},
Module.Event.Fail => |errs| {
@panic("TODO print compile error messages");
},
}
switch (build_event) {
Module.Event.Ok => {
std.debug.warn("Build succeeded\n");
return;
},
Module.Event.Error => |err| {
std.debug.warn("build failed: {}\n", @errorName(err));
@panic("TODO error return trace");
},
Module.Event.Fail => |msgs| {
for (msgs) |msg| {
errmsg.printToFile(&stderr_file, msg, color) catch os.exit(1);
}
},
}
}

Expand Down

0 comments on commit c620a1f

Please sign in to comment.