Commit f7bf61a983

meme <meme@users.noreply.github.com>
2019-09-27 22:51:42
support Android NDK and bionic
1 parent 805f9b3
Changed files (4)
lib/std/c/linux.zig
@@ -1,9 +1,19 @@
+const builtin = @import("builtin");
 const std = @import("../std.zig");
 const maxInt = std.math.maxInt;
 usingnamespace std.c;
 
-extern "c" fn __errno_location() *c_int;
-pub const _errno = __errno_location;
+pub const _errno = switch (builtin.abi) {
+    .android => struct {
+        extern "c" var __errno: c_int;
+        fn getErrno() *c_int {
+            return &__errno;
+        }
+    }.getErrno,
+    else => struct {
+        extern "c" fn __errno_location() *c_int;
+    }.__errno_location,
+};
 
 pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
 
src/link.cpp
@@ -1653,6 +1653,10 @@ static void construct_linker_job_elf(LinkJob *lj) {
         soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
     }
 
+    if (target_requires_pie(g->zig_target) && !is_dyn_lib) {
+        lj->args.append("-pie");
+    }
+
     lj->args.append("-o");
     lj->args.append(buf_ptr(&g->output_file_path));
 
@@ -1660,8 +1664,14 @@ static void construct_linker_job_elf(LinkJob *lj) {
         const char *crt1o;
         if (g->zig_target->os == OsNetBSD) {
             crt1o = "crt0.o";
+        } else if (target_is_android(g->zig_target)) {
+            crt1o = "crtbegin_dynamic.o";
         } else if (!g->have_dynamic_link) {
-            crt1o = "crt1.o";
+            if (target_is_android(g->zig_target)) {
+                crt1o = "crtbegin.o";
+            } else {
+                crt1o = "crt1.o";
+            }
         } else {
             crt1o = "Scrt1.o";
         }
@@ -1768,21 +1778,27 @@ static void construct_linker_job_elf(LinkJob *lj) {
             if (!g->have_dynamic_link) {
                 lj->args.append("--start-group");
                 lj->args.append("-lgcc");
-                lj->args.append("-lgcc_eh");
+                if (!target_is_android(g->zig_target)) {
+                    lj->args.append("-lgcc_eh");
+                }
                 lj->args.append("-lc");
                 lj->args.append("-lm");
                 lj->args.append("--end-group");
             } else {
                 lj->args.append("-lgcc");
-                lj->args.append("--as-needed");
-                lj->args.append("-lgcc_s");
-                lj->args.append("--no-as-needed");
+                if (!target_is_android(g->zig_target)) {
+                    lj->args.append("--as-needed");
+                    lj->args.append("-lgcc_s");
+                    lj->args.append("--no-as-needed");
+                }
                 lj->args.append("-lc");
                 lj->args.append("-lm");
                 lj->args.append("-lgcc");
-                lj->args.append("--as-needed");
-                lj->args.append("-lgcc_s");
-                lj->args.append("--no-as-needed");
+                if (!target_is_android(g->zig_target)) {
+                    lj->args.append("--as-needed");
+                    lj->args.append("-lgcc_s");
+                    lj->args.append("--no-as-needed");
+                }
             }
 
             if (g->zig_target->os == OsFreeBSD) {
@@ -1805,7 +1821,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
     }
 
     // crt end
-    if (lj->link_in_crt && target_libc_needs_crti_crtn(g->zig_target)) {
+    if (target_is_android(g->zig_target) && g->have_dynamic_link) {
+        lj->args.append(get_libc_crt_file(g, "crtend_android.o"));
+    } else if (lj->link_in_crt && target_libc_needs_crti_crtn(g->zig_target)) {
         lj->args.append(get_libc_crt_file(g, "crtn.o"));
     }
 
src/target.cpp
@@ -1590,10 +1590,14 @@ bool target_supports_stack_probing(const ZigTarget *target) {
 
 bool target_requires_pic(const ZigTarget *target, bool linking_libc) {
   // This function returns whether non-pic code is completely invalid on the given target.
-  return target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) ||
+  return target_is_android(target) || target->os == OsWindows || target->os == OsUefi || target_os_requires_libc(target->os) ||
       (linking_libc && target_is_glibc(target));
 }
 
+bool target_requires_pie(const ZigTarget *target) {
+    return target_is_android(target);
+}
+
 bool target_is_glibc(const ZigTarget *target) {
     return target->os == OsLinux && target_abi_is_gnu(target->abi);
 }
@@ -1876,7 +1880,7 @@ bool target_supports_libunwind(const ZigTarget *target) {
 }
 
 bool target_libc_needs_crti_crtn(const ZigTarget *target) {
-    if (target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64) {
+    if (target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64 || target_is_android(target)) {
         return false;
     }
     return true;
src/target.hpp
@@ -182,6 +182,7 @@ const char *target_libc_generic_name(const ZigTarget *target);
 bool target_is_libc_lib_name(const ZigTarget *target, const char *name);
 bool target_supports_fpic(const ZigTarget *target);
 bool target_requires_pic(const ZigTarget *target, bool linking_libc);
+bool target_requires_pie(const ZigTarget *target);
 bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi);
 bool target_abi_is_musl(ZigLLVM_EnvironmentType abi);
 bool target_is_glibc(const ZigTarget *target);