diff options
Diffstat (limited to 'eclass')
30 files changed, 1028 insertions, 397 deletions
diff --git a/eclass/Manifest.gz b/eclass/Manifest.gz Binary files differindex a529a307967c..27b0b676b0a9 100644 --- a/eclass/Manifest.gz +++ b/eclass/Manifest.gz diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass index 7db34efb4e17..c360c2a6c419 100644 --- a/eclass/cargo.eclass +++ b/eclass/cargo.eclass @@ -109,7 +109,7 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo" # # If you enable CARGO_OPTIONAL, you have to set BDEPEND on virtual/rust # for your package and call at least cargo_gen_config manually before using -# other src_functions of this eclass. +# other src_functions or cargo_env of this eclass. # Note that cargo_gen_config is automatically called by cargo_src_unpack. # @ECLASS_VARIABLE: myfeatures @@ -248,7 +248,7 @@ cargo_crate_uris() { # @FUNCTION: cargo_gen_config # @DESCRIPTION: -# Generate the $CARGO_HOME/config necessary to use our local registry and settings. +# Generate the $CARGO_HOME/config.toml necessary to use our local registry and settings. # Cargo can also be configured through environment variables in addition to the TOML syntax below. # For each configuration key below of the form foo.bar the environment variable CARGO_FOO_BAR # can also be used to define the value. @@ -259,9 +259,22 @@ cargo_crate_uris() { cargo_gen_config() { debug-print-function ${FUNCNAME} "$@" + # The default linker is "cc" so override by setting linker to CC in the + # RUSTFLAGS. The given linker cannot include any arguments, so split these + # into link-args along with LDFLAGS. Also include external RUSTFLAGS. + # Note that as of Rust 1.80, the build host RUSTFLAGS are ignored when + # cross-compiling unless you use the unstable host-config feature available + # with USE=nightly. There is no simple way around this. + tc-export_build_env + local LD_A=( $(tc-getBUILD_CC) ${BUILD_LDFLAGS} ) + local MY_BUILD_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}" + [[ ${#LD_A[@]} -gt 1 ]] && MY_BUILD_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")" + MY_BUILD_RUSTFLAGS+=" ${RUSTFLAGS} ${BUILD_RUSTFLAGS}" + tc-is-cross-compiler || MY_BUILD_RUSTFLAGS+=" ${TARGET_RUSTFLAGS}" + mkdir -p "${ECARGO_HOME}" || die - cat > "${ECARGO_HOME}/config" <<- _EOF_ || die "Failed to create cargo config" + cat > "${ECARGO_HOME}/config.toml" <<- _EOF_ || die "Failed to create cargo config" [source.gentoo] directory = "${ECARGO_VENDOR}" @@ -273,6 +286,7 @@ cargo_gen_config() { offline = true [build] + rustflags = "${MY_BUILD_RUSTFLAGS}" jobs = $(makeopts_jobs) incremental = false @@ -523,36 +537,65 @@ cargo_src_configure() { [[ ${ECARGO_ARGS[@]} ]] && einfo "Configured with: ${ECARGO_ARGS[@]}" } -# @FUNCTION: cargo_src_compile +# @FUNCTION: cargo_env +# @USAGE: Command with its arguments # @DESCRIPTION: -# Build the package using cargo build. -cargo_src_compile() { - debug-print-function ${FUNCNAME} "$@" - +# Run the given command under an environment needed for performing tasks with +# Cargo such as building. RUSTFLAGS is used for both the build and target host. +# BUILD_RUSTFLAGS and TARGET_RUSTFLAGS are used for just the build host and +# target host respectively. Ensure these are set consistently between Cargo +# invocations, otherwise rebuilds will occur. +cargo_env() { [[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \ die "FATAL: please call cargo_gen_config before using ${FUNCNAME}" + # Shadow flag variables so that filtering below remains local. + local flag + for flag in $(all-flag-vars); do + local -x "${flag}=${!flag}" + done + + # Rust extensions are incompatible with C/C++ LTO compiler see e.g. + # https://bugs.gentoo.org/910220 filter-lto + tc-export AR CC CXX PKG_CONFIG + # Set vars for cc-rs crate. + local -x \ + HOST_AR=$(tc-getBUILD_AR) + HOST_CC=$(tc-getBUILD_CC) + HOST_CXX=$(tc-getBUILD_CXX) + HOST_CFLAGS=${BUILD_CFLAGS} + HOST_CXXFLAGS=${BUILD_CXXFLAGS} + if tc-is-cross-compiler; then - export CARGO_BUILD_TARGET=$(rust_abi) + local -x CARGO_BUILD_TARGET=$(rust_abi) local TRIPLE=${CARGO_BUILD_TARGET//-/_} - export CARGO_TARGET_"${TRIPLE^^}"_LINKER=$(tc-getCC) - - # Set vars for cc-rs crate. - tc-export_build_env - export \ - HOST_AR=$(tc-getBUILD_AR) - HOST_CC=$(tc-getBUILD_CC) - HOST_CXX=$(tc-getBUILD_CXX) - HOST_CFLAGS=${BUILD_CFLAGS} - HOST_CXXFLAGS=${BUILD_CXXFLAGS} + local TRIPLE=${TRIPLE^^} LD_A=( $(tc-getCC) ${LDFLAGS} ) + local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}" + [[ ${#LD_A[@]} -gt 1 ]] && local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")" + local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" ${RUSTFLAGS} ${TARGET_RUSTFLAGS}" fi + ( + # These variables will override the above, even if empty, so unset them + # locally. Do this in a subshell so that they remain set afterwards. + unset CARGO_BUILD_RUSTFLAGS CARGO_ENCODED_RUSTFLAGS RUSTFLAGS + + "${@}" + ) +} + +# @FUNCTION: cargo_src_compile +# @DESCRIPTION: +# Build the package using cargo build. +cargo_src_compile() { + debug-print-function ${FUNCNAME} "$@" + set -- cargo build $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@" einfo "${@}" - "${@}" || die "cargo build failed" + cargo_env "${@}" || die "cargo build failed" } # @FUNCTION: cargo_src_install @@ -564,16 +607,13 @@ cargo_src_compile() { cargo_src_install() { debug-print-function ${FUNCNAME} "$@" - [[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \ - die "FATAL: please call cargo_gen_config before using ${FUNCNAME}" - set -- cargo install $(has --path ${@} || echo --path ./) \ --root "${ED}/usr" \ ${GIT_CRATES[@]:+--frozen} \ $(usex debug --debug "") \ ${ECARGO_ARGS[@]} "$@" einfo "${@}" - "${@}" || die "cargo install failed" + cargo_env "${@}" || die "cargo install failed" rm -f "${ED}/usr/.crates.toml" || die rm -f "${ED}/usr/.crates2.json" || die @@ -585,12 +625,9 @@ cargo_src_install() { cargo_src_test() { debug-print-function ${FUNCNAME} "$@" - [[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \ - die "FATAL: please call cargo_gen_config before using ${FUNCNAME}" - set -- cargo test $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@" einfo "${@}" - "${@}" || die "cargo test failed" + cargo_env "${@}" || die "cargo test failed" } fi diff --git a/eclass/dist-kernel-utils.eclass b/eclass/dist-kernel-utils.eclass index 4bc3fab44aae..0b0eb0ec8818 100644 --- a/eclass/dist-kernel-utils.eclass +++ b/eclass/dist-kernel-utils.eclass @@ -1,4 +1,4 @@ -# Copyright 2020-2023 Gentoo Authors +# Copyright 2020-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: dist-kernel-utils.eclass @@ -159,6 +159,35 @@ dist-kernel_PV_to_KV() { echo "${kv}" } +# @FUNCTION: dist-kernel_get_module_suffix +# @USAGE: <kernel_dir> +# @DESCRIPTION: +# Returns the suffix for kernel modules based on the CONFIG_MODULES_COMPESS_* +# setting in the kernel config and USE=modules-compress. +dist-kernel_get_module_suffix() { + debug-print-function ${FUNCNAME} "${@}" + + [[ ${#} -eq 1 ]] || die "${FUNCNAME}: invalid arguments" + + local config=${1}/.config + + if ! in_iuse modules-compress || ! use modules-compress; then + echo .ko + elif [[ ! -r ${config} ]]; then + die "Cannot find kernel config ${config}" + elif grep -q "CONFIG_MODULE_COMPRESS_NONE=y" "${config}"; then + echo .ko + elif grep -q "CONFIG_MODULE_COMPRESS_GZIP=y" "${config}"; then + echo .ko.gz + elif grep -q "CONFIG_MODULE_COMPRESS_XZ=y" "${config}"; then + echo .ko.xz + elif grep -q "CONFIG_MODULE_COMPRESS_ZSTD=y" "${config}"; then + echo .ko.zst + else + die "Module compression is enabled, but compressor not known" + fi +} + # @FUNCTION: dist-kernel_compressed_module_cleanup # @USAGE: <path> # @DESCRIPTION: @@ -169,20 +198,29 @@ dist-kernel_compressed_module_cleanup() { [[ ${#} -ne 1 ]] && die "${FUNCNAME}: invalid arguments" local path=${1} - local basename f + local preferred=$(dist-kernel_get_module_suffix "${path}/source") + local basename suffix while read -r basename; do local prev= - for f in "${path}/${basename}"{,.gz,.xz,.zst}; do - if [[ ! -e ${f} ]]; then - continue + for suffix in .ko .ko.gz .ko.xz .ko.zst; do + [[ ${suffix} == ${preferred} ]] && continue + local current=${path}/${basename}${suffix} + [[ -f ${current} ]] || continue + + if [[ -f ${path}/${basename}${preferred} ]]; then + # If the module with the desired compression exists, remove + # all other variations. + rm -v "${current}" || die elif [[ -z ${prev} ]]; then - prev=${f} - elif [[ ${f} -nt ${prev} ]]; then + # If not, then keep whichever of the duplicate modules is the + # newest. Normally you should not end up here. + prev=${current} + elif [[ ${current} -nt ${prev} ]]; then rm -v "${prev}" || die - prev=${f} + prev=${current} else - rm -v "${f}" || die + rm -v "${current}" || die fi done done < <( @@ -192,7 +230,8 @@ dist-kernel_compressed_module_cleanup() { -o -name '*.ko.gz' \ -o -name '*.ko.xz' \ -o -name '*.ko.zst' \ - \) | sed -e 's:[.]\(gz\|xz\|zst\)$::' | sort | uniq -d || die + \) | sed -e 's:[.]ko\(\|[.]gz\|[.]xz\|[.]zst\)$::' | + sort | uniq -d || die ) } diff --git a/eclass/distutils-r1.eclass b/eclass/distutils-r1.eclass index 61c0a80323ec..0f9dc8d14d5e 100644 --- a/eclass/distutils-r1.eclass +++ b/eclass/distutils-r1.eclass @@ -195,7 +195,6 @@ esac # @CODE # @ECLASS_VARIABLE: DISTUTILS_ALLOW_WHEEL_REUSE -# @DEFAULT_UNSET # @USER_VARIABLE # @DESCRIPTION: # If set to a non-empty value, the eclass is allowed to reuse a wheel @@ -205,6 +204,7 @@ esac # This is an optimization that can avoid the overhead of calling into # the build system in pure Python packages and packages using the stable # Python ABI. +: ${DISTUTILS_ALLOW_WHEEL_REUSE=1} # @ECLASS_VARIABLE: BUILD_DIR # @OUTPUT_VARIABLE @@ -572,6 +572,9 @@ distutils_enable_sphinx() { # with the specified test runner. Also copies the current value # of RDEPEND to test?-BDEPEND. The test-runner argument must be one of: # +# - import-check: `pytest --import-check` fallback (for use when there are +# no tests to run) +# # - pytest: dev-python/pytest # # - setup.py: setup.py test (no deps included) @@ -597,9 +600,13 @@ distutils_enable_tests() { [[ ${#} -eq 1 ]] || die "${FUNCNAME} takes exactly one argument: test-runner" local test_deps=${RDEPEND} + local test_pkgs= case ${1} in + import-check) + test_pkgs+=' dev-python/pytest-import-check[${PYTHON_USEDEP}]' + ;& pytest) - local test_pkgs='>=dev-python/pytest-7.4.4[${PYTHON_USEDEP}]' + test_pkgs+=' >=dev-python/pytest-7.4.4[${PYTHON_USEDEP}]' if [[ -n ${EPYTEST_TIMEOUT} ]]; then test_pkgs+=' dev-python/pytest-timeout[${PYTHON_USEDEP}]' fi @@ -929,6 +936,7 @@ _distutils-r1_print_package_versions() { # distutils patches and/or quirks. distutils-r1_python_prepare_all() { debug-print-function ${FUNCNAME} "${@}" + _python_sanity_checks _distutils-r1_check_all_phase_mismatch if [[ ! ${DISTUTILS_OPTIONAL} ]]; then @@ -1244,7 +1252,9 @@ distutils_pep517_install() { die "mydistutilsargs are banned in PEP517 mode (use DISTUTILS_ARGS)" fi - local config_settings= + local cmd=() config_settings= + has cargo ${INHERITED} && cmd+=( cargo_env ) + case ${DISTUTILS_USE_PEP517} in maturin) # `maturin pep517 build-wheel --help` for options @@ -1381,9 +1391,14 @@ distutils_pep517_install() { ;; esac + # https://pyo3.rs/latest/building-and-distribution.html#cross-compiling + if tc-is-cross-compiler; then + local -x PYO3_CROSS_LIB_DIR=${SYSROOT}/$(python_get_stdlib) + fi + local build_backend=$(_distutils-r1_get_backend) einfo " Building the wheel for ${PWD#${WORKDIR}/} via ${build_backend}" - local cmd=( + cmd+=( "${EPYTHON}" -m gpep517 build-wheel --prefix="${EPREFIX}/usr" --backend "${build_backend}" @@ -1560,6 +1575,9 @@ distutils-r1_python_test() { _python_check_EPYTHON case ${_DISTUTILS_TEST_RUNNER} in + import-check) + epytest --import-check "${BUILD_DIR}/install$(python_get_sitedir)" + ;; pytest) epytest ;; @@ -1782,16 +1800,6 @@ distutils-r1_run_phase() { # bug fixes from Cython (this works only when setup.py is using # cythonize() but it's better than nothing) local -x CYTHON_FORCE_REGEN=1 - - # Rust extensions are incompatible with C/C++ LTO compiler - # see e.g. https://bugs.gentoo.org/910220 - if has cargo ${INHERITED}; then - local x - for x in $(all-flag-vars); do - local -x "${x}=${!x}" - done - filter-lto - fi fi # silence warnings when pydevd is loaded on Python 3.11+ @@ -1933,7 +1941,7 @@ _distutils-r1_compare_installed_files() { # Perform the check only if at least one potentially reusable wheel # has been produced. Nonpure packages (e.g. NumPy) may install # interpreter configuration details into sitedir. - if [[ ${!DISTUTILS_WHEELS[*]} != *-none-any.whl* && + if [[ ${!DISTUTILS_WHEELS[*]} != *py3-none-any.whl* && ${!DISTUTILS_WHEELS[*]} != *-abi3-*.whl ]]; then return fi diff --git a/eclass/greadme.eclass b/eclass/greadme.eclass new file mode 100644 index 000000000000..38190becf91d --- /dev/null +++ b/eclass/greadme.eclass @@ -0,0 +1,251 @@ +# Copyright 1999-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: greadme.eclass +# @MAINTAINER: +# Florian Schmaus <flow@gentoo.org> +# @SUPPORTED_EAPIS: 8 +# @BLURB: install a doc file, that will be conditionally shown via elog messages +# @DESCRIPTION: +# An eclass for installing a README.gentoo doc file with important +# information for the user. The content of README.gentoo will shown be +# via elog messages either on fresh installations or if the contents of +# the file have changed. Furthermore, the README.gentoo file will be +# installed under /usr/share/doc/${PF} for later consultation. +# +# This eclass was inspired by readme.gentoo-r1.eclass. The main +# differences are as follows. Firstly, it only displays the doc file +# contents if they have changed (unless GREADME_SHOW is set). +# Secondly, it provides a convenient API to install the doc file via +# stdin. +# +# @CODE +# inherit greadme +# +# src_install() { +# ... +# greadme_stdin <<-EOF +# This is the content of the created readme doc file. +# EOF +# ... +# if use foo; then +# greadme_stdin --append <<-EOF +# This is conditional readme content, based on USE=foo. +# EOF +# fi +# } +# @CODE +# +# If the ebuild overrides the default pkg_preinst or respectively +# pkg_postinst, then it must call greadme_pkg_preinst and +# greadme_pkg_postinst explicitly. + +if [[ -z ${_GREADME_ECLASS} ]]; then +_GREADME_ECLASS=1 + +case ${EAPI} in + 8) ;; + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; +esac + +_GREADME_TMP_FILE="${T}/README.gentoo" +_GREADME_REL_PATH="/usr/share/doc/${PF}/README.gentoo" + +# @ECLASS_VARIABLE: GREADME_SHOW +# @DEFAULT_UNSET +# @DESCRIPTION: +# If set to "yes" then unconditionally show the contents of the readme +# file in pkg_postinst via elog. If set to "no", then do not show the +# contents of the readme file, even if they have changed. + +# @ECLASS_VARIABLE: GREADME_DISABLE_AUTOFORMAT +# @DEFAULT_UNSET +# @DESCRIPTION: +# If non-empty, the readme file will not be automatically formatted. + +# @FUNCTION: greadme_stdin +# @USAGE: [--append] +# @DESCRIPTION: +# Create the readme doc via stdin. You can use --append to append to an +# existing readme doc. +greadme_stdin() { + debug-print-function ${FUNCNAME} "${@}" + + local append + if [[ ${1} = --append ]]; then + append=1 + shift + fi + + [[ $# -eq 0 ]] || die "${FUNCNAME[0]}: Bad parameters: $*" + + if [[ -n ${append} ]]; then + if [[ ! -f ${_GREADME_TMP_FILE} ]]; then + die "Gentoo README does not exist when trying to append to it" + fi + + cat >> "${_GREADME_TMP_FILE}" || die + else + cat > "${_GREADME_TMP_FILE}" || die + fi + + _greadme_install_doc +} + +# @FUNCTION: greadme_file +# @USAGE: <file> +# @DESCRIPTION: +# Installs the provided file as readme doc. +greadme_file() { + debug-print-function ${FUNCNAME} "${@}" + + local input_doc_file="${1}" + if [[ -z ${input_doc_file} ]]; then + die "No file specified" + fi + + cp "${input_doc_file}" "${_GREADME_TMP_FILE}" || die + + _greadme_install_doc +} + +# @FUNCTION: _greadme_install_doc +# @INTERNAL +# @DESCRIPTION: +# Installs the readme file from the temp directory into the image. +_greadme_install_doc() { + debug-print-function ${FUNCNAME} "${@}" + + local greadme="${_GREADME_TMP_FILE}" + if [[ ! ${GREADME_DISABLE_AUTOFORMAT} ]]; then + greadme="${_GREADME_TMP_FILE}".formatted + + # Use fold, followed by a sed to strip trailing whitespace. + # https://bugs.gentoo.org/460050#c7 + fold -s -w 70 "${_GREADME_TMP_FILE}" | + sed 's/[[:space:]]*$//' > "${greadme}" + assert "failed to autoformat README.gentoo" + fi + + # Subshell to avoid pollution of calling environment. + ( + docinto . + newdoc "${greadme}" "README.gentoo" + ) + + # Exclude the readme file from compression, so that its contents can + # be easily compared. + docompress -x "${_GREADME_REL_PATH}" + + # Save the contents of the of the readme. Unfortunately we have to + # do this in src_* phase, because FEATURES=nodoc is applied right + # after src_install and not after pkg_preinst. + _GREADME_CONTENT=$(< "${greadme}") +} + +# @FUNCTION: greadme_pkg_preinst +# @DESCRIPTION: +# Performs checks like comparing the readme doc from the image with a +# potentially existing one in the live system. +greadme_pkg_preinst() { + debug-print-function ${FUNCNAME} "${@}" + + if [[ -z ${REPLACING_VERSIONS} ]]; then + _GREADME_SHOW="fresh-install" + return + fi + + if [[ -v GREADME_SHOW ]]; then + case ${GREADME_SHOW} in + yes) + _GREADME_SHOW="forced" + ;; + no) + _GREADME_SHOW="" + ;; + *) + die "Invalid argument of GREADME_SHOW: ${GREADME_SHOW}" + ;; + esac + return + fi + + local image_greadme_file="${ED}${_GREADME_REL_PATH}" + if [[ ! -f ${image_greadme_file} ]]; then + if [[ -v _GREADME_CONTENT ]]; then + # There is no greadme in the image but the ebuild created + # one. This is likely because FEATURES=nodoc is active. + # Unconditionally show greadme's contents. + _GREADME_SHOW="nodoc-active" + else + # No README file was created by the ebuild. + _GREADME_SHOW="" + fi + + return + fi + + check_live_doc_file() { + local cur_pvr=$1 + local live_greadme_file="${EROOT}/usr/share/doc/${PN}-${cur_pvr}/README.gentoo" + + if [[ ! -f ${live_greadme_file} ]]; then + _GREADME_SHOW="no-current-greadme" + return + fi + + cmp -s "${live_greadme_file}" "${image_greadme_file}" + case $? in + 0) + _GREADME_SHOW="" + ;; + 1) + _GREADME_SHOW="content-differs" + ;; + *) + die "cmp failed with $?" + ;; + esac + } + + local replaced_version + for replaced_version in ${REPLACING_VERSIONS}; do + check_live_doc_file ${replaced_version} + + # Once _GREADME_SHOW is non empty, we found a reason to show the + # readme and we can abort the loop. + if [[ -n ${_GREADME_SHOW} ]]; then + break + fi + done +} + +# @FUNCTION: greadme_pkg_postinst +# @DESCRIPTION: +# Conditionally shows the contents of the readme doc via elog. +greadme_pkg_postinst() { + debug-print-function ${FUNCNAME} "${@}" + + if [[ ! -v _GREADME_SHOW ]]; then + die "_GREADME_SHOW not set. Did you call greadme_pkg_preinst?" + fi + + if [[ -z ${_GREADME_SHOW} ]]; then + # If _GREADME_SHOW is empty, then there is no reason to show the contents. + return + fi + + local line + printf '%s\n' "${_GREADME_CONTENT}" | while read -r line; do + elog "${line}" + done + elog "" + elog "NOTE: Above message is only printed the first time package is" + elog "installed or if the message changed. Please look at" + elog "${EPREFIX}${_GREADME_REL_PATH}" + elog "for future reference." +} + +fi + +EXPORT_FUNCTIONS pkg_preinst pkg_postinst diff --git a/eclass/java-pkg-simple.eclass b/eclass/java-pkg-simple.eclass index 6b473ed768ed..5ed7e3e5b78e 100644 --- a/eclass/java-pkg-simple.eclass +++ b/eclass/java-pkg-simple.eclass @@ -26,8 +26,12 @@ _JAVA_PKG_SIMPLE_ECLASS=1 inherit java-utils-2 -if ! has java-pkg-2 ${INHERITED}; then - eerror "java-pkg-simple eclass can only be inherited AFTER java-pkg-2" +if has java-pkg-2 ${INHERITED}; then + JAVA_PKG_OPT=0 +elif has java-pkg-opt-2 ${INHERITED}; then + JAVA_PKG_OPT=1 +else + eerror "java-pkg-simple eclass can only be inherited AFTER java-pkg-2 or java-pkg-opt-2" fi # We are only interested in finding all java source files, wherever they may be. @@ -50,7 +54,12 @@ if has test ${JAVA_PKG_IUSE}; then test_deps+=" dev-java/testng:0";; esac done - [[ ${test_deps} ]] && DEPEND="test? ( ${test_deps} )" + if [[ ${JAVA_PKG_OPT} == 1 ]]; then + [[ ${test_deps} ]] && DEPEND="test? ( ${JAVA_PKG_OPT_USE}? ( ${test_deps} ) )" + else + [[ ${test_deps} ]] && DEPEND="test? ( ${test_deps} )" + fi + unset test_deps fi @@ -347,6 +356,7 @@ java-pkg-simple_prepend_resources() { # If USE FLAG 'binary' exists and is set, it will just copy # ${JAVA_BINJAR_FILENAME} to ${S} and skip the rest of src_compile. java-pkg-simple_src_compile() { + [[ ${JAVA_PKG_OPT} == 1 ]] && ! use ${JAVA_PKG_OPT_USE} && return local sources=sources.lst classes=target/classes apidoc=target/api moduleinfo # do not compile if we decide to install binary jar @@ -461,6 +471,7 @@ java-pkg-simple_src_compile() { # ${JAVA_JAR_FILENAME}. It will also install a launcher if # ${JAVA_MAIN_CLASS} is set. Also invokes einstalldocs. java-pkg-simple_src_install() { + [[ ${JAVA_PKG_OPT} == 1 ]] && ! use ${JAVA_PKG_OPT_USE} && return local sources=sources.lst classes=target/classes apidoc=target/api # install the jar file that we need @@ -503,6 +514,7 @@ java-pkg-simple_src_install() { # in the "generated-test" directory as content of this directory is preserved, # whereas content of target/test-classes is removed. java-pkg-simple_src_test() { + [[ ${JAVA_PKG_OPT} == 1 ]] && ! use ${JAVA_PKG_OPT_USE} && return local test_sources=test_sources.lst classes=target/test-classes moduleinfo local tests_to_run classpath diff --git a/eclass/java-utils-2.eclass b/eclass/java-utils-2.eclass index 91f8fba8790b..9c657cc4c1f9 100644 --- a/eclass/java-utils-2.eclass +++ b/eclass/java-utils-2.eclass @@ -1838,7 +1838,7 @@ ejunit_() { local junit=${1} shift 1 - local cp=$(java-pkg_getjars --with-dependencies ${junit}${pkgs}) + local cp=$(java-pkg_getjars --build-only --with-dependencies ${junit}${pkgs}) if [[ ${1} = -cp || ${1} = -classpath ]]; then cp="${2}:${cp}" shift 2 @@ -1926,7 +1926,7 @@ etestng() { local runner=org.testng.TestNG if [[ ${PN} != testng ]]; then - local cp=$(java-pkg_getjars --with-dependencies testng) + local cp=$(java-pkg_getjars --build-only --with-dependencies testng) else local cp=testng.jar fi @@ -2723,7 +2723,13 @@ java-pkg_build-vm-from-handle() { fi for vm in ${JAVA_PKG_WANT_BUILD_VM}; do - if java-config-2 --select-vm=${vm} 2>/dev/null; then + local java_config + for java_config in java-config{,-2}; do + type -p ${java_config} >/dev/null && break + done + [[ -z ${java_config} ]] && die "No java-config binary in PATH" + + if ${java_config} --select-vm=${vm} 2>/dev/null; then echo ${vm} return 0 fi diff --git a/eclass/java-vm-2.eclass b/eclass/java-vm-2.eclass index c7a207ae24f7..c90cd8664f30 100644 --- a/eclass/java-vm-2.eclass +++ b/eclass/java-vm-2.eclass @@ -164,58 +164,6 @@ get_system_arch() { } -# @FUNCTION: set_java_env -# @DESCRIPTION: -# Installs a vm env file. -# DEPRECATED, use java-vm_install-env instead. - -set_java_env() { - debug-print-function ${FUNCNAME} $* - - local platform="$(get_system_arch)" - local env_file="${ED}${JAVA_VM_CONFIG_DIR}/${VMHANDLE}" - - if [[ ${1} ]]; then - local source_env_file="${1}" - else - local source_env_file="${FILESDIR}/${VMHANDLE}.env" - fi - - if [[ ! -f ${source_env_file} ]]; then - die "Unable to find the env file: ${source_env_file}" - fi - - dodir ${JAVA_VM_CONFIG_DIR} - sed \ - -e "s/@P@/${P}/g" \ - -e "s/@PN@/${PN}/g" \ - -e "s/@PV@/${PV}/g" \ - -e "s/@PF@/${PF}/g" \ - -e "s/@SLOT@/${SLOT}/g" \ - -e "s/@PLATFORM@/${platform}/g" \ - -e "s/@LIBDIR@/$(get_libdir)/g" \ - -e "/^LDPATH=.*lib\\/\\\"/s|\"\\(.*\\)\"|\"\\1${platform}/:\\1${platform}/server/\"|" \ - < "${source_env_file}" \ - > "${env_file}" || die "sed failed" - - ( - echo "VMHANDLE=\"${VMHANDLE}\"" - echo "BUILD_ONLY=\"${JAVA_VM_BUILD_ONLY}\"" - ) >> "${env_file}" - - eprefixify ${env_file} - - [[ -n ${JAVA_PROVIDE} ]] && echo "PROVIDES=\"${JAVA_PROVIDE}\"" >> ${env_file} - - local java_home=$(source "${env_file}"; echo ${JAVA_HOME}) - [[ -z ${java_home} ]] && die "No JAVA_HOME defined in ${env_file}" - - # Make the symlink - dodir "${JAVA_VM_DIR}" - dosym "${java_home}" "${JAVA_VM_DIR}/${VMHANDLE}" -} - - # @FUNCTION: java-vm_install-env # @DESCRIPTION: # diff --git a/eclass/kernel-build.eclass b/eclass/kernel-build.eclass index cf060fa83766..c4f3db0028a9 100644 --- a/eclass/kernel-build.eclass +++ b/eclass/kernel-build.eclass @@ -131,13 +131,35 @@ fi # Call python-any-r1 and secureboot pkg_setup kernel-build_pkg_setup() { python-any-r1_pkg_setup - if [[ ${KERNEL_IUSE_MODULES_SIGN} ]]; then + if [[ ${KERNEL_IUSE_MODULES_SIGN} && ${MERGE_TYPE} != binary ]]; then secureboot_pkg_setup - if [[ -e ${MODULES_SIGN_KEY} && ${MODULES_SIGN_KEY} != pkcs11:* ]]; then - if [[ -e ${MODULES_SIGN_CERT} && ${MODULES_SIGN_CERT} != ${MODULES_SIGN_KEY} ]]; then - MODULES_SIGN_KEY_CONTENTS="$(cat "${MODULES_SIGN_CERT}" "${MODULES_SIGN_KEY}" || die)" + + if use modules-sign && [[ -n ${MODULES_SIGN_KEY} ]]; then + # Sanity check: fail early if key/cert in DER format or does not exist + local openssl_args=( + -noout -nocert + ) + if [[ -n ${MODULES_SIGN_CERT} ]]; then + openssl_args+=( -inform PEM -in "${MODULES_SIGN_CERT}" ) + else + # If no cert specified, we assume the pem key also contains the cert + openssl_args+=( -inform PEM -in "${MODULES_SIGN_KEY}" ) + fi + if [[ ${MODULES_SIGN_KEY} == pkcs11:* ]]; then + openssl_args+=( -engine pkcs11 -keyform ENGINE -key "${MODULES_SIGN_KEY}" ) else - MODULES_SIGN_KEY_CONTENTS="$(< "${MODULES_SIGN_KEY}")" + openssl_args+=( -keyform PEM -key "${MODULES_SIGN_KEY}" ) + fi + + openssl x509 "${openssl_args[@]}" || + die "Kernel module signing certificate or key not found or not PEM format." + + if [[ ${MODULES_SIGN_KEY} != pkcs11:* ]]; then + if [[ -n ${MODULES_SIGN_CERT} && ${MODULES_SIGN_CERT} != ${MODULES_SIGN_KEY} ]]; then + MODULES_SIGN_KEY_CONTENTS="$(cat "${MODULES_SIGN_CERT}" "${MODULES_SIGN_KEY}" || die)" + else + MODULES_SIGN_KEY_CONTENTS="$(< "${MODULES_SIGN_KEY}")" + fi fi fi fi @@ -165,6 +187,10 @@ kernel-build_src_configure() { fi # force ld.bfd if we can find it easily + local HOSTLD="$(tc-getBUILD_LD)" + if type -P "${HOSTLD}.bfd" &>/dev/null; then + HOSTLD+=.bfd + fi local LD="$(tc-getLD)" if type -P "${LD}.bfd" &>/dev/null; then LD+=.bfd @@ -176,6 +202,8 @@ kernel-build_src_configure() { HOSTCC="$(tc-getBUILD_CC)" HOSTCXX="$(tc-getBUILD_CXX)" + HOSTLD="${HOSTLD}" + HOSTAR="$(tc-getBUILD_AR)" HOSTCFLAGS="${BUILD_CFLAGS}" HOSTLDFLAGS="${BUILD_LDFLAGS}" @@ -188,6 +216,7 @@ kernel-build_src_configure() { STRIP="$(tc-getSTRIP)" OBJCOPY="$(tc-getOBJCOPY)" OBJDUMP="$(tc-getOBJDUMP)" + READELF="$(tc-getREADELF)" # we need to pass it to override colliding Gentoo envvar ARCH=$(tc-arch-kernel) @@ -231,25 +260,21 @@ kernel-build_src_configure() { mkdir -p "${WORKDIR}"/modprep || die mv .config "${WORKDIR}"/modprep/ || die emake O="${WORKDIR}"/modprep "${MAKEARGS[@]}" olddefconfig - emake O="${WORKDIR}"/modprep "${MAKEARGS[@]}" modules_prepare - cp -pR "${WORKDIR}"/modprep "${WORKDIR}"/build || die - # Now that we have a release file, set KV_FULL - local relfile=${WORKDIR}/build/include/config/kernel.release + local k_release=$(emake -s O="${WORKDIR}"/modprep "${MAKEARGS[@]}" kernelrelease) if [[ -z ${KV_FULL} ]]; then - KV_FULL=$(<"${relfile}") || die + KV_FULL=${k_release} fi # Make sure we are about to build the correct kernel if [[ ${PV} != *9999 ]]; then local expected_ver=$(dist-kernel_PV_to_KV "${PV}") - local expected_rel=$(<"${relfile}") - if [[ ${KV_FULL} != ${expected_rel} ]]; then + if [[ ${KV_FULL} != ${k_release} ]]; then eerror "KV_FULL mismatch!" eerror "KV_FULL: ${KV_FULL}" - eerror "Expected: ${expected_rel}" - die "KV_FULL mismatch: got ${KV_FULL}, expected ${expected_rel}" + eerror "Expected: ${k_release}" + die "KV_FULL mismatch: got ${KV_FULL}, expected ${k_release}" fi if [[ ${KV_FULL} != ${expected_ver}* ]]; then @@ -260,6 +285,9 @@ kernel-build_src_configure() { die "Kernel version mismatch: got ${KV_FULL}, expected ${expected_ver}*" fi fi + + emake O="${WORKDIR}"/modprep "${MAKEARGS[@]}" modules_prepare + cp -pR "${WORKDIR}"/modprep "${WORKDIR}"/build || die } # @FUNCTION: kernel-build_src_compile @@ -426,6 +454,8 @@ kernel-build_src_install() { # fix source tree and build dir symlinks dosym "../../../${kernel_dir}" "/lib/modules/${KV_FULL}/build" dosym "../../../${kernel_dir}" "/lib/modules/${KV_FULL}/source" + dosym "../../../${kernel_dir}/.config" "/lib/modules/${KV_FULL}/config" + dosym "../../../${kernel_dir}/System.map" "/lib/modules/${KV_FULL}/System.map" if [[ "${image_path}" == *vmlinux* ]]; then dosym "../../../${kernel_dir}/${image_path}" "/lib/modules/${KV_FULL}/vmlinux" else @@ -491,7 +521,7 @@ kernel-build_src_install() { --output="${image%/*}/uki.efi" ) - if [[ ${KERNEL_IUSE_SECUREBOOT} ]] && use secureboot; then + if [[ ${KERNEL_IUSE_MODULES_SIGN} ]] && use secureboot; then ukify_args+=( --signtool=sbsign --secureboot-private-key="${SECUREBOOT_SIGN_KEY}" diff --git a/eclass/kernel-install.eclass b/eclass/kernel-install.eclass index e6f0b404dcaa..c64dd673084b 100644 --- a/eclass/kernel-install.eclass +++ b/eclass/kernel-install.eclass @@ -560,21 +560,21 @@ kernel-install_pkg_pretend() { ewarn "that distribution kernels will boot without an initramfs." ewarn ewarn "You have disabled the initramfs USE flag, and as a result the package manager" - ewarn "will not enforce the configuration of an initramfs generator in" - ewarn "sys-kernel/installkernel." - ewarn + ewarn "will not enforce the configuration of an initramfs generator in" + ewarn "sys-kernel/installkernel." + ewarn ewarn "If you wish to use a custom initramfs generator, then please ensure that" - ewarn "/sbin/installkernel is capable of calling it via a kernel installation hook," - ewarn "and is also configured to use it via /etc/kernel/install.conf." - ewarn - ewarn "If you wish to boot without an initramfs, then please ensure that" - ewarn "all kernel drivers required to boot your system are built into the" - ewarn "kernel by modifying the default distribution kernel configuration" - ewarn "using /etc/kernel/config.d" - ewarn + ewarn "/sbin/installkernel is capable of calling it via a kernel installation hook," + ewarn "and is also configured to use it via /etc/kernel/install.conf." + ewarn + ewarn "If you wish to boot without an initramfs, then please ensure that" + ewarn "all kernel drivers required to boot your system are built into the" + ewarn "kernel by modifying the default distribution kernel configuration" + ewarn "using /etc/kernel/config.d" + ewarn ewarn "Please refer to the installkernel and distribution kernel documentation:" ewarn " https://wiki.gentoo.org/wiki/Installkernel" - ewarn " https://wiki.gentoo.org/wiki/Project:Distribution_Kernel" + ewarn " https://wiki.gentoo.org/wiki/Project:Distribution_Kernel" fi } @@ -623,6 +623,13 @@ kernel-install_pkg_preinst() { rm "${ED}/lib/modules/${KV_FULL}"/{build,source} || die dosym "../../../src/linux-${KV_FULL}" "/usr/lib/modules/${KV_FULL}/build" dosym "../../../src/linux-${KV_FULL}" "/usr/lib/modules/${KV_FULL}/source" + local file + for file in .config System.map; do + if [[ -L "${ED}/lib/modules/${KV_FULL}/${file#.}" ]]; then + rm "${ED}/lib/modules/${KV_FULL}/${file#.}" || die + dosym "../../../src/linux-${KV_FULL}/${file}" "/usr/lib/modules/${KV_FULL}/${file#.}" + fi + done for file in vmlinux vmlinuz; do if [[ -L "${ED}/lib/modules/${KV_FULL}/${file}" ]]; then rm "${ED}/lib/modules/${KV_FULL}/${file}" || die @@ -759,13 +766,35 @@ kernel-install_compress_modules() { if use modules-compress; then einfo "Compressing kernel modules ..." - # xz options taken from scripts/Makefile.modinst - # we don't do 'xz -T' because it applies multithreading per file, - # so it works only for big files, and we have lots of small files - # instead - find "${ED}/lib" -name '*.ko' -print0 | - xargs -0 -P "$(makeopts_jobs)" -n 128 \ - xz --check=crc32 --lzma2=dict=1MiB + if [[ -z ${KV_FULL} ]]; then + KV_FULL=${PV}${KV_LOCALVERSION} + fi + local suffix=$(dist-kernel_get_module_suffix "${ED}/usr/src/linux-${KV_FULL}") + local compress=() + # Options taken from linux-mod-r1.eclass. + # We don't instruct the compressor to parallelize because it applies + # multithreading per file, so it works only for big files, and we have + # lots of small files instead. + case ${suffix} in + .ko) + return + ;; + .ko.gz) + compress+=( gzip ) + ;; + .ko.xz) + compress+=( xz --check=crc32 --lzma2=dict=1MiB ) + ;; + .ko.zst) + compress+=( zstd -q --rm ) + ;; + *) + die "Unknown compressor: ${suffix}" + ;; + esac + + find "${ED}/lib/modules/${KV_FULL}" -name '*.ko' -print0 | + xargs -0 -P "$(makeopts_jobs)" -n 128 "${compress[@]}" assert "Compressing kernel modules failed" fi } diff --git a/eclass/llvm-r1.eclass b/eclass/llvm-r1.eclass index 075df9218be8..0a53b9a3cb5e 100644 --- a/eclass/llvm-r1.eclass +++ b/eclass/llvm-r1.eclass @@ -61,7 +61,7 @@ _LLVM_OLDEST_SLOT=15 # @DESCRIPTION: # The newest stable LLVM version. Versions newer than that won't # be automatically enabled via USE defaults. -_LLVM_NEWEST_STABLE=17 +_LLVM_NEWEST_STABLE=18 # == control variables == @@ -123,11 +123,16 @@ _llvm_set_globals() { fi if [[ ${stable[@]} ]]; then + # If there is at least one stable slot supported, then enable + # the newest stable slot by default. IUSE="+llvm_slot_${stable[-1]}" unset 'stable[-1]' else - IUSE="+llvm_slot_${unstable[-1]}" - unset 'unstable[-1]' + # Otherwise, enable the "oldest" ~arch slot. We really only + # expect a single ~arch version, so this primarily prevents + # defaulting to non-keyworded slots. + IUSE="+llvm_slot_${unstable[0]}" + unset 'unstable[0]' fi local nondefault=( "${stable[@]}" "${unstable[@]}" ) IUSE+=" ${nondefault[*]/#/llvm_slot_}" diff --git a/eclass/llvm.eclass b/eclass/llvm.eclass index e297fe992c9f..bb5ff5d78290 100644 --- a/eclass/llvm.eclass +++ b/eclass/llvm.eclass @@ -9,6 +9,7 @@ # @SUPPORTED_EAPIS: 7 8 # @PROVIDES: llvm-utils # @BLURB: Utility functions to build against slotted LLVM +# @DEPRECATED: llvm-r1.eclass # @DESCRIPTION: # The llvm.eclass provides utility functions that can be used to build # against specific version of slotted LLVM (with fallback to :0 for old diff --git a/eclass/llvm.org.eclass b/eclass/llvm.org.eclass index 7aa1d0e2b0b8..d705947ce0d2 100644 --- a/eclass/llvm.org.eclass +++ b/eclass/llvm.org.eclass @@ -57,7 +57,7 @@ LLVM_VERSION=$(ver_cut 1-3) # @DESCRIPTION: # The major version of current LLVM trunk. Used to determine # the correct branch to use. -_LLVM_MAIN_MAJOR=19 +_LLVM_MAIN_MAJOR=20 # @ECLASS_VARIABLE: _LLVM_SOURCE_TYPE # @INTERNAL @@ -72,14 +72,8 @@ if [[ -z ${_LLVM_SOURCE_TYPE+1} ]]; then _LLVM_SOURCE_TYPE=snapshot case ${PV} in - 19.0.0_pre20240720) - EGIT_COMMIT=72d8c2737bb557af9d0c735b9fa30b1b03485627 - ;; - 19.0.0_pre20240712) - EGIT_COMMIT=1bad7024561bc64ed4bfda0772b16376b475eba5 - ;; - 19.0.0_pre20240706) - EGIT_COMMIT=0b9f2847da79298ed09c29493245113f02b32d9f + 20.0.0_pre20240801) + EGIT_COMMIT=130c135689ec12ab78c53645808524a8d28f7cae ;; *) die "Unknown snapshot: ${PV}" @@ -241,12 +235,21 @@ llvm.org_set_globals() { EGIT_BRANCH="release/${LLVM_MAJOR}.x" ;; tar) - SRC_URI+=" - https://github.com/llvm/llvm-project/releases/download/llvmorg-${PV/_/-}/llvm-project-${PV/_/}.src.tar.xz - verify-sig? ( - https://github.com/llvm/llvm-project/releases/download/llvmorg-${PV/_/-}/llvm-project-${PV/_/}.src.tar.xz.sig - ) - " + if [[ ${LLVM_MAJOR} -ge 19 ]]; then + SRC_URI+=" + https://github.com/llvm/llvm-project/releases/download/llvmorg-${PV/_/-}/llvm-project-${PV/_/-}.src.tar.xz + verify-sig? ( + https://github.com/llvm/llvm-project/releases/download/llvmorg-${PV/_/-}/llvm-project-${PV/_/-}.src.tar.xz.sig + ) + " + else + SRC_URI+=" + https://github.com/llvm/llvm-project/releases/download/llvmorg-${PV/_/-}/llvm-project-${PV/_/}.src.tar.xz + verify-sig? ( + https://github.com/llvm/llvm-project/releases/download/llvmorg-${PV/_/-}/llvm-project-${PV/_/}.src.tar.xz.sig + ) + " + fi BDEPEND+=" verify-sig? ( >=sec-keys/openpgp-keys-llvm-18.1.6 @@ -359,7 +362,11 @@ llvm.org_src_unpack() { git-r3_checkout '' . '' "${components[@]}" ;; tar) - archive=llvm-project-${PV/_/}.src.tar.xz + if [[ ${LLVM_MAJOR} -ge 19 ]]; then + archive=llvm-project-${PV/_/-}.src.tar.xz + else + archive=llvm-project-${PV/_/}.src.tar.xz + fi if use verify-sig; then verify-sig_verify_detached \ "${DISTDIR}/${archive}" "${DISTDIR}/${archive}.sig" diff --git a/eclass/python-any-r1.eclass b/eclass/python-any-r1.eclass index a21df8e89498..c1f27cfbac0d 100644 --- a/eclass/python-any-r1.eclass +++ b/eclass/python-any-r1.eclass @@ -1,4 +1,4 @@ -# Copyright 1999-2023 Gentoo Authors +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: python-any-r1.eclass @@ -272,6 +272,7 @@ python_gen_any_dep() { # This function will call python_check_deps() if defined. python_setup() { debug-print-function ${FUNCNAME} "${@}" + _python_sanity_checks # support developer override if [[ ${PYTHON_COMPAT_OVERRIDE} ]]; then diff --git a/eclass/python-r1.eclass b/eclass/python-r1.eclass index c5fa6770558f..adf87c2c52f7 100644 --- a/eclass/python-r1.eclass +++ b/eclass/python-r1.eclass @@ -617,6 +617,7 @@ _python_multibuild_wrapper() { # locally, and the former two are exported to the command environment. python_foreach_impl() { debug-print-function ${FUNCNAME} "${@}" + _python_sanity_checks if [[ ${_DISTUTILS_R1_ECLASS} ]]; then if has "${EBUILD_PHASE}" prepare configure compile test install && @@ -708,6 +709,7 @@ python_foreach_impl() { # @CODE python_setup() { debug-print-function ${FUNCNAME} "${@}" + _python_sanity_checks local has_check_deps declare -f python_check_deps >/dev/null && has_check_deps=1 diff --git a/eclass/python-single-r1.eclass b/eclass/python-single-r1.eclass index 4d61f08c06f0..481b6cf91ba0 100644 --- a/eclass/python-single-r1.eclass +++ b/eclass/python-single-r1.eclass @@ -1,4 +1,4 @@ -# Copyright 1999-2022 Gentoo Authors +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: python-single-r1.eclass @@ -393,6 +393,7 @@ python_gen_impl_dep() { # the Python build environment up for it. python_setup() { debug-print-function ${FUNCNAME} "${@}" + _python_sanity_checks unset EPYTHON diff --git a/eclass/python-utils-r1.eclass b/eclass/python-utils-r1.eclass index c47565fa1db2..45d3da6bb98c 100644 --- a/eclass/python-utils-r1.eclass +++ b/eclass/python-utils-r1.eclass @@ -332,6 +332,17 @@ _python_export() { export PYTHON=${BROOT-${EPREFIX}}/usr/bin/${impl} debug-print "${FUNCNAME}: PYTHON = ${PYTHON}" ;; + PYTHON_STDLIB) + [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it" + PYTHON_STDLIB=$( + "${PYTHON}" - "${EPREFIX}/usr" <<-EOF || die + import sys, sysconfig + print(sysconfig.get_path("stdlib", vars={"installed_base": sys.argv[1]})) + EOF + ) + export PYTHON_STDLIB + debug-print "${FUNCNAME}: PYTHON_STDLIB = ${PYTHON_STDLIB}" + ;; PYTHON_SITEDIR) [[ -n ${PYTHON} ]] || die "PYTHON needs to be set for ${var} to be exported, or requested before it" PYTHON_SITEDIR=$( @@ -466,6 +477,18 @@ _python_export() { done } +# @FUNCTION: python_get_stdlib +# @USAGE: [<impl>] +# @DESCRIPTION: +# Obtain and print the 'stdlib' path for the given implementation. If no +# implementation is provided, ${EPYTHON} will be used. +python_get_stdlib() { + debug-print-function ${FUNCNAME} "${@}" + + _python_export "${@}" PYTHON_STDLIB + echo "${PYTHON_STDLIB}" +} + # @FUNCTION: python_get_sitedir # @USAGE: [<impl>] # @DESCRIPTION: @@ -1544,4 +1567,38 @@ python_has_version() { return 0 } +# @FUNCTION: _python_sanity_checks +# @INTERNAL +# @DESCRIPTION: +# Perform additional environment sanity checks. +_python_sanity_checks() { + debug-print-function ${FUNCNAME} "${@}" + + [[ ${_PYTHON_SANITY_CHECKED} ]] && return + + if [[ -v PYTHONPATH ]]; then + local x paths=() + mapfile -d ':' -t paths <<<${PYTHONPATH} + + for x in "${paths[@]}"; do + if [[ ${x} != /* ]]; then + eerror "Relative path found in PYTHONPATH:" + eerror + eerror " PYTHONPATH=${PYTHONPATH@Q}" + eerror + eerror "This is guaranteed to cause random breakage. Please make sure that" + eerror "your PYTHONPATH contains absolute paths only (and only if necessary)." + eerror "Note that empty values (including ':' at either end and an empty" + eerror "PYTHONPATH) count as the current directory. If no PYTHONPATH" + eerror "is intended, it needs to be unset instead." + die "Relative paths in PYTHONPATH are forbidden: ${x@Q}" + fi + done + + elog "PYTHONPATH=${PYTHONPATH@Q}" + fi + + _PYTHON_SANITY_CHECKED=1 +} + fi diff --git a/eclass/rust-toolchain.eclass b/eclass/rust-toolchain.eclass index 111aece796ce..469479b849b3 100644 --- a/eclass/rust-toolchain.eclass +++ b/eclass/rust-toolchain.eclass @@ -31,26 +31,29 @@ esac rust_abi() { local CTARGET=${1:-${CHOST}} case ${CTARGET%%*-} in - aarch64*gnu) echo aarch64-unknown-linux-gnu;; - aarch64*musl) echo aarch64-unknown-linux-musl;; - armv6j*h*) echo arm-unknown-linux-gnueabihf;; - armv6j*s*) echo arm-unknown-linux-gnueabi;; - armv7a*h*) echo armv7-unknown-linux-gnueabihf;; - i?86*) echo i686-unknown-linux-gnu;; - loongarch64*) echo loongarch64-unknown-linux-gnu;; - mips64el*) echo mips64el-unknown-linux-gnuabi64;; - mips64*) echo mips64-unknown-linux-gnuabi64;; - mipsel*) echo mipsel-unknown-linux-gnu;; - mips*) echo mips-unknown-linux-gnu;; - powerpc64le*) echo powerpc64le-unknown-linux-gnu;; - powerpc64*) echo powerpc64-unknown-linux-gnu;; - powerpc*) echo powerpc-unknown-linux-gnu;; - riscv64*gnu) echo riscv64gc-unknown-linux-gnu;; - riscv64*musl) echo riscv64gc-unknown-linux-musl;; - s390x*) echo s390x-unknown-linux-gnu;; - x86_64*gnu) echo x86_64-unknown-linux-gnu;; - x86_64*musl) echo x86_64-unknown-linux-musl;; - *) echo ${CTARGET};; + aarch64*gnu) echo aarch64-unknown-linux-gnu;; + aarch64*musl) echo aarch64-unknown-linux-musl;; + armv6j*h*) echo arm-unknown-linux-gnueabihf;; + armv6j*s*) echo arm-unknown-linux-gnueabi;; + armv7a*h*) echo armv7-unknown-linux-gnueabihf;; + i?86*) echo i686-unknown-linux-gnu;; + loongarch64*) echo loongarch64-unknown-linux-gnu;; + mips64el*) echo mips64el-unknown-linux-gnuabi64;; + mips64*) echo mips64-unknown-linux-gnuabi64;; + mipsel*) echo mipsel-unknown-linux-gnu;; + mips*) echo mips-unknown-linux-gnu;; + powerpc64le*gnu) echo powerpc64le-unknown-linux-gnu;; + powerpc64le*musl) echo powerpc64le-unknown-linux-musl;; + powerpc64*gnu) echo powerpc64-unknown-linux-gnu;; + powerpc64*musl) echo powerpc64-unknown-linux-musl;; + powerpc*gnu) echo powerpc-unknown-linux-gnu;; + powerpc*musl) echo powerpc-unknown-linux-musl;; + riscv64*gnu) echo riscv64gc-unknown-linux-gnu;; + riscv64*musl) echo riscv64gc-unknown-linux-musl;; + s390x*) echo s390x-unknown-linux-gnu;; + x86_64*gnu) echo x86_64-unknown-linux-gnu;; + x86_64*musl) echo x86_64-unknown-linux-musl;; + *) echo ${CTARGET};; esac } diff --git a/eclass/savedconfig.eclass b/eclass/savedconfig.eclass index cc5748543078..65a1f3bfd800 100644 --- a/eclass/savedconfig.eclass +++ b/eclass/savedconfig.eclass @@ -1,10 +1,10 @@ -# Copyright 1999-2023 Gentoo Authors +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: savedconfig.eclass # @MAINTAINER: # base-system@gentoo.org -# @SUPPORTED_EAPIS: 6 7 8 +# @SUPPORTED_EAPIS: 7 8 # @BLURB: common API for saving/restoring complex configuration files # @DESCRIPTION: # It is not uncommon to come across a package which has a very fine @@ -31,7 +31,7 @@ # build. case ${EAPI} in - 6|7|8) ;; + 7|8) ;; *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; esac @@ -60,12 +60,12 @@ save_config() { if [[ $# -eq 1 && -f $1 ]] ; then # Just one file, so have the ${configfile} be that config file dodir "${configfile%/*}" - cp "$@" "${ED%/}/${configfile}" || die "failed to save $*" + cp "$@" "${ED}/${configfile}" || die "failed to save $*" else # A dir, or multiple files, so have the ${configfile} be a dir # with all the saved stuff below it dodir "${configfile}" - treecopy "$@" "${ED%/}/${configfile}" || die "failed to save $*" + treecopy "$@" "${ED}/${configfile}" || die "failed to save $*" fi elog "Your configuration for ${CATEGORY}/${PF} has been saved in " @@ -150,7 +150,7 @@ savedconfig_pkg_postinst() { # are worse :/. if use savedconfig ; then - find "${EROOT%/}/etc/portage/savedconfig/${CATEGORY}/${PF}" \ + find "${EROOT}/etc/portage/savedconfig/${CATEGORY}/${PF}" \ -exec touch {} + 2>/dev/null fi } diff --git a/eclass/secureboot.eclass b/eclass/secureboot.eclass index a9ba514cb7a0..4459b0341845 100644 --- a/eclass/secureboot.eclass +++ b/eclass/secureboot.eclass @@ -1,4 +1,4 @@ -# Copyright 1999-2023 Gentoo Authors +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: secureboot.eclass @@ -44,7 +44,12 @@ case ${EAPI} in esac IUSE="secureboot" -BDEPEND="secureboot? ( app-crypt/sbsigntools )" +BDEPEND=" + secureboot? ( + app-crypt/sbsigntools + dev-libs/openssl + ) +" # @ECLASS_VARIABLE: SECUREBOOT_SIGN_KEY # @USER_VARIABLE @@ -75,12 +80,19 @@ _secureboot_die_if_unset() { if [[ -z ${SECUREBOOT_SIGN_KEY} || -z ${SECUREBOOT_SIGN_CERT} ]]; then die "USE=secureboot enabled but SECUREBOOT_SIGN_KEY and/or SECUREBOOT_SIGN_CERT not set." fi - if [[ ! ${SECUREBOOT_SIGN_KEY} == pkcs11:* && ! -r ${SECUREBOOT_SIGN_KEY} ]]; then - die "SECUREBOOT_SIGN_KEY=${SECUREBOOT_SIGN_KEY} not found or not readable!" - fi - if [[ ! -r ${SECUREBOOT_SIGN_CERT} ]]; then - die "SECUREBOOT_SIGN_CERT=${SECUREBOOT_SIGN_CERT} not found or not readable!" + + # Sanity check: fail early if key/cert in DER format or does not exist + local openssl_args=( + -inform PEM -in "${SECUREBOOT_SIGN_CERT}" + -noout -nocert + ) + if [[ ${SECUREBOOT_SIGN_KEY} == pkcs11:* ]]; then + openssl_args+=( -engine pkcs11 -keyform ENGINE -key "${SECUREBOOT_SIGN_KEY}" ) + else + openssl_args+=( -keyform PEM -key "${SECUREBOOT_SIGN_KEY}" ) fi + openssl x509 "${openssl_args[@]}" || + die "Secure Boot signing certificate or key not found or not PEM format." } # @FUNCTION: secureboot_pkg_setup diff --git a/eclass/tests/Makefile b/eclass/tests/Makefile index 99e824dea86d..23027aed6b66 100644 --- a/eclass/tests/Makefile +++ b/eclass/tests/Makefile @@ -1,5 +1,5 @@ SH_FILES := $(wildcard *.sh) -TEST_FILES := $(filter-out tests-common.sh version-funcs.sh, $(SH_FILES)) +TEST_FILES := $(filter-out tests-common.sh, $(SH_FILES)) TEST_OK_FILES := $(patsubst %.sh, .%.sh.ok,$ $(TEST_FILES)) # !!! _All_ recipe lines for each target will be provided to a single diff --git a/eclass/tests/dist-kernel-utils.sh b/eclass/tests/dist-kernel-utils.sh index 50ba001f8e9c..28c8f7213a53 100755 --- a/eclass/tests/dist-kernel-utils.sh +++ b/eclass/tests/dist-kernel-utils.sh @@ -20,9 +20,68 @@ test_PV_to_KV() { tend $? } +test_compressed_module_cleanup() { + mkdir -p "${tmpdir}/source" || die + pushd "${tmpdir}" >/dev/null || die + + local module option fail=0 + for option in NONE GZIP XZ ZSTD; do + tbegin "CONFIG_MODULE_COMPRESS_${option}" + echo "CONFIG_MODULE_COMPRESS_${option}=y" > source/.config + + touch a.ko b.ko.gz c.ko.xz d.ko.gz e.ko f.ko.xz || die + # ensure some files are older + touch -d "2 hours ago" d.ko e.ko.xz f.ko.gz || die + + IUSE=modules-compress dist-kernel_compressed_module_cleanup . + + local to_keep=( a.ko b.ko.gz c.ko.xz ) + local to_remove=() + + case ${option} in + NONE) + to_keep+=( d.ko e.ko f.ko.xz ) + to_remove+=( d.ko.gz e.ko.xz f.ko.gz ) + ;; + GZIP) + to_keep+=( d.ko.gz e.ko f.ko.gz ) + to_remove+=( d.ko e.ko.xz f.ko.xz ) + ;; + XZ) + to_keep+=( d.ko.gz e.ko.xz f.ko.xz ) + to_remove+=( d.ko e.ko f.ko.gz ) + ;; + ZSTD) + to_keep+=( d.ko.gz e.ko f.ko.xz ) + to_remove+=( d.ko e.ko.xz f.ko.gz ) + ;; + esac + + for module in "${to_keep[@]}"; do + if [[ ! -f ${module} ]]; then + eerror "Module ${module} was removed" + fail=1 + fi + done + + for module in "${to_remove[@]}"; do + if [[ -f ${module} ]]; then + eerror "Module ${module} was not removed" + fail=1 + fi + done + tend ${fail} + done + + popd >/dev/null || die +} + + test_PV_to_KV 6.0_rc1 6.0.0-rc1 test_PV_to_KV 6.0 6.0.0 test_PV_to_KV 6.0.1_rc1 6.0.1-rc1 test_PV_to_KV 6.0.1 6.0.1 +test_compressed_module_cleanup + texit diff --git a/eclass/tests/eapi7-ver.sh b/eclass/tests/eapi7-ver.sh deleted file mode 100755 index ee7e6d728ef7..000000000000 --- a/eclass/tests/eapi7-ver.sh +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/bash -# Copyright 1999-2024 Gentoo Authors -# Distributed under the terms of the GNU General Public License v2 - -source tests-common.sh || exit -source version-funcs.sh || exit - -teq() { - local expected=${1}; shift - - tbegin "${*} -> ${expected}" - local got=$("${@}") - [[ ${got} == ${expected} ]] - tend ${?} "returned: ${got}" -} - -teqr() { - local expected=$1; shift - tbegin "$* -> ${expected}" - "$@" - local ret=$? - [[ ${ret} -eq ${expected} ]] - tend $? "returned: ${ret}" -} - -txf() { - tbegin "XFAIL: ${*}" - local got=$("${@}" 2>&1) - [[ ${got} == die:* ]] - tend ${?} "function did not die" -} - -teq 1 ver_cut 1 1.2.3 -teq 1 ver_cut 1-1 1.2.3 -teq 1.2 ver_cut 1-2 1.2.3 -teq 2.3 ver_cut 2- 1.2.3 -teq 1.2.3 ver_cut 1- 1.2.3 -teq 3b ver_cut 3-4 1.2.3b_alpha4 -teq alpha ver_cut 5 1.2.3b_alpha4 -teq 1.2 ver_cut 1-2 .1.2.3 -teq .1.2 ver_cut 0-2 .1.2.3 -teq 2.3 ver_cut 2-3 1.2.3. -teq 2.3. ver_cut 2- 1.2.3. -teq 2.3. ver_cut 2-4 1.2.3. - -teq 1-2.3 ver_rs 1 - 1.2.3 -teq 1.2-3 ver_rs 2 - 1.2.3 -teq 1-2-3.4 ver_rs 1-2 - 1.2.3.4 -teq 1.2-3-4 ver_rs 2- - 1.2.3.4 -teq 1.2.3 ver_rs 2 . 1.2-3 -teq 1.2.3.a ver_rs 3 . 1.2.3a -teq 1.2-alpha-4 ver_rs 2-3 - 1.2_alpha4 -teq 1.23-b_alpha4 ver_rs 3 - 2 "" 1.2.3b_alpha4 -teq a1b_2-c-3-d4e5 ver_rs 3-5 _ 4-6 - a1b2c3d4e5 -teq .1-2.3 ver_rs 1 - .1.2.3 -teq -1.2.3 ver_rs 0 - .1.2.3 - -# truncating range -teq 1.2 ver_cut 0-2 1.2.3 -teq 2.3 ver_cut 2-5 1.2.3 -teq "" ver_cut 4 1.2.3 -teq "" ver_cut 0 1.2.3 -teq "" ver_cut 4- 1.2.3 -teq 1.2.3 ver_rs 0 - 1.2.3 -teq 1.2.3 ver_rs 3 . 1.2.3 -teq 1.2.3 ver_rs 3- . 1.2.3 -teq 1.2.3 ver_rs 3-5 . 1.2.3 - -txf ver_cut foo 1.2.3 -txf ver_rs -3 _ a1b2c3d4e5 -txf ver_rs 5-3 _ a1b2c3d4e5 - -# Tests from Portage's test_vercmp.py -teqr 0 ver_test 6.0 -gt 5.0 -teqr 0 ver_test 5.0 -gt 5 -teqr 0 ver_test 1.0-r1 -gt 1.0-r0 -teqr 0 ver_test 999999999999999999 -gt 999999999999999998 # 18 digits -teqr 0 ver_test 1.0.0 -gt 1.0 -teqr 0 ver_test 1.0.0 -gt 1.0b -teqr 0 ver_test 1b -gt 1 -teqr 0 ver_test 1b_p1 -gt 1_p1 -teqr 0 ver_test 1.1b -gt 1.1 -teqr 0 ver_test 12.2.5 -gt 12.2b -teqr 0 ver_test 4.0 -lt 5.0 -teqr 0 ver_test 5 -lt 5.0 -teqr 0 ver_test 1.0_pre2 -lt 1.0_p2 -teqr 0 ver_test 1.0_alpha2 -lt 1.0_p2 -teqr 0 ver_test 1.0_alpha1 -lt 1.0_beta1 -teqr 0 ver_test 1.0_beta3 -lt 1.0_rc3 -teqr 0 ver_test 1.001000000000000001 -lt 1.001000000000000002 -teqr 0 ver_test 1.00100000000 -lt 1.001000000000000001 -teqr 0 ver_test 999999999999999998 -lt 999999999999999999 -teqr 0 ver_test 1.01 -lt 1.1 -teqr 0 ver_test 1.0-r0 -lt 1.0-r1 -teqr 0 ver_test 1.0 -lt 1.0-r1 -teqr 0 ver_test 1.0 -lt 1.0.0 -teqr 0 ver_test 1.0b -lt 1.0.0 -teqr 0 ver_test 1_p1 -lt 1b_p1 -teqr 0 ver_test 1 -lt 1b -teqr 0 ver_test 1.1 -lt 1.1b -teqr 0 ver_test 12.2b -lt 12.2.5 -teqr 0 ver_test 4.0 -eq 4.0 -teqr 0 ver_test 1.0 -eq 1.0 -teqr 0 ver_test 1.0-r0 -eq 1.0 -teqr 0 ver_test 1.0 -eq 1.0-r0 -teqr 0 ver_test 1.0-r0 -eq 1.0-r0 -teqr 0 ver_test 1.0-r1 -eq 1.0-r1 -teqr 1 ver_test 1 -eq 2 -teqr 1 ver_test 1.0_alpha -eq 1.0_pre -teqr 1 ver_test 1.0_beta -eq 1.0_alpha -teqr 1 ver_test 1 -eq 0.0 -teqr 1 ver_test 1.0-r0 -eq 1.0-r1 -teqr 1 ver_test 1.0-r1 -eq 1.0-r0 -teqr 1 ver_test 1.0 -eq 1.0-r1 -teqr 1 ver_test 1.0-r1 -eq 1.0 -teqr 1 ver_test 1.0 -eq 1.0.0 -teqr 1 ver_test 1_p1 -eq 1b_p1 -teqr 1 ver_test 1b -eq 1 -teqr 1 ver_test 1.1b -eq 1.1 -teqr 1 ver_test 12.2b -eq 12.2 - -# A subset of tests from Paludis -teqr 0 ver_test 1.0_alpha -gt 1_alpha -teqr 0 ver_test 1.0_alpha -gt 1 -teqr 0 ver_test 1.0_alpha -lt 1.0 -teqr 0 ver_test 1.2.0.0_alpha7-r4 -gt 1.2_alpha7-r4 -teqr 0 ver_test 0001 -eq 1 -teqr 0 ver_test 01 -eq 001 -teqr 0 ver_test 0001.1 -eq 1.1 -teqr 0 ver_test 01.01 -eq 1.01 -teqr 0 ver_test 1.010 -eq 1.01 -teqr 0 ver_test 1.00 -eq 1.0 -teqr 0 ver_test 1.0100 -eq 1.010 -teqr 0 ver_test 1-r00 -eq 1-r0 - -# Additional tests -teqr 0 ver_test 0_rc99 -lt 0 -teqr 0 ver_test 011 -eq 11 -teqr 0 ver_test 019 -eq 19 -teqr 0 ver_test 1.2 -eq 001.2 -teqr 0 ver_test 1.2 -gt 1.02 -teqr 0 ver_test 1.2a -lt 1.2b -teqr 0 ver_test 1.2_pre1 -gt 1.2_pre1_beta2 -teqr 0 ver_test 1.2_pre1 -lt 1.2_pre1_p2 -teqr 0 ver_test 1.00 -lt 1.0.0 -teqr 0 ver_test 1.010 -eq 1.01 -teqr 0 ver_test 1.01 -lt 1.1 -teqr 0 ver_test 1.2_pre08-r09 -eq 1.2_pre8-r9 -teqr 0 ver_test 0 -lt 576460752303423488 # 2**59 -teqr 0 ver_test 0 -lt 9223372036854775808 # 2**63 - -# Bad number or ordering of arguments -txf ver_test 1 -txf ver_test 1 -lt 2 3 -txf ver_test -lt 1 2 - -# Bad operators -txf ver_test 1 "<" 2 -txf ver_test 1 lt 2 -txf ver_test 1 -foo 2 - -# Malformed versions -txf ver_test "" -ne 1 -txf ver_test 1. -ne 1 -txf ver_test 1ab -ne 1 -txf ver_test b -ne 1 -txf ver_test 1-r1_pre -ne 1 -txf ver_test 1-pre1 -ne 1 -txf ver_test 1_foo -ne 1 -txf ver_test 1_pre1.1 -ne 1 -txf ver_test 1-r1.0 -ne 1 -txf ver_test cvs.9999 -ne 9999 - -texit diff --git a/eclass/tests/llvm-r1.sh b/eclass/tests/llvm-r1.sh index 9958f5bba420..8583fd6c799b 100755 --- a/eclass/tests/llvm-r1.sh +++ b/eclass/tests/llvm-r1.sh @@ -121,22 +121,30 @@ test_fix_tool_path() { tend ${?} } +# full range +test_globals '14 15 16 17 18 19' \ + "+llvm_slot_18 llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_19" \ + "^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 llvm_slot_19 )" \ + "llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?,llvm_slot_19(-)?" test_globals '14 15 16 17 18' \ - "+llvm_slot_17 llvm_slot_15 llvm_slot_16 llvm_slot_18" \ + "+llvm_slot_18 llvm_slot_15 llvm_slot_16 llvm_slot_17" \ "^^ ( llvm_slot_15 llvm_slot_16 llvm_slot_17 llvm_slot_18 )" \ "llvm_slot_15(-)?,llvm_slot_16(-)?,llvm_slot_17(-)?,llvm_slot_18(-)?" +# older than stable test_globals '14 15 16' \ "+llvm_slot_16 llvm_slot_15" \ "^^ ( llvm_slot_15 llvm_slot_16 )" \ "llvm_slot_15(-)?,llvm_slot_16(-)?" -test_globals '15 18' \ - "+llvm_slot_15 llvm_slot_18" \ - "^^ ( llvm_slot_15 llvm_slot_18 )" \ - "llvm_slot_15(-)?,llvm_slot_18(-)?" -test_globals '18' \ - "+llvm_slot_18" \ - "^^ ( llvm_slot_18 )" \ - "llvm_slot_18(-)?" +# old + newer than current stable +test_globals '15 19' \ + "+llvm_slot_15 llvm_slot_19" \ + "^^ ( llvm_slot_15 llvm_slot_19 )" \ + "llvm_slot_15(-)?,llvm_slot_19(-)?" +# newer than current stable +test_globals '19' \ + "+llvm_slot_19" \ + "^^ ( llvm_slot_19 )" \ + "llvm_slot_19(-)?" LLVM_COMPAT=( {14..18} ) inherit llvm-r1 diff --git a/eclass/tests/tests-common.sh b/eclass/tests/tests-common.sh index 45b1e20b933a..f4e18f38fee9 100644 --- a/eclass/tests/tests-common.sh +++ b/eclass/tests/tests-common.sh @@ -55,6 +55,8 @@ has() { } use() { has "$1" ${IUSE} ; } +in_iuse() { use "$@" ; } + die() { echo "die: $*" 1>&2 exit 1 diff --git a/eclass/tests/toolchain-funcs.sh b/eclass/tests/toolchain-funcs.sh index ee10ddf50c1e..0d6745862148 100755 --- a/eclass/tests/toolchain-funcs.sh +++ b/eclass/tests/toolchain-funcs.sh @@ -210,6 +210,36 @@ if type -P gcc &>/dev/null; then tbegin "tc-get-c-rtlib (gcc)" [[ $(CC=gcc tc-get-c-rtlib) == libgcc ]] tend $? + + tbegin "tc-is-lto (gcc, -fno-lto)" + CC=gcc CFLAGS=-fno-lto tc-is-lto + [[ $? -eq 1 ]] + tend $? + + tbegin "tc-is-lto (gcc, -flto)" + CC=gcc CFLAGS=-flto tc-is-lto + [[ $? -eq 0 ]] + tend $? + + case $(gcc -dumpmachine) in + i*86*-gnu*|arm*-gnu*|powerpc-*-gnu) + tbegin "tc-has-64bit-time_t (_TIME_BITS=32)" + CC=gcc CFLAGS="-U_TIME_BITS -D_TIME_BITS=32" tc-has-64bit-time_t + [[ $? -eq 1 ]] + tend $? + + tbegin "tc-has-64bit-time_t (_TIME_BITS=64)" + CC=gcc CFLAGS="-U_FILE_OFFSET_BITS -U_TIME_BITS -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64" tc-has-64bit-time_t + [[ $? -eq 0 ]] + tend $? + ;; + *) + tbegin "tc-has-64bit-time_t" + CC=gcc tc-has-64bit-time_t + [[ $? -eq 0 ]] + tend $? + ;; + esac fi if type -P clang &>/dev/null; then @@ -232,6 +262,16 @@ if type -P clang &>/dev/null; then [[ $(CC=clang CFLAGS="--rtlib=${rtlib}" tc-get-c-rtlib) == ${rtlib} ]] tend $? done + + tbegin "tc-is-lto (clang, -fno-lto)" + CC=clang CFLAGS=-fno-lto tc-is-lto + [[ $? -eq 1 ]] + tend $? + + tbegin "tc-is-lto (clang, -flto)" + CC=clang CFLAGS=-flto tc-is-lto + [[ $? -eq 0 ]] + tend $? fi texit diff --git a/eclass/tests/version-funcs.sh b/eclass/tests/version-funcs.sh index 6e83c01666f0..cb2a92342c65 100644..100755 --- a/eclass/tests/version-funcs.sh +++ b/eclass/tests/version-funcs.sh @@ -300,3 +300,177 @@ ver_test() { _ver_compare "${va}" "${vb}" test $? "${op}" 2 } + +# Return if we are being sourced +return 2>/dev/null + + +source tests-common.sh || exit + +teq() { + local expected=${1}; shift + + tbegin "${*} -> ${expected}" + local got=$("${@}") + [[ ${got} == ${expected} ]] + tend ${?} "returned: ${got}" +} + +teqr() { + local expected=$1; shift + tbegin "$* -> ${expected}" + "$@" + local ret=$? + [[ ${ret} -eq ${expected} ]] + tend $? "returned: ${ret}" +} + +txf() { + tbegin "XFAIL: ${*}" + local got=$("${@}" 2>&1) + [[ ${got} == die:* ]] + tend ${?} "function did not die" +} + +teq 1 ver_cut 1 1.2.3 +teq 1 ver_cut 1-1 1.2.3 +teq 1.2 ver_cut 1-2 1.2.3 +teq 2.3 ver_cut 2- 1.2.3 +teq 1.2.3 ver_cut 1- 1.2.3 +teq 3b ver_cut 3-4 1.2.3b_alpha4 +teq alpha ver_cut 5 1.2.3b_alpha4 +teq 1.2 ver_cut 1-2 .1.2.3 +teq .1.2 ver_cut 0-2 .1.2.3 +teq 2.3 ver_cut 2-3 1.2.3. +teq 2.3. ver_cut 2- 1.2.3. +teq 2.3. ver_cut 2-4 1.2.3. + +teq 1-2.3 ver_rs 1 - 1.2.3 +teq 1.2-3 ver_rs 2 - 1.2.3 +teq 1-2-3.4 ver_rs 1-2 - 1.2.3.4 +teq 1.2-3-4 ver_rs 2- - 1.2.3.4 +teq 1.2.3 ver_rs 2 . 1.2-3 +teq 1.2.3.a ver_rs 3 . 1.2.3a +teq 1.2-alpha-4 ver_rs 2-3 - 1.2_alpha4 +teq 1.23-b_alpha4 ver_rs 3 - 2 "" 1.2.3b_alpha4 +teq a1b_2-c-3-d4e5 ver_rs 3-5 _ 4-6 - a1b2c3d4e5 +teq .1-2.3 ver_rs 1 - .1.2.3 +teq -1.2.3 ver_rs 0 - .1.2.3 + +# truncating range +teq 1.2 ver_cut 0-2 1.2.3 +teq 2.3 ver_cut 2-5 1.2.3 +teq "" ver_cut 4 1.2.3 +teq "" ver_cut 0 1.2.3 +teq "" ver_cut 4- 1.2.3 +teq 1.2.3 ver_rs 0 - 1.2.3 +teq 1.2.3 ver_rs 3 . 1.2.3 +teq 1.2.3 ver_rs 3- . 1.2.3 +teq 1.2.3 ver_rs 3-5 . 1.2.3 + +txf ver_cut foo 1.2.3 +txf ver_rs -3 _ a1b2c3d4e5 +txf ver_rs 5-3 _ a1b2c3d4e5 + +# Tests from Portage's test_vercmp.py +teqr 0 ver_test 6.0 -gt 5.0 +teqr 0 ver_test 5.0 -gt 5 +teqr 0 ver_test 1.0-r1 -gt 1.0-r0 +teqr 0 ver_test 999999999999999999 -gt 999999999999999998 # 18 digits +teqr 0 ver_test 1.0.0 -gt 1.0 +teqr 0 ver_test 1.0.0 -gt 1.0b +teqr 0 ver_test 1b -gt 1 +teqr 0 ver_test 1b_p1 -gt 1_p1 +teqr 0 ver_test 1.1b -gt 1.1 +teqr 0 ver_test 12.2.5 -gt 12.2b +teqr 0 ver_test 4.0 -lt 5.0 +teqr 0 ver_test 5 -lt 5.0 +teqr 0 ver_test 1.0_pre2 -lt 1.0_p2 +teqr 0 ver_test 1.0_alpha2 -lt 1.0_p2 +teqr 0 ver_test 1.0_alpha1 -lt 1.0_beta1 +teqr 0 ver_test 1.0_beta3 -lt 1.0_rc3 +teqr 0 ver_test 1.001000000000000001 -lt 1.001000000000000002 +teqr 0 ver_test 1.00100000000 -lt 1.001000000000000001 +teqr 0 ver_test 999999999999999998 -lt 999999999999999999 +teqr 0 ver_test 1.01 -lt 1.1 +teqr 0 ver_test 1.0-r0 -lt 1.0-r1 +teqr 0 ver_test 1.0 -lt 1.0-r1 +teqr 0 ver_test 1.0 -lt 1.0.0 +teqr 0 ver_test 1.0b -lt 1.0.0 +teqr 0 ver_test 1_p1 -lt 1b_p1 +teqr 0 ver_test 1 -lt 1b +teqr 0 ver_test 1.1 -lt 1.1b +teqr 0 ver_test 12.2b -lt 12.2.5 +teqr 0 ver_test 4.0 -eq 4.0 +teqr 0 ver_test 1.0 -eq 1.0 +teqr 0 ver_test 1.0-r0 -eq 1.0 +teqr 0 ver_test 1.0 -eq 1.0-r0 +teqr 0 ver_test 1.0-r0 -eq 1.0-r0 +teqr 0 ver_test 1.0-r1 -eq 1.0-r1 +teqr 1 ver_test 1 -eq 2 +teqr 1 ver_test 1.0_alpha -eq 1.0_pre +teqr 1 ver_test 1.0_beta -eq 1.0_alpha +teqr 1 ver_test 1 -eq 0.0 +teqr 1 ver_test 1.0-r0 -eq 1.0-r1 +teqr 1 ver_test 1.0-r1 -eq 1.0-r0 +teqr 1 ver_test 1.0 -eq 1.0-r1 +teqr 1 ver_test 1.0-r1 -eq 1.0 +teqr 1 ver_test 1.0 -eq 1.0.0 +teqr 1 ver_test 1_p1 -eq 1b_p1 +teqr 1 ver_test 1b -eq 1 +teqr 1 ver_test 1.1b -eq 1.1 +teqr 1 ver_test 12.2b -eq 12.2 + +# A subset of tests from Paludis +teqr 0 ver_test 1.0_alpha -gt 1_alpha +teqr 0 ver_test 1.0_alpha -gt 1 +teqr 0 ver_test 1.0_alpha -lt 1.0 +teqr 0 ver_test 1.2.0.0_alpha7-r4 -gt 1.2_alpha7-r4 +teqr 0 ver_test 0001 -eq 1 +teqr 0 ver_test 01 -eq 001 +teqr 0 ver_test 0001.1 -eq 1.1 +teqr 0 ver_test 01.01 -eq 1.01 +teqr 0 ver_test 1.010 -eq 1.01 +teqr 0 ver_test 1.00 -eq 1.0 +teqr 0 ver_test 1.0100 -eq 1.010 +teqr 0 ver_test 1-r00 -eq 1-r0 + +# Additional tests +teqr 0 ver_test 0_rc99 -lt 0 +teqr 0 ver_test 011 -eq 11 +teqr 0 ver_test 019 -eq 19 +teqr 0 ver_test 1.2 -eq 001.2 +teqr 0 ver_test 1.2 -gt 1.02 +teqr 0 ver_test 1.2a -lt 1.2b +teqr 0 ver_test 1.2_pre1 -gt 1.2_pre1_beta2 +teqr 0 ver_test 1.2_pre1 -lt 1.2_pre1_p2 +teqr 0 ver_test 1.00 -lt 1.0.0 +teqr 0 ver_test 1.010 -eq 1.01 +teqr 0 ver_test 1.01 -lt 1.1 +teqr 0 ver_test 1.2_pre08-r09 -eq 1.2_pre8-r9 +teqr 0 ver_test 0 -lt 576460752303423488 # 2**59 +teqr 0 ver_test 0 -lt 9223372036854775808 # 2**63 + +# Bad number or ordering of arguments +txf ver_test 1 +txf ver_test 1 -lt 2 3 +txf ver_test -lt 1 2 + +# Bad operators +txf ver_test 1 "<" 2 +txf ver_test 1 lt 2 +txf ver_test 1 -foo 2 + +# Malformed versions +txf ver_test "" -ne 1 +txf ver_test 1. -ne 1 +txf ver_test 1ab -ne 1 +txf ver_test b -ne 1 +txf ver_test 1-r1_pre -ne 1 +txf ver_test 1-pre1 -ne 1 +txf ver_test 1_foo -ne 1 +txf ver_test 1_pre1.1 -ne 1 +txf ver_test 1-r1.0 -ne 1 +txf ver_test cvs.9999 -ne 9999 + +texit diff --git a/eclass/texlive-common.eclass b/eclass/texlive-common.eclass index 072581dde78e..36b90a327fde 100644 --- a/eclass/texlive-common.eclass +++ b/eclass/texlive-common.eclass @@ -42,6 +42,13 @@ _TEXLIVE_COMMON_ECLASS=1 # @CODE : "${CTAN_MIRROR_URL:="https://mirrors.ctan.org"}" +# @ECLASS_VARIABLE: TEXLIVE_SCRIPTS_W_FILE_EXT +# @DEFAULT_UNSET +# @DESCRIPTION: +# If set, contains a space separated list of script names that should be +# linked including their file extensions, i.e., without stripping +# potentially existing filename extensions from the link's name. + # @FUNCTION: texlive-common_handle_config_files # @DESCRIPTION: # Has to be called in src_install after having installed the files in ${D} @@ -160,8 +167,17 @@ etexlinks() { # Called by app-text/epspdf and texlive-module.eclass. dobin_texmf_scripts() { while [[ ${#} -gt 0 ]] ; do - local trg - trg=$(basename "${1}" | sed 's,\.[^/]*$,,' | tr '[:upper:]' '[:lower:]') + # -l: TexLive target links are always lowercase. + local -l trg + + # Get the basename of the script. + trg="${1##*/}" + + # Only strip the filename extensions if trg is not listed in TEXLIVE_SCRIPTS_W_FILE_EXT. + if ! has "${trg}" ${TEXLIVE_SCRIPTS_W_FILE_EXT}; then + trg="${trg%.*}" + fi + einfo "Installing ${1} as ${trg} bin wrapper" [[ -x ${ED}/usr/share/${1} ]] || die "Trying to install a non existing or non executable symlink to /usr/bin: ${1}" dosym "../share/${1}" "/usr/bin/${trg}" diff --git a/eclass/toolchain-funcs.eclass b/eclass/toolchain-funcs.eclass index cde84e6f34c8..9f0953c079e3 100644 --- a/eclass/toolchain-funcs.eclass +++ b/eclass/toolchain-funcs.eclass @@ -1,4 +1,4 @@ -# Copyright 2002-2023 Gentoo Authors +# Copyright 2002-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: toolchain-funcs.eclass @@ -1234,6 +1234,7 @@ tc-get-build-ptr-size() { # @RETURN: Shell true if we are using LTO, shell false otherwise tc-is-lto() { local f="${T}/test-lto.o" + local ret=1 case $(tc-get-compiler-type) in clang) @@ -1241,14 +1242,25 @@ tc-is-lto() { # If LTO is used, clang will output bytecode and llvm-bcanalyzer # will run successfully. Otherwise, it will output plain object # file and llvm-bcanalyzer will exit with error. - llvm-bcanalyzer "${f}" &>/dev/null && return 0 + llvm-bcanalyzer "${f}" &>/dev/null && ret=0 ;; gcc) $(tc-getCC) ${CFLAGS} -c -o "${f}" -x c - <<<"" || die - [[ $($(tc-getREADELF) -S "${f}") == *.gnu.lto* ]] && return 0 + [[ $($(tc-getREADELF) -S "${f}") == *.gnu.lto* ]] && ret=0 ;; esac - return 1 + rm -f "${f}" || die + return "${ret}" +} + +# @FUNCTION: tc-has-64bit-time_t +# @RETURN: Shell true if time_t is at least 64 bits long, false otherwise +tc-has-64bit-time_t() { + $(tc-getCC) ${CFLAGS} ${CPPFLAGS} -c -x c - -o /dev/null <<-EOF &>/dev/null + #include <sys/types.h> + int test[sizeof(time_t) >= 8 ? 1 : -1]; + EOF + return $? } fi diff --git a/eclass/toolchain.eclass b/eclass/toolchain.eclass index c7c366a37ad0..e81116973c67 100644 --- a/eclass/toolchain.eclass +++ b/eclass/toolchain.eclass @@ -1214,7 +1214,14 @@ toolchain_src_configure() { # - https://git.musl-libc.org/cgit/musl/tree/INSTALL # - bug #704784 # - https://gcc.gnu.org/PR93157 - [[ ${CTARGET} == powerpc64-*-musl ]] && confgcc+=( --with-abi=elfv2 ) + # musl additionally does not support libquadmath. See: + # - https://gcc.gnu.org/PR116007 + [[ ${CTARGET} == powerpc64-*-musl ]] && confgcc+=( + --with-abi=elfv2 + --disable-libquadmath + --disable-libquadmath-support + --with-long-double-128=no + ) if in_iuse ieee-long-double; then # musl requires 64-bit long double, not IBM double-double or IEEE quad. @@ -1654,9 +1661,6 @@ gcc_do_filter_flags() { # New in GCC 14. filter-flags -Walloc-size - else - # Makes things painfully slow and no real benefit for the compiler. - append-flags $(test-flags-CC -fno-harden-control-flow-redundancy) fi # Please use USE=lto instead (bug #906007). @@ -1894,7 +1898,6 @@ gcc_do_make() { #---->> src_test <<---- # TODO: add JIT testing -# TODO: add multilib testing toolchain_src_test() { # GCC's testsuite is a special case. # @@ -1919,11 +1922,53 @@ toolchain_src_test() { # Controls running expensive tests in e.g. the torture testsuite. local -x GCC_TEST_RUN_EXPENSIVE=1 - # nonfatal here as we die if the comparison below fails. Also, note that - # the exit code of targets other than 'check' may be unreliable. - nonfatal emake -C "${WORKDIR}"/build -k "${GCC_TESTS_CHECK_TARGET}" RUNTESTFLAGS="${GCC_TESTS_RUNTESTFLAGS}" + # Use a subshell to allow meddling with flags just for the testsuite + ( + # Workaround our -Wformat-security default which breaks + # various tests as it adds unexpected warning output. + append-flags -Wno-format-security -Wno-format + # Workaround our -Wtrampolines default which breaks + # tests too. + append-flags -Wno-trampolines + + # Issues with Ada tests: + # gnat.dg/align_max.adb + # gnat.dg/trampoline4.adb + # + # A handful of Ada tests use -fstack-check and conflict + # with -fstack-clash-protection. + # + # TODO: This isn't ideal given it obv. affects codegen + # and we want to be sure it works. + append-flags -fno-stack-clash-protection + # A handful of Ada (and objc++?) tests need an executable stack + append-ldflags -Wl,--no-warn-execstack + + # Go doesn't support this and causes noisy warnings + filter-flags -Wbuiltin-declaration-mismatch + + local suppress_warn="/-Wno-format/-Wno-format-security/-Wno-trampolines" + GCC_TESTS_RUNTESTFLAGS+=" --target_board=unix\{${suppress_warn}" + # TODO: Does this handle s390 (-m31) correctly? + is_multilib && GCC_TESTS_RUNTESTFLAGS+=",-m32/${suppress_warn}" + GCC_TESTS_RUNTESTFLAGS+="\}" + + # nonfatal here as we die if the comparison below fails. Also, note that + # the exit code of targets other than 'check' may be unreliable. + nonfatal emake -C "${WORKDIR}"/build -k "${GCC_TESTS_CHECK_TARGET}" \ + RUNTESTFLAGS="${GCC_TESTS_RUNTESTFLAGS}" \ + CFLAGS_FOR_TARGET="${CFLAGS_FOR_TARGET:-${CFLAGS}}" \ + CXXFLAGS_FOR_TARGET="${CXXFLAGS_FOR_TARGET:-${CXXFLAGS}}" \ + LDFLAGS_FOR_TARGET="${LDFLAGS_FOR_TARGET:-${LDFLAGS}}" \ + CFLAGS="${CFLAGS}" \ + CXXFLAGS="${CXXFLAGS}" \ + FCFLAGS="${FCFLAGS}" \ + FFLAGS="${FFLAGS}" \ + LDFLAGS="${LDFLAGS}" + ) # Produce an updated failure manifest. + # XXX: Manifests aren't ideal w/ multilib because of https://gcc.gnu.org/PR116260 einfo "Generating a new failure manifest ${T}/${CHOST}.xfail" rm -f "${T}"/${CHOST}.xfail edo "${T}"/validate_failures.py \ |