| author | |
| committer | |
| log | ebdc6b594ddc0762ed9e41b5f36e6da5e03c19e0 |
| tree | fcc648080b4684e96d1016a912c647d0c8e313cd |
| parent | 5fd579a51c44c31b99cf34d9e8ada3b7692b4c43 |
depends on LLD 5.0.0 with 3 patches
See #2738 files changed, 131 insertions(+), 17 deletions(-)
ci/travis_osx_script+1-1| ... | @@ -12,4 +12,4 @@ cd build | ... | @@ -12,4 +12,4 @@ cd build |
| 12 | cmake .. -DCMAKE_PREFIX_PATH=$PREFIX_DIR -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_LIB_DIR=$(dirname $($CC -print-file-name=crt1.o)) -DZIG_LIBC_INCLUDE_DIR=$(echo -n | $CC -E -x c - -v 2>&1 | grep -B1 "End of search list." | head -n1 | cut -c 2- | sed "s/ .*//") -DZIG_LIBC_STATIC_LIB_DIR=$(dirname $($CC -print-file-name=crtbegin.o)) | 12 | cmake .. -DCMAKE_PREFIX_PATH=$PREFIX_DIR -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_LIB_DIR=$(dirname $($CC -print-file-name=crt1.o)) -DZIG_LIBC_INCLUDE_DIR=$(echo -n | $CC -E -x c - -v 2>&1 | grep -B1 "End of search list." | head -n1 | cut -c 2- | sed "s/ .*//") -DZIG_LIBC_STATIC_LIB_DIR=$(dirname $($CC -print-file-name=crtbegin.o)) |
| 13 | make VERBOSE=1 | 13 | make VERBOSE=1 |
| 14 | make install | 14 | make install |
| 15 | ./zig build --build-file ../build.zig test-behavior test-std test-compiler-rt test-compare-output test-compile-errors test-asm-link test-debug-safety test-parseh | 15 | ./zig build --build-file ../build.zig test |
example/mix_o_files/test.c+1-1| ... | @@ -8,7 +8,7 @@ int main(int argc, char **argv) { | ... | @@ -8,7 +8,7 @@ int main(int argc, char **argv) { |
| 8 | const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz"; | 8 | const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz"; |
| 9 | char buf[200]; | 9 | char buf[200]; |
| 10 | 10 | ||
| 11 | size_t len = decode_base_64(buf, 200, encoded, strlen(encoded)); | 11 | size_t len = decode_base_64((uint8_t *)buf, 200, (uint8_t *)encoded, strlen(encoded)); |
| 12 | buf[len] = 0; | 12 | buf[len] = 0; |
| 13 | assert(strcmp(buf, "all your base are belong to us") == 0); | 13 | assert(strcmp(buf, "all your base are belong to us") == 0); |
| 14 | 14 |
src/link.cpp+30-2| ... | @@ -634,7 +634,29 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -634,7 +634,29 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 634 | } | 634 | } |
| 635 | 635 | ||
| 636 | if (is_lib) { | 636 | if (is_lib) { |
| 637 | zig_panic("TODO linker args on darwin for making a library"); | 637 | if (!g->is_static) { |
| 638 | lj->args.append("-dylib"); | ||
| 639 | |||
| 640 | Buf *compat_vers = buf_sprintf("%" ZIG_PRI_usize ".0.0", g->version_major); | ||
| 641 | lj->args.append("-compatibility_version"); | ||
| 642 | lj->args.append(buf_ptr(compat_vers)); | ||
| 643 | |||
| 644 | Buf *cur_vers = buf_sprintf("%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize, | ||
| 645 | g->version_major, g->version_minor, g->version_patch); | ||
| 646 | lj->args.append("-current_version"); | ||
| 647 | lj->args.append(buf_ptr(cur_vers)); | ||
| 648 | |||
| 649 | // TODO getting an error when running an executable when doing this rpath thing | ||
| 650 | //Buf *dylib_install_name = buf_sprintf("@rpath/lib%s.%" ZIG_PRI_usize ".dylib", | ||
| 651 | // buf_ptr(g->root_out_name), g->version_major); | ||
| 652 | //lj->args.append("-install_name"); | ||
| 653 | //lj->args.append(buf_ptr(dylib_install_name)); | ||
| 654 | |||
| 655 | if (buf_len(&lj->out_file) == 0) { | ||
| 656 | buf_appendf(&lj->out_file, "lib%s.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib", | ||
| 657 | buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch); | ||
| 658 | } | ||
| 659 | } | ||
| 638 | } | 660 | } |
| 639 | 661 | ||
| 640 | lj->args.append("-arch"); | 662 | lj->args.append("-arch"); |
| ... | @@ -667,8 +689,14 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -667,8 +689,14 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 667 | lj->args.append("-o"); | 689 | lj->args.append("-o"); |
| 668 | lj->args.append(buf_ptr(&lj->out_file)); | 690 | lj->args.append(buf_ptr(&lj->out_file)); |
| 669 | 691 | ||
| 692 | for (size_t i = 0; i < g->rpath_list.length; i += 1) { | ||
| 693 | Buf *rpath = g->rpath_list.at(i); | ||
| 694 | add_rpath(lj, rpath); | ||
| 695 | } | ||
| 696 | add_rpath(lj, &lj->out_file); | ||
| 697 | |||
| 670 | if (shared) { | 698 | if (shared) { |
| 671 | zig_panic("TODO"); | 699 | lj->args.append("-headerpad_max_install_names"); |
| 672 | } else if (g->is_static) { | 700 | } else if (g->is_static) { |
| 673 | lj->args.append("-lcrt0.o"); | 701 | lj->args.append("-lcrt0.o"); |
| 674 | } else { | 702 | } else { |
std/build.zig+38-4| ... | @@ -784,10 +784,27 @@ pub const LibExeObjStep = struct { | ... | @@ -784,10 +784,27 @@ pub const LibExeObjStep = struct { |
| 784 | if (self.static) { | 784 | if (self.static) { |
| 785 | self.out_filename = self.builder.fmt("lib{}.a", self.name); | 785 | self.out_filename = self.builder.fmt("lib{}.a", self.name); |
| 786 | } else { | 786 | } else { |
| 787 | self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", | 787 | const target_os = switch (self.target) { |
| 788 | self.name, self.version.major, self.version.minor, self.version.patch); | 788 | Target.Native => builtin.os, |
| 789 | self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major); | 789 | Target.Cross => |t| t.os, |
| 790 | self.name_only_filename = self.builder.fmt("lib{}.so", self.name); | 790 | }; |
| 791 | switch (target_os) { | ||
| 792 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => { | ||
| 793 | self.out_filename = self.builder.fmt("lib{}.dylib.{d}.{d}.{d}", | ||
| 794 | self.name, self.version.major, self.version.minor, self.version.patch); | ||
| 795 | self.major_only_filename = self.builder.fmt("lib{}.dylib.{d}", self.name, self.version.major); | ||
| 796 | self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name); | ||
| 797 | }, | ||
| 798 | builtin.Os.windows => { | ||
| 799 | self.out_filename = self.builder.fmt("lib{}.dll", self.name); | ||
| 800 | }, | ||
| 801 | else => { | ||
| 802 | self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", | ||
| 803 | self.name, self.version.major, self.version.minor, self.version.patch); | ||
| 804 | self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major); | ||
| 805 | self.name_only_filename = self.builder.fmt("lib{}.so", self.name); | ||
| 806 | }, | ||
| 807 | } | ||
| 791 | } | 808 | } |
| 792 | }, | 809 | }, |
| 793 | } | 810 | } |
| ... | @@ -1124,6 +1141,7 @@ pub const CLibExeObjStep = struct { | ... | @@ -1124,6 +1141,7 @@ pub const CLibExeObjStep = struct { |
| 1124 | kind: Kind, | 1141 | kind: Kind, |
| 1125 | build_mode: builtin.Mode, | 1142 | build_mode: builtin.Mode, |
| 1126 | strip: bool, | 1143 | strip: bool, |
| 1144 | need_flat_namespace_hack: bool, | ||
| 1127 | 1145 | ||
| 1128 | const Kind = enum { | 1146 | const Kind = enum { |
| 1129 | Exe, | 1147 | Exe, |
| ... | @@ -1178,6 +1196,7 @@ pub const CLibExeObjStep = struct { | ... | @@ -1178,6 +1196,7 @@ pub const CLibExeObjStep = struct { |
| 1178 | .object_src = undefined, | 1196 | .object_src = undefined, |
| 1179 | .build_mode = builtin.Mode.Debug, | 1197 | .build_mode = builtin.Mode.Debug, |
| 1180 | .strip = false, | 1198 | .strip = false, |
| 1199 | .need_flat_namespace_hack = false, | ||
| 1181 | }; | 1200 | }; |
| 1182 | clib.computeOutFileNames(); | 1201 | clib.computeOutFileNames(); |
| 1183 | return clib; | 1202 | return clib; |
| ... | @@ -1223,6 +1242,7 @@ pub const CLibExeObjStep = struct { | ... | @@ -1223,6 +1242,7 @@ pub const CLibExeObjStep = struct { |
| 1223 | %%self.full_path_libs.append(lib.getOutputPath()); | 1242 | %%self.full_path_libs.append(lib.getOutputPath()); |
| 1224 | // TODO should be some kind of isolated directory that only has this header in it | 1243 | // TODO should be some kind of isolated directory that only has this header in it |
| 1225 | %%self.include_dirs.append(self.builder.cache_root); | 1244 | %%self.include_dirs.append(self.builder.cache_root); |
| 1245 | self.need_flat_namespace_hack = true; | ||
| 1226 | } | 1246 | } |
| 1227 | 1247 | ||
| 1228 | pub fn linkSystemLibrary(self: &CLibExeObjStep, name: []const u8) { | 1248 | pub fn linkSystemLibrary(self: &CLibExeObjStep, name: []const u8) { |
| ... | @@ -1448,6 +1468,20 @@ pub const CLibExeObjStep = struct { | ... | @@ -1448,6 +1468,20 @@ pub const CLibExeObjStep = struct { |
| 1448 | 1468 | ||
| 1449 | %%cc_args.append("-rdynamic"); | 1469 | %%cc_args.append("-rdynamic"); |
| 1450 | 1470 | ||
| 1471 | const target_os = switch (self.target) { | ||
| 1472 | Target.Native => builtin.os, | ||
| 1473 | Target.Cross => |t| t.os, | ||
| 1474 | }; | ||
| 1475 | switch (target_os) { | ||
| 1476 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => { | ||
| 1477 | if (self.need_flat_namespace_hack) { | ||
| 1478 | %%cc_args.append("-Wl,-flat_namespace"); | ||
| 1479 | } | ||
| 1480 | %%cc_args.append("-Wl,-search_paths_first"); | ||
| 1481 | }, | ||
| 1482 | else => {} | ||
| 1483 | } | ||
| 1484 | |||
| 1451 | for (self.full_path_libs.toSliceConst()) |full_path_lib| { | 1485 | for (self.full_path_libs.toSliceConst()) |full_path_lib| { |
| 1452 | %%cc_args.append(builder.pathFromRoot(full_path_lib)); | 1486 | %%cc_args.append(builder.pathFromRoot(full_path_lib)); |
| 1453 | } | 1487 | } |
std/c/index.zig+1| ... | @@ -37,3 +37,4 @@ pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8, | ... | @@ -37,3 +37,4 @@ pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8, |
| 37 | pub extern "c" fn dup(fd: c_int) -> c_int; | 37 | pub extern "c" fn dup(fd: c_int) -> c_int; |
| 38 | pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) -> c_int; | 38 | pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) -> c_int; |
| 39 | pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) -> isize; | 39 | pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) -> isize; |
| 40 | pub extern "c" fn realpath(noalias file_name: &const u8, noalias resolved_name: &u8) -> ?&u8; |
std/os/darwin.zig+6| ... | @@ -3,6 +3,8 @@ const assert = @import("../debug.zig").assert; | ... | @@ -3,6 +3,8 @@ const assert = @import("../debug.zig").assert; |
| 3 | 3 | ||
| 4 | pub use @import("darwin_errno.zig"); | 4 | pub use @import("darwin_errno.zig"); |
| 5 | 5 | ||
| 6 | pub const PATH_MAX = 1024; | ||
| 7 | |||
| 6 | pub const STDIN_FILENO = 0; | 8 | pub const STDIN_FILENO = 0; |
| 7 | pub const STDOUT_FILENO = 1; | 9 | pub const STDOUT_FILENO = 1; |
| 8 | pub const STDERR_FILENO = 2; | 10 | pub const STDERR_FILENO = 2; |
| ... | @@ -203,6 +205,10 @@ pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) - | ... | @@ -203,6 +205,10 @@ pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) - |
| 203 | errnoWrap(c.readlink(path, buf_ptr, buf_len)) | 205 | errnoWrap(c.readlink(path, buf_ptr, buf_len)) |
| 204 | } | 206 | } |
| 205 | 207 | ||
| 208 | pub fn realpath(noalias filename: &const u8, noalias resolved_name: &u8) -> usize { | ||
| 209 | if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0 | ||
| 210 | } | ||
| 211 | |||
| 206 | /// Takes the return value from a syscall and formats it back in the way | 212 | /// Takes the return value from a syscall and formats it back in the way |
| 207 | /// that the kernel represents it to libc. Errno was a mistake, let's make | 213 | /// that the kernel represents it to libc. Errno was a mistake, let's make |
| 208 | /// it go away forever. | 214 | /// it go away forever. |
std/os/linux.zig+2| ... | @@ -6,6 +6,8 @@ const arch = switch (builtin.arch) { | ... | @@ -6,6 +6,8 @@ const arch = switch (builtin.arch) { |
| 6 | }; | 6 | }; |
| 7 | pub use @import("linux_errno.zig"); | 7 | pub use @import("linux_errno.zig"); |
| 8 | 8 | ||
| 9 | pub const PATH_MAX = 4096; | ||
| 10 | |||
| 9 | pub const STDIN_FILENO = 0; | 11 | pub const STDIN_FILENO = 0; |
| 10 | pub const STDOUT_FILENO = 1; | 12 | pub const STDOUT_FILENO = 1; |
| 11 | pub const STDERR_FILENO = 2; | 13 | pub const STDERR_FILENO = 2; |
std/os/path.zig+52-9| ... | @@ -8,6 +8,8 @@ const Allocator = mem.Allocator; | ... | @@ -8,6 +8,8 @@ const Allocator = mem.Allocator; |
| 8 | const os = @import("index.zig"); | 8 | const os = @import("index.zig"); |
| 9 | const math = @import("../math.zig"); | 9 | const math = @import("../math.zig"); |
| 10 | const posix = os.posix; | 10 | const posix = os.posix; |
| 11 | const c = @import("../c/index.zig"); | ||
| 12 | const cstr = @import("../cstr.zig"); | ||
| 11 | 13 | ||
| 12 | pub const sep = switch (builtin.os) { | 14 | pub const sep = switch (builtin.os) { |
| 13 | Os.windows => '\\', | 15 | Os.windows => '\\', |
| ... | @@ -279,19 +281,60 @@ fn testRelative(from: []const u8, to: []const u8, expected_output: []const u8) { | ... | @@ -279,19 +281,60 @@ fn testRelative(from: []const u8, to: []const u8, expected_output: []const u8) { |
| 279 | assert(mem.eql(u8, result, expected_output)); | 281 | assert(mem.eql(u8, result, expected_output)); |
| 280 | } | 282 | } |
| 281 | 283 | ||
| 284 | error AccessDenied; | ||
| 285 | error FileNotFound; | ||
| 286 | error NotSupported; | ||
| 287 | error NotDir; | ||
| 288 | error NameTooLong; | ||
| 289 | error SymLinkLoop; | ||
| 290 | error InputOutput; | ||
| 291 | error Unexpected; | ||
| 282 | /// Return the canonicalized absolute pathname. | 292 | /// Return the canonicalized absolute pathname. |
| 283 | /// Expands all symbolic links and resolves references to `.`, `..`, and | 293 | /// Expands all symbolic links and resolves references to `.`, `..`, and |
| 284 | /// extra `/` characters in ::pathname. | 294 | /// extra `/` characters in ::pathname. |
| 285 | /// Caller must deallocate result. | 295 | /// Caller must deallocate result. |
| 286 | pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | 296 | pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 287 | if (builtin.os == builtin.Os.windows) { | 297 | switch (builtin.os) { |
| 288 | @compileError("TODO implement os.path.real for windows"); | 298 | Os.windows => @compileError("TODO implement os.path.real for windows"), |
| 299 | Os.darwin, Os.macosx, Os.ios => { | ||
| 300 | // TODO instead of calling the libc function here, port the implementation | ||
| 301 | // to Zig, and then remove the NameTooLong error possibility. | ||
| 302 | const pathname_buf = %return allocator.alloc(u8, pathname.len + 1); | ||
| 303 | defer allocator.free(pathname_buf); | ||
| 304 | |||
| 305 | const result_buf = %return allocator.alloc(u8, posix.PATH_MAX); | ||
| 306 | %defer allocator.free(result_buf); | ||
| 307 | |||
| 308 | mem.copy(u8, pathname_buf, pathname); | ||
| 309 | pathname_buf[pathname.len] = 0; | ||
| 310 | |||
| 311 | const err = posix.getErrno(posix.realpath(pathname_buf.ptr, result_buf.ptr)); | ||
| 312 | if (err > 0) { | ||
| 313 | return switch (err) { | ||
| 314 | posix.EINVAL => unreachable, | ||
| 315 | posix.EBADF => unreachable, | ||
| 316 | posix.EFAULT => unreachable, | ||
| 317 | posix.EACCES => error.AccessDenied, | ||
| 318 | posix.ENOENT => error.FileNotFound, | ||
| 319 | posix.ENOTSUP => error.NotSupported, | ||
| 320 | posix.ENOTDIR => error.NotDir, | ||
| 321 | posix.ENAMETOOLONG => error.NameTooLong, | ||
| 322 | posix.ELOOP => error.SymLinkLoop, | ||
| 323 | posix.EIO => error.InputOutput, | ||
| 324 | else => error.Unexpected, | ||
| 325 | }; | ||
| 326 | } | ||
| 327 | return cstr.toSlice(result_buf.ptr); | ||
| 328 | }, | ||
| 329 | Os.linux => { | ||
| 330 | const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); | ||
| 331 | defer os.posixClose(fd); | ||
| 332 | |||
| 333 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; | ||
| 334 | const proc_path = fmt.bufPrint(buf[0..], "/proc/self/fd/{}", fd); | ||
| 335 | |||
| 336 | return os.readLink(allocator, proc_path); | ||
| 337 | }, | ||
| 338 | else => @compileError("TODO implement os.path.real for " ++ @enumTagName(builtin.os)), | ||
| 289 | } | 339 | } |
| 290 | const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); | ||
| 291 | defer os.posixClose(fd); | ||
| 292 | |||
| 293 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; | ||
| 294 | const proc_path = fmt.bufPrint(buf[0..], "/proc/self/fd/{}", fd); | ||
| 295 | |||
| 296 | return os.readLink(allocator, proc_path); | ||
| 297 | } | 340 | } |