# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # @ECLASS: linux-info.eclass # @MAINTAINER: # kernel@gentoo.org # @AUTHOR: # Original author: John Mylchreest # @SUPPORTED_EAPIS: 6 7 8 # @BLURB: eclass used for accessing kernel related information # @DESCRIPTION: # This eclass is used as a central eclass for accessing kernel # related information for source or binary already installed. # It is vital for linux-mod.eclass to function correctly, and is split # out so that any ebuild behaviour "templates" are abstracted out # using additional eclasses. # # "kernel config" in this file means: # The .config of the currently installed sources is used as the first # preference, with a fall-back to bundled config (/proc/config.gz) if available. # # Before using any of the config-handling functions in this eclass, you must # ensure that one of the following functions has been called (in order of # preference), otherwise you will get bugs like #364041): # linux-info_pkg_setup # linux-info_get_any_version # get_version # get_running_version case ${EAPI} in 6|7|8) ;; *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;; esac if [[ -z ${_LINUX_INFO_ECLASS} ]]; then _LINUX_INFO_ECLASS=1 # A Couple of env vars are available to effect usage of this eclass # These are as follows: # @ECLASS_VARIABLE: CHECKCONFIG_DONOTHING # @USER_VARIABLE # @DEFAULT_UNSET # @DESCRIPTION: # Do not error out in check_extra_config if CONFIG settings are not met. # This is a user flag and should under _no circumstances_ be set in the ebuild. : "${CHECKCONFIG_DONOTHING:=""}" # @ECLASS_VARIABLE: KERNEL_DIR # @DESCRIPTION: # A string containing the directory of the target kernel sources. The default value is # "/usr/src/linux" KERNEL_DIR="${KERNEL_DIR:-${ROOT%/}/usr/src/linux}" # @ECLASS_VARIABLE: CONFIG_CHECK # @DEFAULT_UNSET # @DESCRIPTION: # A string containing a list of .config options to check for before # proceeding with the install. # # e.g.: CONFIG_CHECK="MTRR" # # You can also check that an option doesn't exist by # prepending it with an exclamation mark (!). # # e.g.: CONFIG_CHECK="!MTRR" # # To simply warn about a missing option, prepend a '~'. # It may be combined with '!'. # # In general, most checks should be non-fatal. The only time fatal checks should # be used is for building kernel modules or cases that a compile will fail # without the option. # # This is to allow usage of binary kernels, and minimal systems without kernel # sources. # @ECLASS_VARIABLE: ERROR_ # @DEFAULT_UNSET # @DESCRIPTION: # A string containing the error message to display when the check against CONFIG_CHECK # fails. should reference the appropriate option used in CONFIG_CHECK. # # e.g.: ERROR_MTRR="MTRR exists in the .config but shouldn't!!" # # CONFIG_CHECK="CFG" with ERROR_="Error Message" will die # CONFIG_CHECK="~CFG" with ERROR_="Error Message" calls eerror without dying # CONFIG_CHECK="~CFG" with WARNING_="Warning Message" calls ewarn without dying # @ECLASS_VARIABLE: KBUILD_OUTPUT # @DEFAULT_UNSET # @DESCRIPTION: # A string passed on commandline, or set from the kernel makefile. It contains the directory # which is to be used as the kernel object directory. # There are also a couple of variables which are set by this, and shouldn't be # set by hand. These are as follows: # @ECLASS_VARIABLE: KERNEL_MAKEFILE # @INTERNAL # @DESCRIPTION: # According to upstream documentation, by default, when make looks for the makefile, it tries # the following names, in order: GNUmakefile, makefile and Makefile. Set this variable to the # proper Makefile name or the eclass will search in this order for it. # See https://www.gnu.org/software/make/manual/make.html : "${KERNEL_MAKEFILE:=""}" # @ECLASS_VARIABLE: KV_FULL # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's a string containing the full kernel version. ie: 2.6.9-gentoo-johnm-r1 # @ECLASS_VARIABLE: KV_MAJOR # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's an integer containing the kernel major version. ie: 2 # @ECLASS_VARIABLE: KV_MINOR # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's an integer containing the kernel minor version. ie: 6 # @ECLASS_VARIABLE: KV_PATCH # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's an integer containing the kernel patch version. ie: 9 # @ECLASS_VARIABLE: KV_EXTRA # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's a string containing the kernel EXTRAVERSION. ie: -gentoo # @ECLASS_VARIABLE: KV_LOCAL # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's a string containing the kernel LOCALVERSION concatenation. ie: -johnm # @ECLASS_VARIABLE: KV_DIR # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's a string containing the kernel source directory, will be null if # KERNEL_DIR is invalid. # @ECLASS_VARIABLE: KV_OUT_DIR # @OUTPUT_VARIABLE # @DESCRIPTION: # A read-only variable. It's a string containing the kernel object directory, will be KV_DIR unless # KBUILD_OUTPUT is used. This should be used for referencing .config. # @ECLASS_VARIABLE: SKIP_KERNEL_CHECK # @USER_VARIABLE # @DEFAULT_UNSET # @DESCRIPTION: # Do not check for kernel sources or a running kernel version. # Main use-case is for chroots. # This is a user flag and should under _no circumstances_ be set in the ebuild. : "${SKIP_KERNEL_CHECK:=""}" # And to ensure all the weirdness with crosscompile inherit toolchain-funcs [[ ${EAPI} == 6 ]] && inherit eapi7-ver # bug #75034 case ${ARCH} in ppc) BUILD_FIXES="${BUILD_FIXES} TOUT=${T}/.tmp_gas_check";; ppc64) BUILD_FIXES="${BUILD_FIXES} TOUT=${T}/.tmp_gas_check";; esac # @FUNCTION: set_arch_to_kernel # @DESCRIPTION: # Set the env ARCH to match what the kernel expects. set_arch_to_kernel() { export ARCH=$(tc-arch-kernel); } # @FUNCTION: set_arch_to_pkgmgr # @DESCRIPTION: # Set the env ARCH to match what the package manager expects. set_arch_to_pkgmgr() { export ARCH=$(tc-arch); } # @FUNCTION: qout # @DESCRIPTION: # qout is a quiet call when EBUILD_PHASE should not have visible output. qout() { local outputmsg type type=${1} shift outputmsg="${@}" case "${EBUILD_PHASE}" in depend) unset outputmsg;; clean) unset outputmsg;; preinst) unset outputmsg;; esac [[ -n "${outputmsg}" ]] && ${type} "${outputmsg}" } # @FUNCTION: qeinfo # @DESCRIPTION: # qeinfo is a quiet einfo call when EBUILD_PHASE should not have visible output. qeinfo() { qout einfo "${@}" ; } # @FUNCTION: qewarn # @DESCRIPTION: # qewarn is a quiet ewarn call when EBUILD_PHASE should not have visible output. qewarn() { qout ewarn "${@}" ; } # @FUNCTION: qeerror # @DESCRIPTION: # qeerror is a quiet error call when EBUILD_PHASE should not have visible output. qeerror() { qout eerror "${@}" ; } # File Functions # --------------------------------------- # @FUNCTION: getfilevar # @USAGE: # @RETURN: the value of the variable # @DESCRIPTION: # It detects the value of the variable defined in the file 'configfile'. This is # done by including the 'configfile', and printing the variable with Make. # It WILL break if your makefile has missing dependencies! getfilevar() { local ERROR basefname basedname myARCH="${ARCH}" ERROR=0 [[ -z "${1}" ]] && ERROR=1 [[ ! -f "${2}" ]] && ERROR=1 if [[ "${ERROR}" = 1 ]]; then echo -e "\n" eerror "getfilevar requires 2 variables, with the second a valid file." eerror " getfilevar " else basefname="$(basename ${2})" basedname="$(dirname ${2})" unset ARCH # We use nonfatal because we want the caller to take care of things #373151 # Pass need-config= to make to avoid config check in kernel Makefile. # Pass dot-config=0 to avoid the config check in kernels prior to 5.4. echo -e "e:\\n\\t@echo \$(${1})\\ninclude ${basefname}" | \ nonfatal emake -C "${basedname}" --no-print-directory M="${T}" \ dot-config=0 need-config= need-compiler= \ ${BUILD_FIXES} -s -f - 2>/dev/null ARCH=${myARCH} fi } # @FUNCTION: getfilevar_noexec # @USAGE: # @RETURN: the value of the variable # @DESCRIPTION: # It detects the value of the variable defined in the file 'configfile'. # This is done with sed matching an expression only. If the variable is defined, # you will run into problems. See getfilevar for those cases. getfilevar_noexec() { local ERROR basefname basedname mycat myARCH="${ARCH}" ERROR=0 mycat='cat' [[ -z "${1}" ]] && ERROR=1 [[ ! -f "${2}" ]] && ERROR=1 [[ "${2%.gz}" != "${2}" ]] && mycat='zcat' if [[ "${ERROR}" = 1 ]]; then echo -e "\n" eerror "getfilevar_noexec requires 2 variables, with the second a valid file." eerror " getfilevar_noexec " else ${mycat} "${2}" | \ sed -n \ -e "/^[[:space:]]*${1}[[:space:]]*:\\?=[[:space:]]*\(.*\)\$/{ s,^[^=]*[[:space:]]*=[[:space:]]*,,g ; s,[[:space:]]*\$,,g ; p }" fi } # @ECLASS_VARIABLE: _LINUX_CONFIG_EXISTS_DONE # @INTERNAL # @DESCRIPTION: # This is only set if one of the linux_config_*exists functions has been called. # We use it for a QA warning that the check for a config has not been performed, # as linux_chkconfig* in non-legacy mode WILL return an undefined value if no # config is available at all. _LINUX_CONFIG_EXISTS_DONE= # @FUNCTION: linux_config_qa_check # @INTERNAL # @DESCRIPTION: # Helper function which returns an error before the function argument is run if no config exists linux_config_qa_check() { local f="$1" if [[ -z "${_LINUX_CONFIG_EXISTS_DONE}" ]]; then ewarn "QA: You called $f before any linux_config_exists!" ewarn "QA: The return value of $f will NOT guaranteed later!" fi if ! use kernel_linux; then die "$f called on non-Linux system, please fix the ebuild" fi } # @FUNCTION: linux_config_src_exists # @RETURN: true or false # @DESCRIPTION: # It returns true if .config exists in a build directory otherwise false linux_config_src_exists() { export _LINUX_CONFIG_EXISTS_DONE=1 use kernel_linux && [[ -n ${KV_OUT_DIR} && -s ${KV_OUT_DIR}/.config ]] } # @FUNCTION: linux_config_bin_exists # @RETURN: true or false # @DESCRIPTION: # It returns true if .config exists in /proc, otherwise false linux_config_bin_exists() { export _LINUX_CONFIG_EXISTS_DONE=1 use kernel_linux && [[ -s /proc/config.gz ]] } # @FUNCTION: linux_config_exists # @RETURN: true or false # @DESCRIPTION: # It returns true if .config exists otherwise false # # This function MUST be checked before using any of the linux_chkconfig_* # functions. linux_config_exists() { linux_config_src_exists || linux_config_bin_exists } # @FUNCTION: linux_config_path # @DESCRIPTION: # Echo the name of the config file to use. If none are found, # then return false. linux_config_path() { if linux_config_src_exists; then echo "${KV_OUT_DIR}/.config" elif linux_config_bin_exists; then echo "/proc/config.gz" else return 1 fi } # @FUNCTION: require_configured_kernel # @DESCRIPTION: # This function verifies that the current kernel is configured (it checks against the existence of .config) # otherwise it dies. require_configured_kernel() { [[ -n ${SKIP_KERNEL_CHECK} ]] && return if ! use kernel_linux; then die "${FUNCNAME}() called on non-Linux system, please fix the ebuild" fi if ! linux_config_src_exists; then qeerror "Could not find a usable .config in the kernel source directory." qeerror "Please ensure that ${KERNEL_DIR} points to a configured set of Linux sources." qeerror "If you are using KBUILD_OUTPUT, please set the environment var so that" qeerror "it points to the necessary object directory so that it might find .config." die "Kernel not configured; no .config found in ${KV_OUT_DIR}" fi get_version || die "Unable to determine configured kernel version" } # @FUNCTION: linux_chkconfig_present # @USAGE: