From 36ff26609b1d81a253053e7d7785392fae240dab Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 3 Jan 2018 04:55:16 -0500 Subject: [PATCH] fix self hosted compiler on windows --- build.zig | 43 +++++++++++++++++++++++++++++++------------ src-self-hosted/c.zig | 1 + src/config.h.in | 2 ++ src/link.cpp | 6 ++++-- src/main.cpp | 2 +- std/buffer.zig | 9 +++++---- std/os/index.zig | 4 ++-- std/os/path.zig | 8 ++++++++ 8 files changed, 54 insertions(+), 21 deletions(-) diff --git a/build.zig b/build.zig index 7c0570bf46..9727be0843 100644 --- a/build.zig +++ b/build.zig @@ -36,23 +36,33 @@ pub fn build(b: &Builder) { if (findLLVM(b)) |llvm| { // find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library const build_info = b.exec([][]const u8{b.zig_exe, "BUILD_INFO"}); - var build_info_it = mem.split(build_info, "\n"); - const cmake_binary_dir = ??build_info_it.next(); - const cxx_compiler = ??build_info_it.next(); + var index: usize = 0; + const cmake_binary_dir = nextValue(&index, build_info); + const cxx_compiler = nextValue(&index, build_info); + const lld_include_dir = nextValue(&index, build_info); + const lld_libraries = nextValue(&index, build_info); var exe = b.addExecutable("zig", "src-self-hosted/main.zig"); exe.setBuildMode(mode); exe.addIncludeDir("src"); exe.addIncludeDir(cmake_binary_dir); - addCppLib(b, exe, cmake_binary_dir, "libzig_cpp"); - addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_elf"); - addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_coff"); - addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_lib"); + 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_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.isWindows()) { const libstdcxx_path_padded = b.exec([][]const u8{cxx_compiler, "-print-file-name=libstdc++.a"}); - const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\n").next(); + const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\r\n").next(); exe.addObjectFile(libstdcxx_path); exe.linkSystemLibrary("pthread"); @@ -114,8 +124,9 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) { } fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) { + 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_name, lib_exe_obj.target.libFileExt()))); + b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt()))); } const LibraryDep = struct { @@ -150,7 +161,7 @@ fn findLLVM(b: &Builder) -> ?LibraryDep { .libdirs = ArrayList([]const u8).init(b.allocator), }; { - var it = mem.split(libs_output, " \n"); + var it = mem.split(libs_output, " \r\n"); while (it.next()) |lib_arg| { if (mem.startsWith(u8, lib_arg, "-l")) { %%result.system_libs.append(lib_arg[2..]); @@ -164,7 +175,7 @@ fn findLLVM(b: &Builder) -> ?LibraryDep { } } { - var it = mem.split(includes_output, " \n"); + var it = mem.split(includes_output, " \r\n"); while (it.next()) |include_arg| { if (mem.startsWith(u8, include_arg, "-I")) { %%result.includes.append(include_arg[2..]); @@ -174,7 +185,7 @@ fn findLLVM(b: &Builder) -> ?LibraryDep { } } { - var it = mem.split(libdir_output, " \n"); + var it = mem.split(libdir_output, " \r\n"); while (it.next()) |libdir| { if (mem.startsWith(u8, libdir, "-L")) { %%result.libdirs.append(libdir[2..]); @@ -310,3 +321,11 @@ pub fn installStdLib(b: &Builder) { b.installFile(src_path, dest_path); } } + +fn nextValue(index: &usize, build_info: []const u8) -> []const u8 { + const start = *index; + while (build_info[*index] != '\n' and build_info[*index] != '\r') : (*index += 1) { } + const result = build_info[start..*index]; + *index += 1; + return result; +} diff --git a/src-self-hosted/c.zig b/src-self-hosted/c.zig index 9a4b56adea..08060fbe3a 100644 --- a/src-self-hosted/c.zig +++ b/src-self-hosted/c.zig @@ -1,4 +1,5 @@ pub use @cImport({ + @cInclude("inttypes.h"); @cInclude("config.h"); @cInclude("zig_llvm.h"); }); diff --git a/src/config.h.in b/src/config.h.in index 73e1de27c1..0712c008a6 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -27,5 +27,7 @@ // Used for communicating build information to self hosted build. #define ZIG_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@" #define ZIG_CXX_COMPILER "@CMAKE_CXX_COMPILER@" +#define ZIG_LLD_INCLUDE_PATH "@LLD_INCLUDE_DIRS@" +#define ZIG_LLD_LIBRARIES "@LLD_LIBRARIES@" #endif diff --git a/src/link.cpp b/src/link.cpp index f07364e5bc..13e61dd4e7 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -426,8 +426,7 @@ static void construct_linker_job_coff(LinkJob *lj) { if (g->is_static) { Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str); lj->args.append(buf_ptr(cmt_lib_name)); - } - else { + } else { Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str); lj->args.append(buf_ptr(msvcrt_lib_name)); } @@ -452,6 +451,9 @@ static void construct_linker_job_coff(LinkJob *lj) { // } //} //lj->args.append(get_libc_static_file(g, "crtbegin.o")); + + // msvcrt depends on kernel32 + lj->args.append("kernel32.lib"); } else { lj->args.append("-NODEFAULTLIB"); if (!is_library) { diff --git a/src/main.cpp b/src/main.cpp index 66ffbbde82..4c606c95be 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -267,7 +267,7 @@ static void add_package(CodeGen *g, CliPkg *cli_pkg, PackageTableEntry *pkg) { int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "BUILD_INFO") == 0) { - printf("%s\n%s\n", ZIG_CMAKE_BINARY_DIR, ZIG_CXX_COMPILER); + printf("%s\n%s\n%s\n%s\n", ZIG_CMAKE_BINARY_DIR, ZIG_CXX_COMPILER, ZIG_LLD_INCLUDE_PATH, ZIG_LLD_LIBRARIES); return 0; } diff --git a/std/buffer.zig b/std/buffer.zig index 2bb395d0fb..69e5a6d673 100644 --- a/std/buffer.zig +++ b/std/buffer.zig @@ -112,11 +112,12 @@ pub const Buffer = struct { // TODO: remove, use OutStream for this pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void { var prev_size: usize = self.len(); - %return self.resize(prev_size + count); + const new_size = prev_size + count; + %return self.resize(new_size); - var i: usize = 0; - while (i < count) : (i += 1) { - self.list.items[prev_size + i] = byte; + var i: usize = prev_size; + while (i < new_size) : (i += 1) { + self.list.items[i] = byte; } } diff --git a/std/os/index.zig b/std/os/index.zig index 0fd3f02e9a..e1b6a9dcce 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -851,7 +851,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { // march end_index backward until next path component while (true) { end_index -= 1; - if (resolved_path[end_index] == '/') + if (os.path.isSep(resolved_path[end_index])) break; } continue; @@ -864,7 +864,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { // march end_index forward until next path component while (true) { end_index += 1; - if (end_index == resolved_path.len or resolved_path[end_index] == '/') + if (end_index == resolved_path.len or os.path.isSep(resolved_path[end_index])) break; } } diff --git a/std/os/path.zig b/std/os/path.zig index 9417cb4299..fda1f60811 100644 --- a/std/os/path.zig +++ b/std/os/path.zig @@ -22,6 +22,14 @@ pub const delimiter = if (is_windows) delimiter_windows else delimiter_posix; const is_windows = builtin.os == builtin.Os.windows; +pub fn isSep(byte: u8) -> bool { + if (is_windows) { + return byte == '/' or byte == '\\'; + } else { + return byte == '/'; + } +} + /// Naively combines a series of paths with the native path seperator. /// Allocates memory for the result, which must be freed by the caller. pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {