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