Commit eb0979189b

Andrew Kelley <superjoe30@gmail.com>
2017-08-31 17:41:58
add windows to test targets
cross-compiling hello world with no libc for windows is working
1 parent 156a84e
Changed files (7)
src/link.cpp
@@ -78,14 +78,6 @@ static Buf *build_compiler_rt(CodeGen *parent_gen) {
     return build_o_raw(parent_gen, "compiler_rt", full_path);
 }
 
-static const char *get_exe_file_extension(CodeGen *g) {
-    if (g->zig_target.os == ZigLLVM_Win32) {
-        return ".exe";
-    } else {
-        return "";
-    }
-}
-
 static const char *get_darwin_arch_string(const ZigTarget *t) {
     switch (t->arch.arch) {
         case ZigLLVM_aarch64:
@@ -835,7 +827,7 @@ void codegen_link(CodeGen *g, const char *out_file) {
 
         buf_init_from_buf(&lj.out_file, g->root_out_name);
         if (g->out_type == OutTypeExe) {
-            buf_append_str(&lj.out_file, get_exe_file_extension(g));
+            buf_append_str(&lj.out_file, target_exe_file_ext(&g->zig_target));
         }
     }
 
src/main.cpp
@@ -509,6 +509,36 @@ int main(int argc, char **argv) {
         return EXIT_FAILURE;
     }
 
+    init_all_targets();
+
+    ZigTarget alloc_target;
+    ZigTarget *target;
+    if (!target_arch && !target_os && !target_environ) {
+        target = nullptr;
+    } else {
+        target = &alloc_target;
+        get_unknown_target(target);
+        if (target_arch) {
+            if (parse_target_arch(target_arch, &target->arch)) {
+                fprintf(stderr, "invalid --target-arch argument\n");
+                return usage(arg0);
+            }
+        }
+        if (target_os) {
+            if (parse_target_os(target_os, &target->os)) {
+                fprintf(stderr, "invalid --target-os argument\n");
+                return usage(arg0);
+            }
+        }
+        if (target_environ) {
+            if (parse_target_environ(target_environ, &target->env_type)) {
+                fprintf(stderr, "invalid --target-environ argument\n");
+                return usage(arg0);
+            }
+        }
+    }
+
+
     switch (cmd) {
     case CmdBuild:
     case CmdParseH:
@@ -527,35 +557,6 @@ int main(int argc, char **argv) {
 
             assert(cmd != CmdBuild || out_type != OutTypeUnknown);
 
-            init_all_targets();
-
-            ZigTarget alloc_target;
-            ZigTarget *target;
-            if (!target_arch && !target_os && !target_environ) {
-                target = nullptr;
-            } else {
-                target = &alloc_target;
-                get_unknown_target(target);
-                if (target_arch) {
-                    if (parse_target_arch(target_arch, &target->arch)) {
-                        fprintf(stderr, "invalid --target-arch argument\n");
-                        return usage(arg0);
-                    }
-                }
-                if (target_os) {
-                    if (parse_target_os(target_os, &target->os)) {
-                        fprintf(stderr, "invalid --target-os argument\n");
-                        return usage(arg0);
-                    }
-                }
-                if (target_environ) {
-                    if (parse_target_environ(target_environ, &target->env_type)) {
-                        fprintf(stderr, "invalid --target-environ argument\n");
-                        return usage(arg0);
-                    }
-                }
-            }
-
             bool need_name = (cmd == CmdBuild || cmd == CmdParseH);
 
             Buf *in_file_buf = nullptr;
@@ -674,24 +675,30 @@ int main(int argc, char **argv) {
                     codegen_print_timing_report(g, stdout);
                 return EXIT_SUCCESS;
             } else if (cmd == CmdTest) {
-                codegen_build(g);
-                codegen_link(g, "./test");
-
                 ZigTarget native;
                 get_native_target(&native);
+
+                ZigTarget *non_null_target = target ? target : &native;
+
+                Buf *test_exe_name = buf_sprintf("./test%s", target_exe_file_ext(non_null_target));
+
+                codegen_build(g);
+                codegen_link(g, buf_ptr(test_exe_name));
+
                 bool is_native_target = target == nullptr || (target->os == native.os &&
                         target->arch.arch == native.arch.arch && target->arch.sub_arch == native.arch.sub_arch);
                 if (!is_native_target) {
-                    fprintf(stderr, "Skipping execution of non-native test binary.\n");
+                    fprintf(stderr, "Created %s but skipping execution because it is non-native.\n",
+                            buf_ptr(test_exe_name));
                     return 0;
                 }
 
                 ZigList<const char *> args = {0};
                 Termination term;
-                os_spawn_process("./test", args, &term);
+                os_spawn_process(buf_ptr(test_exe_name), args, &term);
                 if (term.how != TerminationIdClean || term.code != 0) {
                     fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n");
-                    fprintf(stderr, "./test\n");
+                    fprintf(stderr, "%s\n", buf_ptr(test_exe_name));
                 } else if (timing_info) {
                     codegen_print_timing_report(g, stdout);
                 }
src/target.cpp
@@ -555,6 +555,14 @@ const char *target_o_file_ext(ZigTarget *target) {
     }
 }
 
+const char *target_exe_file_ext(ZigTarget *target) {
+    if (target->os == ZigLLVM_Win32) {
+        return ".exe";
+    } else {
+        return "";
+    }
+}
+
 enum FloatAbi {
     FloatAbiHard,
     FloatAbiSoft,
src/target.hpp
@@ -73,6 +73,7 @@ void resolve_target_object_format(ZigTarget *target);
 uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);
 
 const char *target_o_file_ext(ZigTarget *target);
+const char *target_exe_file_ext(ZigTarget *target);
 
 Buf *target_dynamic_linker(ZigTarget *target);
 
std/special/compiler_rt/index.zig
@@ -98,6 +98,38 @@ export nakedcc fn __aeabi_uidivmod() {
     @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal);
 }
 
+export nakedcc fn __chkstk() {
+    @setDebugSafety(this, false);
+
+    if (comptime builtin.arch == builtin.Arch.x86_64) {
+        asm volatile (
+            \\         push   %%rcx
+            \\         cmp    $0x1000,%%rax
+            \\         lea    16(%%rsp),%%rcx     // rsp before calling this routine -> rcx
+            \\         jb     1f
+            \\ 2:
+            \\         sub    $0x1000,%%rcx
+            \\         test   %%rcx,(%%rcx)
+            \\         sub    $0x1000,%%rax
+            \\         cmp    $0x1000,%%rax
+            \\         ja     2b
+            \\ 1:
+            \\         sub    %%rax,%%rcx
+            \\         test   %%rcx,(%%rcx)
+            \\ 
+            \\         lea    8(%%rsp),%%rax     // load pointer to the return address into rax
+            \\         mov    %%rcx,%%rsp        // install the new top of stack pointer into rsp
+            \\         mov    -8(%%rax),%%rcx    // restore rcx
+            \\         push   (%%rax)           // push return address onto the stack
+            \\         sub    %%rsp,%%rax        // restore the original value in rax
+            \\         ret
+        );
+        unreachable;
+    }
+
+    @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal);
+}
+
 export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
     @setDebugSafety(this, is_test);
     @setGlobalLinkage(__udivmodsi4, builtin.GlobalLinkage.LinkOnce);
@@ -316,3 +348,4 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) {
     const q: u32 = __udivsi3(a, b);
     assert(q == expected_q);
 }
+
std/special/builtin.zig
@@ -22,8 +22,8 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
         (??dest)[index] = (??src)[index];
 }
 
-export fn __stack_chk_fail() {
-    if (builtin.mode == builtin.Mode.ReleaseFast) {
+export fn __stack_chk_fail() -> noreturn {
+    if (builtin.mode == builtin.Mode.ReleaseFast or builtin.os == builtin.Os.windows) {
         @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal);
         unreachable;
     }
test/tests.zig
@@ -36,6 +36,11 @@ const test_targets = []TestTarget {
         .arch = builtin.Arch.x86_64,
         .environ = builtin.Environ.unknown,
     },
+    TestTarget {
+        .os = builtin.Os.windows,
+        .arch = builtin.Arch.x86_64,
+        .environ = builtin.Environ.msvc,
+    },
 };
 
 error TestFailed;