From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 0E737158042 for ; Fri, 25 Oct 2024 21:34:09 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 56021E09CC; Fri, 25 Oct 2024 21:34:05 +0000 (UTC) Received: from mail.landless-city.net (mail.landless-city.net [95.164.19.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id E447FE09BF for ; Fri, 25 Oct 2024 21:34:04 +0000 (UTC) Received: from mail.landless-city.net (unknown [37.99.36.156]) by mail.landless-city.net (Postfix) with ESMTPSA id D258D7D6ED for ; Sat, 26 Oct 2024 02:34:02 +0500 (+05) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=landless-city.net; s=2024031301_rsa; t=1729892042; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Mt9E51MUU//YOhVE7Cf1ftWlxT8vRM9W2/5G/KrDskM=; b=ZcW27k+MEY9o0VAAWZ/bCGgrosp1E1gbNuzTb9N33aUQ32xDFQFLrTLJTTlT2K7Ummg3i/ JTZwehLap1ReWS6g5Jm3sYDx988jLtoJGVqDH+OXFY96zFnZhmBJYJ/Kcg/2QpY/oRWqb5 6zLgLBXwbY8a5uDMZ+9OdE+QklX6DWkdMvx/kXROhwp2+eD5x/aNq8ZDXX+YfzeTF9/+b5 WgKUvXVlFBHbku9W0rxWtTqsXwcEGzf0moPzBZzjVRZ67FqSRUm9T7vhfsCBkO18dZjrmd A8A0AHS4gOkF8hNBzCXd9ef5MWzpIDWJBMJichWYIaijj6ls2QnM52PVtlDZZA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=landless-city.net; s=2024031301_ed25519; t=1729892042; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Mt9E51MUU//YOhVE7Cf1ftWlxT8vRM9W2/5G/KrDskM=; b=RtoccvaIKrPx/B2QKO9aBz8hhxE3q1/ZgH0BfHFY9edHXzEtTpG7IfeBXh6Lz5ba4NrS0c DwfwU6WSpJv8SiAg== From: Eric Joldasov To: gentoo-dev@lists.gentoo.org Subject: [gentoo-dev] [PATCH v2 1/5] zig-toolchain.eclass: new eclass Date: Sat, 26 Oct 2024 02:33:48 +0500 Message-ID: <20241025213359.8925-2-bratishkaerik@landless-city.net> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241025213359.8925-1-bratishkaerik@landless-city.net> References: <20241024014626.31175-1-bratishkaerik@landless-city.net> <20241025213359.8925-1-bratishkaerik@landless-city.net> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Archives-Salt: 9328d974-94fe-4f11-bc11-c3994646a729 X-Archives-Hash: 6094c908c4dfc1a686872fa55a1ffb60 Signed-off-by: Eric Joldasov --- eclass/zig-toolchain.eclass | 375 ++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 eclass/zig-toolchain.eclass diff --git a/eclass/zig-toolchain.eclass b/eclass/zig-toolchain.eclass new file mode 100644 index 000000000000..42a3f8ec3706 --- /dev/null +++ b/eclass/zig-toolchain.eclass @@ -0,0 +1,375 @@ +# Copyright 2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: zig-toolchain.eclass +# @MAINTAINER: +# Eric Joldasov +# @AUTHOR: +# Eric Joldasov +# @SUPPORTED_EAPIS: 8 +# @BLURB: Prepare Zig toolchain and set environment variables +# @DESCRIPTION: +# Prepare Zig toolchain and set environment variables. +# Supports Zig 0.13+. +# Does not set any default function, ebuilds must call them manually. +# Generally, only "zig-toolchain_populate_env_vars" is needed. +# +# Intended to be used by ebuilds that call "zig build-exe/lib/obj" +# or "zig test" directly and by "dev-lang/zig". +# For ebuilds with ZBS (Zig Build System), it's usually better +# to inherit zig-build instead, as it has default phases-functions. + +if [[ ! ${_ZIG_TOOLCHAIN_ECLASS} ]]; then +_ZIG_TOOLCHAIN_ECLASS=1 + +case ${EAPI} in + 8) ;; + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; +esac + +inherit edo flag-o-matic + +# @ECLASS_VARIABLE: ZIG_SLOT +# @PRE_INHERIT +# @REQUIRED +# @DESCRIPTION: +# Zig slot that will be used in "ezig" function. Also, if +# ZIG_OPTIONAL is empty, adds dev-lang/zig and dev-lang/zig-bin +# dependency to BDEPEND. Must be >= "0.13". +# +# Example: +# @CODE +# 0.13 +# @CODE +# +# When a new Zig release occurs, it is advisable for maintainers to +# check whether their ebuild supports that new version. If yes, they +# they should bump ZIG_SLOT to the latest version; if not supported, +# they need to patch any issues with new version and again bump +# ZIG_SLOT. This helps to reduce dependencies on outdated Zig +# versions. +# +# This policy of "1 exclusive Zig slot" will work until it +# stabilizes enough (probably near 1.0), then it will be re-evaluated +# and most likely changed to more common in other eclasses ZIG_MIN/ +# ZIG_MAX form. + +# @ECLASS_VARIABLE: ZIG_OPTIONAL +# @PRE_INHERIT +# @DEFAULT_UNSET +# @DESCRIPTION: +# If set to a non-empty value, all logic in zig-toolchain and +# zig-build eclasses will be considered optional. No dependencies +# will be added and no phase functions will be exported. +# +# For zig-toolchain.eclass users: +# You have to add Zig dependency in your BDEPEND manually and call +# at least "zig-toolchain_populate_env_vars" before using "ezig". +# +# For zig-build.eclass users: see documentation in zig-build.eclass +# instead. +if [[ ! ${ZIG_OPTIONAL} ]]; then + BDEPEND="|| ( + dev-lang/zig:${ZIG_SLOT} + dev-lang/zig-bin:${ZIG_SLOT} + )" +fi + +# @ECLASS_VARIABLE: ZIG_TARGET +# @DESCRIPTION: +# Zig target triple to use. Has the following format: +# arch-os[.os_version_range]-abi[.abi_version] +# Can be passed as: +# * "-target " option in "zig test" or "zig build-exe/lib/obj", +# * "-Dtarget=" option in "zig build" +# (if project uses "std.Build.standardTargetOptions"). +# +# Can be overriden by user. If not overriden, then set by +# "zig-toolchain_populate_env_vars". +# +# Example: +# @CODE +# # Autodetected by Zig: +# native +# # Machine running Linux x86_64 system, with glibc: +# x86_64-linux-gnu +# # Similar to above, but versions are passed explicitly: +# x86_64-linux.6.1.12...6.6.16-gnu.2.38 +# # Machine running Linux PPC64 little-endian system, with musl +# powerpc64le-linux-musl +# @CODE +# + +# @ECLASS_VARIABLE: ZIG_CPU +# @DESCRIPTION: +# Zig target CPU and features to use. Has the following format: +# family_name(\+enable_feature|\-disable_feature)* +# Can be passed as: +# * "-mcpu " option in "zig test" or "zig build-exe/lib/obj", +# * "-Dcpu=" option in "zig build" +# (if project uses "std.Build.standardTargetOptions"). +# +# Can be overriden by user. If not overriden, then set by +# "zig-toolchain_populate_env_vars". +# +# Example: +# @CODE +# # Autodetected by Zig: +# native +# # AMD Zen 2 processor +# znver2 +# # x86_64 processor, X87 support enabled, SSE2 support disabled +# x86_64+x87-sse2 +# @CODE + +# @ECLASS_VARIABLE: ZIG_EXE +# @DESCRIPTION: +# Absolute path to the used Zig executable. +# +# Please note that when passing one flag several times with different +# values: +# * (only "zig build") in "-Dbar=false -Dbar" form: +# errors due to conflict of flags, +# * (only "zig build") in "-Dbar=false -Dbar=true" form: +# "bar" becomes a list, which is likely not what you want, +# * in "-fbar -fno-bar" form: +# latest value overwrites values before. +# Example above shows only boolean option, but it is same with other +# types of options (enums, "std.zig.BuildId", "std.SemanticVersion", +# integers, strings, etc.). +# +# Can be overriden by user. If not overriden, then set by +# "zig-toolchain_populate_env_vars". + +# @ECLASS_VARIABLE: ZIG_VER +# @OUTPUT_VARIABLE +# @DESCRIPTION: +# Zig version found during "zig-toolchain_find_installation", +# as reported in dev-lang/zig-${PV} PV part. +# +# Example: +# @CODE +# 0.13.0 +# @CODE + +# @FUNCTION: zig-toolchain_get_target +# @USAGE: +# @DESCRIPTION: +# Translates C-style target triple (like CHOST or CBUILD) +# to Zig-style target triple. Some information (like ARM features) +# is handled by "zig-toolchain_get_cpu". Mostly used during +# cross-compiling if user does not set ZIG_TARGET variable. +# +# See ZIG_TARGET description for more information. +zig-toolchain_get_target() { + if [[ ${#} -ne 1 ]]; then + die "${FUNCNAME[0]}: expected 1 arguments, got ${#}" + fi + local c_target=${1} + local c_target_prefix=${c_target%%-*} + local c_target_suffix=${c_target##*-} + + local arch os abi + + case ${c_target_prefix} in + i?86) arch=x86;; + arm64) arch=aarch64;; + arm*) arch=arm;; + *) arch=${c_target_prefix};; + esac + + case ${c_target} in + *linux*) os=linux;; + *apple*) os=macos;; + esac + + case ${c_target_suffix} in + solaris*) os=solaris abi=none;; + darwin*) abi=none;; + *) abi=${c_target_suffix};; + esac + + if [[ ${arch} == arm && ${abi} == gnu ]]; then + die "${FUNCNAME[0]}: Zig does not support old ARM ABI" + fi + + echo ${arch}-${os}-${abi} +} + + + +# @FUNCTION: zig-toolchain_get_cpu +# @USAGE: +# @DESCRIPTION: +# Translates C-style target triple (like CHOST or CBUILD) +# to Zig-style target CPU and features. Mostly used to get generic +# target CPU during cross-compiling if user does not set ZIG_CPU +# variable. +# +# See ZIG_CPU description for more information. +zig-toolchain_get_cpu() { + if [[ ${#} -ne 1 ]]; then + die "${FUNCNAME[0]}: expected 1 arguments, got ${#}" + fi + local c_target=${1} + local c_target_prefix=${c_target%%-*} + + local base_cpu features="" + + case ${c_target_prefix} in + i?86) base_cpu=${c_target_prefix};; + loongarch64) base_cpu=generic_la64;; + powerpc | powerpcle) base_cpu=ppc;; + powerpc64) base_cpu=ppc64;; + powerpc64le) base_cpu=ppc64le;; + riscv32) base_cpu=generic_rv32;; + riscv64) base_cpu=generic_rv64;; + *) base_cpu=generic;; + esac + + case ${c_target_prefix} in + armv5tel) features+="+v5te";; + armv*) features+="+${c_target_prefix##armv}";; + esac + + case ${c_target_prefix} in + arm64) ;; + arm*) + local is_softfloat=$(CTARGET=${c_target} tc-tuple-is-softfloat) + case ${is_softfloat} in + only | yes) features+="+soft_float";; + softfp | no) features+="-soft_float";; + *) die "${FUNCNAME[0]}: tc-tuple-is-softfloat returned unexpected value" + esac + ;; + esac + + echo ${base_cpu}${features} +} + +# @FUNCTION: zig-toolchain_find_installation +# @DESCRIPTION: +# Detects suitable Zig installation and sets ZIG_VER and ZIG_EXE +# variables. +# +# See ZIG_EXE and ZIG_VER descriptions for more information. +zig-toolchain_find_installation() { + # Adapted from https://github.com/gentoo/gentoo/pull/28986 + # Many thanks to Florian Schmaus (Flowdalic)! + + [[ -n ${ZIG_SLOT} ]] || die "${FUNCNAME[0]}: ZIG_SLOT must be set" + if ver_test "${ZIG_SLOT}" -lt "0.13"; then + die "${ECLASS}: ZIG_SLOT must be >= 0.13, found ${ZIG_SLOT}" + fi + + einfo "Searching Zig ${ZIG_SLOT}..." + + local zig_supported_versions=( + "9999" + "0.13.1" + "0.13.0" + ) + + local base_path="${BROOT}/usr/bin" + + local selected_path selected_ver + for selected_ver in "${zig_supported_versions[@]}"; do + # Check if candidate satisfies ZIG_SLOT condition. + local candidate_slot + candidate_slot=$(ver_cut 1-2 ${selected_ver}) + if ver_test "${candidate_slot}" -ne ${ZIG_SLOT}; then + continue + fi + + local candidate_path + # Prefer "dev-lang/zig" over "dev-lang/zig-bin" + candidate_path="${base_path}/zig-${selected_ver}" + if [[ -x "${candidate_path}" ]]; then + selected_path="${candidate_path}" + break; + fi + + candidate_path="${base_path}/zig-bin-${selected_ver}" + if [[ -x "${candidate_path}" ]]; then + selected_path="${candidate_path}" + break; + fi + done + + if [[ -z "${selected_path}" ]]; then + die "Could not find (suitable) Zig at \"${base_path}\"" + fi + + export ZIG_EXE="${selected_path}" + export ZIG_VER="${selected_ver}" + # Sanity check, comment from upstream: + # > Check libc++ linkage to make sure Zig was built correctly, + # > but only for "env" and "version" to avoid affecting the + # > startup time for build-critical commands + # > (check takes about ~10 μs) + "${ZIG_EXE}" version > /dev/null \ + || die "Sanity check failed for \"${ZIG_EXE}\"" +} + +# @FUNCTION: zig-toolchain_populate_env_vars +# @DESCRIPTION: +# Populates ZIG_TARGET, ZIG_CPU, ZIG_EXE and ZIG_VER environment +# variables with detected values, or, if user set them already, +# leaves as-is. +zig-toolchain_populate_env_vars() { + # Should be first because it sets ZIG_VER which might be used + # in the future when setting ZIG_TARGET and ZIG_CPU variables + # for incompatible versions. + if [[ -z "${ZIG_EXE}" ]]; then + zig-toolchain_find_installation + fi + + if [[ -z ${ZIG_TARGET} ]]; then + if tc-is-cross-compiler; then + export ZIG_TARGET=$(zig-toolchain_get_target ${CHOST}) + else + export ZIG_TARGET=native + fi + fi + + if [[ -z ${ZIG_CPU} ]]; then + if tc-is-cross-compiler; then + export ZIG_CPU=$(zig-toolchain_get_cpu ${CHOST}) + else + export ZIG_CPU=native + fi + fi + + einfo "ZIG_EXE: \"${ZIG_EXE}\"" + einfo "ZIG_VER: ${ZIG_VER}" + einfo "ZIG_TARGET: ${ZIG_TARGET}" + einfo "ZIG_CPU: ${ZIG_CPU}" +} + +# @FUNCTION: ezig +# @USAGE: [...] +# @DESCRIPTION: +# Runs ZIG_EXE with supplied arguments. Dies if ZIG_EXE is not set or +# if command exits with error. Respects `nonfatal`. +# +# Always disables progress tree. By default enables ANSI escape codes +# (colours, etc.), user can set NO_COLOR environment variable to +# disable them. +ezig() { + # Sync description above and comments below with upstream's + # "std.io.tty.detectConfig". + debug-print-function "${FUNCNAME[0]}" "${@}" + + if [[ -z "${ZIG_EXE}" ]] ; then + die "${FUNCNAME[0]}: ZIG_EXE is not set. Was 'zig-toolchain_populate_env_vars' called before using ezig?" + fi + + # Progress tree is helpful indicator in TTY, but unfortunately + # they make Portage logs harder to read in plaintext. We pass + # "TERM=dumb" here to have clean logs, and CLICOLOR_FORCE to + # preserve colors. + # User's NO_COLOR takes precendence over this. + TERM=dumb CLICOLOR_FORCE=1 "${ZIG_EXE}" "${@}" \ + || die -n "Failed to run command: ${ZIG_EXE} ${@}" +} +fi -- 2.47.0