cmake-utils.eclass (28519B)
1 # Copyright 1999-2022 Gentoo Authors 2 # Distributed under the terms of the GNU General Public License v2 3 4 # @DEAD 5 # @ECLASS: cmake-utils.eclass 6 # @MAINTAINER: 7 # kde@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: 5 6 7 14 # @PROVIDES: ninja-utils 15 # @BLURB: common ebuild functions for cmake-based packages 16 # @DEPRECATED: cmake.eclass 17 # @DESCRIPTION: 18 # DEPRECATED: This no longer receives any changes. Everyone must port to cmake.eclass. 19 # The cmake-utils eclass makes creating ebuilds for cmake-based packages much easier. 20 # It provides all inherited features (DOCS, HTML_DOCS, PATCHES) along with out-of-source 21 # builds (default), in-source builds and an implementation of the well-known use_enable 22 # and use_with functions for CMake. 23 24 if [[ -z ${_CMAKE_UTILS_ECLASS} ]]; then 25 _CMAKE_UTILS_ECLASS=1 26 27 # @ECLASS_VARIABLE: BUILD_DIR 28 # @DESCRIPTION: 29 # Build directory where all cmake processed files should be generated. 30 # For in-source build it's fixed to ${CMAKE_USE_DIR}. 31 # For out-of-source build it can be overridden, by default it uses 32 # ${WORKDIR}/${P}_build. 33 # 34 # This variable has been called CMAKE_BUILD_DIR formerly. 35 # It is set under that name for compatibility. 36 37 # @ECLASS_VARIABLE: CMAKE_BINARY 38 # @DESCRIPTION: 39 # Eclass can use different cmake binary than the one provided in by system. 40 : ${CMAKE_BINARY:=cmake} 41 42 # @ECLASS_VARIABLE: CMAKE_BUILD_TYPE 43 # @DESCRIPTION: 44 # Set to override default CMAKE_BUILD_TYPE. Only useful for packages 45 # known to make use of "if (CMAKE_BUILD_TYPE MATCHES xxx)". 46 # If about to be set - needs to be set before invoking cmake-utils_src_configure. 47 # You usualy do *NOT* want nor need to set it as it pulls CMake default build-type 48 # specific compiler flags overriding make.conf. 49 : ${CMAKE_BUILD_TYPE:=Gentoo} 50 51 # @ECLASS_VARIABLE: CMAKE_IN_SOURCE_BUILD 52 # @DEFAULT_UNSET 53 # @DESCRIPTION: 54 # Set to enable in-source build. 55 56 # @ECLASS_VARIABLE: CMAKE_MAKEFILE_GENERATOR 57 # @DEFAULT_UNSET 58 # @DESCRIPTION: 59 # Specify a makefile generator to be used by cmake. 60 # At this point only "emake" and "ninja" are supported. 61 # In EAPI 7 and above, the default is set to "ninja", 62 # whereas in EAPIs below 7, it is set to "emake". 63 64 # @ECLASS_VARIABLE: CMAKE_MIN_VERSION 65 # @DESCRIPTION: 66 # Specify the minimum required CMake version. 67 : ${CMAKE_MIN_VERSION:=3.9.6} 68 69 # @ECLASS_VARIABLE: CMAKE_REMOVE_MODULES 70 # @DESCRIPTION: 71 # Do we want to remove anything? yes or whatever else for no 72 : ${CMAKE_REMOVE_MODULES:=yes} 73 74 # @ECLASS_VARIABLE: CMAKE_REMOVE_MODULES_LIST 75 # @DESCRIPTION: 76 # Space-separated list of CMake modules that will be removed in $S during src_prepare, 77 # in order to force packages to use the system version. 78 : ${CMAKE_REMOVE_MODULES_LIST:=FindBLAS FindLAPACK} 79 80 # @ECLASS_VARIABLE: CMAKE_USE_DIR 81 # @DESCRIPTION: 82 # Sets the directory where we are working with cmake. 83 # For example when application uses autotools and only one 84 # plugin needs to be done by cmake. 85 # By default it uses ${S}. 86 87 # @ECLASS_VARIABLE: CMAKE_VERBOSE 88 # @DESCRIPTION: 89 # Set to OFF to disable verbose messages during compilation 90 : ${CMAKE_VERBOSE:=ON} 91 92 # @ECLASS_VARIABLE: CMAKE_WARN_UNUSED_CLI 93 # @DESCRIPTION: 94 # Warn about variables that are declared on the command line 95 # but not used. Might give false-positives. 96 # "no" to disable (default) or anything else to enable. 97 98 # @ECLASS_VARIABLE: CMAKE_EXTRA_CACHE_FILE 99 # @USER_VARIABLE 100 # @DEFAULT_UNSET 101 # @DESCRIPTION: 102 # Specifies an extra cache file to pass to cmake. This is the analog of EXTRA_ECONF 103 # for econf and is needed to pass TRY_RUN results when cross-compiling. 104 # Should be set by user in a per-package basis in /etc/portage/package.env. 105 106 # @ECLASS_VARIABLE: CMAKE_UTILS_QA_SRC_DIR_READONLY 107 # @USER_VARIABLE 108 # @DEFAULT_UNSET 109 # @DESCRIPTION: 110 # After running cmake-utils_src_prepare, sets ${S} to read-only. This is 111 # a user flag and should under _no circumstances_ be set in the ebuild. 112 # Helps in improving QA of build systems that write to source tree. 113 114 case ${EAPI} in 115 5) : ${CMAKE_WARN_UNUSED_CLI:=no} ;; 116 6|7) : ${CMAKE_WARN_UNUSED_CLI:=yes} ;; 117 *) die "EAPI=${EAPI:-0} is not supported" ;; 118 esac 119 120 inherit toolchain-funcs ninja-utils flag-o-matic multiprocessing xdg-utils 121 122 case ${EAPI} in 123 [56]) 124 : ${CMAKE_MAKEFILE_GENERATOR:=emake} 125 inherit eutils multilib 126 ;; 127 *) 128 : ${CMAKE_MAKEFILE_GENERATOR:=ninja} 129 ;; 130 esac 131 132 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install 133 134 if [[ ${WANT_CMAKE} ]]; then 135 if [[ ${EAPI} != [56] ]]; then 136 die "\${WANT_CMAKE} has been removed and is a no-op now" 137 else 138 eqawarn "\${WANT_CMAKE} has been removed and is a no-op now" 139 fi 140 fi 141 [[ ${PREFIX} ]] && die "\${PREFIX} has been removed and is a no-op now" 142 143 case ${CMAKE_MAKEFILE_GENERATOR} in 144 emake) 145 BDEPEND="sys-devel/make" 146 ;; 147 ninja) 148 BDEPEND="dev-util/ninja" 149 ;; 150 *) 151 eerror "Unknown value for \${CMAKE_MAKEFILE_GENERATOR}" 152 die "Value ${CMAKE_MAKEFILE_GENERATOR} is not supported" 153 ;; 154 esac 155 156 if [[ ${PN} != cmake ]]; then 157 BDEPEND+=" >=dev-util/cmake-${CMAKE_MIN_VERSION}" 158 fi 159 160 case ${EAPI} in 161 7) ;; 162 *) DEPEND=" ${BDEPEND}" ;; 163 esac 164 165 # Internal functions used by cmake-utils_use_* 166 _cmake_use_me_now() { 167 debug-print-function ${FUNCNAME} "$@" 168 169 local arg=$2 170 [[ ! -z $3 ]] && arg=$3 171 172 [[ ${EAPI} == 5 ]] || die "${FUNCNAME[1]} is banned in EAPI 6 and later: use -D$1<related_CMake_variable>=\"\$(usex $2)\" instead" 173 174 local uper capitalised x 175 [[ -z $2 ]] && die "cmake-utils_use-$1 <USE flag> [<flag name>]" 176 if [[ ! -z $3 ]]; then 177 # user specified the use name so use it 178 echo "-D$1$3=$(use $2 && echo ON || echo OFF)" 179 else 180 # use all various most used combinations 181 uper=$(echo ${2} | tr '[:lower:]' '[:upper:]') 182 capitalised=$(echo ${2} | sed 's/\<\(.\)\([^ ]*\)/\u\1\L\2/g') 183 for x in $2 $uper $capitalised; do 184 echo "-D$1$x=$(use $2 && echo ON || echo OFF) " 185 done 186 fi 187 } 188 _cmake_use_me_now_inverted() { 189 debug-print-function ${FUNCNAME} "$@" 190 191 local arg=$2 192 [[ ! -z $3 ]] && arg=$3 193 194 if [[ ${EAPI} != 5 && "${FUNCNAME[1]}" != cmake-utils_use_find_package ]] ; then 195 die "${FUNCNAME[1]} is banned in EAPI 6 and later: use -D$1<related_CMake_variable>=\"\$(usex $2)\" instead" 196 fi 197 198 local uper capitalised x 199 [[ -z $2 ]] && die "cmake-utils_use-$1 <USE flag> [<flag name>]" 200 if [[ ! -z $3 ]]; then 201 # user specified the use name so use it 202 echo "-D$1$3=$(use $2 && echo OFF || echo ON)" 203 else 204 # use all various most used combinations 205 uper=$(echo ${2} | tr '[:lower:]' '[:upper:]') 206 capitalised=$(echo ${2} | sed 's/\<\(.\)\([^ ]*\)/\u\1\L\2/g') 207 for x in $2 $uper $capitalised; do 208 echo "-D$1$x=$(use $2 && echo OFF || echo ON) " 209 done 210 fi 211 } 212 213 # Determine using IN or OUT source build 214 _cmake_check_build_dir() { 215 : ${CMAKE_USE_DIR:=${S}} 216 if [[ -n ${CMAKE_IN_SOURCE_BUILD} ]]; then 217 # we build in source dir 218 BUILD_DIR="${CMAKE_USE_DIR}" 219 else 220 # Respect both the old variable and the new one, depending 221 # on which one was set by the ebuild. 222 if [[ ! ${BUILD_DIR} && ${CMAKE_BUILD_DIR} ]]; then 223 if [[ ${EAPI} != [56] ]]; then 224 eerror "The CMAKE_BUILD_DIR variable has been renamed to BUILD_DIR." 225 die "The ebuild must be migrated to BUILD_DIR." 226 else 227 eqawarn "The CMAKE_BUILD_DIR variable has been renamed to BUILD_DIR." 228 eqawarn "Please migrate the ebuild to use the new one." 229 fi 230 231 # In the next call, both variables will be set already 232 # and we'd have to know which one takes precedence. 233 _RESPECT_CMAKE_BUILD_DIR=1 234 fi 235 236 if [[ ${_RESPECT_CMAKE_BUILD_DIR} ]]; then 237 BUILD_DIR=${CMAKE_BUILD_DIR:-${WORKDIR}/${P}_build} 238 else 239 : ${BUILD_DIR:=${WORKDIR}/${P}_build} 240 fi 241 fi 242 243 # Backwards compatibility for getting the value. 244 [[ ${EAPI} == [56] ]] && CMAKE_BUILD_DIR=${BUILD_DIR} 245 246 mkdir -p "${BUILD_DIR}" || die 247 echo ">>> Working in BUILD_DIR: \"$BUILD_DIR\"" 248 } 249 250 # Determine which generator to use 251 _cmake_generator_to_use() { 252 local generator_name 253 254 case ${CMAKE_MAKEFILE_GENERATOR} in 255 ninja) 256 # if ninja is enabled but not installed, the build could fail 257 # this could happen if ninja is manually enabled (eg. make.conf) but not installed 258 case ${EAPI} in 259 5|6) 260 if ! ROOT=/ has_version dev-util/ninja; then 261 die "CMAKE_MAKEFILE_GENERATOR is set to ninja, but ninja is not installed. Please install dev-util/ninja or unset CMAKE_MAKEFILE_GENERATOR." 262 fi 263 ;; 264 *) 265 if ! has_version -b dev-util/ninja; then 266 die "CMAKE_MAKEFILE_GENERATOR is set to ninja, but ninja is not installed. Please install dev-util/ninja or unset CMAKE_MAKEFILE_GENERATOR." 267 fi 268 ;; 269 esac 270 generator_name="Ninja" 271 ;; 272 emake) 273 generator_name="Unix Makefiles" 274 ;; 275 *) 276 eerror "Unknown value for \${CMAKE_MAKEFILE_GENERATOR}" 277 die "Value ${CMAKE_MAKEFILE_GENERATOR} is not supported" 278 ;; 279 esac 280 281 echo ${generator_name} 282 } 283 284 # @FUNCTION: cmake_comment_add_subdirectory 285 # @USAGE: <subdirectory> 286 # @DESCRIPTION: 287 # Comment out one or more add_subdirectory calls in CMakeLists.txt in the current directory 288 cmake_comment_add_subdirectory() { 289 if [[ -z ${1} ]]; then 290 die "comment_add_subdirectory must be passed at least one directory name to comment" 291 fi 292 293 if [[ -e "CMakeLists.txt" ]]; then 294 local d 295 for d in $@; do 296 sed -e "/add_subdirectory[[:space:]]*([[:space:]]*${d//\//\\/}[[:space:]]*)/I s/^/#DONOTCOMPILE /" \ 297 -i CMakeLists.txt || die "failed to comment add_subdirectory(${d})" 298 done 299 fi 300 } 301 302 # @FUNCTION: comment_add_subdirectory 303 # @USAGE: <subdirectory> 304 # @DESCRIPTION: 305 # Comment out an add_subdirectory call in CMakeLists.txt in the current directory 306 # Banned in EAPI 6 and later - use cmake_comment_add_subdirectory instead. 307 comment_add_subdirectory() { 308 [[ ${EAPI} == 5 ]] || die "comment_add_subdirectory is banned in EAPI 6 and later - use cmake_comment_add_subdirectory instead" 309 310 cmake_comment_add_subdirectory "$@" 311 } 312 313 # @FUNCTION: cmake-utils_use_with 314 # @USAGE: <USE flag> [flag name] 315 # @DESCRIPTION: 316 # Based on use_with. See ebuild(5). 317 # 318 # `cmake-utils_use_with foo FOO` echoes -DWITH_FOO=ON if foo is enabled 319 # and -DWITH_FOO=OFF if it is disabled. 320 cmake-utils_use_with() { _cmake_use_me_now WITH_ "$@" ; } 321 322 # @FUNCTION: cmake-utils_use_enable 323 # @USAGE: <USE flag> [flag name] 324 # @DESCRIPTION: 325 # Based on use_enable. See ebuild(5). 326 # 327 # `cmake-utils_use_enable foo FOO` echoes -DENABLE_FOO=ON if foo is enabled 328 # and -DENABLE_FOO=OFF if it is disabled. 329 cmake-utils_use_enable() { _cmake_use_me_now ENABLE_ "$@" ; } 330 331 # @FUNCTION: cmake-utils_use_find_package 332 # @USAGE: <USE flag> <package name> 333 # @DESCRIPTION: 334 # Based on use_enable. See ebuild(5). 335 # 336 # `cmake-utils_use_find_package foo LibFoo` echoes -DCMAKE_DISABLE_FIND_PACKAGE_LibFoo=OFF 337 # if foo is enabled and -DCMAKE_DISABLE_FIND_PACKAGE_LibFoo=ON if it is disabled. 338 # This can be used to make find_package optional. 339 cmake-utils_use_find_package() { 340 if [[ ${EAPI} != 5 && "$#" != 2 ]] ; then 341 die "Usage: cmake-utils_use_find_package <USE flag> <package name>" 342 fi 343 344 _cmake_use_me_now_inverted CMAKE_DISABLE_FIND_PACKAGE_ "$@" ; 345 } 346 347 # @FUNCTION: cmake_use_find_package 348 # @USAGE: <USE flag> <package name> 349 # @DESCRIPTION: 350 # Alias for cmake-utils_use_find_package. 351 cmake_use_find_package() { 352 if [[ "$#" != 2 ]] ; then 353 die "Usage: cmake_use_find_package <USE flag> <package name>" 354 fi 355 356 cmake-utils_use_find_package "$@" ; 357 } 358 359 # @FUNCTION: cmake-utils_use_disable 360 # @USAGE: <USE flag> [flag name] 361 # @DESCRIPTION: 362 # Based on inversion of use_enable. See ebuild(5). 363 # 364 # `cmake-utils_use_enable foo FOO` echoes -DDISABLE_FOO=OFF if foo is enabled 365 # and -DDISABLE_FOO=ON if it is disabled. 366 cmake-utils_use_disable() { _cmake_use_me_now_inverted DISABLE_ "$@" ; } 367 368 # @FUNCTION: cmake-utils_use_no 369 # @USAGE: <USE flag> [flag name] 370 # @DESCRIPTION: 371 # Based on use_disable. See ebuild(5). 372 # 373 # `cmake-utils_use_no foo FOO` echoes -DNO_FOO=OFF if foo is enabled 374 # and -DNO_FOO=ON if it is disabled. 375 cmake-utils_use_no() { _cmake_use_me_now_inverted NO_ "$@" ; } 376 377 # @FUNCTION: cmake-utils_use_want 378 # @USAGE: <USE flag> [flag name] 379 # @DESCRIPTION: 380 # Based on use_enable. See ebuild(5). 381 # 382 # `cmake-utils_use_want foo FOO` echoes -DWANT_FOO=ON if foo is enabled 383 # and -DWANT_FOO=OFF if it is disabled. 384 cmake-utils_use_want() { _cmake_use_me_now WANT_ "$@" ; } 385 386 # @FUNCTION: cmake-utils_use_build 387 # @USAGE: <USE flag> [flag name] 388 # @DESCRIPTION: 389 # Based on use_enable. See ebuild(5). 390 # 391 # `cmake-utils_use_build foo FOO` echoes -DBUILD_FOO=ON if foo is enabled 392 # and -DBUILD_FOO=OFF if it is disabled. 393 cmake-utils_use_build() { _cmake_use_me_now BUILD_ "$@" ; } 394 395 # @FUNCTION: cmake-utils_use_has 396 # @USAGE: <USE flag> [flag name] 397 # @DESCRIPTION: 398 # Based on use_enable. See ebuild(5). 399 # 400 # `cmake-utils_use_has foo FOO` echoes -DHAVE_FOO=ON if foo is enabled 401 # and -DHAVE_FOO=OFF if it is disabled. 402 cmake-utils_use_has() { _cmake_use_me_now HAVE_ "$@" ; } 403 404 # @FUNCTION: cmake-utils_use_use 405 # @USAGE: <USE flag> [flag name] 406 # @DESCRIPTION: 407 # Based on use_enable. See ebuild(5). 408 # 409 # `cmake-utils_use_use foo FOO` echoes -DUSE_FOO=ON if foo is enabled 410 # and -DUSE_FOO=OFF if it is disabled. 411 cmake-utils_use_use() { _cmake_use_me_now USE_ "$@" ; } 412 413 # @FUNCTION: cmake-utils_use 414 # @USAGE: <USE flag> [flag name] 415 # @DESCRIPTION: 416 # Based on use_enable. See ebuild(5). 417 # 418 # `cmake-utils_use foo FOO` echoes -DFOO=ON if foo is enabled 419 # and -DFOO=OFF if it is disabled. 420 cmake-utils_use() { _cmake_use_me_now "" "$@" ; } 421 422 # @FUNCTION: cmake-utils_useno 423 # @USAGE: <USE flag> [flag name] 424 # @DESCRIPTION: 425 # Based on use_enable. See ebuild(5). 426 # 427 # `cmake-utils_useno foo NOFOO` echoes -DNOFOO=OFF if foo is enabled 428 # and -DNOFOO=ON if it is disabled. 429 cmake-utils_useno() { _cmake_use_me_now_inverted "" "$@" ; } 430 431 # Internal function for modifying hardcoded definitions. 432 # Removes dangerous definitions that override Gentoo settings. 433 _cmake_modify-cmakelists() { 434 debug-print-function ${FUNCNAME} "$@" 435 436 # Only edit the files once 437 grep -qs "<<< Gentoo configuration >>>" "${CMAKE_USE_DIR}"/CMakeLists.txt && return 0 438 439 # Comment out all set (<some_should_be_user_defined_variable> value) 440 find "${CMAKE_USE_DIR}" -name CMakeLists.txt -exec sed \ 441 -e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_BUILD_TYPE\([[:space:]].*)\|)\)/I{s/^/#_cmake_modify_IGNORE /g}' \ 442 -e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_COLOR_MAKEFILE[[:space:]].*)/I{s/^/#_cmake_modify_IGNORE /g}' \ 443 -e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_INSTALL_PREFIX[[:space:]].*)/I{s/^/#_cmake_modify_IGNORE /g}' \ 444 -e '/^[[:space:]]*set[[:space:]]*([[:space:]]*CMAKE_VERBOSE_MAKEFILE[[:space:]].*)/I{s/^/#_cmake_modify_IGNORE /g}' \ 445 -i {} + || die "${LINENO}: failed to disable hardcoded settings" 446 local x 447 for x in $(find "${CMAKE_USE_DIR}" -name CMakeLists.txt -exec grep -l "^#_cmake_modify_IGNORE" {} +;); do 448 einfo "Hardcoded definition(s) removed in $(echo "${x}" | cut -c $((${#CMAKE_USE_DIR}+2))-):" 449 einfo "$(grep -se '^#_cmake_modify_IGNORE' ${x} | cut -c 22-99)" 450 done 451 452 # NOTE Append some useful summary here 453 cat >> "${CMAKE_USE_DIR}"/CMakeLists.txt <<- _EOF_ || die 454 455 MESSAGE(STATUS "<<< Gentoo configuration >>> 456 Build type \${CMAKE_BUILD_TYPE} 457 Install path \${CMAKE_INSTALL_PREFIX} 458 Compiler flags: 459 C \${CMAKE_C_FLAGS} 460 C++ \${CMAKE_CXX_FLAGS} 461 Linker flags: 462 Executable \${CMAKE_EXE_LINKER_FLAGS} 463 Module \${CMAKE_MODULE_LINKER_FLAGS} 464 Shared \${CMAKE_SHARED_LINKER_FLAGS}\n") 465 _EOF_ 466 } 467 468 # temporary function for moving cmake cleanups from from src_configure -> src_prepare. 469 # bug #378850 470 _cmake_cleanup_cmake() { 471 : ${CMAKE_USE_DIR:=${S}} 472 473 if [[ "${CMAKE_REMOVE_MODULES}" == "yes" ]] ; then 474 local name 475 for name in ${CMAKE_REMOVE_MODULES_LIST} ; do 476 find "${S}" -name ${name}.cmake -exec rm -v {} + || die 477 done 478 fi 479 480 # check if CMakeLists.txt exist and if no then die 481 if [[ ! -e ${CMAKE_USE_DIR}/CMakeLists.txt ]] ; then 482 eerror "Unable to locate CMakeLists.txt under:" 483 eerror "\"${CMAKE_USE_DIR}/CMakeLists.txt\"" 484 eerror "Consider not inheriting the cmake eclass." 485 die "FATAL: Unable to find CMakeLists.txt" 486 fi 487 488 # Remove dangerous things. 489 _cmake_modify-cmakelists 490 } 491 492 # @FUNCTION: cmake-utils_src_prepare 493 # @DESCRIPTION: 494 # Apply ebuild and user patches. 495 cmake-utils_src_prepare() { 496 debug-print-function ${FUNCNAME} "$@" 497 498 pushd "${S}" > /dev/null || die 499 500 if [[ ${EAPI} != 5 ]]; then 501 default_src_prepare 502 _cmake_cleanup_cmake 503 else 504 debug-print "$FUNCNAME: PATCHES=$PATCHES" 505 [[ ${PATCHES[@]} ]] && epatch "${PATCHES[@]}" 506 507 debug-print "$FUNCNAME: applying user patches" 508 epatch_user 509 fi 510 511 popd > /dev/null || die 512 513 # make ${S} read-only in order to detect broken build-systems 514 if [[ ${CMAKE_UTILS_QA_SRC_DIR_READONLY} && ! ${CMAKE_IN_SOURCE_BUILD} ]]; then 515 chmod -R a-w "${S}" 516 fi 517 518 _CMAKE_UTILS_SRC_PREPARE_HAS_RUN=1 519 } 520 521 # @VARIABLE: mycmakeargs 522 # @DEFAULT_UNSET 523 # @DESCRIPTION: 524 # Optional cmake defines as a bash array. Should be defined before calling 525 # src_configure. 526 # @CODE 527 # src_configure() { 528 # local mycmakeargs=( 529 # $(cmake-utils_use_with openconnect) 530 # ) 531 # 532 # cmake-utils_src_configure 533 # } 534 # @CODE 535 536 # @FUNCTION: cmake-utils_src_configure 537 # @DESCRIPTION: 538 # General function for configuring with cmake. Default behaviour is to start an 539 # out-of-source build. 540 cmake-utils_src_configure() { 541 debug-print-function ${FUNCNAME} "$@" 542 543 if [[ ! ${_CMAKE_UTILS_SRC_PREPARE_HAS_RUN} ]]; then 544 if [[ ${EAPI} != [56] ]]; then 545 die "FATAL: cmake-utils_src_prepare has not been run" 546 else 547 eqawarn "cmake-utils_src_prepare has not been run, please open a bug on https://bugs.gentoo.org/" 548 fi 549 fi 550 551 [[ ${EAPI} == 5 ]] && _cmake_cleanup_cmake 552 553 _cmake_check_build_dir 554 555 # Fix xdg collision with sandbox 556 xdg_environment_reset 557 558 # @SEE CMAKE_BUILD_TYPE 559 if [[ ${CMAKE_BUILD_TYPE} = Gentoo ]]; then 560 # Handle release builds 561 if ! has debug ${IUSE//+} || ! use debug; then 562 local CPPFLAGS=${CPPFLAGS} 563 append-cppflags -DNDEBUG 564 fi 565 fi 566 567 # Prepare Gentoo override rules (set valid compiler, append CPPFLAGS etc.) 568 local build_rules=${BUILD_DIR}/gentoo_rules.cmake 569 570 cat > "${build_rules}" <<- _EOF_ || die 571 SET (CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <DEFINES> <INCLUDES> ${CPPFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "ASM compile command" FORCE) 572 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) 573 SET (CMAKE_ASM-ATT_LINK_FLAGS "-nostdlib" CACHE STRING "ASM-ATT link flags" FORCE) 574 SET (CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> ${CPPFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "C compile command" FORCE) 575 SET (CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> ${CPPFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "C++ compile command" FORCE) 576 SET (CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> ${FCFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "Fortran compile command" FORCE) 577 _EOF_ 578 579 local myCC=$(tc-getCC) myCXX=$(tc-getCXX) myFC=$(tc-getFC) 580 581 # !!! IMPORTANT NOTE !!! 582 # Single slash below is intentional. CMake is weird and wants the 583 # CMAKE_*_VARIABLES split into two elements: the first one with 584 # compiler path, and the second one with all command-line options, 585 # space separated. 586 local toolchain_file=${BUILD_DIR}/gentoo_toolchain.cmake 587 cat > ${toolchain_file} <<- _EOF_ || die 588 SET (CMAKE_ASM_COMPILER "${myCC/ /;}") 589 SET (CMAKE_ASM-ATT_COMPILER "${myCC/ /;}") 590 SET (CMAKE_C_COMPILER "${myCC/ /;}") 591 SET (CMAKE_CXX_COMPILER "${myCXX/ /;}") 592 SET (CMAKE_Fortran_COMPILER "${myFC/ /;}") 593 SET (CMAKE_AR $(type -P $(tc-getAR)) CACHE FILEPATH "Archive manager" FORCE) 594 SET (CMAKE_RANLIB $(type -P $(tc-getRANLIB)) CACHE FILEPATH "Archive index generator" FORCE) 595 SET (CMAKE_SYSTEM_PROCESSOR "${CHOST%%-*}") 596 _EOF_ 597 598 # We are using the C compiler for assembly by default. 599 local -x ASMFLAGS=${CFLAGS} 600 local -x PKG_CONFIG=$(tc-getPKG_CONFIG) 601 602 if tc-is-cross-compiler; then 603 local sysname 604 case "${KERNEL:-linux}" in 605 Cygwin) sysname="CYGWIN_NT-5.1" ;; 606 HPUX) sysname="HP-UX" ;; 607 linux) sysname="Linux" ;; 608 Winnt) 609 sysname="Windows" 610 cat >> "${toolchain_file}" <<- _EOF_ || die 611 SET (CMAKE_RC_COMPILER $(tc-getRC)) 612 _EOF_ 613 ;; 614 *) sysname="${KERNEL}" ;; 615 esac 616 617 cat >> "${toolchain_file}" <<- _EOF_ || die 618 SET (CMAKE_SYSTEM_NAME "${sysname}") 619 _EOF_ 620 621 if [ "${SYSROOT:-/}" != "/" ] ; then 622 # When cross-compiling with a sysroot (e.g. with crossdev's emerge wrappers) 623 # we need to tell cmake to use libs/headers from the sysroot but programs from / only. 624 cat >> "${toolchain_file}" <<- _EOF_ || die 625 SET (CMAKE_FIND_ROOT_PATH "${SYSROOT}") 626 SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 627 SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 628 SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 629 _EOF_ 630 fi 631 fi 632 633 if use prefix-guest; then 634 cat >> "${build_rules}" <<- _EOF_ || die 635 # in Prefix we need rpath and must ensure cmake gets our default linker path 636 # right ... except for Darwin hosts 637 IF (NOT APPLE) 638 SET (CMAKE_SKIP_RPATH OFF CACHE BOOL "" FORCE) 639 SET (CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH "${EPREFIX}/usr/${CHOST}/lib/gcc;${EPREFIX}/usr/${CHOST}/lib;${EPREFIX}/usr/$(get_libdir);${EPREFIX}/$(get_libdir)" 640 CACHE STRING "" FORCE) 641 642 ELSE () 643 644 SET (CMAKE_PREFIX_PATH "${EPREFIX}/usr" CACHE STRING "" FORCE) 645 SET (CMAKE_MACOSX_RPATH ON CACHE BOOL "" FORCE) 646 SET (CMAKE_SKIP_BUILD_RPATH OFF CACHE BOOL "" FORCE) 647 SET (CMAKE_SKIP_RPATH OFF CACHE BOOL "" FORCE) 648 SET (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE BOOL "" FORCE) 649 650 ENDIF (NOT APPLE) 651 _EOF_ 652 fi 653 654 # Common configure parameters (invariants) 655 local common_config=${BUILD_DIR}/gentoo_common_config.cmake 656 local libdir=$(get_libdir) 657 cat > "${common_config}" <<- _EOF_ || die 658 SET (CMAKE_GENTOO_BUILD ON CACHE BOOL "Indicate Gentoo package build") 659 SET (LIB_SUFFIX ${libdir/lib} CACHE STRING "library path suffix" FORCE) 660 SET (CMAKE_INSTALL_LIBDIR ${libdir} CACHE PATH "Output directory for libraries") 661 SET (CMAKE_INSTALL_INFODIR "${EPREFIX}/usr/share/info" CACHE PATH "") 662 SET (CMAKE_INSTALL_MANDIR "${EPREFIX}/usr/share/man" CACHE PATH "") 663 SET (CMAKE_USER_MAKE_RULES_OVERRIDE "${build_rules}" CACHE FILEPATH "Gentoo override rules") 664 _EOF_ 665 666 # See bug 689410 667 if [[ "${ARCH}" == riscv ]]; then 668 echo 'SET (CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX '"${libdir#lib}"' CACHE STRING "library search suffix" FORCE)' >> "${common_config}" || die 669 fi 670 671 [[ "${NOCOLOR}" = true || "${NOCOLOR}" = yes ]] && echo 'SET (CMAKE_COLOR_MAKEFILE OFF CACHE BOOL "pretty colors during make" FORCE)' >> "${common_config}" 672 673 if [[ ${EAPI} != [56] ]]; then 674 cat >> "${common_config}" <<- _EOF_ || die 675 SET (CMAKE_INSTALL_DOCDIR "${EPREFIX}/usr/share/doc/${PF}" CACHE PATH "") 676 SET (BUILD_SHARED_LIBS ON CACHE BOOL "") 677 _EOF_ 678 fi 679 680 # Wipe the default optimization flags out of CMake 681 if [[ ${CMAKE_BUILD_TYPE} != Gentoo && ${EAPI} != 5 ]]; then 682 cat >> ${common_config} <<- _EOF_ || die 683 SET (CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 684 SET (CMAKE_ASM-ATT_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 685 SET (CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 686 SET (CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 687 SET (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 688 SET (CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 689 SET (CMAKE_MODULE_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 690 SET (CMAKE_SHARED_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 691 SET (CMAKE_STATIC_LINKER_FLAGS_${CMAKE_BUILD_TYPE^^} "" CACHE STRING "") 692 _EOF_ 693 fi 694 695 # Convert mycmakeargs to an array, for backwards compatibility 696 # Make the array a local variable since <=portage-2.1.6.x does not 697 # support global arrays (see bug #297255). 698 local mycmakeargstype=$(declare -p mycmakeargs 2>&-) 699 if [[ "${mycmakeargstype}" != "declare -a mycmakeargs="* ]]; then 700 if [[ -n "${mycmakeargstype}" ]] ; then 701 if [[ ${EAPI} == 5 ]]; then 702 eqawarn "Declaring mycmakeargs as a variable is deprecated. Please use an array instead." 703 else 704 die "Declaring mycmakeargs as a variable is banned in EAPI=${EAPI}. Please use an array instead." 705 fi 706 fi 707 local mycmakeargs_local=(${mycmakeargs}) 708 else 709 local mycmakeargs_local=("${mycmakeargs[@]}") 710 fi 711 712 if [[ ${CMAKE_WARN_UNUSED_CLI} == no ]] ; then 713 local warn_unused_cli="--no-warn-unused-cli" 714 else 715 local warn_unused_cli="" 716 fi 717 718 # Common configure parameters (overridable) 719 # NOTE CMAKE_BUILD_TYPE can be only overridden via CMAKE_BUILD_TYPE eclass variable 720 # No -DCMAKE_BUILD_TYPE=xxx definitions will be in effect. 721 local cmakeargs=( 722 ${warn_unused_cli} 723 -C "${common_config}" 724 -G "$(_cmake_generator_to_use)" 725 -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr" 726 "${mycmakeargs_local[@]}" 727 -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" 728 $([[ ${EAPI} == 5 ]] && echo -DCMAKE_INSTALL_DO_STRIP=OFF) 729 -DCMAKE_TOOLCHAIN_FILE="${toolchain_file}" 730 "${MYCMAKEARGS}" 731 ) 732 733 if [[ -n "${CMAKE_EXTRA_CACHE_FILE}" ]] ; then 734 cmakeargs+=( -C "${CMAKE_EXTRA_CACHE_FILE}" ) 735 fi 736 737 pushd "${BUILD_DIR}" > /dev/null || die 738 debug-print "${LINENO} ${ECLASS} ${FUNCNAME}: mycmakeargs is ${mycmakeargs_local[*]}" 739 echo "${CMAKE_BINARY}" "${cmakeargs[@]}" "${CMAKE_USE_DIR}" 740 "${CMAKE_BINARY}" "${cmakeargs[@]}" "${CMAKE_USE_DIR}" || die "cmake failed" 741 popd > /dev/null || die 742 } 743 744 # @FUNCTION: cmake-utils_src_compile 745 # @DESCRIPTION: 746 # General function for compiling with cmake. 747 # Automatically detects the build type. All arguments are passed to emake. 748 cmake-utils_src_compile() { 749 debug-print-function ${FUNCNAME} "$@" 750 751 cmake-utils_src_make "$@" 752 } 753 754 # @FUNCTION: _cmake_ninja_src_make 755 # @INTERNAL 756 # @DESCRIPTION: 757 # Build the package using ninja generator 758 _cmake_ninja_src_make() { 759 debug-print-function ${FUNCNAME} "$@" 760 761 [[ -e build.ninja ]] || die "build.ninja not found. Error during configure stage." 762 763 eninja "$@" 764 } 765 766 # @FUNCTION: _cmake_emake_src_make 767 # @INTERNAL 768 # @DESCRIPTION: 769 # Build the package using make generator 770 _cmake_emake_src_make() { 771 debug-print-function ${FUNCNAME} "$@" 772 773 [[ -e Makefile ]] || die "Makefile not found. Error during configure stage." 774 775 if [[ "${CMAKE_VERBOSE}" != "OFF" ]]; then 776 emake VERBOSE=1 "$@" || die 777 else 778 emake "$@" || die 779 fi 780 781 } 782 783 # @FUNCTION: cmake-utils_src_make 784 # @DESCRIPTION: 785 # Function for building the package. Automatically detects the build type. 786 # All arguments are passed to emake. 787 cmake-utils_src_make() { 788 debug-print-function ${FUNCNAME} "$@" 789 790 _cmake_check_build_dir 791 pushd "${BUILD_DIR}" > /dev/null || die 792 793 _cmake_${CMAKE_MAKEFILE_GENERATOR}_src_make "$@" 794 795 popd > /dev/null || die 796 } 797 798 # @FUNCTION: cmake-utils_src_test 799 # @DESCRIPTION: 800 # Function for testing the package. Automatically detects the build type. 801 cmake-utils_src_test() { 802 debug-print-function ${FUNCNAME} "$@" 803 804 _cmake_check_build_dir 805 pushd "${BUILD_DIR}" > /dev/null || die 806 [[ -e CTestTestfile.cmake ]] || { echo "No tests found. Skipping."; return 0 ; } 807 808 [[ -n ${TEST_VERBOSE} ]] && myctestargs+=( --extra-verbose --output-on-failure ) 809 810 set -- ctest -j "$(makeopts_jobs "${MAKEOPTS}" 999)" \ 811 --test-load "$(makeopts_loadavg)" "${myctestargs[@]}" "$@" 812 echo "$@" >&2 813 if "$@" ; then 814 einfo "Tests succeeded." 815 popd > /dev/null || die 816 return 0 817 else 818 if [[ -n "${CMAKE_YES_I_WANT_TO_SEE_THE_TEST_LOG}" ]] ; then 819 # on request from Diego 820 eerror "Tests failed. Test log ${BUILD_DIR}/Testing/Temporary/LastTest.log follows:" 821 eerror "--START TEST LOG--------------------------------------------------------------" 822 cat "${BUILD_DIR}/Testing/Temporary/LastTest.log" 823 eerror "--END TEST LOG----------------------------------------------------------------" 824 die "Tests failed." 825 else 826 die "Tests failed. When you file a bug, please attach the following file: \n\t${BUILD_DIR}/Testing/Temporary/LastTest.log" 827 fi 828 829 # die might not die due to nonfatal 830 popd > /dev/null || die 831 return 1 832 fi 833 } 834 835 # @FUNCTION: cmake-utils_src_install 836 # @DESCRIPTION: 837 # Function for installing the package. Automatically detects the build type. 838 cmake-utils_src_install() { 839 debug-print-function ${FUNCNAME} "$@" 840 841 _cmake_check_build_dir 842 pushd "${BUILD_DIR}" > /dev/null || die 843 DESTDIR="${D}" ${CMAKE_MAKEFILE_GENERATOR} install "$@" || die "died running ${CMAKE_MAKEFILE_GENERATOR} install" 844 popd > /dev/null || die 845 846 pushd "${S}" > /dev/null || die 847 einstalldocs 848 popd > /dev/null || die 849 } 850 851 fi