From 5ac91794cce8bd53916a378815be01e4365d53d9 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Mon, 10 May 2021 21:29:20 +0200 Subject: [PATCH 1/4] stage2: use system libc when targeting the native OS/ABI Currently zig will always try to build its own libc and compile against that. This of course makes sense for cross-compilation, but can cause problems when targeting the native OS/ABI. For example, if the system uses a newer glibc version than zig ships zig will fall back to using the newest version it does ship. However this causes linking system libraries to fail as they are built against a different glibc version than the zig code is built against. To remedy this, simply default to linking the system libc when targeting the native OS/ABI. --- src/Compilation.zig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 87d4c4c41e87a1b167c46b62e6c58b283e95602c..71df7768551b1fb358ecbbf42f9ff8f25ad0f223 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -848,7 +848,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { arena, options.zig_lib_directory.path.?, options.target, - options.is_native_os, + options.is_native_abi, link_libc, options.libc_installation, ); @@ -2885,7 +2885,7 @@ fn detectLibCIncludeDirs( arena: *Allocator, zig_lib_dir: []const u8, target: Target, - is_native_os: bool, + is_native_abi: bool, link_libc: bool, libc_installation: ?*const LibCInstallation, ) !LibCDirs { @@ -2900,6 +2900,12 @@ fn detectLibCIncludeDirs( return detectLibCFromLibCInstallation(arena, target, lci); } + if (is_native_abi) { + const libc = try arena.create(LibCInstallation); + libc.* = try LibCInstallation.findNative(.{ .allocator = arena }); + return detectLibCFromLibCInstallation(arena, target, libc); + } + if (target_util.canBuildLibC(target)) { const generic_name = target_util.libCGenericName(target); // Some architectures are handled by the same set of headers. @@ -2950,12 +2956,6 @@ fn detectLibCIncludeDirs( }; } - if (is_native_os) { - const libc = try arena.create(LibCInstallation); - libc.* = try LibCInstallation.findNative(.{ .allocator = arena }); - return detectLibCFromLibCInstallation(arena, target, libc); - } - return LibCDirs{ .libc_include_dir_list = &[0][]u8{}, .libc_installation = null, -- 2.54.0 From 01e30002c52eda1ab3574f55c2e0568c56f2ed09 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Mon, 10 May 2021 23:12:17 +0200 Subject: [PATCH 2/4] stage2: error if requested glibc version too high Falling back to the max provided glibc version is insufficient as linking to shared objects compiled against the requested version will fail. --- src/glibc.zig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/glibc.zig b/src/glibc.zig index 7600f19503ab4e233041965f900850febcb8754f..6b288ac46df3f68a2829357fed764469d62dfac2 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -764,16 +764,17 @@ pub fn buildSharedObjects(comp: *Compilation) !void { .lt => continue, .gt => { // TODO Expose via compile error mechanism instead of log. - std.log.warn("invalid target glibc version: {}", .{target_version}); + std.log.err("invalid target glibc version: {}", .{target_version}); return error.InvalidTargetGLibCVersion; }, } - } else blk: { + } else { const latest_index = metadata.all_versions.len - 1; - std.log.warn("zig cannot build new glibc version {}; providing instead {}", .{ + // TODO Expose via compile error mechanism instead of log. + std.log.err("zig does not yet provide glibc version {}, the max provided version is {}", .{ target_version, metadata.all_versions[latest_index], }); - break :blk latest_index; + return error.InvalidTargetGLibCVersion; }; { var map_contents = std.ArrayList(u8).init(arena); -- 2.54.0 From 3b2c9ef828cc97a4c4664324d93ddbe3696b17fb Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 11 May 2021 15:27:43 +0200 Subject: [PATCH 3/4] stage2: link all libc components if using system libc --- src/link/Elf.zig | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index c31a0940939891930e4837d616c604a36cb7957a..91ee6f3206e6e60d545db4350f686325ed3519db 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1650,9 +1650,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { if (self.base.options.libc_installation != null) { const needs_grouping = self.base.options.link_mode == .Static; if (needs_grouping) try argv.append("--start-group"); - try argv.append("-lm"); - try argv.append("-lpthread"); - try argv.append("-lc"); + // This matches the order of glibc.libs + try argv.appendSlice(&[_][]const u8{ + "-lm", + "-lpthread", + "-lc", + "-ldl", + "-lrt", + "-lutil", + }); if (needs_grouping) try argv.append("--end-group"); } else if (target.isGnuLibC()) { try argv.append(comp.libunwind_static_lib.?.full_object_path); -- 2.54.0 From f8cf106fc971c9c61709443860b1f728ca4cfc9a Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 11 May 2021 20:11:22 +0200 Subject: [PATCH 4/4] ci: unset CC/CXX before make install on macos arm64 Having these set causes zig's native libc detection code to fail. --- ci/azure/macos_arm64_script | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci/azure/macos_arm64_script b/ci/azure/macos_arm64_script index c1b93012dbc4b9366988e83c07b57cb8dccf763d..612edf677fe7c8539732ef00c96cd71377d6c795 100755 --- a/ci/azure/macos_arm64_script +++ b/ci/azure/macos_arm64_script @@ -55,11 +55,11 @@ cmake .. \ -DZIG_TARGET_MCPU="$HOST_MCPU" \ -DZIG_STATIC=ON -make $JOBS install - unset CC unset CXX +make $JOBS install + # Build zig compiler cross-compiled for arm64 cd $ZIGDIR @@ -79,11 +79,11 @@ cmake .. \ -DZIG_EXECUTABLE="$ZIG" \ -DZIG_STATIC=ON -make $JOBS install - unset CC unset CXX +make $JOBS install + if [ "${BUILD_REASON}" != "PullRequest" ]; then mv ../LICENSE release/ -- 2.54.0