Commit 1d6c804b29

Isaac Freund <ifreund@ifreund.xyz>
2021-05-18 23:09:28
stage2: only default to linking system libc if linking system libs
We do need to link the system libc if linking system libraries as they may potentially be compiled against e.g. a newer glibc version than zig can provide. However if not linking system libraries, using the zig provided libc is more reliable as it does not depend on any quirks of the host system or being able to invoke the system cc to find include dirs.
1 parent 8861ee1
Changed files (1)
src/Compilation.zig
@@ -951,6 +951,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
             options.target,
             options.is_native_abi,
             link_libc,
+            options.system_libs.len != 0,
             options.libc_installation,
         );
 
@@ -3129,6 +3130,7 @@ fn detectLibCIncludeDirs(
     target: Target,
     is_native_abi: bool,
     link_libc: bool,
+    link_system_libs: bool,
     libc_installation: ?*const LibCInstallation,
 ) !LibCDirs {
     if (!link_libc) {
@@ -3142,12 +3144,16 @@ fn detectLibCIncludeDirs(
         return detectLibCFromLibCInstallation(arena, target, lci);
     }
 
-    if (is_native_abi) {
+    // If linking system libraries and targeting the native abi, default to
+    // using the system libc installation.
+    if (link_system_libs and is_native_abi) {
         const libc = try arena.create(LibCInstallation);
         libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true });
         return detectLibCFromLibCInstallation(arena, target, libc);
     }
 
+    // If not linking system libraries, build and provide our own libc by
+    // default if possible.
     if (target_util.canBuildLibC(target)) {
         const generic_name = target_util.libCGenericName(target);
         // Some architectures are handled by the same set of headers.
@@ -3198,6 +3204,14 @@ fn detectLibCIncludeDirs(
         };
     }
 
+    // If zig can't build the libc for the target and we are targeting the
+    // native abi, fall back to using the system libc installation.
+    if (is_native_abi) {
+        const libc = try arena.create(LibCInstallation);
+        libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true });
+        return detectLibCFromLibCInstallation(arena, target, libc);
+    }
+
     return LibCDirs{
         .libc_include_dir_list = &[0][]u8{},
         .libc_installation = null,