libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

cmake.eclass (24259B)


      1 # Copyright 1999-2023 Gentoo Authors
      2 # Distributed under the terms of the GNU General Public License v2
      3 
      4 # @ECLASS: cmake.eclass
      5 # @MAINTAINER:
      6 # kde@gentoo.org
      7 # base-system@gentoo.org
      8 # @AUTHOR:
      9 # Tomáš Chvátal <scarabeus@gentoo.org>
     10 # Maciej Mrozowski <reavertm@gentoo.org>
     11 # (undisclosed contributors)
     12 # Original author: Zephyrus (zephyrus@mirach.it)
     13 # @SUPPORTED_EAPIS: 7 8
     14 # @PROVIDES: ninja-utils
     15 # @BLURB: common ebuild functions for cmake-based packages
     16 # @DESCRIPTION:
     17 # The cmake eclass makes creating ebuilds for cmake-based packages much easier.
     18 # It provides all inherited features (DOCS, HTML_DOCS, PATCHES) along with
     19 # out-of-source builds (default) and in-source builds.
     20 
     21 case ${EAPI} in
     22 	7|8) ;;
     23 	*) die "${ECLASS}: EAPI=${EAPI:-0} is not supported" ;;
     24 esac
     25 
     26 if [[ -z ${_CMAKE_ECLASS} ]]; then
     27 _CMAKE_ECLASS=1
     28 
     29 inherit flag-o-matic multiprocessing ninja-utils toolchain-funcs xdg-utils
     30 
     31 # @ECLASS_VARIABLE: BUILD_DIR
     32 # @DEFAULT_UNSET
     33 # @DESCRIPTION:
     34 # Build directory where all cmake processed files should be generated.
     35 # For in-source build it's fixed to ${CMAKE_USE_DIR}.
     36 # For out-of-source build it can be overridden, by default it uses
     37 # ${CMAKE_USE_DIR}_build (in EAPI-7: ${WORKDIR}/${P}_build).
     38 [[ ${EAPI} == 7 ]] && : ${BUILD_DIR:=${WORKDIR}/${P}_build}
     39 # EAPI-8: set inside _cmake_check_build_dir
     40 
     41 # @ECLASS_VARIABLE: CMAKE_BINARY
     42 # @DESCRIPTION:
     43 # Eclass can use different cmake binary than the one provided in by system.
     44 : ${CMAKE_BINARY:=cmake}
     45 
     46 [[ ${EAPI} == 7 ]] && : ${CMAKE_BUILD_TYPE:=Gentoo}
     47 # @ECLASS_VARIABLE: CMAKE_BUILD_TYPE
     48 # @DESCRIPTION:
     49 # Set to override default CMAKE_BUILD_TYPE. Only useful for packages
     50 # known to make use of "if (CMAKE_BUILD_TYPE MATCHES xxx)".
     51 # If about to be set - needs to be set before invoking cmake_src_configure.
     52 #
     53 # The default is RelWithDebInfo as that is least likely to append undesirable
     54 # flags. However, you may still need to sed CMake files or choose a different
     55 # build type to achieve desirable results.
     56 #
     57 # In EAPI 7, the default was non-standard build type of Gentoo.
     58 : ${CMAKE_BUILD_TYPE:=RelWithDebInfo}
     59 
     60 # @ECLASS_VARIABLE: CMAKE_IN_SOURCE_BUILD
     61 # @DEFAULT_UNSET
     62 # @DESCRIPTION:
     63 # Set to enable in-source build.
     64 
     65 # @ECLASS_VARIABLE: CMAKE_MAKEFILE_GENERATOR
     66 # @PRE_INHERIT
     67 # @DEFAULT_UNSET
     68 # @DESCRIPTION:
     69 # Specify a makefile generator to be used by cmake.
     70 # At this point only "emake" and "ninja" are supported.
     71 # The default is set to "ninja".
     72 : ${CMAKE_MAKEFILE_GENERATOR:=ninja}
     73 
     74 # @ECLASS_VARIABLE: CMAKE_REMOVE_MODULES_LIST
     75 # @PRE_INHERIT
     76 # @DEFAULT_UNSET
     77 # @DESCRIPTION:
     78 # Array of .cmake modules to be removed in ${CMAKE_USE_DIR} (in EAPI-7: ${S})
     79 # during src_prepare, in order to force packages to use the system version.
     80 # By default, contains "FindBLAS" and "FindLAPACK".
     81 # Set to empty to disable removing modules entirely.
     82 if [[ ${CMAKE_REMOVE_MODULES_LIST} ]]; then
     83 	if [[ ${EAPI} != 7 ]]; then
     84 		[[ ${CMAKE_REMOVE_MODULES_LIST@a} == *a* ]] ||
     85 			die "CMAKE_REMOVE_MODULES_LIST must be an array"
     86 	fi
     87 else
     88 	if ! [[ ${CMAKE_REMOVE_MODULES_LIST@a} == *a* && ${#CMAKE_REMOVE_MODULES_LIST[@]} -eq 0 ]]; then
     89 		CMAKE_REMOVE_MODULES_LIST=( FindBLAS FindLAPACK )
     90 	fi
     91 fi
     92 
     93 # @ECLASS_VARIABLE: CMAKE_USE_DIR
     94 # @DESCRIPTION:
     95 # Sets the directory where we are working with cmake, for example when
     96 # application uses autotools and only one plugin needs to be done by cmake.
     97 # By default it uses current working directory (in EAPI-7: ${S}).
     98 
     99 # @ECLASS_VARIABLE: CMAKE_VERBOSE
    100 # @USER_VARIABLE
    101 # @DESCRIPTION:
    102 # Set to OFF to disable verbose messages during compilation
    103 : ${CMAKE_VERBOSE:=ON}
    104 
    105 # @ECLASS_VARIABLE: CMAKE_WARN_UNUSED_CLI
    106 # @DESCRIPTION:
    107 # Warn about variables that are declared on the command line
    108 # but not used. Might give false-positives.
    109 # "no" to disable (default) or anything else to enable.
    110 : ${CMAKE_WARN_UNUSED_CLI:=yes}
    111 
    112 # @ECLASS_VARIABLE: CMAKE_EXTRA_CACHE_FILE
    113 # @USER_VARIABLE
    114 # @DEFAULT_UNSET
    115 # @DESCRIPTION:
    116 # Specifies an extra cache file to pass to cmake. This is the analog of EXTRA_ECONF
    117 # for econf and is needed to pass TRY_RUN results when cross-compiling.
    118 # Should be set by user in a per-package basis in /etc/portage/package.env.
    119 
    120 # @ECLASS_VARIABLE: CMAKE_QA_SRC_DIR_READONLY
    121 # @USER_VARIABLE
    122 # @DEFAULT_UNSET
    123 # @DESCRIPTION:
    124 # After running cmake_src_prepare, sets ${CMAKE_USE_DIR} (in EAPI-7: ${S}) to
    125 # read-only. This is a user flag and should under _no circumstances_ be set in
    126 # the ebuild. Helps in improving QA of build systems that write to source tree.
    127 
    128 [[ ${CMAKE_MIN_VERSION} ]] && die "CMAKE_MIN_VERSION is banned; if necessary, set BDEPEND=\">=dev-util/cmake-${CMAKE_MIN_VERSION}\" directly"
    129 [[ ${CMAKE_BUILD_DIR} ]] && die "The ebuild must be migrated to BUILD_DIR"
    130 [[ ${CMAKE_REMOVE_MODULES} ]] && die "CMAKE_REMOVE_MODULES is banned, set CMAKE_REMOVE_MODULES_LIST array instead"
    131 [[ ${CMAKE_UTILS_QA_SRC_DIR_READONLY} ]] && die "Use CMAKE_QA_SRC_DIR_READONLY instead"
    132 [[ ${WANT_CMAKE} ]] && die "WANT_CMAKE has been removed and is a no-op"
    133 [[ ${PREFIX} ]] && die "PREFIX has been removed and is a no-op"
    134 
    135 case ${CMAKE_MAKEFILE_GENERATOR} in
    136 	emake)
    137 		BDEPEND="sys-devel/make"
    138 		;;
    139 	ninja)
    140 		BDEPEND="${NINJA_DEPEND}"
    141 		;;
    142 	*)
    143 		eerror "Unknown value for \${CMAKE_MAKEFILE_GENERATOR}"
    144 		die "Value ${CMAKE_MAKEFILE_GENERATOR} is not supported"
    145 		;;
    146 esac
    147 
    148 if [[ ${PN} != cmake ]]; then
    149 	BDEPEND+=" >=dev-util/cmake-3.20.5"
    150 fi
    151 
    152 # @FUNCTION: cmake_run_in
    153 # @USAGE: <working dir> <run command>
    154 # @DESCRIPTION:
    155 # Set the desired working dir for a function or command.
    156 cmake_run_in() {
    157 	if [[ -z ${2} ]]; then
    158 		die "${FUNCNAME[0]} must be passed at least two arguments"
    159 	fi
    160 
    161 	[[ -e ${1} ]] || die "${FUNCNAME[0]}: Nonexistent path: ${1}"
    162 
    163 	pushd ${1} > /dev/null || die
    164 		"${@:2}"
    165 	popd > /dev/null || die
    166 }
    167 
    168 # @FUNCTION: cmake_comment_add_subdirectory
    169 # @USAGE: <subdirectory>
    170 # @DESCRIPTION:
    171 # Comment out one or more add_subdirectory calls in CMakeLists.txt in the current directory
    172 cmake_comment_add_subdirectory() {
    173 	if [[ -z ${1} ]]; then
    174 		die "${FUNCNAME[0]} must be passed at least one directory name to comment"
    175 	fi
    176 
    177 	[[ -e "CMakeLists.txt" ]] || return
    178 
    179 	local d
    180 	for d in $@; do
    181 		d=${d//\//\\/}
    182 		sed -e "/add_subdirectory[[:space:]]*([[:space:]]*${d}[[:space:]]*)/I s/^/#DONOTCOMPILE /" \
    183 			-i CMakeLists.txt || die "failed to comment add_subdirectory(${d})"
    184 	done
    185 }
    186 
    187 # @FUNCTION: comment_add_subdirectory
    188 # @INTERNAL
    189 # @DESCRIPTION:
    190 # Banned. Use cmake_comment_add_subdirectory instead.
    191 comment_add_subdirectory() {
    192 	die "comment_add_subdirectory is banned. Use cmake_comment_add_subdirectory instead"
    193 }
    194 
    195 # @FUNCTION: cmake_use_find_package
    196 # @USAGE: <USE flag> <package name>
    197 # @DESCRIPTION:
    198 # Based on use_enable. See ebuild(5).
    199 #
    200 # `cmake_use_find_package foo LibFoo` echoes -DCMAKE_DISABLE_FIND_PACKAGE_LibFoo=OFF
    201 # if foo is enabled and -DCMAKE_DISABLE_FIND_PACKAGE_LibFoo=ON if it is disabled.
    202 # This can be used to make find_package optional.
    203 cmake_use_find_package() {
    204 	debug-print-function ${FUNCNAME} "$@"
    205 
    206 	if [[ "$#" != 2 || -z $1 ]] ; then
    207 		die "Usage: cmake_use_find_package <USE flag> <package name>"
    208 	fi
    209 
    210 	echo "-DCMAKE_DISABLE_FIND_PACKAGE_$2=$(use $1 && echo OFF || echo ON)"
    211 }
    212 
    213 # @FUNCTION: _cmake_banned_func
    214 # @INTERNAL
    215 # @DESCRIPTION:
    216 # Banned functions are banned.
    217 _cmake_banned_func() {
    218 	die "${FUNCNAME[1]} is banned. use -D$1<related_CMake_variable>=\"\$(usex $2)\" instead"
    219 }
    220 
    221 # @FUNCTION: cmake-utils_use_with
    222 # @INTERNAL
    223 # @DESCRIPTION:
    224 # Banned. Use -DWITH_FOO=$(usex foo) instead.
    225 cmake-utils_use_with() { _cmake_banned_func WITH_ "$@" ; }
    226 
    227 # @FUNCTION: cmake-utils_use_enable
    228 # @INTERNAL
    229 # @DESCRIPTION:
    230 # Banned. Use -DENABLE_FOO=$(usex foo) instead.
    231 cmake-utils_use_enable() { _cmake_banned_func ENABLE_ "$@" ; }
    232 
    233 # @FUNCTION: cmake-utils_use_disable
    234 # @INTERNAL
    235 # @DESCRIPTION:
    236 # Banned. Use -DDISABLE_FOO=$(usex !foo) instead.
    237 cmake-utils_use_disable() { _cmake_banned_func DISABLE_ "$@" ; }
    238 
    239 # @FUNCTION: cmake-utils_use_no
    240 # @INTERNAL
    241 # @DESCRIPTION:
    242 # Banned. Use -DNO_FOO=$(usex !foo) instead.
    243 cmake-utils_use_no() { _cmake_banned_func NO_ "$@" ; }
    244 
    245 # @FUNCTION: cmake-utils_use_want
    246 # @INTERNAL
    247 # @DESCRIPTION:
    248 # Banned. Use -DWANT_FOO=$(usex foo) instead.
    249 cmake-utils_use_want() { _cmake_banned_func WANT_ "$@" ; }
    250 
    251 # @FUNCTION: cmake-utils_use_build
    252 # @INTERNAL
    253 # @DESCRIPTION:
    254 # Banned. Use -DBUILD_FOO=$(usex foo) instead.
    255 cmake-utils_use_build() { _cmake_banned_func BUILD_ "$@" ; }
    256 
    257 # @FUNCTION: cmake-utils_use_has
    258 # @INTERNAL
    259 # @DESCRIPTION:
    260 # Banned. Use -DHAVE_FOO=$(usex foo) instead.
    261 cmake-utils_use_has() { _cmake_banned_func HAVE_ "$@" ; }
    262 
    263 # @FUNCTION: cmake-utils_use_use
    264 # @INTERNAL
    265 # @DESCRIPTION:
    266 # Banned. Use -DUSE_FOO=$(usex foo) instead.
    267 cmake-utils_use_use() { _cmake_banned_func USE_ "$@" ; }
    268 
    269 # @FUNCTION: cmake-utils_use
    270 # @INTERNAL
    271 # @DESCRIPTION:
    272 # Banned. Use -DFOO=$(usex foo) instead.
    273 cmake-utils_use() { _cmake_banned_func "" "$@" ; }
    274 
    275 # @FUNCTION: cmake-utils_useno
    276 # @INTERNAL
    277 # @DESCRIPTION:
    278 # Banned. Use -DNOFOO=$(usex !foo) instead.
    279 cmake-utils_useno() { _cmake_banned_func "" "$@" ; }
    280 
    281 # @FUNCTION: _cmake_check_build_dir
    282 # @INTERNAL
    283 # @DESCRIPTION:
    284 # Determine using IN or OUT source build
    285 _cmake_check_build_dir() {
    286 	if [[ ${EAPI} == 7 ]]; then
    287 		: ${CMAKE_USE_DIR:=${S}}
    288 	else
    289 		: ${CMAKE_USE_DIR:=${PWD}}
    290 	fi
    291 	if [[ -n ${CMAKE_IN_SOURCE_BUILD} ]]; then
    292 		# we build in source dir
    293 		BUILD_DIR="${CMAKE_USE_DIR}"
    294 	else
    295 		: ${BUILD_DIR:=${CMAKE_USE_DIR}_build}
    296 	fi
    297 
    298 	einfo "Source directory (CMAKE_USE_DIR): \"${CMAKE_USE_DIR}\""
    299 	einfo "Build directory  (BUILD_DIR):     \"${BUILD_DIR}\""
    300 
    301 	mkdir -p "${BUILD_DIR}" || die
    302 }
    303 
    304 # @FUNCTION: _cmake_modify-cmakelists
    305 # @INTERNAL
    306 # @DESCRIPTION:
    307 # Internal function for modifying hardcoded definitions.
    308 # Removes dangerous definitions that override Gentoo settings.
    309 _cmake_modify-cmakelists() {
    310 	debug-print-function ${FUNCNAME} "$@"
    311 
    312 	# Only edit the files once
    313 	grep -qs "<<< Gentoo configuration >>>" "${CMAKE_USE_DIR}"/CMakeLists.txt && return 0
    314 
    315 	# Comment out all set (<some_should_be_user_defined_variable> value)
    316 	find "${CMAKE_USE_DIR}" -name CMakeLists.txt -exec sed \
    317 		-e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_BUILD_TYPE\([[:space:]].*)\|)\)/I{s/^/#_cmake_modify_IGNORE /g}' \
    318 		-e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_COLOR_MAKEFILE[[:space:]].*)/I{s/^/#_cmake_modify_IGNORE /g}' \
    319 		-e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_INSTALL_PREFIX[[:space:]].*)/I{s/^/#_cmake_modify_IGNORE /g}' \
    320 		-e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_VERBOSE_MAKEFILE[[:space:]].*)/I{s/^/#_cmake_modify_IGNORE /g}' \
    321 		-i {} + || die "${LINENO}: failed to disable hardcoded settings"
    322 	local x
    323 	for x in $(find "${CMAKE_USE_DIR}" -name CMakeLists.txt -exec grep -l "^#_cmake_modify_IGNORE" {} +;); do
    324 		einfo "Hardcoded definition(s) removed in $(echo "${x}" | cut -c $((${#CMAKE_USE_DIR}+2))-):"
    325 		einfo "$(grep -se '^#_cmake_modify_IGNORE' ${x} | cut -c 22-99)"
    326 	done
    327 
    328 	# NOTE Append some useful summary here
    329 	cat >> "${CMAKE_USE_DIR}"/CMakeLists.txt <<- _EOF_ || die
    330 
    331 		message(STATUS "<<< Gentoo configuration >>>
    332 		Build type      \${CMAKE_BUILD_TYPE}
    333 		Install path    \${CMAKE_INSTALL_PREFIX}
    334 		Compiler flags:
    335 		C               \${CMAKE_C_FLAGS}
    336 		C++             \${CMAKE_CXX_FLAGS}
    337 		Linker flags:
    338 		Executable      \${CMAKE_EXE_LINKER_FLAGS}
    339 		Module          \${CMAKE_MODULE_LINKER_FLAGS}
    340 		Shared          \${CMAKE_SHARED_LINKER_FLAGS}\n")
    341 	_EOF_
    342 }
    343 
    344 # @FUNCTION: cmake_src_prepare
    345 # @DESCRIPTION:
    346 # Apply ebuild and user patches. *MUST* be run or cmake_src_configure will fail.
    347 cmake_src_prepare() {
    348 	debug-print-function ${FUNCNAME} "$@"
    349 
    350 	if [[ ${EAPI} == 7 ]]; then
    351 		pushd "${S}" > /dev/null || die # workaround from cmake-utils
    352 		# in EAPI-8, we use current working directory instead, bug #704524
    353 		# esp. test with 'special' pkgs like: app-arch/brotli, media-gfx/gmic, net-libs/quiche
    354 	fi
    355 	_cmake_check_build_dir
    356 
    357 	default_src_prepare
    358 
    359 	# check if CMakeLists.txt exists and if not then die
    360 	if [[ ! -e ${CMAKE_USE_DIR}/CMakeLists.txt ]] ; then
    361 		eerror "Unable to locate CMakeLists.txt under:"
    362 		eerror "\"${CMAKE_USE_DIR}/CMakeLists.txt\""
    363 		eerror "Consider not inheriting the cmake eclass."
    364 		die "FATAL: Unable to find CMakeLists.txt"
    365 	fi
    366 
    367 	local modules_list
    368 	if [[ ${EAPI} == 7 && $(declare -p CMAKE_REMOVE_MODULES_LIST) != "declare -a"* ]]; then
    369 		modules_list=( ${CMAKE_REMOVE_MODULES_LIST} )
    370 	else
    371 		modules_list=( "${CMAKE_REMOVE_MODULES_LIST[@]}" )
    372 	fi
    373 
    374 	local name
    375 	for name in "${modules_list[@]}" ; do
    376 		if [[ ${EAPI} == 7 ]]; then
    377 			find "${S}" -name ${name}.cmake -exec rm -v {} + || die
    378 		else
    379 			find -name "${name}.cmake" -exec rm -v {} + || die
    380 		fi
    381 	done
    382 
    383 	# Remove dangerous things.
    384 	_cmake_modify-cmakelists
    385 
    386 	if [[ ${EAPI} == 7 ]]; then
    387 		popd > /dev/null || die
    388 	fi
    389 
    390 	# Make ${CMAKE_USE_DIR} (in EAPI-7: ${S}) read-only in order to detect
    391 	# broken build systems.
    392 	if [[ ${CMAKE_QA_SRC_DIR_READONLY} && ! ${CMAKE_IN_SOURCE_BUILD} ]]; then
    393 		if [[ ${EAPI} == 7 ]]; then
    394 			chmod -R a-w "${S}"
    395 		else
    396 			chmod -R a-w "${CMAKE_USE_DIR}"
    397 		fi
    398 	fi
    399 
    400 	_CMAKE_SRC_PREPARE_HAS_RUN=1
    401 }
    402 
    403 # @VARIABLE: MYCMAKEARGS
    404 # @DEFAULT_UNSET
    405 # @DESCRIPTION:
    406 # User-controlled environment variable containing arguments to be passed to
    407 # cmake in cmake_src_configure.
    408 
    409 # @FUNCTION: cmake_src_configure
    410 # @DESCRIPTION:
    411 # General function for configuring with cmake. Default behaviour is to start an
    412 # out-of-source build.
    413 # Passes arguments to cmake by reading from an optionally pre-defined local
    414 # mycmakeargs bash array.
    415 # @CODE
    416 # src_configure() {
    417 # 	local mycmakeargs=(
    418 # 		$(cmake_use_find_package foo LibFoo)
    419 # 	)
    420 # 	cmake_src_configure
    421 # }
    422 # @CODE
    423 cmake_src_configure() {
    424 	debug-print-function ${FUNCNAME} "$@"
    425 
    426 	[[ ${_CMAKE_SRC_PREPARE_HAS_RUN} ]] || \
    427 		die "FATAL: cmake_src_prepare has not been run"
    428 
    429 	_cmake_check_build_dir
    430 
    431 	# Fix xdg collision with sandbox
    432 	xdg_environment_reset
    433 
    434 	# Prepare Gentoo override rules (set valid compiler, append CPPFLAGS etc.)
    435 	local build_rules=${BUILD_DIR}/gentoo_rules.cmake
    436 
    437 	cat > "${build_rules}" <<- _EOF_ || die
    438 		set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <DEFINES> <INCLUDES> ${CPPFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "ASM compile command" FORCE)
    439 		set(CMAKE_ASM-ATT_COMPILE_OBJECT "<CMAKE_ASM-ATT_COMPILER> <DEFINES> <INCLUDES> ${CPPFLAGS} <FLAGS> -o <OBJECT> -c -x assembler <SOURCE>" CACHE STRING "ASM-ATT compile command" FORCE)
    440 		set(CMAKE_ASM-ATT_LINK_FLAGS "-nostdlib" CACHE STRING "ASM-ATT link flags" FORCE)
    441 		set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> ${CPPFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "C compile command" FORCE)
    442 		set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> ${CPPFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "C++ compile command" FORCE)
    443 		set(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> ${FCFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "Fortran compile command" FORCE)
    444 	_EOF_
    445 
    446 	local myCC=$(tc-getCC) myCXX=$(tc-getCXX) myFC=$(tc-getFC)
    447 
    448 	# !!! IMPORTANT NOTE !!!
    449 	# Single slash below is intentional. CMake is weird and wants the
    450 	# CMAKE_*_VARIABLES split into two elements: the first one with
    451 	# compiler path, and the second one with all command-line options,
    452 	# space separated.
    453 	local toolchain_file=${BUILD_DIR}/gentoo_toolchain.cmake
    454 	cat > ${toolchain_file} <<- _EOF_ || die
    455 		set(CMAKE_ASM_COMPILER "${myCC/ /;}")
    456 		set(CMAKE_ASM-ATT_COMPILER "${myCC/ /;}")
    457 		set(CMAKE_C_COMPILER "${myCC/ /;}")
    458 		set(CMAKE_CXX_COMPILER "${myCXX/ /;}")
    459 		set(CMAKE_Fortran_COMPILER "${myFC/ /;}")
    460 		set(CMAKE_AR $(type -P $(tc-getAR)) CACHE FILEPATH "Archive manager" FORCE)
    461 		set(CMAKE_RANLIB $(type -P $(tc-getRANLIB)) CACHE FILEPATH "Archive index generator" FORCE)
    462 		set(CMAKE_SYSTEM_PROCESSOR "${CHOST%%-*}")
    463 	_EOF_
    464 
    465 	# We are using the C compiler for assembly by default.
    466 	local -x ASMFLAGS=${CFLAGS}
    467 	local -x PKG_CONFIG=$(tc-getPKG_CONFIG)
    468 
    469 	if tc-is-cross-compiler; then
    470 		local sysname
    471 		case "${KERNEL:-linux}" in
    472 			Cygwin) sysname="CYGWIN_NT-5.1" ;;
    473 			HPUX) sysname="HP-UX" ;;
    474 			linux) sysname="Linux" ;;
    475 			Winnt)
    476 				sysname="Windows"
    477 				cat >> "${toolchain_file}" <<- _EOF_ || die
    478 					set(CMAKE_RC_COMPILER $(tc-getRC))
    479 				_EOF_
    480 				;;
    481 			*) sysname="${KERNEL}" ;;
    482 		esac
    483 
    484 		cat >> "${toolchain_file}" <<- _EOF_ || die
    485 			set(CMAKE_SYSTEM_NAME "${sysname}")
    486 		_EOF_
    487 
    488 		if [ "${SYSROOT:-/}" != "/" ] ; then
    489 			# When cross-compiling with a sysroot (e.g. with crossdev's emerge wrappers)
    490 			# we need to tell cmake to use libs/headers from the sysroot but programs from / only.
    491 			cat >> "${toolchain_file}" <<- _EOF_ || die
    492 				set(CMAKE_FIND_ROOT_PATH "${SYSROOT}")
    493 				set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    494 				set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    495 				set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    496 			_EOF_
    497 		fi
    498 	fi
    499 
    500 	if use prefix-guest; then
    501 		cat >> "${build_rules}" <<- _EOF_ || die
    502 			# in Prefix we need rpath and must ensure cmake gets our default linker path
    503 			# right ... except for Darwin hosts
    504 			if(NOT APPLE)
    505 				set(CMAKE_SKIP_RPATH OFF CACHE BOOL "" FORCE)
    506 				set(CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH "${EPREFIX}/usr/${CHOST}/lib/gcc;${EPREFIX}/usr/${CHOST}/lib;${EPREFIX}/usr/$(get_libdir);${EPREFIX}/$(get_libdir)" CACHE STRING "" FORCE)
    507 			else()
    508 				set(CMAKE_PREFIX_PATH "${EPREFIX}/usr" CACHE STRING "" FORCE)
    509 				set(CMAKE_MACOSX_RPATH ON CACHE BOOL "" FORCE)
    510 				set(CMAKE_SKIP_BUILD_RPATH OFF CACHE BOOL "" FORCE)
    511 				set(CMAKE_SKIP_RPATH OFF CACHE BOOL "" FORCE)
    512 				set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE BOOL "" FORCE)
    513 			endif()
    514 		_EOF_
    515 	fi
    516 
    517 	# Common configure parameters (invariants)
    518 	local common_config=${BUILD_DIR}/gentoo_common_config.cmake
    519 	local libdir=$(get_libdir)
    520 	cat > "${common_config}" <<- _EOF_ || die
    521 		set(CMAKE_GENTOO_BUILD ON CACHE BOOL "Indicate Gentoo package build")
    522 		set(LIB_SUFFIX ${libdir/lib} CACHE STRING "library path suffix" FORCE)
    523 		set(CMAKE_INSTALL_LIBDIR ${libdir} CACHE PATH "Output directory for libraries")
    524 		set(CMAKE_INSTALL_INFODIR "${EPREFIX}/usr/share/info" CACHE PATH "")
    525 		set(CMAKE_INSTALL_MANDIR "${EPREFIX}/usr/share/man" CACHE PATH "")
    526 		set(CMAKE_USER_MAKE_RULES_OVERRIDE "${build_rules}" CACHE FILEPATH "Gentoo override rules")
    527 		set(CMAKE_INSTALL_DOCDIR "${EPREFIX}/usr/share/doc/${PF}" CACHE PATH "")
    528 		set(BUILD_SHARED_LIBS ON CACHE BOOL "")
    529 	_EOF_
    530 
    531 	if [[ -n ${_ECM_ECLASS} ]]; then
    532 		echo 'set(ECM_DISABLE_QMLPLUGINDUMP ON CACHE BOOL "")' >> "${common_config}" || die
    533 	fi
    534 
    535 	# See bug 689410
    536 	if [[ "${ARCH}" == riscv ]]; then
    537 		echo 'set(CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX '"${libdir#lib}"' CACHE STRING "library search suffix" FORCE)' >> "${common_config}" || die
    538 	fi
    539 
    540 	if [[ "${NOCOLOR}" = true || "${NOCOLOR}" = yes ]]; then
    541 		echo 'set(CMAKE_COLOR_MAKEFILE OFF CACHE BOOL "pretty colors during make" FORCE)' >> "${common_config}" || die
    542 	fi
    543 
    544 	# See bug 735820
    545 	if [[ ${EAPI} != 7 ]]; then
    546 		echo 'set(CMAKE_INSTALL_ALWAYS 1)' >> "${common_config}" || die
    547 	fi
    548 
    549 	# Wipe the default optimization flags out of CMake
    550 	if [[ ${CMAKE_BUILD_TYPE} != Gentoo ]]; then
    551 		cat >> ${common_config} <<- _EOF_ || die
    552 			set(CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    553 			set(CMAKE_ASM-ATT_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    554 			set(CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    555 			set(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    556 			set(CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    557 			set(CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    558 			set(CMAKE_MODULE_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    559 			set(CMAKE_SHARED_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    560 			set(CMAKE_STATIC_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "")
    561 		_EOF_
    562 	fi
    563 
    564 	# Make the array a local variable since <=portage-2.1.6.x does not support
    565 	# global arrays (see bug #297255). But first make sure it is initialised.
    566 	[[ -z ${mycmakeargs} ]] && declare -a mycmakeargs=()
    567 	local mycmakeargstype=$(declare -p mycmakeargs 2>&-)
    568 	if [[ "${mycmakeargstype}" != "declare -a mycmakeargs="* ]]; then
    569 		die "mycmakeargs must be declared as array"
    570 	fi
    571 
    572 	local mycmakeargs_local=( "${mycmakeargs[@]}" )
    573 
    574 	local warn_unused_cli=""
    575 	if [[ ${CMAKE_WARN_UNUSED_CLI} == no ]] ; then
    576 		warn_unused_cli="--no-warn-unused-cli"
    577 	fi
    578 
    579 	local generator_name
    580 	case ${CMAKE_MAKEFILE_GENERATOR} in
    581 		ninja) generator_name="Ninja" ;;
    582 		emake) generator_name="Unix Makefiles" ;;
    583 	esac
    584 
    585 	# Common configure parameters (overridable)
    586 	# NOTE CMAKE_BUILD_TYPE can be only overridden via CMAKE_BUILD_TYPE eclass variable
    587 	# No -DCMAKE_BUILD_TYPE=xxx definitions will be in effect.
    588 	local cmakeargs=(
    589 		${warn_unused_cli}
    590 		-C "${common_config}"
    591 		-G "${generator_name}"
    592 		-DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr"
    593 		"${mycmakeargs_local[@]}"
    594 		-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
    595 		-DCMAKE_TOOLCHAIN_FILE="${toolchain_file}"
    596 	)
    597 
    598 	if [[ -n ${MYCMAKEARGS} ]] ; then
    599 		cmakeargs+=( "${MYCMAKEARGS}" )
    600 	fi
    601 
    602 	if [[ -n "${CMAKE_EXTRA_CACHE_FILE}" ]] ; then
    603 		cmakeargs+=( -C "${CMAKE_EXTRA_CACHE_FILE}" )
    604 	fi
    605 
    606 	pushd "${BUILD_DIR}" > /dev/null || die
    607 	debug-print "${LINENO} ${ECLASS} ${FUNCNAME}: mycmakeargs is ${mycmakeargs_local[*]}"
    608 	echo "${CMAKE_BINARY}" "${cmakeargs[@]}" "${CMAKE_USE_DIR}"
    609 	"${CMAKE_BINARY}" "${cmakeargs[@]}" "${CMAKE_USE_DIR}" || die "cmake failed"
    610 	popd > /dev/null || die
    611 }
    612 
    613 # @FUNCTION: cmake_src_compile
    614 # @DESCRIPTION:
    615 # General function for compiling with cmake. All arguments are passed
    616 # to cmake_build.
    617 cmake_src_compile() {
    618 	debug-print-function ${FUNCNAME} "$@"
    619 
    620 	cmake_build "$@"
    621 }
    622 
    623 # @FUNCTION: cmake_build
    624 # @DESCRIPTION:
    625 # Function for building the package. Automatically detects the build type.
    626 # All arguments are passed to eninja (default) or emake depending on the value
    627 # of CMAKE_MAKEFILE_GENERATOR.
    628 cmake_build() {
    629 	debug-print-function ${FUNCNAME} "$@"
    630 
    631 	_cmake_check_build_dir
    632 	pushd "${BUILD_DIR}" > /dev/null || die
    633 
    634 	case ${CMAKE_MAKEFILE_GENERATOR} in
    635 		emake)
    636 			[[ -e Makefile ]] || die "Makefile not found. Error during configure stage."
    637 			case ${CMAKE_VERBOSE} in
    638 				OFF) emake "$@" ;;
    639 				*) emake VERBOSE=1 "$@" ;;
    640 			esac
    641 			;;
    642 		ninja)
    643 			[[ -e build.ninja ]] || die "build.ninja not found. Error during configure stage."
    644 			eninja "$@"
    645 			;;
    646 	esac
    647 
    648 	popd > /dev/null || die
    649 }
    650 
    651 # @FUNCTION: cmake-utils_src_make
    652 # @INTERNAL
    653 # @DESCRIPTION:
    654 # Banned. Use cmake_build instead.
    655 cmake-utils_src_make() {
    656 	die "cmake-utils_src_make is banned. Use cmake_build instead"
    657 }
    658 
    659 # @FUNCTION: cmake_src_test
    660 # @DESCRIPTION:
    661 # Function for testing the package. Automatically detects the build type.
    662 cmake_src_test() {
    663 	debug-print-function ${FUNCNAME} "$@"
    664 
    665 	_cmake_check_build_dir
    666 	pushd "${BUILD_DIR}" > /dev/null || die
    667 	[[ -e CTestTestfile.cmake ]] || { echo "No tests found. Skipping."; return 0 ; }
    668 
    669 	[[ -n ${TEST_VERBOSE} ]] && myctestargs+=( --extra-verbose --output-on-failure )
    670 
    671 	set -- ctest -j "$(makeopts_jobs "${MAKEOPTS}" 999)" \
    672 		--test-load "$(makeopts_loadavg)" "${myctestargs[@]}" "$@"
    673 	echo "$@" >&2
    674 	if "$@" ; then
    675 		einfo "Tests succeeded."
    676 		popd > /dev/null || die
    677 		return 0
    678 	else
    679 		if [[ -n "${CMAKE_YES_I_WANT_TO_SEE_THE_TEST_LOG}" ]] ; then
    680 			# on request from Diego
    681 			eerror "Tests failed. Test log ${BUILD_DIR}/Testing/Temporary/LastTest.log follows:"
    682 			eerror "--START TEST LOG--------------------------------------------------------------"
    683 			cat "${BUILD_DIR}/Testing/Temporary/LastTest.log"
    684 			eerror "--END TEST LOG----------------------------------------------------------------"
    685 			die "Tests failed."
    686 		else
    687 			die "Tests failed. When you file a bug, please attach the following file: \n\t${BUILD_DIR}/Testing/Temporary/LastTest.log"
    688 		fi
    689 
    690 		# die might not die due to nonfatal
    691 		popd > /dev/null || die
    692 		return 1
    693 	fi
    694 }
    695 
    696 # @FUNCTION: cmake_src_install
    697 # @DESCRIPTION:
    698 # Function for installing the package. Automatically detects the build type.
    699 cmake_src_install() {
    700 	debug-print-function ${FUNCNAME} "$@"
    701 
    702 	DESTDIR="${D}" cmake_build install "$@"
    703 
    704 	if [[ ${EAPI} == 7 ]]; then
    705 		pushd "${S}" > /dev/null || die
    706 		einstalldocs
    707 		popd > /dev/null || die
    708 	else
    709 		pushd "${CMAKE_USE_DIR}" > /dev/null || die
    710 		einstalldocs
    711 		popd > /dev/null || die
    712 	fi
    713 }
    714 
    715 fi
    716 
    717 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install