# # CMake configuration support for stage/install # # Copyright 2017 Peter Dimov # # Distributed under the Boost Software License, 1.0 # import print ; import option ; import os ; import path ; import boostcpp ; import modules ; import property-set ; import "class" : new ; import feature ; import toolset ; import regex ; if "--debug-cmake" in [ modules.peek : ARGV ] { .info-enabled = 1 ; } local rule .info ( messages * ) { if $(.info-enabled) { ECHO info: $(messages) ; } } # local BOOST_STAGE_LOCATE = [ option.get stagedir : ../stage ] ; .info BOOST_STAGE_LOCATE is $(BOOST_STAGE_LOCATE) ; local BOOST_VERSION_TAG = [ modules.peek boostcpp : BOOST_VERSION_TAG ] ; .info BOOST_VERSION_TAG is $(BOOST_VERSION_TAG) ; # layout local layout = [ modules.peek boostcpp : layout ] ; .info layout is $(layout) ; # prefix local default-prefix = "" ; if [ os.name ] = NT { default-prefix = C:/Boost ; } else { default-prefix = /usr/local ; } .info default-prefix is $(default-prefix) ; local prefix = [ option.get prefix : $(default-prefix) ] ; .info prefix is $(prefix) ; # header-subdir header-subdir = "" ; if $(layout) = versioned { header-subdir = /boost-$(BOOST_VERSION_TAG) ; } .info header-subdir is $(header-subdir) ; # libdir local libdir = [ option.get libdir : $(prefix)/lib ] ; .info libdir is $(libdir) ; # generate-config local rule generate-config ( target type ) { .info generate-config $(target) :: $(type) ; local name = [ MATCH boost_(.*)-config.cmake : $(target) ] ; .info generate-config: name is $(name) ; local cmake-lib = boost_$(name) ; local cmake-target = boost::$(name) ; print.output $(target) ; print.text "# Generated by Boost $(BOOST_VERSION)" "" "cmake_minimum_required(VERSION 3.5)" "" "if(TARGET $(cmake-target))" " return()" "endif()" "" "# Compute the installation prefix relative to this file." "get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)" "get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)" "get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)" "get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)" "" "# Create imported target $(cmake-target)" "add_library($(cmake-target) $(type) IMPORTED)" "" "set_target_properties($(cmake-target) PROPERTIES" " INTERFACE_INCLUDE_DIRECTORIES \"\${_IMPORT_PREFIX}/include$(header-subdir)\"" ")" "" "get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)" "file(GLOB CONFIG_FILES "${_DIR}/libboost_$(name)-config-variant*.cmake")" "foreach(f ${CONFIG_FILES})" " include(${f})" "endforeach()" "" "set(CONFIG_FILES)" "set(_DIR)" "set(_IMPORT_PREFIX)" "" "include(CMakeFindDependencyMacro)" "function(boost_declare_dependency package type target)" " find_dependency(${package} $(BOOST_VERSION) EXACT)" " set_property(TARGET boost::$(name) APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${target})" "endfunction()" "include(\${CMAKE_CURRENT_LIST_DIR}/$(cmake-lib)-dependencies.cmake)" "" : true ; } rule generate-header-config ( target : sources * : properties * ) { generate-config $(target) INTERFACE ; } rule generate-static-config ( target : sources * : properties * ) { generate-config $(target) UNKNOWN ; } # generate-config-version rule generate-config-version ( target : sources * : properties * ) { .info generate-config-version $(target) ; local name = [ MATCH boost_(.*)-config-version.cmake : $(target) ] ; .info generate-config-version: name is $(name) ; print.output $(target) ; print.text "# Generated by Boost $(BOOST_VERSION)" "" "set(PACKAGE_VERSION $(BOOST_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-config-variant- rule generate-config-variant- ( target : sources * : properties * ) { .info generate-config-variant- $(target) ; local ps = [ property-set.create $(properties) ] ; print.output $(target) ; print.text "# Generated by Boost $(BOOST_VERSION)" "" : true ; local variant = [ $(ps).get ] ; .info generate-config-variant-: variant is $(variant) ; print.text "# variant=$(variant)" "" : true ; if $(variant) = debug { print.text "if(\"${BOOST_BUILD_VARIANT}\" STREQUAL \"RELEASE\")" " return()" "endif()" "" : true ; } else { print.text "if(\"${BOOST_BUILD_VARIANT}\" STREQUAL \"DEBUG\")" " return()" "endif()" "" : true ; } local link = [ $(ps).get ] ; .info generate-config-variant-: link is $(link) ; print.text "# link=$(link)" "" : true ; if $(link) = static { print.text "if(\"${BOOST_LINK_TYPE}\" STREQUAL \"SHARED\")" " return()" "endif()" "" : true ; } else { print.text "if(NOT \"${BOOST_LINK_TYPE}\" STREQUAL \"SHARED\")" " return()" "endif()" "" : true ; } local runtime-link = [ $(ps).get ] ; .info generate-config-variant-: runtime-link is $(runtime-link) ; print.text "# runtime-link=$(runtime-link)" "" : true ; if $(runtime-link) = static { print.text "if(NOT \"${BOOST_RUNTIME_LINK}\" STREQUAL \"STATIC\")" " return()" "endif()" "" : true ; } else { print.text "if(\"${BOOST_RUNTIME_LINK}\" STREQUAL \"STATIC\")" " return()" "endif()" "" : true ; } local runtime-debugging = [ $(ps).get ] ; .info generate-config-variant-: runtime-debugging is $(runtime-debugging) ; print.text "# runtime-debugging=$(runtime-debugging)" "" : true ; local toolset = [ $(ps).get ] ; .info generate-config-variant-: toolset is $(toolset) ; print.text "# toolset=$(toolset)" "" : true ; local name = [ MATCH boost_(.*)-config-variant-.*cmake : $(target) ] ; .info generate-config-variant-: name is $(name) ; local ftype = STATIC_LIB ; if $(link) = shared { if [ os.name ] = NT { ftype = IMPORT_LIB ; } else { ftype = SHARED_LIB ; } } local fname = [ boostcpp.tag boost_$(name) : $(ftype) : $(ps) ] ; .info generate-config-variant-: fname is $(fname) ; print.text "# Target file name: $(fname)" "" : true ; print.text "set_property(TARGET boost::$(name) APPEND PROPERTY IMPORTED_CONFIGURATIONS $(variant:U))" "set_target_properties(boost::$(name) PROPERTIES" " IMPORTED_LINK_INTERFACE_LANGUAGES_$(variant:U) CXX" " IMPORTED_LOCATION_$(variant:U) \"${_IMPORT_PREFIX}/lib/$(fname)\"" " )" "" : true ; } # tag rule tag ( name : type ? : property-set ) { .info tag $(name) :: $(type) :: $(property-set) ; local link = [ $(property-set).get ] ; .info tag: link is $(link) ; local r = [ boostcpp.tag $(name) : STATIC_LIB : $(property-set) ] ; r = $(r:S=$(name:S)) ; r = $(r:B=$(r:B)-$(link)) ; .info tag: returning $(r) ; return $(r) ; } # generate-config-variant rule generate-config-variant ( project name : property-set : sources * ) { .info generate-config-variant $(project) $(name) :: $(property-set) :: $(sources) ; local tag = [ tag $(name) : : $(property-set) ] ; .info generate-config-variant: tag is $(tag) ; local result ; local a = [ new non-scanning-action : $(__name__).generate-config-variant- : $(property-set) ] ; result += [ new file-target $(tag) : : $(project) : $(a) ] ; return $(result) ; } # exists local rule exists ( path ) { return [ glob $(path) ] ; } # boostdep-cmake alias boostdep : ../tools/boostdep/build//boostdep : release static shared off NDEBUG multi ; feature.feature boostdep-module : : free ; toolset.flags boostdep-cmake MODULE : ; actions boostdep-cmake { $(2) --cmake $(MODULE) > $(1) } # create stage and install targets local library-dirs = [ MATCH (.*)/include : [ glob ../libs/*/include ../libs/numeric/*/include ] ] ; for dir in $(library-dirs) { .info Processing directory $(dir) ; local rname = [ MATCH .*/libs/(.*) : $(dir) ] ; .info rname is $(rname) ; local name = [ regex.replace $(rname) "/" "_" ] ; .info name is $(name) ; local reqs = release static shared off NDEBUG multi ; # generate -config.cmake local config-targets ; # boost_math, a dependency of lexical_cast, has six optional libraries, none of which named boost_math # boost_exception has an optional MSVC-only library, which creates problems under Linux if [ exists $(dir)/build ] && [ exists $(dir)/src ] && $(name) != "math" && $(name) != "exception" { .info Library $(name) is not header-only ; make boost_$(name)-config.cmake : : @generate-static-config : $(reqs) ; explicit boost_$(name)-config.cmake ; config-targets = boost_$(name)-config.cmake ; generate boost_$(name)-config-variant.cmake : : @generate-config-variant multi ; explicit boost_$(name)-config-variant.cmake ; config-targets += boost_$(name)-config-variant.cmake ; } else { .info Library $(name) is header-only ; make boost_$(name)-config.cmake : : @generate-header-config : $(reqs) ; explicit boost_$(name)-config.cmake ; config-targets = boost_$(name)-config.cmake ; } # generate -config-version.cmake make boost_$(name)-config-version.cmake : : @generate-config-version : $(reqs) ; explicit boost_$(name)-config-version.cmake ; config-targets += boost_$(name)-config-version.cmake ; # generate -dependencies.cmake make boost_$(name)-dependencies.cmake : boostdep : @boostdep-cmake : $(rname) $(reqs) ; config-targets += boost_$(name)-dependencies.cmake ; .info The config-targets of $(name) are $(config-targets) ; # stage local stage-location = $(BOOST_STAGE_LOCATE)/lib/cmake/boost_$(name)-$(BOOST_VERSION) ; .info The staging location of $(name) is $(stage-location) ; install $(dir)-stage : $(config-targets) : $(stage-location) ; explicit $(dir)-stage ; # install local install-location = $(libdir)/cmake/boost_$(name)-$(BOOST_VERSION) ; .info The install location of $(name) is $(install-location) ; install $(dir)-install : $(config-targets) : $(install-location) ; explicit $(dir)-install ; } # stage alias stage : $(library-dirs)-stage ; explicit stage ; # install alias install : $(library-dirs)-install ; explicit install ;