| 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,14 +78,6 @@ static Buf *build_compiler_rt(CodeGen *parent_gen) { |
| 78 | return build_o_raw(parent_gen, "compiler_rt", full_path); | 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 | static const char *get_darwin_arch_string(const ZigTarget *t) { | 81 | static const char *get_darwin_arch_string(const ZigTarget *t) { |
| 90 | switch (t->arch.arch) { | 82 | switch (t->arch.arch) { |
| 91 | case ZigLLVM_aarch64: | 83 | case ZigLLVM_aarch64: |
| ... | @@ -835,7 +827,7 @@ void codegen_link(CodeGen *g, const char *out_file) { | ... | @@ -835,7 +827,7 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 835 | 827 | ||
| 836 | buf_init_from_buf(&lj.out_file, g->root_out_name); | 828 | buf_init_from_buf(&lj.out_file, g->root_out_name); |
| 837 | if (g->out_type == OutTypeExe) { | 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,6 +509,36 @@ int main(int argc, char **argv) { |
| 509 | return EXIT_FAILURE; | 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 | switch (cmd) { | 542 | switch (cmd) { |
| 513 | case CmdBuild: | 543 | case CmdBuild: |
| 514 | case CmdParseH: | 544 | case CmdParseH: |
| ... | @@ -527,35 +557,6 @@ int main(int argc, char **argv) { | ... | @@ -527,35 +557,6 @@ int main(int argc, char **argv) { |
| 527 | 557 | ||
| 528 | assert(cmd != CmdBuild || out_type != OutTypeUnknown); | 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 | bool need_name = (cmd == CmdBuild || cmd == CmdParseH); | 560 | bool need_name = (cmd == CmdBuild || cmd == CmdParseH); |
| 560 | 561 | ||
| 561 | Buf *in_file_buf = nullptr; | 562 | Buf *in_file_buf = nullptr; |
| ... | @@ -674,24 +675,30 @@ int main(int argc, char **argv) { | ... | @@ -674,24 +675,30 @@ int main(int argc, char **argv) { |
| 674 | codegen_print_timing_report(g, stdout); | 675 | codegen_print_timing_report(g, stdout); |
| 675 | return EXIT_SUCCESS; | 676 | return EXIT_SUCCESS; |
| 676 | } else if (cmd == CmdTest) { | 677 | } else if (cmd == CmdTest) { |
| 677 | codegen_build(g); | ||
| 678 | codegen_link(g, "./test"); | ||
| 679 | |||
| 680 | ZigTarget native; | 678 | ZigTarget native; |
| 681 | get_native_target(&native); | 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 | bool is_native_target = target == nullptr || (target->os == native.os && | 688 | bool is_native_target = target == nullptr || (target->os == native.os && |
| 683 | target->arch.arch == native.arch.arch && target->arch.sub_arch == native.arch.sub_arch); | 689 | target->arch.arch == native.arch.arch && target->arch.sub_arch == native.arch.sub_arch); |
| 684 | if (!is_native_target) { | 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 | return 0; | 693 | return 0; |
| 687 | } | 694 | } |
| 688 | 695 | ||
| 689 | ZigList<const char *> args = {0}; | 696 | ZigList<const char *> args = {0}; |
| 690 | Termination term; | 697 | Termination term; |
| 691 | os_spawn_process("./test", args, &term); | 698 | os_spawn_process(buf_ptr(test_exe_name), args, &term); |
| 692 | if (term.how != TerminationIdClean || term.code != 0) { | 699 | if (term.how != TerminationIdClean || term.code != 0) { |
| 693 | fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n"); | 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 | } else if (timing_info) { | 702 | } else if (timing_info) { |
| 696 | codegen_print_timing_report(g, stdout); | 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,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 | enum FloatAbi { | 566 | enum FloatAbi { |
| 559 | FloatAbiHard, | 567 | FloatAbiHard, |
| 560 | FloatAbiSoft, | 568 | FloatAbiSoft, |
src/target.hpp+1| ... | @@ -73,6 +73,7 @@ void resolve_target_object_format(ZigTarget *target); | ... | @@ -73,6 +73,7 @@ void resolve_target_object_format(ZigTarget *target); |
| 73 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id); | 73 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id); |
| 74 | 74 | ||
| 75 | const char *target_o_file_ext(ZigTarget *target); | 75 | const char *target_o_file_ext(ZigTarget *target); |
| 76 | const char *target_exe_file_ext(ZigTarget *target); | ||
| 76 | 77 | ||
| 77 | Buf *target_dynamic_linker(ZigTarget *target); | 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,8 +22,8 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { |
| 22 | (??dest)[index] = (??src)[index]; | 22 | (??dest)[index] = (??src)[index]; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | export fn __stack_chk_fail() { | 25 | export fn __stack_chk_fail() -> noreturn { |
| 26 | if (builtin.mode == builtin.Mode.ReleaseFast) { | 26 | if (builtin.mode == builtin.Mode.ReleaseFast or builtin.os == builtin.Os.windows) { |
| 27 | @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal); | 27 | @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal); |
| 28 | unreachable; | 28 | unreachable; |
| 29 | } | 29 | } |
std/special/compiler_rt/index.zig+33| ... | @@ -98,6 +98,38 @@ export nakedcc fn __aeabi_uidivmod() { | ... | @@ -98,6 +98,38 @@ export nakedcc fn __aeabi_uidivmod() { |
| 98 | @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal); | 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 | export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { | 133 | export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { |
| 102 | @setDebugSafety(this, is_test); | 134 | @setDebugSafety(this, is_test); |
| 103 | @setGlobalLinkage(__udivmodsi4, builtin.GlobalLinkage.LinkOnce); | 135 | @setGlobalLinkage(__udivmodsi4, builtin.GlobalLinkage.LinkOnce); |
| ... | @@ -316,3 +348,4 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) { | ... | @@ -316,3 +348,4 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) { |
| 316 | const q: u32 = __udivsi3(a, b); | 348 | const q: u32 = __udivsi3(a, b); |
| 317 | assert(q == expected_q); | 349 | assert(q == expected_q); |
| 318 | } | 350 | } |
| 351 |
test/tests.zig+5| ... | @@ -36,6 +36,11 @@ const test_targets = []TestTarget { | ... | @@ -36,6 +36,11 @@ const test_targets = []TestTarget { |
| 36 | .arch = builtin.Arch.x86_64, | 36 | .arch = builtin.Arch.x86_64, |
| 37 | .environ = builtin.Environ.unknown, | 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 | error TestFailed; | 46 | error TestFailed; |