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