# Copyright 2018 Peter Dimov # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) import modules ; import boostcpp ; import property-set ; import "class" : new ; import project ; import common ; import virtual-target ; import print ; import os ; import feature ; import package ; import sequence ; import type ; import boost-install-dependencies ; feature.feature library-type : : free ; if "--verbose" in [ modules.peek : ARGV ] { .info-enabled = 1 ; } if "--debug-boost-install" in [ modules.peek : ARGV ] { .debug-enabled = 1 ; } local rule .info ( messages * ) { if $(.info-enabled) { ECHO "info:" $(messages) ; } } local rule .debug ( messages * ) { if $(.debug-enabled) { ECHO "boost-install:" $(messages) ; } } # generate-cmake-variant- rule generate-cmake-variant- ( target : sources * : properties * ) { .info generate-cmake-variant- $(target) ":" $(sources) ; local ps = [ property-set.create $(properties) ] ; print.output $(target) ; local version = [ $(ps).get ] ; .info " version=" $(version) ; local name = [ $(ps).get ] ; .info " name=" $(name) ; local variant = [ $(ps).get ] ; .info " variant=" $(variant) ; local link = [ $(ps).get ] ; .info " link= " $(link) ; local runtime-link = [ $(ps).get ] ; .info " runtime-link=" $(runtime-link) ; local runtime-debugging = [ $(ps).get ] ; .info " runtime-debugging=" $(runtime-debugging) ; local threading = [ $(ps).get ] ; .info " threading=" $(threading) ; local address-model = [ $(ps).get ] ; .info " address-model=" $(address-model) ; local toolset = [ MATCH ^-(.*) : [ common.format-name : "" : "" : $(ps) ] ] ; .info " toolset=" $(toolset) ; local fname = $(sources[1]:BS) ; .info " fname=" $(fname) ; print.text "# Generated by Boost $(version)" "" : true ; print.text "# variant=$(variant)" "" : true ; if $(variant) = debug { print.text "if(NOT \"${Boost_USE_DEBUG_LIBS}\" STREQUAL \"\" AND NOT Boost_USE_DEBUG_LIBS)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to NOT Boost_USE_DEBUG_LIBS\")" " endif()" " return()" "endif()" "" : true ; } else { print.text "if(NOT \"${Boost_USE_RELEASE_LIBS}\" STREQUAL \"\" AND NOT Boost_USE_RELEASE_LIBS)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to NOT Boost_USE_RELEASE_LIBS\")" " endif()" " return()" "endif()" "" : true ; } print.text "# link=$(link)" "" : true ; if $(link) = static { print.text "if(NOT Boost_USE_STATIC_LIBS)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to NOT Boost_USE_STATIC_LIBS\")" " endif()" " return()" "endif()" "" : true ; } else { print.text "if(Boost_USE_STATIC_LIBS)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to Boost_USE_STATIC_LIBS\")" " endif()" " return()" "endif()" "" : true ; } print.text "# runtime-link=$(runtime-link)" "" : true ; if $(runtime-link) = static { print.text "if(NOT Boost_USE_STATIC_RUNTIME)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to NOT Boost_USE_STATIC_RUNTIME\")" " endif()" " return()" "endif()" "" : true ; } else { print.text "if(Boost_USE_STATIC_RUNTIME)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to Boost_USE_STATIC_RUNTIME\")" " endif()" " return()" "endif()" "" : true ; } print.text "# runtime-debugging=$(runtime-debugging)" "" : true ; #| if $(runtime-debugging) = "on" { print.text "if(NOT Boost_USE_DEBUG_RUNTIME)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to NOT Boost_USE_DEBUG_RUNTIME\")" " endif()" " return()" "endif()" "" : true ; } else { print.text "if(Boost_USE_DEBUG_RUNTIME)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to Boost_USE_DEBUG_RUNTIME\")" " endif()" " return()" "endif()" "" : true ; } |# print.text "# threading=$(threading)" "" : true ; print.text "# address-model=$(address-model)" "" : true ; if $(address-model) = 32 { print.text "if(CMAKE_SIZEOF_VOID_P EQUAL 8)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to CMAKE_SIZEOF_VOID_P == 8\")" " endif()" " return()" "endif()" "" : true ; } else { print.text "if(CMAKE_SIZEOF_VOID_P EQUAL 4)" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to CMAKE_SIZEOF_VOID_P == 4\")" " endif()" " return()" "endif()" "" : true ; } print.text "# toolset=$(toolset)" "" : true ; print.text "if(Boost_COMPILER AND NOT Boost_COMPILER STREQUAL \"$(toolset)\")" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to Boost_COMPILER (${Boost_COMPILER}) != $(toolset)\")" " endif()" " return()" "endif()" "" "if(BOOST_DETECTED_TOOLSET AND NOT BOOST_DETECTED_TOOLSET STREQUAL \"$(toolset)\")" " if(Boost_DEBUG)" " message(STATUS \" $(fname) skipped due to BOOST_DETECTED_TOOLSET (${BOOST_DETECTED_TOOLSET}) != $(toolset)\")" " endif()" " return()" "endif()" "" "message(STATUS \" $(fname)\")" "" : true ; local lname = [ MATCH boost_(.*) : $(name) ] ; .info " lname=" $(lname) ; local target = "Boost::$(lname)" ; .info " target=" $(target) ; print.text "# Target file name: $(fname)" : true ; print.text "set_property(TARGET $(target) APPEND PROPERTY IMPORTED_CONFIGURATIONS $(variant:U))" "set_target_properties($(target) PROPERTIES" " IMPORTED_LINK_INTERFACE_LANGUAGES_$(variant:U) CXX" " IMPORTED_LOCATION_$(variant:U) \"${_IMPORT_PREFIX}/lib/$(fname)\"" " )" "" : true ; if $(link) = shared { print.text "set_target_properties($(target) PROPERTIES" " INTERFACE_COMPILE_DEFINITIONS \"BOOST_$(lname:U)_DYN_LINK\"" " )" "" : true ; } } # tag local rule tag ( name : type ? : property-set ) { #.debug tag $(name) ":" $(type) ":" $(property-set) ; local link = [ $(property-set).get ] ; #.debug "tag: link is $(link)" ; local r = [ boostcpp.tag $(name) : STATIC_LIB : $(property-set) ] ; r = $(r:S=$(name:S)) ; r = $(r:B=$(r:B)-$(link)) ; #.debug "tag: returning $(r)" ; return $(r) ; } # choose-lib-target: get the import library, if present, the # shared/static library otherwise, ignore .pdb et al local rule choose-lib-target ( sources * ) { local result ; for local t in $(sources) { if [ type.is-derived [ $(t).type ] IMPORT_LIB ] { return $(t) ; } else if [ type.is-derived [ $(t).type ] LIB ] { result = $(t) ; } } return $(result) ; } # generate-cmake-variant rule generate-cmake-variant ( project name : property-set : sources * ) { .debug generate-cmake-variant $(name) ; for local s in $(sources) { .debug " name=" [ $(s).name ] ; } local lib-target = [ choose-lib-target $(sources) ] ; if $(lib-target) { .debug " lib-target=" [ $(lib-target).name ] ; } local tag = [ tag $(name) : : $(property-set) ] ; #.debug "generate-cmake-variant:" tag is $(tag) ; local result ; local a = [ new non-scanning-action $(lib-target) : boost-install.generate-cmake-variant- : $(property-set) ] ; result += [ new file-target $(tag) : : $(project) : $(a) ] ; return $(result) ; } # deps local rule deps ( ln ) { if $(ln) = "prg_exec_monitor" || $(ln) = "test_exec_monitor" || $(ln) = "unit_test_framework" { ln = test ; } local r = [ modules.peek boost-install-dependencies : $(ln) ] ; if ! $(r) { ln = [ MATCH "([a-z]+)_.*" : $(ln) ] ; if $(ln) { r = [ modules.peek boost-install-dependencies : $(ln) ] ; } } return $(r) ; } # generate-cmake-config- rule generate-cmake-config- ( target : sources * : properties * ) { .info generate-cmake-config- $(target) ":" $(sources) ; local ps = [ property-set.create $(properties) ] ; print.output $(target) ; local version = [ $(ps).get ] ; .info " version=" $(version) ; local name = [ $(ps).get ] ; .info " name=" $(name) ; local library-type = [ $(ps).get ] ; .info " library-type=" $(library-type) ; local lname = [ MATCH boost_(.*) : $(name) ] ; .info " lname=" $(lname) ; local ltarget = "Boost::$(lname)" ; .info " ltarget=" $(ltarget) ; local BOOST_VERSION_TAG = [ modules.peek boostcpp : BOOST_VERSION_TAG ] ; .info " BOOST_VERSION_TAG=" $(BOOST_VERSION_TAG) ; local layout = [ modules.peek boostcpp : layout ] ; .info " layout=" $(layout) ; local header-subdir = "" ; if $(layout) = versioned { header-subdir = /boost-$(BOOST_VERSION_TAG) ; } .info " header-subdir=" $(header-subdir) ; print.output $(target) ; print.text "# Generated by Boost $(version)" "" "cmake_minimum_required(VERSION 3.5)" "" "if(TARGET $(ltarget))" " return()" "endif()" "" "message(STATUS \"Found $(name)\")" "" "# Compute the installation prefix relative to this file." "get_filename_component(_IMPORT_PREFIX \"${CMAKE_CURRENT_LIST_DIR}/../../../\" ABSOLUTE)" "" "# Create imported target $(ltarget)" "add_library($(ltarget) $(library-type) IMPORTED)" "" "set_target_properties($(ltarget) PROPERTIES" " INTERFACE_INCLUDE_DIRECTORIES \"\${_IMPORT_PREFIX}/include$(header-subdir)\"" " INTERFACE_COMPILE_DEFINITIONS \"BOOST_ALL_NO_LIB\"" ")" : true ; if $(library-type) != INTERFACE { print.text "" "include(${CMAKE_CURRENT_LIST_DIR}/../BoostDetectToolset-$(version).cmake)" "" "if(Boost_DEBUG)" " message(STATUS \"Scanning ${CMAKE_CURRENT_LIST_DIR}/lib$(name)-variant*.cmake\")" "endif()" "" "file(GLOB variants \"${CMAKE_CURRENT_LIST_DIR}/lib$(name)-variant*.cmake\")" "" "foreach(f IN LISTS variants)" " if(Boost_DEBUG)" " message(STATUS \" Including ${f}\")" " endif()" " include(${f})" "endforeach()" "" "unset(variants)" "unset(_IMPORT_PREFIX)" "" "include(CMakeFindDependencyMacro)" "" : true ; local deps = [ deps $(lname) ] ; .info " deps=" $(deps) ; for local dep in $(deps) { print.text "find_dependency(boost_$(dep) $(version) EXACT)" "set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_LINK_LIBRARIES Boost::$(dep))" "" : true ; } if $(name) = boost_thread { print.text "find_dependency(Threads)" "set_property(TARGET $(ltarget) APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads)" "" : true ; } } } # generate-cmake-config rule generate-cmake-config ( project name : property-set : sources * ) { .debug generate-cmake-config $(name) ; local pname = [ $(property-set).get ] ; local version = [ $(property-set).get ] ; local location = [ $(property-set).get ] ; local library-type = [ $(property-set).get ] ; local ps = [ property-set.create $(pname) $(version) $(location) $(library-type) ] ; local result ; local a = [ new non-scanning-action : boost-install.generate-cmake-config- : $(ps) ] ; result += [ new file-target $(name) : : $(project) : $(a) ] ; return $(result) ; } # generate-cmake-config-version- rule generate-cmake-config-version- ( target : sources * : properties * ) { .info generate-cmake-config-version- $(target) ":" $(sources) ; local ps = [ property-set.create $(properties) ] ; print.output $(target) ; local version = [ $(ps).get ] ; .info " version=" $(version) ; print.output $(target) ; print.text "# Generated by Boost $(version)" "" "set(PACKAGE_VERSION $(version))" "" "if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)" " set(PACKAGE_VERSION_COMPATIBLE FALSE)" "else()" " set(PACKAGE_VERSION_COMPATIBLE TRUE)" " if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)" " set(PACKAGE_VERSION_EXACT TRUE)" " endif()" "endif()" "" : true ; } # generate-cmake-config-version rule generate-cmake-config-version ( project name : property-set : sources * ) { .debug generate-cmake-config-version $(name) ; local pname = [ $(property-set).get ] ; local version = [ $(property-set).get ] ; local location = [ $(property-set).get ] ; local ps = [ property-set.create $(pname) $(version) $(location) ] ; local result ; local a = [ new non-scanning-action : boost-install.generate-cmake-config-version- : $(ps) ] ; result += [ new file-target $(name) : : $(project) : $(a) ] ; return $(result) ; } # install-cmake-config- local rule install-cmake-config- ( location : version : name ) { #.debug install-cmake-config- $(name) ; local loc = $(location)/cmake/$(name)-$(version) ; local library-type = UNKNOWN ; if $(name) = boost_headers || $(name) = boost_math || $(name) = boost_exception { library-type = INTERFACE ; } local reqs = $(name) $(version) $(loc) $(library-type) ; local r ; r += [ generate $(name)-config.cmake : $(name) : @generate-cmake-config $(reqs) ] ; r += [ generate $(name)-config-version.cmake : $(name) : @generate-cmake-config-version $(reqs) ] ; if $(library-type) != INTERFACE { r += [ generate $(name)-variant.cmake : $(name) : @generate-cmake-variant $(reqs) ] ; } return $(r) ; } # install-cmake-config rule install-cmake-config ( location : version : name * ) { #.debug install-cmake-config $(name) ; local configs ; for local nm in $(name) { configs += [ install-cmake-config- $(location) : $(version) : $(nm) ] ; } local p = [ project.current ] ; alias install-cmake-config : $(configs) ; $(p).mark-target-as-explicit install-cmake-config ; } # boost-install rule boost-install ( ROOT : VERSION : libraries * ) { .debug boost-install $(libraries) ; # Compute install-requirements local install-requirements ; local layout = [ modules.peek boostcpp : layout ] ; local BOOST_VERSION_TAG = [ modules.peek boostcpp : BOOST_VERSION_TAG ] ; if $(layout) = versioned { install-requirements += boost-$(BOOST_VERSION_TAG) ; } local install-default-prefix ; if [ os.name ] = NT { install-default-prefix = C:/Boost ; } else { install-default-prefix = /usr/local ; } install-requirements += $(install-default-prefix) ; # Target install-libraries local p = [ project.current ] ; package.install install-libraries boost : $(install-requirements) : # No binaries : $(libraries) : # No headers ; $(p).mark-target-as-explicit install-libraries ; # Target install-cmake-config local prefix = [ option.get prefix : $(install-default-prefix) ] ; local lib-locate = [ option.get libdir : $(prefix)/lib ] ; install-cmake-config $(lib-locate) : $(VERSION) : $(libraries) ; # Target install-detect-toolset local boost-install-dir = [ modules.binding $(__name__) ] ; boost-install-dir = $(boost-install-dir:D) ; install install-detect-toolset : $(boost-install-dir)/BoostDetectToolset.cmake : $(lib-locate)/cmake BoostDetectToolset-$(VERSION).cmake ; $(p).mark-target-as-explicit install-detect-toolset ; # Gather dependencies local deps = ; for local lib in $(libraries) { local lname = [ MATCH boost_(.*) : $(lib) ] ; deps += [ deps $(lname) ] ; } deps = [ sequence.unique $(deps) ] ; # Target install alias install : install-libraries install-cmake-config install-detect-toolset /boost/$(deps)//install ; $(p).mark-target-as-explicit install ; # Target stage local stage-locate = [ modules.peek boostcpp : BOOST_STAGE_LOCATE ] ; install stage-libraries : $(libraries) : $(stage-locate)/lib ; $(p).mark-target-as-explicit stage-libraries ; alias stage : stage-libraries /boost/$(deps)//stage ; $(p).mark-target-as-explicit stage ; }