| author | |
| committer | |
| log | eb0979189be33d6d957dad5104650cb5c532055b |
| tree | a94044c19e0e002b89c74b89d922a653c35362f2 |
| parent | 156a84e80ff68441fcc630b1bfbc3eb7d881b267 |
cross-compiling hello world with no libc for windows is working7 files changed, 92 insertions(+), 46 deletions(-)
src/link.cpp+1-9| ... | ... | @@ -78,14 +78,6 @@ static Buf *build_compiler_rt(CodeGen *parent_gen) { |
| 78 | 78 | return build_o_raw(parent_gen, "compiler_rt", full_path); |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | static const char *get_exe_file_extension(CodeGen *g) { | |
| 82 | if (g->zig_target.os == ZigLLVM_Win32) { | |
| 83 | return ".exe"; | |
| 84 | } else { | |
| 85 | return ""; | |
| 86 | } | |
| 87 | } | |
| 88 | ||
| 89 | 81 | static const char *get_darwin_arch_string(const ZigTarget *t) { |
| 90 | 82 | switch (t->arch.arch) { |
| 91 | 83 | case ZigLLVM_aarch64: |
| ... | ... | @@ -835,7 +827,7 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 835 | 827 | |
| 836 | 828 | buf_init_from_buf(&lj.out_file, g->root_out_name); |
| 837 | 829 | if (g->out_type == OutTypeExe) { |
| 838 | buf_append_str(&lj.out_file, get_exe_file_extension(g)); | |
| 830 | buf_append_str(&lj.out_file, target_exe_file_ext(&g->zig_target)); | |
| 839 | 831 | } |
| 840 | 832 | } |
| 841 | 833 |
src/main.cpp+42-35| ... | ... | @@ -509,6 +509,36 @@ int main(int argc, char **argv) { |
| 509 | 509 | return EXIT_FAILURE; |
| 510 | 510 | } |
| 511 | 511 | |
| 512 | init_all_targets(); | |
| 513 | ||
| 514 | ZigTarget alloc_target; | |
| 515 | ZigTarget *target; | |
| 516 | if (!target_arch && !target_os && !target_environ) { | |
| 517 | target = nullptr; | |
| 518 | } else { | |
| 519 | target = &alloc_target; | |
| 520 | get_unknown_target(target); | |
| 521 | if (target_arch) { | |
| 522 | if (parse_target_arch(target_arch, &target->arch)) { | |
| 523 | fprintf(stderr, "invalid --target-arch argument\n"); | |
| 524 | return usage(arg0); | |
| 525 | } | |
| 526 | } | |
| 527 | if (target_os) { | |
| 528 | if (parse_target_os(target_os, &target->os)) { | |
| 529 | fprintf(stderr, "invalid --target-os argument\n"); | |
| 530 | return usage(arg0); | |
| 531 | } | |
| 532 | } | |
| 533 | if (target_environ) { | |
| 534 | if (parse_target_environ(target_environ, &target->env_type)) { | |
| 535 | fprintf(stderr, "invalid --target-environ argument\n"); | |
| 536 | return usage(arg0); | |
| 537 | } | |
| 538 | } | |
| 539 | } | |
| 540 | ||
| 541 | ||
| 512 | 542 | switch (cmd) { |
| 513 | 543 | case CmdBuild: |
| 514 | 544 | case CmdParseH: |
| ... | ... | @@ -527,35 +557,6 @@ int main(int argc, char **argv) { |
| 527 | 557 | |
| 528 | 558 | assert(cmd != CmdBuild || out_type != OutTypeUnknown); |
| 529 | 559 | |
| 530 | init_all_targets(); | |
| 531 | ||
| 532 | ZigTarget alloc_target; | |
| 533 | ZigTarget *target; | |
| 534 | if (!target_arch && !target_os && !target_environ) { | |
| 535 | target = nullptr; | |
| 536 | } else { | |
| 537 | target = &alloc_target; | |
| 538 | get_unknown_target(target); | |
| 539 | if (target_arch) { | |
| 540 | if (parse_target_arch(target_arch, &target->arch)) { | |
| 541 | fprintf(stderr, "invalid --target-arch argument\n"); | |
| 542 | return usage(arg0); | |
| 543 | } | |
| 544 | } | |
| 545 | if (target_os) { | |
| 546 | if (parse_target_os(target_os, &target->os)) { | |
| 547 | fprintf(stderr, "invalid --target-os argument\n"); | |
| 548 | return usage(arg0); | |
| 549 | } | |
| 550 | } | |
| 551 | if (target_environ) { | |
| 552 | if (parse_target_environ(target_environ, &target->env_type)) { | |
| 553 | fprintf(stderr, "invalid --target-environ argument\n"); | |
| 554 | return usage(arg0); | |
| 555 | } | |
| 556 | } | |
| 557 | } | |
| 558 | ||
| 559 | 560 | bool need_name = (cmd == CmdBuild || cmd == CmdParseH); |
| 560 | 561 | |
| 561 | 562 | Buf *in_file_buf = nullptr; |
| ... | ... | @@ -674,24 +675,30 @@ int main(int argc, char **argv) { |
| 674 | 675 | codegen_print_timing_report(g, stdout); |
| 675 | 676 | return EXIT_SUCCESS; |
| 676 | 677 | } else if (cmd == CmdTest) { |
| 677 | codegen_build(g); | |
| 678 | codegen_link(g, "./test"); | |
| 679 | ||
| 680 | 678 | ZigTarget native; |
| 681 | 679 | get_native_target(&native); |
| 680 | ||
| 681 | ZigTarget *non_null_target = target ? target : &native; | |
| 682 | ||
| 683 | Buf *test_exe_name = buf_sprintf("./test%s", target_exe_file_ext(non_null_target)); | |
| 684 | ||
| 685 | codegen_build(g); | |
| 686 | codegen_link(g, buf_ptr(test_exe_name)); | |
| 687 | ||
| 682 | 688 | bool is_native_target = target == nullptr || (target->os == native.os && |
| 683 | 689 | target->arch.arch == native.arch.arch && target->arch.sub_arch == native.arch.sub_arch); |
| 684 | 690 | if (!is_native_target) { |
| 685 | fprintf(stderr, "Skipping execution of non-native test binary.\n"); | |
| 691 | fprintf(stderr, "Created %s but skipping execution because it is non-native.\n", | |
| 692 | buf_ptr(test_exe_name)); | |
| 686 | 693 | return 0; |
| 687 | 694 | } |
| 688 | 695 | |
| 689 | 696 | ZigList<const char *> args = {0}; |
| 690 | 697 | Termination term; |
| 691 | os_spawn_process("./test", args, &term); | |
| 698 | os_spawn_process(buf_ptr(test_exe_name), args, &term); | |
| 692 | 699 | if (term.how != TerminationIdClean || term.code != 0) { |
| 693 | 700 | fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n"); |
| 694 | fprintf(stderr, "./test\n"); | |
| 701 | fprintf(stderr, "%s\n", buf_ptr(test_exe_name)); | |
| 695 | 702 | } else if (timing_info) { |
| 696 | 703 | codegen_print_timing_report(g, stdout); |
| 697 | 704 | } |
src/target.cpp+8| ... | ... | @@ -555,6 +555,14 @@ const char *target_o_file_ext(ZigTarget *target) { |
| 555 | 555 | } |
| 556 | 556 | } |
| 557 | 557 | |
| 558 | const char *target_exe_file_ext(ZigTarget *target) { | |
| 559 | if (target->os == ZigLLVM_Win32) { | |
| 560 | return ".exe"; | |
| 561 | } else { | |
| 562 | return ""; | |
| 563 | } | |
| 564 | } | |
| 565 | ||
| 558 | 566 | enum FloatAbi { |
| 559 | 567 | FloatAbiHard, |
| 560 | 568 | FloatAbiSoft, |
src/target.hpp+1| ... | ... | @@ -73,6 +73,7 @@ void resolve_target_object_format(ZigTarget *target); |
| 73 | 73 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id); |
| 74 | 74 | |
| 75 | 75 | const char *target_o_file_ext(ZigTarget *target); |
| 76 | const char *target_exe_file_ext(ZigTarget *target); | |
| 76 | 77 | |
| 77 | 78 | Buf *target_dynamic_linker(ZigTarget *target); |
| 78 | 79 |
std/special/builtin.zig+2-2| ... | ... | @@ -22,8 +22,8 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { |
| 22 | 22 | (??dest)[index] = (??src)[index]; |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | export fn __stack_chk_fail() { | |
| 26 | if (builtin.mode == builtin.Mode.ReleaseFast) { | |
| 25 | export fn __stack_chk_fail() -> noreturn { | |
| 26 | if (builtin.mode == builtin.Mode.ReleaseFast or builtin.os == builtin.Os.windows) { | |
| 27 | 27 | @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal); |
| 28 | 28 | unreachable; |
| 29 | 29 | } |
std/special/compiler_rt/index.zig+33| ... | ... | @@ -98,6 +98,38 @@ export nakedcc fn __aeabi_uidivmod() { |
| 98 | 98 | @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal); |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | export nakedcc fn __chkstk() { | |
| 102 | @setDebugSafety(this, false); | |
| 103 | ||
| 104 | if (comptime builtin.arch == builtin.Arch.x86_64) { | |
| 105 | asm volatile ( | |
| 106 | \\ push %%rcx | |
| 107 | \\ cmp $0x1000,%%rax | |
| 108 | \\ lea 16(%%rsp),%%rcx // rsp before calling this routine -> rcx | |
| 109 | \\ jb 1f | |
| 110 | \\ 2: | |
| 111 | \\ sub $0x1000,%%rcx | |
| 112 | \\ test %%rcx,(%%rcx) | |
| 113 | \\ sub $0x1000,%%rax | |
| 114 | \\ cmp $0x1000,%%rax | |
| 115 | \\ ja 2b | |
| 116 | \\ 1: | |
| 117 | \\ sub %%rax,%%rcx | |
| 118 | \\ test %%rcx,(%%rcx) | |
| 119 | \\ | |
| 120 | \\ lea 8(%%rsp),%%rax // load pointer to the return address into rax | |
| 121 | \\ mov %%rcx,%%rsp // install the new top of stack pointer into rsp | |
| 122 | \\ mov -8(%%rax),%%rcx // restore rcx | |
| 123 | \\ push (%%rax) // push return address onto the stack | |
| 124 | \\ sub %%rsp,%%rax // restore the original value in rax | |
| 125 | \\ ret | |
| 126 | ); | |
| 127 | unreachable; | |
| 128 | } | |
| 129 | ||
| 130 | @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal); | |
| 131 | } | |
| 132 | ||
| 101 | 133 | export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { |
| 102 | 134 | @setDebugSafety(this, is_test); |
| 103 | 135 | @setGlobalLinkage(__udivmodsi4, builtin.GlobalLinkage.LinkOnce); |
| ... | ... | @@ -316,3 +348,4 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) { |
| 316 | 348 | const q: u32 = __udivsi3(a, b); |
| 317 | 349 | assert(q == expected_q); |
| 318 | 350 | } |
| 351 |
test/tests.zig+5| ... | ... | @@ -36,6 +36,11 @@ const test_targets = []TestTarget { |
| 36 | 36 | .arch = builtin.Arch.x86_64, |
| 37 | 37 | .environ = builtin.Environ.unknown, |
| 38 | 38 | }, |
| 39 | TestTarget { | |
| 40 | .os = builtin.Os.windows, | |
| 41 | .arch = builtin.Arch.x86_64, | |
| 42 | .environ = builtin.Environ.msvc, | |
| 43 | }, | |
| 39 | 44 | }; |
| 40 | 45 | |
| 41 | 46 | error TestFailed; |