Commit fae6cf0961

Andrew Kelley <andrew@ziglang.org>
2020-03-26 01:32:40
improved handling of native system directories
* `-isystem` instead of `-I` for system include directories fixes a problem with native system directories interfering with zig's bundled libc. * separate Stage2Target.is_native into Stage2Target.is_native_os and Stage2Target.is_native_cpu.
1 parent dd66fbb
lib/std/zig/cross_target.zig
@@ -480,12 +480,19 @@ pub const CrossTarget = struct {
         return Target.libPrefix_cpu_arch_abi(self.getCpuArch(), self.getAbi());
     }
 
-    pub fn isNative(self: CrossTarget) bool {
+    pub fn isNativeCpu(self: CrossTarget) bool {
         return self.cpu_arch == null and
             (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
-            self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and
-            self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
-            self.abi == null and self.dynamic_linker.get() == null and self.glibc_version == null;
+            self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty();
+    }
+
+    pub fn isNativeOs(self: CrossTarget) bool {
+        return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
+            self.dynamic_linker.get() == null and self.glibc_version == null;
+    }
+
+    pub fn isNative(self: CrossTarget) bool {
+        return self.isNativeCpu() and self.isNativeOs() and self.abi == null;
     }
 
     pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 {
src/codegen.cpp
@@ -8782,7 +8782,8 @@ static Error define_builtin_compile_vars(CodeGen *g) {
     cache_bool(&cache_hash, g->is_single_threaded);
     cache_bool(&cache_hash, g->test_is_evented);
     cache_int(&cache_hash, g->code_model);
-    cache_int(&cache_hash, g->zig_target->is_native);
+    cache_int(&cache_hash, g->zig_target->is_native_os);
+    cache_int(&cache_hash, g->zig_target->is_native_cpu);
     cache_int(&cache_hash, g->zig_target->arch);
     cache_int(&cache_hash, g->zig_target->vendor);
     cache_int(&cache_hash, g->zig_target->os);
@@ -8917,7 +8918,7 @@ static void init(CodeGen *g) {
     const char *target_specific_cpu_args = "";
     const char *target_specific_features = "";
 
-    if (g->zig_target->is_native) {
+    if (g->zig_target->is_native_cpu) {
         target_specific_cpu_args = ZigLLVMGetHostCPUName();
         target_specific_features = ZigLLVMGetNativeFeatures();
     }
@@ -9034,7 +9035,7 @@ static void detect_libc(CodeGen *g) {
         return;
     }
 
-    if (g->zig_target->is_native) {
+    if (g->zig_target->is_native_os) {
         g->libc = heap::c_allocator.create<Stage2LibCInstallation>();
 
         // search for native_libc.txt in following dirs:
@@ -9672,7 +9673,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
     cache_int(cache_hash, g->err_color);
     cache_buf(cache_hash, g->zig_c_headers_dir);
     cache_list_of_str(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len);
-    cache_int(cache_hash, g->zig_target->is_native);
+    cache_int(cache_hash, g->zig_target->is_native_os);
+    cache_int(cache_hash, g->zig_target->is_native_cpu);
     cache_int(cache_hash, g->zig_target->arch);
     cache_int(cache_hash, g->zig_target->vendor);
     cache_int(cache_hash, g->zig_target->os);
@@ -10474,7 +10476,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
     cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length);
     cache_int(ch, g->build_mode);
     cache_int(ch, g->out_type);
-    cache_bool(ch, g->zig_target->is_native);
+    cache_bool(ch, g->zig_target->is_native_os);
+    cache_bool(ch, g->zig_target->is_native_cpu);
     cache_int(ch, g->zig_target->arch);
     cache_int(ch, g->zig_target->vendor);
     cache_int(ch, g->zig_target->os);
@@ -10941,7 +10944,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
     os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);
 
     assert(target != nullptr);
-    if (!target->is_native) {
+    if (!target->is_native_os) {
         g->each_lib_rpath = false;
     } else {
         g->each_lib_rpath = true;
src/link.cpp
@@ -635,7 +635,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress
         c_file->args.append("-fPIC");
         c_file->args.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS");
         c_file->args.append("-Wa,--noexecstack");
-        if (parent->zig_target->is_native) {
+        if (parent->zig_target->is_native_os && parent->zig_target->is_native_cpu) {
             c_file->args.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
         }
         if (parent->build_mode == BuildModeDebug) {
@@ -1829,7 +1829,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
         }
     }
 
-    if (!g->zig_target->is_native) {
+    if (!g->zig_target->is_native_os) {
         lj->args.append("--allow-shlib-undefined");
     }
 }
@@ -2460,7 +2460,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
         lj->args.append(buf_ptr(compiler_rt_o_path));
     }
 
-    if (g->zig_target->is_native) {
+    if (g->zig_target->is_native_os) {
         for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
             LinkLib *link_lib = g->link_libs_list.at(lib_i);
             if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) {
src/main.cpp
@@ -1325,7 +1325,15 @@ static int main0(int argc, char **argv) {
                 return print_error_usage(arg0);
             }
 
-            if (target.is_native && link_libs.length != 0) {
+            bool any_non_c_link_libs = false;
+            for (size_t i = 0; i < link_libs.length; i += 1) {
+                if (!target_is_libc_lib_name(&target, link_libs.at(i))) {
+                    any_non_c_link_libs = true;
+                    break;
+                }
+            }
+
+            if (target.is_native_os && any_non_c_link_libs) {
                 Error err;
                 Stage2NativePaths paths;
                 if ((err = stage2_detect_native_paths(&paths))) {
@@ -1338,7 +1346,7 @@ static int main0(int argc, char **argv) {
                 }
                 for (size_t i = 0; i < paths.include_dirs_len; i += 1) {
                     const char *include_dir = paths.include_dirs_ptr[i];
-                    clang_argv.append("-I");
+                    clang_argv.append("-isystem");
                     clang_argv.append(include_dir);
                 }
                 for (size_t i = 0; i < paths.lib_dirs_len; i += 1) {
src/stage2.cpp
@@ -181,7 +181,8 @@ static void get_native_target(ZigTarget *target) {
             &target->abi,
             &oformat);
     target->os = get_zig_os_type(os_type);
-    target->is_native = true;
+    target->is_native_os = true;
+    target->is_native_cpu = true;
     if (target->abi == ZigLLVM_UnknownEnvironment) {
         target->abi = target_default_abi(target->arch, target->os);
     }
@@ -204,7 +205,8 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons
             target->llvm_cpu_features = ZigLLVMGetNativeFeatures();
             target->cache_hash = "native\n\n";
         } else if (strcmp(mcpu, "baseline") == 0) {
-            target->is_native = false;
+            target->is_native_os = false;
+            target->is_native_cpu = false;
             target->llvm_cpu_name = "";
             target->llvm_cpu_features = "";
             target->cache_hash = "baseline\n\n";
src/stage2.h
@@ -280,7 +280,8 @@ struct ZigTarget {
     enum ZigLLVM_EnvironmentType abi;
     Os os;
 
-    bool is_native;
+    bool is_native_os;
+    bool is_native_cpu;
 
     // null means default. this is double-purposed to be darwin min version
     struct Stage2SemVer *glibc_or_darwin_version;
src/target.cpp
@@ -1239,7 +1239,8 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {
     out_target->os = libcs_available[index].os;
     out_target->abi = libcs_available[index].abi;
     out_target->vendor = ZigLLVM_UnknownVendor;
-    out_target->is_native = false;
+    out_target->is_native_os = false;
+    out_target->is_native_cpu = false;
 }
 
 bool target_has_debug_info(const ZigTarget *target) {
src-self-hosted/stage2.zig
@@ -898,7 +898,8 @@ const Stage2Target = extern struct {
     abi: c_int,
     os: c_int,
 
-    is_native: bool,
+    is_native_os: bool,
+    is_native_cpu: bool,
 
     glibc_or_darwin_version: ?*Stage2SemVer,
 
@@ -1166,7 +1167,8 @@ const Stage2Target = extern struct {
             .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr,
             .cache_hash = cache_hash_slice.ptr,
             .cache_hash_len = cache_hash_slice.len,
-            .is_native = cross_target.isNative(),
+            .is_native_os = cross_target.isNativeOs(),
+            .is_native_cpu = cross_target.isNativeCpu(),
             .glibc_or_darwin_version = glibc_or_darwin_version,
             .dynamic_linker = dynamic_linker,
             .standard_dynamic_linker_path = std_dl_z,