1# Copyright 2018-2020 Peter Dimov 2# Distributed under the Boost Software License, Version 1.0. 3# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) 4 5import modules ; 6import boostcpp ; 7import property-set ; 8import "class" : new ; 9import project ; 10import common ; 11import print ; 12import os ; 13import feature ; 14import package ; 15import sequence ; 16import set ; 17import type ; 18import path ; 19import regex ; 20import ./boost-install-dirs ; 21 22feature.feature library-type : : free ; 23feature.feature boost-install.dependency : : free ; 24feature.feature boost-install.cmakedir : : free ; 25feature.feature boost-install.includedir : : free ; 26feature.feature boost-install.libdir : : free ; 27feature.feature boost-install.lib-target-type : : free ; 28 29if "--verbose" in [ modules.peek : ARGV ] 30{ 31 .info-enabled = 1 ; 32} 33 34if "--debug-boost-install" in [ modules.peek : ARGV ] 35{ 36 .debug-enabled = 1 ; 37} 38 39local rule .info ( messages * ) 40{ 41 if $(.info-enabled) 42 { 43 ECHO "info:" $(messages) ; 44 } 45} 46 47local rule .debug ( messages * ) 48{ 49 if $(.debug-enabled) 50 { 51 ECHO "boost-install:" $(messages) ; 52 } 53} 54 55# generate-cmake-variant- 56 57rule generate-cmake-variant- ( target : sources * : properties * ) 58{ 59 .info generate-cmake-variant- $(target) ":" $(sources) ; 60 61 local ps = [ property-set.create $(properties) ] ; 62 63 print.output $(target) ; 64 65 local version = [ $(ps).get <version> ] ; 66 .info " version=" $(version) ; 67 68 local name = [ $(ps).get <name> ] ; 69 .info " name=" $(name) ; 70 71 local variant = [ $(ps).get <variant> ] ; 72 .info " variant=" $(variant) ; 73 74 local link = [ $(ps).get <link> ] ; 75 .info " link= " $(link) ; 76 77 local runtime-link = [ $(ps).get <runtime-link> ] ; 78 .info " runtime-link=" $(runtime-link) ; 79 80 local runtime-debugging = [ $(ps).get <runtime-debugging> ] ; 81 .info " runtime-debugging=" $(runtime-debugging) ; 82 83 local threading = [ $(ps).get <threading> ] ; 84 .info " threading=" $(threading) ; 85 86 local address-model = [ $(ps).get <address-model> ] ; 87 .info " address-model=" $(address-model) ; 88 89 local toolset = [ MATCH ^-(.*) : [ common.format-name <toolset> : "" : "" : $(ps) ] ] ; 90 .info " toolset=" $(toolset) ; 91 92 local fname = $(sources[1]:BS) ; 93 .info " fname=" $(fname) ; 94 95 local layout = [ modules.peek boostcpp : layout ] ; 96 .info " layout=" $(layout) ; 97 98 print.text 99 100 "# Generated by Boost $(version)" 101 "" 102 : true ; 103 104 print.text "# address-model=$(address-model)" "" : true ; 105 106 if $(address-model) = 32 107 { 108 print.text 109 110 "if(CMAKE_SIZEOF_VOID_P EQUAL 8)" 111 " _BOOST_SKIPPED(\"$(fname)\" \"32 bit, need 64\")" 112 " return()" 113 "endif()" 114 "" 115 : true ; 116 } 117 else 118 { 119 print.text 120 121 "if(CMAKE_SIZEOF_VOID_P EQUAL 4)" 122 " _BOOST_SKIPPED(\"$(fname)\" \"64 bit, need 32\")" 123 " return()" 124 "endif()" 125 "" 126 : true ; 127 } 128 129 local python ; 130 131 local relevant = [ $(ps).get <relevant> ] ; 132 relevant = [ feature.expand-relevant $(relevant) ] ; 133 134 if python in $(relevant) 135 { 136 python = [ $(ps).get <python> ] ; 137 } 138 139 if $(python) 140 { 141 .info " python=" $(python) ; 142 143 print.text "# python=$(python)" "" : true ; 144 145 print.text 146 147 "if(Boost_PYTHON_VERSION)" 148 " string(REGEX REPLACE \"([0-9]+[.][0-9]+)([.].*)?\" \"\\\\1\" __boost_pyver ${Boost_PYTHON_VERSION})" 149 " if(NOT __boost_pyver VERSION_EQUAL \"$(python)\")" 150 " _BOOST_SKIPPED(\"$(fname)\" \"$(python), Boost_PYTHON_VERSION=${Boost_PYTHON_VERSION}\")" 151 " return()" 152 " endif()" 153 "endif()" 154 "" 155 "if(Boost_PYTHON_VERSION_MAJOR)" 156 " if(NOT \"$(python)\" MATCHES \"^${Boost_PYTHON_VERSION_MAJOR}[.]\")" 157 " _BOOST_SKIPPED(\"$(fname)\" \"$(python), Boost_PYTHON_VERSION_MAJOR=${Boost_PYTHON_VERSION_MAJOR}\")" 158 " return()" 159 " endif()" 160 "endif()" 161 "" 162 : true ; 163 } 164 165 print.text "# layout=$(layout)" "" : true ; 166 167 print.text "# toolset=$(toolset)" "" : true ; 168 169 if $(layout) = versioned 170 { 171 print.text 172 173 "if(Boost_COMPILER)" 174 " if(NOT Boost_COMPILER STREQUAL \"$(toolset)\" AND NOT Boost_COMPILER STREQUAL \"-$(toolset)\")" 175 " _BOOST_SKIPPED(\"$(fname)\" \"$(toolset), Boost_COMPILER=${Boost_COMPILER}\")" 176 " return()" 177 " endif()" 178 "else()" 179 " if(BOOST_DETECTED_TOOLSET AND NOT BOOST_DETECTED_TOOLSET STREQUAL \"$(toolset)\")" 180 " _BOOST_SKIPPED(\"$(fname)\" \"$(toolset), detected ${BOOST_DETECTED_TOOLSET}, set Boost_COMPILER to override\")" 181 " return()" 182 " endif()" 183 "endif()" 184 "" 185 : true ; 186 } 187 188 print.text "# link=$(link)" "" : true ; 189 190 if $(link) = static 191 { 192 print.text 193 194 "if(DEFINED Boost_USE_STATIC_LIBS)" 195 " if(NOT Boost_USE_STATIC_LIBS)" 196 " _BOOST_SKIPPED(\"$(fname)\" \"static, Boost_USE_STATIC_LIBS=${Boost_USE_STATIC_LIBS}\")" 197 " return()" 198 " endif()" 199 "else()" 200 " if(NOT WIN32 AND NOT _BOOST_SINGLE_VARIANT)" 201 " _BOOST_SKIPPED(\"$(fname)\" \"static, default is shared, set Boost_USE_STATIC_LIBS=ON to override\")" 202 " return()" 203 " endif()" 204 "endif()" 205 "" 206 : true ; 207 } 208 else 209 { 210 print.text 211 212 "if(DEFINED Boost_USE_STATIC_LIBS)" 213 " if(Boost_USE_STATIC_LIBS)" 214 " _BOOST_SKIPPED(\"$(fname)\" \"shared, Boost_USE_STATIC_LIBS=${Boost_USE_STATIC_LIBS}\")" 215 " return()" 216 " endif()" 217 "else()" 218 " if(WIN32 AND NOT _BOOST_SINGLE_VARIANT)" 219 " _BOOST_SKIPPED(\"$(fname)\" \"shared, default on Windows is static, set Boost_USE_STATIC_LIBS=OFF to override\")" 220 " return()" 221 " endif()" 222 "endif()" 223 "" 224 : true ; 225 } 226 227 print.text "# runtime-link=$(runtime-link)" "" : true ; 228 229 if $(runtime-link) = static 230 { 231 print.text 232 233 "if(NOT Boost_USE_STATIC_RUNTIME)" 234 " _BOOST_SKIPPED(\"$(fname)\" \"static runtime, Boost_USE_STATIC_RUNTIME not ON\")" 235 " return()" 236 "endif()" 237 "" 238 : true ; 239 } 240 else 241 { 242 print.text 243 244 "if(Boost_USE_STATIC_RUNTIME)" 245 " _BOOST_SKIPPED(\"$(fname)\" \"shared runtime, Boost_USE_STATIC_RUNTIME=${Boost_USE_STATIC_RUNTIME}\")" 246 " return()" 247 "endif()" 248 "" 249 : true ; 250 } 251 252 print.text "# runtime-debugging=$(runtime-debugging)" "" : true ; 253 254 if $(runtime-debugging) = "on" 255 { 256 print.text 257 258 "if(NOT \"${Boost_USE_DEBUG_RUNTIME}\" STREQUAL \"\" AND NOT Boost_USE_DEBUG_RUNTIME)" 259 " _BOOST_SKIPPED(\"$(fname)\" \"debug runtime, Boost_USE_DEBUG_RUNTIME=${Boost_USE_DEBUG_RUNTIME}\")" 260 " return()" 261 "endif()" 262 "" 263 : true ; 264 } 265 else 266 { 267 print.text 268 269 "if(Boost_USE_DEBUG_RUNTIME)" 270 " _BOOST_SKIPPED(\"$(fname)\" \"release runtime, Boost_USE_DEBUG_RUNTIME=${Boost_USE_DEBUG_RUNTIME}\")" 271 " return()" 272 "endif()" 273 "" 274 : true ; 275 } 276 277 print.text "# threading=$(threading)" "" : true ; 278 279 if $(layout) != system 280 { 281 if $(threading) = "multi" 282 { 283 print.text 284 285 "if(DEFINED Boost_USE_MULTITHREADED AND NOT Boost_USE_MULTITHREADED)" 286 " _BOOST_SKIPPED(\"$(fname)\" \"multithreaded, Boost_USE_MULTITHREADED=${Boost_USE_MULTITHREADED}\")" 287 " return()" 288 "endif()" 289 "" 290 : true ; 291 } 292 else 293 { 294 print.text 295 296 "if(NOT DEFINED Boost_USE_MULTITHREADED)" 297 " _BOOST_SKIPPED(\"$(fname)\" \"single-threaded, Boost_USE_MULTITHREADED is not set and defaults to ON, set to OFF to override\")" 298 " return()" 299 "endif()" 300 "" 301 "if(Boost_USE_MULTITHREADED)" 302 " _BOOST_SKIPPED(\"$(fname)\" \"single-threaded, Boost_USE_MULTITHREADED=${Boost_USE_MULTITHREADED}\")" 303 " return()" 304 "endif()" 305 "" 306 : true ; 307 } 308 } 309 310 print.text "# variant=$(variant)" "" : true ; 311 312 if $(variant) = debug 313 { 314 print.text 315 316 "if(NOT \"${Boost_USE_DEBUG_LIBS}\" STREQUAL \"\" AND NOT Boost_USE_DEBUG_LIBS)" 317 " _BOOST_SKIPPED(\"$(fname)\" \"debug, Boost_USE_DEBUG_LIBS=${Boost_USE_DEBUG_LIBS}\")" 318 " return()" 319 "endif()" 320 "" 321 : true ; 322 } 323 else 324 { 325 print.text 326 327 "if(NOT \"${Boost_USE_RELEASE_LIBS}\" STREQUAL \"\" AND NOT Boost_USE_RELEASE_LIBS)" 328 " _BOOST_SKIPPED(\"$(fname)\" \"release, Boost_USE_RELEASE_LIBS=${Boost_USE_RELEASE_LIBS}\")" 329 " return()" 330 "endif()" 331 "" 332 : true ; 333 } 334 335 print.text 336 337 "if(Boost_VERBOSE OR Boost_DEBUG)" 338 " message(STATUS \" [x] $(fname)\")" 339 "endif()" 340 "" 341 : true ; 342 343 if $(python) 344 { 345 print.text 346 347 "if(NOT Boost_PYTHON_VERSION)" 348 " if(Boost_DEBUG)" 349 " message(STATUS \" Setting Boost_PYTHON_VERSION to $(python)\")" 350 " endif()" 351 " set(Boost_PYTHON_VERSION \"$(python)\")" 352 "endif()" 353 "" 354 : true ; 355 } 356 357 local lname = [ MATCH boost_(.*) : $(name) ] ; 358 .info " lname=" $(lname) ; 359 360 local target = "Boost::$(lname)" ; 361 .info " target=" $(target) ; 362 363 print.text 364 365 "# Create imported target $(target)" 366 "" 367 "if(NOT TARGET $(target))" 368 " add_library($(target) $(link:U) IMPORTED)" 369 "" 370 " set_target_properties($(target) PROPERTIES" 371 " INTERFACE_INCLUDE_DIRECTORIES \"\${_BOOST_INCLUDEDIR}\"" 372 " INTERFACE_COMPILE_DEFINITIONS \"BOOST_ALL_NO_LIB\"" 373 " )" 374 "endif()" 375 "" 376 : true ; 377 378 print.text "# Target file name: $(fname)" "" : true ; 379 380 local lib-target-type = [ $(ps).get <boost-install.lib-target-type> ] ; 381 .info " lib-target-type=" $(lib-target-type) ; 382 383 local loc-prop = LOCATION ; 384 385 if $(lib-target-type) = IMPORT_LIB 386 { 387 loc-prop = IMPLIB ; 388 } 389 390 .info " loc-prop=" $(loc-prop) ; 391 392 print.text 393 394 "get_target_property(__boost_imploc $(target) IMPORTED_$(loc-prop)_$(variant:U))" 395 "if(__boost_imploc)" 396 " message(SEND_ERROR \"Target $(target) already has an imported location '${__boost_imploc}', which is being overwritten with '${_BOOST_LIBDIR}/$(fname)'\")" 397 "endif()" 398 "unset(__boost_imploc)" 399 "" 400 "set_property(TARGET $(target) APPEND PROPERTY IMPORTED_CONFIGURATIONS $(variant:U))" 401 "" 402 "set_target_properties($(target) PROPERTIES" 403 " IMPORTED_LINK_INTERFACE_LANGUAGES_$(variant:U) CXX" 404 " IMPORTED_$(loc-prop)_$(variant:U) \"${_BOOST_LIBDIR}/$(fname)\"" 405 " )" 406 "" 407 : true ; 408 409 if $(variant) = release 410 { 411 print.text 412 413 "set_target_properties($(target) PROPERTIES" 414 " MAP_IMPORTED_CONFIG_MINSIZEREL Release" 415 " MAP_IMPORTED_CONFIG_RELWITHDEBINFO Release" 416 " )" 417 "" 418 : true ; 419 } 420 421 if $(link) = shared 422 { 423 print.text 424 425 "set_property(TARGET $(target) APPEND" 426 " PROPERTY INTERFACE_COMPILE_DEFINITIONS \"BOOST_$(lname:U)_DYN_LINK\"" 427 " )" 428 "" 429 : true ; 430 } 431 432 local deps = [ MATCH "boost_(.*)" : [ $(ps).get <boost-install.dependency> ] ] headers ; 433 .info " deps=" $(deps) ; 434 435 if $(deps) 436 { 437 print.text 438 439 "list(APPEND _BOOST_$(lname:U)_DEPS $(deps:S=:J= ))" 440 "" 441 : true ; 442 } 443} 444 445actions generate-cmake-variant- 446{ 447} 448 449# tag 450 451local rule tag ( name : type ? : property-set ) 452{ 453 .debug tag $(name) ; 454 455 local link = [ $(property-set).get <link> ] ; 456 .debug " link=" $(link) ; 457 458 local python = ; 459 460 local relevant = [ $(property-set).get <relevant> ] ; 461 relevant = [ feature.expand-relevant $(relevant) ] ; 462 463 if python in $(relevant) 464 { 465 python = [ $(property-set).get <python> ] ; 466 .debug " python=" $(python) ; 467 } 468 469 local r = [ boostcpp.tag $(name) : STATIC_LIB : $(property-set) ] ; 470 471 r = $(r:S=$(name:S)) ; 472 r = $(r:B=$(r:B)-$(link)) ; 473 474 if $(python) 475 { 476 r = $(r:B=$(r:B)-py$(python)) ; 477 } 478 479 .debug " result=" $(r) ; 480 481 return $(r) ; 482} 483 484# choose-lib-target: get the import library, if present, the 485# shared/static library otherwise, ignore .pdb et al 486 487local rule choose-lib-target ( sources * ) 488{ 489 local result ; 490 491 for local t in $(sources) 492 { 493 if [ type.is-derived [ $(t).type ] IMPORT_LIB ] 494 { 495 return $(t) ; 496 } 497 else if [ type.is-derived [ $(t).type ] LIB ] 498 { 499 result = $(t) ; 500 } 501 } 502 503 return $(result) ; 504} 505 506# get-dependency-names: Returns the base names of all 507# dependency libraries. 508# 509local rule get-dependency-names ( sources * ) 510{ 511 local all-targets = [ collect-targets $(sources) ] ; 512 local lib-names ; 513 for local t in [ set.difference $(all-targets) : $(sources) ] 514 { 515 if [ $(t).type ] && [ type.is-derived [ $(t).type ] LIB ] 516 { 517 # Get back the original unmangled name of the library 518 local subvariant = [ $(t).creating-subvariant ] ; 519 local main-target = [ $(subvariant).main-target ] ; 520 lib-names += [ $(main-target).name ] ; 521 } 522 } 523 return [ sequence.unique $(lib-names) ] ; 524} 525 526# generate-cmake-variant 527 528rule generate-cmake-variant ( project name : property-set : sources * ) 529{ 530 .debug generate-cmake-variant $(name) ; 531 532 for local s in $(sources) 533 { 534 .debug " name=" [ $(s).name ] ; 535 } 536 537 local lib-target = [ choose-lib-target $(sources) ] ; 538 539 local other-names = [ get-dependency-names $(sources) ] ; 540 property-set = [ $(property-set).add-raw <boost-install.dependency>$(other-names) ] ; 541 542 local result ; 543 544 if $(lib-target) 545 { 546 .debug " lib-target=" [ $(lib-target).name ] ; 547 548 local lib-target-type = [ $(lib-target).type ] ; 549 550 .debug " lib-target-type=" $(lib-target-type) ; 551 552 local tag = [ tag $(name) : : $(property-set) ] ; 553 554 property-set = [ $(property-set).add-raw <boost-install.lib-target-type>$(lib-target-type) ] ; 555 556 local a = [ new non-scanning-action $(lib-target) : boost-install.generate-cmake-variant- : $(property-set) ] ; 557 558 result += [ new file-target $(tag) : : $(project) : $(a) ] ; 559 } 560 561 # The result is an optional property set, the usage requirements, 562 # followed by a list of targets. When the list is empty, we need 563 # to include the property set, to avoid a warning. 564 565 return [ property-set.empty ] $(result) ; 566} 567 568# generate-cmake-config- 569 570local rule path-native-fwd ( path ) 571{ 572 path = [ path.native $(path) ] ; 573 574 if [ os.name ] = NT 575 { 576 path = $(path:T) ; 577 } 578 579 return $(path) ; 580} 581 582local rule get-dir ( name : dir ) 583{ 584 if [ path.is-rooted $(dir) ] 585 { 586 dir = [ path-native-fwd $(dir) ] ; 587 588 print.text 589 590 "set($(name) \"$(dir)\")" 591 592 : true ; 593 } 594 else 595 { 596 print.text 597 598 "get_filename_component($(name) \"${_BOOST_CMAKEDIR}/$(dir)/\" ABSOLUTE)" 599 600 : true ; 601 } 602} 603 604rule generate-cmake-config- ( target : sources * : properties * ) 605{ 606 .info generate-cmake-config- $(target) ":" $(sources) ; 607 608 local ps = [ property-set.create $(properties) ] ; 609 610 print.output $(target) ; 611 612 local version = [ $(ps).get <version> ] ; 613 .info " version=" $(version) ; 614 615 local name = [ $(ps).get <name> ] ; 616 .info " name=" $(name) ; 617 618 local library-type = [ $(ps).get <library-type> ] ; 619 .info " library-type=" $(library-type) ; 620 621 local cmakedir = [ $(ps).get <boost-install.cmakedir> ] ; 622 .info " cmakedir=" $(cmakedir) ; 623 624 local includedir = [ $(ps).get <boost-install.includedir> ] ; 625 .info " includedir=" $(includedir) ; 626 627 local libdir = [ $(ps).get <boost-install.libdir> ] ; 628 .info " libdir=" $(libdir) ; 629 630 local lname = [ MATCH boost_(.*) : $(name) ] ; 631 .info " lname=" $(lname) ; 632 633 local ltarget = "Boost::$(lname)" ; 634 .info " ltarget=" $(ltarget) ; 635 636 print.output $(target) ; 637 638 print.text 639 640 "# Generated by Boost $(version)" 641 "" 642 "if(TARGET $(ltarget))" 643 " return()" 644 "endif()" 645 "" 646 "if(Boost_VERBOSE OR Boost_DEBUG)" 647 " message(STATUS \"Found $(name) ${$(name)_VERSION} at ${$(name)_DIR}\")" 648 "endif()" 649 "" 650 "# Compute the include and library directories relative to this file." 651 "" 652 "get_filename_component(_BOOST_CMAKEDIR \"${CMAKE_CURRENT_LIST_DIR}/../\" REALPATH)" 653 : true ; 654 655 if [ path.is-rooted $(cmakedir) ] 656 { 657 local cmakedir-native = [ path-native-fwd $(cmakedir) ] ; 658 659 print.text 660 661 "" 662 "# If the computed and the original directories are symlink-equivalent, use original" 663 "if(EXISTS \"$(cmakedir-native)\")" 664 " get_filename_component(_BOOST_CMAKEDIR_ORIGINAL \"$(cmakedir-native)\" REALPATH)" 665 " if(_BOOST_CMAKEDIR STREQUAL _BOOST_CMAKEDIR_ORIGINAL)" 666 " set(_BOOST_CMAKEDIR \"$(cmakedir-native)\")" 667 " endif()" 668 " unset(_BOOST_CMAKEDIR_ORIGINAL)" 669 "endif()" 670 "" 671 : true ; 672 } 673 674 get-dir "_BOOST_INCLUDEDIR" : $(includedir) ; 675 676 if $(library-type) = INTERFACE 677 { 678 print.text 679 680 "" 681 "add_library($(ltarget) INTERFACE IMPORTED)" 682 "" 683 "set_target_properties($(ltarget) PROPERTIES" 684 " INTERFACE_INCLUDE_DIRECTORIES \"\${_BOOST_INCLUDEDIR}\"" 685 " INTERFACE_COMPILE_DEFINITIONS \"BOOST_ALL_NO_LIB\"" 686 ")" 687 "" 688 "unset(_BOOST_INCLUDEDIR)" 689 "unset(_BOOST_CMAKEDIR)" 690 "" 691 : true ; 692 } 693 else 694 { 695 get-dir "_BOOST_LIBDIR" : $(libdir) ; 696 697 print.text 698 699 "" 700 "include(${CMAKE_CURRENT_LIST_DIR}/../BoostDetectToolset-$(version).cmake)" 701 "" 702 "if(Boost_DEBUG)" 703 " message(STATUS \"Scanning ${CMAKE_CURRENT_LIST_DIR}/lib$(name)-variant*.cmake\")" 704 "endif()" 705 "" 706 "file(GLOB __boost_variants \"${CMAKE_CURRENT_LIST_DIR}/lib$(name)-variant*.cmake\")" 707 "" 708 "macro(_BOOST_SKIPPED fname reason)" 709 " if(Boost_VERBOSE OR Boost_DEBUG)" 710 " message(STATUS \" [ ] ${fname}\")" 711 " endif()" 712 " list(APPEND __boost_skipped \"${fname} (${reason})\")" 713 "endmacro()" 714 "" 715 "list(LENGTH __boost_variants _BOOST_SINGLE_VARIANT)" 716 "if(NOT _BOOST_SINGLE_VARIANT EQUAL 1)" 717 " set(_BOOST_SINGLE_VARIANT 0)" 718 "endif()" 719 "" 720 "foreach(f IN LISTS __boost_variants)" 721 " if(Boost_DEBUG)" 722 " message(STATUS \" Including ${f}\")" 723 " endif()" 724 " include(${f})" 725 "endforeach()" 726 "" 727 "unset(_BOOST_SINGLE_VARIANT)" 728 "unset(_BOOST_LIBDIR)" 729 "unset(_BOOST_INCLUDEDIR)" 730 "unset(_BOOST_CMAKEDIR)" 731 "" 732 "if(NOT __boost_variants AND (Boost_VERBOSE OR Boost_DEBUG))" 733 " message(STATUS \" Library has no variants and is considered not found\")" 734 "endif()" 735 "" 736 "if(NOT TARGET $(ltarget))" 737 " set(__boost_message \"No suitable build variant has been found.\")" 738 " if(__boost_skipped)" 739 " set(__boost_message \"${__boost_message}\\nThe following variants have been tried and rejected:\")" 740 " foreach(s IN LISTS __boost_skipped)" 741 " set(__boost_message \"${__boost_message}\\n* ${s}\")" 742 " endforeach()" 743 " endif()" 744 " set($(name)_FOUND 0)" 745 " set($(name)_NOT_FOUND_MESSAGE ${__boost_message})" 746 " unset(__boost_message)" 747 " unset(__boost_skipped)" 748 " unset(__boost_variants)" 749 " unset(_BOOST_$(lname:U)_DEPS)" 750 " return()" 751 "endif()" 752 "" 753 "unset(__boost_skipped)" 754 "unset(__boost_variants)" 755 "" 756 "if(_BOOST_$(lname:U)_DEPS)" 757 " list(REMOVE_DUPLICATES _BOOST_$(lname:U)_DEPS)" 758 " if(Boost_VERBOSE OR Boost_DEBUG)" 759 " message(STATUS \"Adding $(name) dependencies: ${_BOOST_$(lname:U)_DEPS}\")" 760 " endif()" 761 "endif()" 762 "" 763 "foreach(dep_$(name) IN LISTS _BOOST_$(lname:U)_DEPS") 764 " set(_BOOST_QUIET)" 765 " if($(name)_FIND_QUIETLY)" 766 " set(_BOOST_QUIET QUIET)" 767 " endif()" 768 " set(_BOOST_REQUIRED)" 769 " if($(name)_FIND_REQUIRED)" 770 " set(_BOOST_REQUIRED REQUIRED)" 771 " endif()" 772 " get_filename_component(_BOOST_CMAKEDIR \"${CMAKE_CURRENT_LIST_DIR}/../\" ABSOLUTE)" 773 " find_package(boost_${dep_$(name)} $(version) EXACT CONFIG ${_BOOST_REQUIRED} ${_BOOST_QUIET} HINTS ${_BOOST_CMAKEDIR})" 774 " set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_LINK_LIBRARIES Boost::${dep_$(name)})" 775 " unset(_BOOST_QUIET)" 776 " unset(_BOOST_REQUIRED)" 777 " unset(_BOOST_CMAKEDIR)" 778 " if(NOT boost_${dep_$(name)}_FOUND)" 779 " set($(name)_FOUND 0)" 780 " set($(name)_NOT_FOUND_MESSAGE \"A required dependency, boost_${dep_$(name)}, has not been found.\")" 781 " unset(_BOOST_$(lname:U)_DEPS)" 782 " return()" 783 " endif()" 784 "endforeach()" 785 "" 786 "unset(_BOOST_$(lname:U)_DEPS)" 787 "" 788 : true ; 789 790 if $(name) = boost_thread 791 { 792 print.text 793 794 "include(CMakeFindDependencyMacro)" 795 "find_dependency(Threads)" 796 "set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads)" 797 "" 798 : true ; 799 } 800 801 if $(name) = boost_mpi 802 { 803 print.text 804 805 "include(CMakeFindDependencyMacro)" 806 "find_dependency(MPI)" 807 "" 808 "if(MPI_CXX_FOUND AND NOT TARGET MPI::MPI_CXX)" 809 " if(MPI_CXX_COMPILE_FLAGS)" 810 " set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_COMPILE_OPTIONS \"${MPI_CXX_COMPILE_FLAGS}\")" 811 " endif()" 812 " if(MPI_CXX_INCLUDE_PATH)" 813 " set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES \"${MPI_CXX_INCLUDE_PATH}\")" 814 " endif()" 815 " if(MPI_CXX_LINK_FLAGS)" 816 " set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_LINK_OPTIONS \"SHELL:${MPI_CXX_LINK_FLAGS}\")" 817 " endif()" 818 " if(MPI_CXX_LIBRARIES)" 819 " set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_LINK_LIBRARIES \"${MPI_CXX_LIBRARIES}\")" 820 " endif()" 821 "else()" 822 " set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_LINK_LIBRARIES MPI::MPI_CXX)" 823 "endif()" 824 "" 825 : true ; 826 } 827 } 828 829 print.text 830 831 "mark_as_advanced($(name)_DIR)" 832 "" 833 : true ; 834} 835 836actions generate-cmake-config- 837{ 838} 839 840# generate-cmake-config 841 842rule generate-cmake-config ( project name : property-set : sources * ) 843{ 844 .debug generate-cmake-config $(name) ; 845 846 local pname = [ $(property-set).get <name> ] ; 847 local version = [ $(property-set).get <version> ] ; 848 local location = [ $(property-set).get <location> ] ; 849 local library-type = [ $(property-set).get <library-type> ] ; 850 local cmakedir = [ $(property-set).get <boost-install.cmakedir> ] ; 851 local includedir = [ $(property-set).get <boost-install.includedir> ] ; 852 local libdir = [ $(property-set).get <boost-install.libdir> ] ; 853 854 local ps = [ property-set.create 855 <name>$(pname) <version>$(version) <location>$(location) 856 <library-type>$(library-type) 857 <boost-install.cmakedir>$(cmakedir) 858 <boost-install.includedir>$(includedir) 859 <boost-install.libdir>$(libdir) ] ; 860 861 local result ; 862 863 local a = [ new non-scanning-action : boost-install.generate-cmake-config- : $(ps) ] ; 864 865 result += [ new file-target $(name) : : $(project) : $(a) ] ; 866 867 return $(result) ; 868} 869 870# generate-cmake-config-version- 871 872rule generate-cmake-config-version- ( target : sources * : properties * ) 873{ 874 .info generate-cmake-config-version- $(target) ":" $(sources) ; 875 876 local ps = [ property-set.create $(properties) ] ; 877 878 print.output $(target) ; 879 880 local version = [ $(ps).get <version> ] ; 881 .info " version=" $(version) ; 882 883 print.output $(target) ; 884 885 print.text 886 887 "# Generated by Boost $(version)" 888 "" 889 "set(PACKAGE_VERSION $(version))" 890 "" 891 "if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)" 892 " set(PACKAGE_VERSION_COMPATIBLE FALSE)" 893 "else()" 894 " set(PACKAGE_VERSION_COMPATIBLE TRUE)" 895 " if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)" 896 " set(PACKAGE_VERSION_EXACT TRUE)" 897 " endif()" 898 "endif()" 899 "" 900 : true ; 901} 902 903actions generate-cmake-config-version- 904{ 905} 906 907# generate-cmake-config-version 908 909rule generate-cmake-config-version ( project name : property-set : sources * ) 910{ 911 .debug generate-cmake-config-version $(name) ; 912 913 local pname = [ $(property-set).get <name> ] ; 914 local version = [ $(property-set).get <version> ] ; 915 local location = [ $(property-set).get <location> ] ; 916 917 local ps = [ property-set.create <name>$(pname) <version>$(version) <location>$(location) ] ; 918 919 local result ; 920 921 local a = [ new non-scanning-action : boost-install.generate-cmake-config-version- : $(ps) ] ; 922 923 result += [ new file-target $(name) : : $(project) : $(a) ] ; 924 925 return $(result) ; 926} 927 928# install-cmake-config- 929 930local rule install-cmake-config- ( install-or-stage : location : includedir : libdir : version : name ) 931{ 932 #.debug install-cmake-config- $(name) ; 933 934 local r ; 935 936 if [ MATCH boost_(.*) : $(name) ] 937 { 938 local loc = $(location)/$(name)-$(version) ; 939 940 local library-type = UNKNOWN ; 941 942 if $(name) = boost_headers || $(name) = boost_math || $(name) = boost_exception 943 { 944 library-type = INTERFACE ; 945 } 946 947 local reqs = <name>$(name) <version>$(version) <library-type>$(library-type) <boost-install.cmakedir>$(location) <boost-install.includedir>$(includedir) <boost-install.libdir>$(libdir) ; 948 949 r += [ generate $(install-or-stage)/$(name)-config.cmake : $(name) : <generating-rule>@boost-install%generate-cmake-config $(reqs) ] ; 950 r += [ install $(install-or-stage)-$(name)-config.cmake : $(install-or-stage)/$(name)-config.cmake : <location>$(loc) ] ; 951 952 r += [ generate $(install-or-stage)/$(name)-config-version.cmake : $(name) : <generating-rule>@boost-install%generate-cmake-config-version $(reqs) ] ; 953 r += [ install $(install-or-stage)-$(name)-config-version.cmake : $(install-or-stage)/$(name)-config-version.cmake : <location>$(loc) ] ; 954 955 if $(library-type) != INTERFACE 956 { 957 local v = [ generate $(install-or-stage)/$(name)-variant.cmake : $(name) : <generating-rule>@boost-install%generate-cmake-variant $(reqs) ] ; 958 r += $(v) ; 959 r += [ install $(install-or-stage)-$(name)-config-variant.cmake : $(v) : <location>$(loc) ] ; 960 } 961 } 962 else 963 { 964 .info "target '$(name)' not prefixed by 'boost_', omitting CMake config" ; 965 } 966 967 return $(r) ; 968} 969 970# install-or-stage-cmake-config 971# 972# includedir, libdir, cmakedir should be in canonical path.make format 973 974rule install-or-stage-cmake-config ( name * : install-or-stage : includedir : libdir : cmakedir ) 975{ 976 local p = [ project.current ] ; 977 978 if "--no-cmake-config" in [ modules.peek : ARGV ] 979 { 980 alias $(install-or-stage)-cmake-config ; 981 $(p).mark-target-as-explicit $(install-or-stage)-cmake-config ; 982 } 983 else 984 { 985 includedir = [ path.relative-to $(cmakedir) $(includedir) ] ; 986 libdir = [ path.relative-to $(cmakedir) $(libdir) ] ; 987 988 local BOOST_VERSION = [ modules.peek boostcpp : BOOST_VERSION ] ; 989 990 local configs ; 991 992 for local nm in $(name) 993 { 994 configs += [ install-cmake-config- $(install-or-stage) : $(cmakedir) : $(includedir) : $(libdir) : $(BOOST_VERSION) : $(nm) ] ; 995 } 996 997 # Target install/stage-detect-toolset 998 999 local boost-install-dir = [ modules.binding $(__name__) ] ; 1000 boost-install-dir = $(boost-install-dir:D) ; 1001 1002 install $(install-or-stage)-detect-toolset : $(boost-install-dir)/BoostDetectToolset.cmake : <location>$(cmakedir) <name>BoostDetectToolset-$(BOOST_VERSION).cmake ; 1003 $(p).mark-target-as-explicit $(install-or-stage)-detect-toolset ; 1004 1005 # Target install/stage-boost-config 1006 1007 install $(install-or-stage)-boost-config : $(boost-install-dir)/BoostConfig.cmake : <location>$(cmakedir)/Boost-$(BOOST_VERSION) ; 1008 $(p).mark-target-as-explicit $(install-or-stage)-boost-config ; 1009 1010 # Target install/stage-boost-config-version 1011 1012 project.load [ path.make $(boost-install-dir) ] ; 1013 1014 install $(install-or-stage)-boost-config-version : /boost/tools/boost_install//BoostConfigVersion.cmake : <location>$(cmakedir)/Boost-$(BOOST_VERSION) ; 1015 $(p).mark-target-as-explicit $(install-or-stage)-boost-config-version ; 1016 1017 # Target install/stage-cmake-config 1018 1019 alias $(install-or-stage)-cmake-config : $(configs) $(install-or-stage)-detect-toolset $(install-or-stage)-boost-config $(install-or-stage)-boost-config-version ; 1020 $(p).mark-target-as-explicit $(install-or-stage)-cmake-config ; 1021 } 1022} 1023 1024# install-cmake-config 1025 1026rule install-cmake-config ( name * ) 1027{ 1028 #.debug install-cmake-config $(name) ; 1029 1030 local includedir = [ boost-install-dirs.includedir ] ; 1031 local libdir = [ boost-install-dirs.libdir ] ; 1032 local cmakedir = [ boost-install-dirs.cmakedir ] ; 1033 local header-subdir = [ boost-install-dirs.header-subdir ] ; 1034 1035 if $(header-subdir) 1036 { 1037 includedir = $(includedir)/$(header-subdir) ; 1038 } 1039 1040 install-or-stage-cmake-config $(name) : install : $(includedir) : $(libdir) : $(cmakedir) ; 1041} 1042 1043rule stage-cmake-config ( name * ) 1044{ 1045 local includedir = [ path.make [ modules.peek boostcpp : BOOST_ROOT ] ] ; 1046 local libdir = [ boost-install-dirs.stage-libdir ] ; 1047 local cmakedir = $(libdir)/cmake ; 1048 1049 install-or-stage-cmake-config $(name) : stage : $(includedir) : $(libdir) : $(cmakedir) ; 1050} 1051 1052# stage-cmake-config 1053 1054# collect-targets: Returns the targets and all their dependencies. 1055# Copied from stage.jam 1056# TODO: Factor this out as a utility in virtal-target.jam 1057 1058rule collect-targets ( targets * ) 1059{ 1060 # Find subvariants 1061 local s ; 1062 for local t in $(targets) 1063 { 1064 s += [ $(t).creating-subvariant ] ; 1065 } 1066 s = [ sequence.unique $(s) ] ; 1067 1068 local result = [ new set ] ; 1069 $(result).add $(targets) ; 1070 1071 for local i in $(s) 1072 { 1073 $(i).all-referenced-targets $(result) ; 1074 } 1075 local result2 ; 1076 for local r in [ $(result).list ] 1077 { 1078 if $(r:G) != <use> 1079 { 1080 result2 += $(r:G=) ; 1081 } 1082 } 1083 DELETE_MODULE $(result) ; 1084 return [ sequence.unique $(result2) ] ; 1085} 1086 1087# get-dependency-projects: Returns all the projects of any dependency of the sources. 1088 1089rule get-dependency-projects ( sources * ) 1090{ 1091 local result ; 1092 for local t in [ collect-targets $(sources) ] 1093 { 1094 result += [ $(t).project ] ; 1095 } 1096 return [ sequence.unique $(result) ] ; 1097} 1098 1099# generate-dependencies: find and generate the stage and install targets 1100# corresponding to the source libraries. 1101 1102rule generate-dependencies ( project name ? : property-set : sources * ) 1103{ 1104 local stage-targets ; 1105 local stage-or-install = [ $(property-set).get <name> ] ; 1106 local excluded-projects = $(project) [ $(project).find /boost ] ; 1107 for local p in [ get-dependency-projects $(sources) ] [ $(project).find /boost/headers ] 1108 { 1109 if ! ( $(p) in $(excluded-projects) ) 1110 { 1111 stage-targets += [ $(p).find $(stage-or-install) : no-error ] ; 1112 } 1113 } 1114 local props = [ $(property-set).propagated ] ; 1115 local result ; 1116 local usage-requirements = [ property-set.empty ] ; 1117 for local t in $(stage-targets) 1118 { 1119 local g = [ $(t).generate $(props) ] ; 1120 usage-requirements = [ $(usage-requirements).add $(g[1]) ] ; 1121 result += $(g[2-]) ; 1122 } 1123 return $(usage-requirements) $(result) ; 1124} 1125 1126# boost-install 1127 1128local rule install-stage-subdir ( properties * ) 1129{ 1130 local ps = [ property-set.create $(properties) ] ; 1131 1132 local r = [ boostcpp.tag boost : STATIC_LIB : $(ps) ] ; 1133 1134 r = $(r:S=) ; 1135 1136 local r2 = [ MATCH "lib(.*)" : $(r) ] ; 1137 if $(r2) { r = $(r2) ; } 1138 1139 local python = [ $(ps).get <python> ] ; 1140 1141 if $(python) 1142 { 1143 r = $(r:B=$(r:B)-python$(python)) ; 1144 } 1145 1146 return $(r) ; 1147} 1148 1149rule stage-subdir ( properties * ) 1150{ 1151 local r = [ install-stage-subdir $(properties) ] ; 1152 1153 local libdir = [ boost-install-dirs.stage-libdir ] ; 1154 1155 return <location>$(libdir)/$(r) ; 1156} 1157 1158rule install-subdir ( properties * ) 1159{ 1160 local r = [ install-stage-subdir $(properties) ] ; 1161 1162 local libdir = [ boost-install-dirs.libdir ] ; 1163 1164 return <location>$(libdir)/$(r) ; 1165} 1166 1167rule boost-install ( libraries * ) 1168{ 1169 .debug boost-install $(libraries) ; 1170 1171 local l2 = ; 1172 local unprefixed = ; 1173 1174 for local lib in $(libraries) 1175 { 1176 if [ MATCH boost_(.*) : $(lib) ] 1177 { 1178 l2 += $(lib) ; 1179 } 1180 else 1181 { 1182 unprefixed += $(lib) ; 1183 } 1184 } 1185 1186 libraries = $(l2) ; 1187 1188 # Target install 1189 1190 local p = [ project.current ] ; 1191 1192 package.install install-libraries Boost 1193 : <install-no-version-symlinks>on 1194 : # No binaries 1195 : $(libraries) 1196 : # No headers 1197 ; 1198 1199 $(p).mark-target-as-explicit install-libraries ; 1200 1201 install install-unprefixed-static : $(unprefixed) : <install-type>STATIC_LIB <conditional>@boost-install%install-subdir ; 1202 $(p).mark-target-as-explicit install-unprefixed-static ; 1203 1204 install install-unprefixed-shared : $(unprefixed) : <install-type>SHARED_LIB <install-no-version-symlinks>on <conditional>@boost-install%install-subdir ; 1205 $(p).mark-target-as-explicit install-unprefixed-shared ; 1206 1207 install-cmake-config $(libraries) ; 1208 1209 generate install-dependencies : $(libraries) : <generating-rule>@boost-install%generate-dependencies <name>install ; 1210 $(p).mark-target-as-explicit install-dependencies ; 1211 1212 alias install : install-libraries install-unprefixed-static install-unprefixed-shared install-cmake-config install-dependencies ; 1213 $(p).mark-target-as-explicit install ; 1214 1215 # Target stage 1216 1217 local stage-libdir = [ boost-install-dirs.stage-libdir ] ; 1218 1219 stage-cmake-config $(libraries) ; 1220 1221 install stage-libraries-static : $(libraries) : <location>$(stage-libdir) <install-dependencies>on <install-type>STATIC_LIB ; 1222 $(p).mark-target-as-explicit stage-libraries-static ; 1223 1224 install stage-libraries-shared : $(libraries) : <location>$(stage-libdir) <install-dependencies>on <install-type>SHARED_LIB <install-no-version-symlinks>on ; 1225 $(p).mark-target-as-explicit stage-libraries-shared ; 1226 1227 install stage-unprefixed-static : $(unprefixed) : <install-type>STATIC_LIB <conditional>@boost-install%stage-subdir ; 1228 $(p).mark-target-as-explicit stage-unprefixed-static ; 1229 1230 install stage-unprefixed-shared : $(unprefixed) : <install-type>SHARED_LIB <install-no-version-symlinks>on <conditional>@boost-install%stage-subdir ; 1231 $(p).mark-target-as-explicit stage-unprefixed-shared ; 1232 1233 generate stage-dependencies : $(libraries) : <generating-rule>@boost-install%generate-dependencies <name>stage ; 1234 $(p).mark-target-as-explicit stage-dependencies ; 1235 1236 alias stage : stage-libraries-static stage-libraries-shared stage-unprefixed-static stage-unprefixed-shared stage-cmake-config stage-dependencies ; 1237 $(p).mark-target-as-explicit stage ; 1238} 1239