From 06ed65a6f49c290bbf1b773da8874353344a5b55 Mon Sep 17 00:00:00 2001 Message-Id: <06ed65a6f49c290bbf1b773da8874353344a5b55.1631421568.git.iskarian@mgsn.dev> In-Reply-To: References: From: Liliana Prikler Date: Thu, 9 Sep 2021 15:32:22 +0200 Subject: [WIP PATCH v3 2/2] gnu: Add zig. * gnu/packages/patches/zig-disable-libc-note-test.patch, gnu/packages/patches/zig-disable-MIPS-tests.patch, gnu/packages/patches/zig-fix-cross-native-execution.patch, gnu/packages/patches/zig-use-explicit-paths.patch: New files. * gnu/packages/zig.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES, dist_patch_DATA): Adjust accordingly. --- gnu/local.mk | 5 + .../patches/zig-disable-MIPS-tests.patch | 87 ++++++++++++ .../patches/zig-disable-libc-note-test.patch | 31 ++++ .../zig-fix-cross-native-execution.patch | 64 +++++++++ .../patches/zig-use-explicit-paths.patch | 132 ++++++++++++++++++ gnu/packages/zig.scm | 109 +++++++++++++++ 6 files changed, 428 insertions(+) create mode 100644 gnu/packages/patches/zig-disable-MIPS-tests.patch create mode 100644 gnu/packages/patches/zig-disable-libc-note-test.patch create mode 100644 gnu/packages/patches/zig-fix-cross-native-execution.patch create mode 100644 gnu/packages/patches/zig-use-explicit-paths.patch create mode 100644 gnu/packages/zig.scm diff --git a/gnu/local.mk b/gnu/local.mk index 2a56c4a9e2..dab959845c 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -598,6 +598,7 @@ GNU_SYSTEM_MODULES = \ %D%/packages/xdisorg.scm \ %D%/packages/xorg.scm \ %D%/packages/xfce.scm \ + %D%/packages/zig.scm \ %D%/packages/zile.scm \ %D%/packages/zwave.scm \ \ @@ -1903,6 +1904,10 @@ dist_patch_DATA = \ %D%/packages/patches/ytfzf-updates.patch \ %D%/packages/patches/ytnef-CVE-2021-3403.patch \ %D%/packages/patches/ytnef-CVE-2021-3404.patch \ + %D%/packages/patches/zig-disable-libc-note-test.patch \ + %D%/packages/patches/zig-disable-MIPS-tests.patch \ + %D%/packages/patches/zig-fix-cross-native-execution.patch \ + %D%/packages/patches/zig-use-explicit-paths.patch \ %D%/packages/patches/zstd-CVE-2021-24031_CVE-2021-24032.patch \ %D%/packages/patches/zziplib-CVE-2018-16548.patch diff --git a/gnu/packages/patches/zig-disable-MIPS-tests.patch b/gnu/packages/patches/zig-disable-MIPS-tests.patch new file mode 100644 index 0000000000..80d72f1b9c --- /dev/null +++ b/gnu/packages/patches/zig-disable-MIPS-tests.patch @@ -0,0 +1,87 @@ +Upstream issue: https://github.com/ziglang/zig/issues/8155 + +Zig fails to cross-compile to MIPS architectures with LLVM 12.0.0. The issue +is fixed in LLVM 12.0.1. + +diff --git a/test/tests.zig b/test/tests.zig +index b80c082fb..cd0c24fc9 100644 +--- a/test/tests.zig ++++ b/test/tests.zig +@@ -153,22 +153,22 @@ const test_targets = blk: { + // .link_libc = true, + //}, + +- TestTarget{ +- .target = .{ +- .cpu_arch = .mips, +- .os_tag = .linux, +- .abi = .none, +- }, +- }, +- +- TestTarget{ +- .target = .{ +- .cpu_arch = .mips, +- .os_tag = .linux, +- .abi = .musl, +- }, +- .link_libc = true, +- }, ++ // TestTarget{ ++ // .target = .{ ++ // .cpu_arch = .mips, ++ // .os_tag = .linux, ++ // .abi = .none, ++ // }, ++ // }, ++ ++ // TestTarget{ ++ // .target = .{ ++ // .cpu_arch = .mips, ++ // .os_tag = .linux, ++ // .abi = .musl, ++ // }, ++ // .link_libc = true, ++ // }, + + // https://github.com/ziglang/zig/issues/4927 + //TestTarget{ +@@ -180,22 +180,22 @@ const test_targets = blk: { + // .link_libc = true, + //}, + +- TestTarget{ +- .target = .{ +- .cpu_arch = .mipsel, +- .os_tag = .linux, +- .abi = .none, +- }, +- }, +- +- TestTarget{ +- .target = .{ +- .cpu_arch = .mipsel, +- .os_tag = .linux, +- .abi = .musl, +- }, +- .link_libc = true, +- }, ++ // TestTarget{ ++ // .target = .{ ++ // .cpu_arch = .mipsel, ++ // .os_tag = .linux, ++ // .abi = .none, ++ // }, ++ // }, ++ ++ // TestTarget{ ++ // .target = .{ ++ // .cpu_arch = .mipsel, ++ // .os_tag = .linux, ++ // .abi = .musl, ++ // }, ++ // .link_libc = true, ++ // }, + + // https://github.com/ziglang/zig/issues/4927 + //TestTarget{ diff --git a/gnu/packages/patches/zig-disable-libc-note-test.patch b/gnu/packages/patches/zig-disable-libc-note-test.patch new file mode 100644 index 0000000000..971ae53912 --- /dev/null +++ b/gnu/packages/patches/zig-disable-libc-note-test.patch @@ -0,0 +1,31 @@ +This test fails with "error.CompilationIncorrectlySucceeded". + +diff --git a/test/compile_errors.zig b/test/compile_errors.zig +index fd1255c..20d5548 100644 +--- a/test/compile_errors.zig ++++ b/test/compile_errors.zig +@@ -2751,15 +2751,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { + "tmp.zig:3:5: error: dependency on libc must be explicitly specified in the build command", + }); + +- cases.addTest("libc headers note", +- \\const c = @cImport(@cInclude("stdio.h")); +- \\export fn entry() void { +- \\ _ = c.printf("hello, world!\n"); +- \\} +- , &[_][]const u8{ +- "tmp.zig:1:11: error: C import failed", +- "tmp.zig:1:11: note: libc headers not available; compilation does not link against libc", +- }); ++// cases.addTest("libc headers note", ++// \\const c = @cImport(@cInclude("stdio.h")); ++// \\export fn entry() void { ++// \\ _ = c.printf("hello, world!\n"); ++// \\} ++// , &[_][]const u8{ ++// "tmp.zig:1:11: error: C import failed", ++// "tmp.zig:1:11: note: libc headers not available; compilation does not link against libc", ++// }); + } + + cases.addTest("comptime vector overflow shows the index", diff --git a/gnu/packages/patches/zig-fix-cross-native-execution.patch b/gnu/packages/patches/zig-fix-cross-native-execution.patch new file mode 100644 index 0000000000..1952c6b867 --- /dev/null +++ b/gnu/packages/patches/zig-fix-cross-native-execution.patch @@ -0,0 +1,64 @@ +Upstream issue: https://github.com/ziglang/zig/issues/9738 + +Without this patch, 'zig run' or 'zig test' attempts to run cross-native +binaries even if their dynamic loader isn't present, which causes a crash +with "error: FileNotFound". + +--- +diff --git a/src/main.zig b/src/main.zig +index c1d12fcba..9b1bee0d6 100644 +--- a/src/main.zig ++++ b/src/main.zig +@@ -2040,7 +2040,7 @@ fn buildOutputType( + test_exec_args.items, + self_exe_path, + arg_mode, +- target_info.target, ++ target_info, + watch, + &comp_destroyed, + all_args, +@@ -2110,7 +2110,7 @@ fn buildOutputType( + test_exec_args.items, + self_exe_path, + arg_mode, +- target_info.target, ++ target_info, + watch, + &comp_destroyed, + all_args, +@@ -2134,7 +2134,7 @@ fn buildOutputType( + test_exec_args.items, + self_exe_path, + arg_mode, +- target_info.target, ++ target_info, + watch, + &comp_destroyed, + all_args, +@@ -2158,7 +2158,7 @@ fn runOrTest( + test_exec_args: []const ?[]const u8, + self_exe_path: []const u8, + arg_mode: ArgMode, +- target: std.Target, ++ target: std.zig.system.NativeTargetInfo, + watch: bool, + comp_destroyed: *bool, + all_args: []const []const u8, +@@ -2174,7 +2174,15 @@ fn runOrTest( + defer argv.deinit(); + + if (test_exec_args.len == 0) { +- if (!std.Target.current.canExecBinariesOf(target)) { ++ const can_run = blk: { ++ if (!std.Target.current.canExecBinariesOf(target.target)) break :blk false; ++ if (target.dynamic_linker.get()) |dl| { ++ std.fs.cwd().access(dl, .{}) catch break :blk false; ++ break :blk true; ++ } ++ break :blk false; ++ }; ++ if (!can_run) { + switch (arg_mode) { + .zig_test => { + warn("created {s} but skipping execution because it is non-native", .{exe_path}); diff --git a/gnu/packages/patches/zig-use-explicit-paths.patch b/gnu/packages/patches/zig-use-explicit-paths.patch new file mode 100644 index 0000000000..ab0d2c7f8b --- /dev/null +++ b/gnu/packages/patches/zig-use-explicit-paths.patch @@ -0,0 +1,132 @@ +This patch replaces the OS-specific detection mechanism by one that solely +relies on environment variables. This has the benefit that said environment +variables can be used as search paths in Guix. + +Index: zig-0.8.1/lib/std/zig/system.zig +=================================================================== +--- zig-0.8.1.orig/lib/std/zig/system.zig ++++ zig-0.8.1/lib/std/zig/system.zig +@@ -39,101 +39,44 @@ pub const NativePaths = struct { + }; + errdefer self.deinit(); + +- var is_nix = false; +- if (process.getEnvVarOwned(allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { +- defer allocator.free(nix_cflags_compile); +- +- is_nix = true; +- var it = mem.tokenize(nix_cflags_compile, " "); ++ // TODO: Support cross-compile paths? ++ if (process.getEnvVarOwned(allocator, "ZIG_INCLUDE_DIRS")) |zig_include_dirs| { ++ defer allocator.free(zig_include_dirs); ++ var it = mem.tokenize(zig_include_dirs, ":"); + while (true) { +- const word = it.next() orelse break; +- if (mem.eql(u8, word, "-isystem")) { +- const include_path = it.next() orelse { +- try self.addWarning("Expected argument after -isystem in NIX_CFLAGS_COMPILE"); +- break; +- }; +- try self.addIncludeDir(include_path); +- } else { +- if (mem.startsWith(u8, word, "-frandom-seed=")) { +- continue; +- } +- try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {s}", .{word}); +- } ++ const dir = it.next() orelse break; ++ try self.addIncludeDir(dir); + } + } else |err| switch (err) { + error.InvalidUtf8 => {}, + error.EnvironmentVariableNotFound => {}, + error.OutOfMemory => |e| return e, + } +- if (process.getEnvVarOwned(allocator, "NIX_LDFLAGS")) |nix_ldflags| { +- defer allocator.free(nix_ldflags); + +- is_nix = true; +- var it = mem.tokenize(nix_ldflags, " "); ++ if (process.getEnvVarOwned(allocator, "ZIG_LIB_DIRS")) |zig_lib_dirs| { ++ defer allocator.free(zig_lib_dirs); ++ var it = mem.tokenize(zig_lib_dirs, ":"); + while (true) { +- const word = it.next() orelse break; +- if (mem.eql(u8, word, "-rpath")) { +- const rpath = it.next() orelse { +- try self.addWarning("Expected argument after -rpath in NIX_LDFLAGS"); +- break; +- }; +- try self.addRPath(rpath); +- } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') { +- const lib_path = word[2..]; +- try self.addLibDir(lib_path); +- } else { +- try self.addWarningFmt("Unrecognized C flag from NIX_LDFLAGS: {s}", .{word}); +- break; +- } ++ const dir = it.next() orelse break; ++ try self.addLibDir(dir); + } + } else |err| switch (err) { + error.InvalidUtf8 => {}, + error.EnvironmentVariableNotFound => {}, + error.OutOfMemory => |e| return e, + } +- if (is_nix) { +- return self; +- } +- +- if (comptime Target.current.isDarwin()) { +- try self.addIncludeDir("/usr/include"); +- try self.addIncludeDir("/usr/local/include"); +- +- try self.addLibDir("/usr/lib"); +- try self.addLibDir("/usr/local/lib"); +- +- try self.addFrameworkDir("/Library/Frameworks"); +- try self.addFrameworkDir("/System/Library/Frameworks"); +- +- return self; +- } +- +- if (native_target.os.tag != .windows) { +- const triple = try native_target.linuxTriple(allocator); +- const qual = native_target.cpu.arch.ptrBitWidth(); +- +- // TODO: $ ld --verbose | grep SEARCH_DIR +- // the output contains some paths that end with lib64, maybe include them too? +- // TODO: what is the best possible order of things? +- // TODO: some of these are suspect and should only be added on some systems. audit needed. + +- try self.addIncludeDir("/usr/local/include"); +- try self.addLibDirFmt("/usr/local/lib{d}", .{qual}); +- try self.addLibDir("/usr/local/lib"); +- +- try self.addIncludeDirFmt("/usr/include/{s}", .{triple}); +- try self.addLibDirFmt("/usr/lib/{s}", .{triple}); +- +- try self.addIncludeDir("/usr/include"); +- try self.addLibDirFmt("/lib{d}", .{qual}); +- try self.addLibDir("/lib"); +- try self.addLibDirFmt("/usr/lib{d}", .{qual}); +- try self.addLibDir("/usr/lib"); +- +- // example: on a 64-bit debian-based linux distro, with zlib installed from apt: +- // zlib.h is in /usr/include (added above) +- // libz.so.1 is in /lib/x86_64-linux-gnu (added here) +- try self.addLibDirFmt("/lib/{s}", .{triple}); ++ if (process.getEnvVarOwned(allocator, "ZIG_FRAMEWORK_DIRS")) |zig_framework_dirs| { ++ defer allocator.free(zig_framework_dirs); ++ var it = mem.tokenize(zig_framework_dirs, ":"); ++ while (true) { ++ const dir = it.next() orelse break; ++ try self.addFrameworkDir(dir); ++ } ++ } else |err| switch (err) { ++ error.InvalidUtf8 => {}, ++ error.EnvironmentVariableNotFound => {}, ++ error.OutOfMemory => |e| return e, + } + + return self; diff --git a/gnu/packages/zig.scm b/gnu/packages/zig.scm new file mode 100644 index 0000000000..639cc937e6 --- /dev/null +++ b/gnu/packages/zig.scm @@ -0,0 +1,109 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2021 Liliana Prikler +;;; Copyright © 2021 Sarah Morgensen +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu packages zig) + #:use-module (guix packages) + #:use-module (guix git-download) + #:use-module ((guix licenses) #:prefix license:) + #:use-module (guix build-system cmake) + #:use-module (gnu packages) + #:use-module (gnu packages llvm)) + +(define-public zig + (package + (name "zig") + (version "0.8.1") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/ziglang/zig.git") + (commit version))) + (file-name (git-file-name name version)) + (sha256 + (base32 "147qx7xgj0r353wh5ragzn6kmm1vrf31i8038z3zqwjnqqgqxi6c")) + (patches + (search-patches + "zig-disable-libc-note-test.patch" + ;; XXX: Remove the following patch when updating LLVM to 12.0.1. + "zig-disable-MIPS-tests.patch" + "zig-fix-cross-native-execution.patch" + "zig-use-explicit-paths.patch")))) + (build-system cmake-build-system) + (inputs + `(("clang" ,clang-12) ; Clang propagates llvm. + ("lld" ,lld-12))) + ;; Zig compiles fine with GCC, but also needs native LLVM libraries. + (native-inputs + `(("llvm" ,llvm-12))) + (arguments + `(#:configure-flags + (list ,@(if (%current-target-system) + (string-append "-DZIG_TARGET_TRIPLE=" + (%current-target-system)) + '())) + #:out-of-source? #f ; for tests + #:phases + (modify-phases %standard-phases + (add-after 'configure 'set-cache-dir + (lambda _ + ;; Set cache dir, otherwise Zig looks for `$HOME/.cache'. + (setenv "ZIG_GLOBAL_CACHE_DIR" + (string-append (getcwd) "/zig-cache")))) + (delete 'check) + (add-after 'install 'check + (lambda* (#:key outputs tests? #:allow-other-keys) + (when tests? + (invoke (string-append (assoc-ref outputs "out") "/bin/zig") + ;; Testing the standard library takes >7.5GB RAM, and + ;; will fail if it is OOM-killed. The 'test-toolchain' + ;; target skips standard library and doc tests. + "build" "test-toolchain" + ;; Stage 2 is experimental, not what we run with `zig', + ;; and stage 2 tests require a lot of RAM. + "-Dskip-stage2-tests" + ;; Options to drop some test configurations. + ;;"-Dskip-non-native" "-Dskip-release-small" + ;;"-Dskip-release-fast" "-Dskip-release-safe" + ))))))) + (native-search-paths + (list + (search-path-specification + (variable "ZIG_INCLUDE_DIRS") + ;; XXX: It doesn't seem as though Zig can distinguish between C and C++ + ;; include paths, so provide both. + (files '("include/c++" "include"))) + (search-path-specification + ;; TODO: Might be confused with "ZIG_LIB_DIR"... Maybe use + ;; "ZIG_INCLUDE_PATH" and "ZIG_LIBRARY_PATH"? + (variable "ZIG_LIB_DIRS") + (files '("lib" "lib64"))))) + (synopsis "General purpose programming language and toolchain") + (description "Zig is a general-purpose programming language and +toolchain. Among other features it provides +@itemize +@item an Optional type instead of null pointers, +@item manual memory management, +@item generic data structures and functions, +@item compile-time reflection and compile-time code execution, +@item integration with C using zig as a C compiler, and +@item concurrency via async functions. +@end itemize") + (home-page "https://github.com/ziglang/zig") + (license license:expat))) -- 2.33.0