]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/src/tools/cray.jam
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / tools / build / src / tools / cray.jam
CommitLineData
92f5a8d4
TL
1# Copyright 2001 David Abrahams
2# Copyright 2004, 2005 Markus Schoepflin
3# Copyright 2011 John Maddock
4# Copyright 2013, 2017-2018 Cray, Inc.
5#
7c673cae 6# Distributed under the Boost Software License, Version 1.0.
92f5a8d4
TL
7# (See accompanying file LICENSE_1_0.txt or copy at
8# http://www.boost.org/LICENSE_1_0.txt)
7c673cae 9
92f5a8d4
TL
10# README.md
11#
12# This toolset is for the Cray Compiling Environment (CCE).
13#
14# The assembler, linker, and archiver are the same as those used in the
15# `gcc` toolset. Therefore, there is some duplication of code between the
16# `gcc` toolset and this toolset.
17#
18# # CCE Introduction
19#
20# Users want to compile and run massively parallel applications on Cray
21# supercomputers. Typically, the user compiles code on a login node of the
22# supercomputer and then runs the compiled program on multiple compute
23# nodes using a batch control system. This means the user is almost always
24# cross compiling.
25#
26# But, they're not just cross compiling. In order for a program to run on
27# a Cray supercomputer it has to link to particular libraries. There are
28# three general categories of libraries that user programs must link to:
7c673cae 29#
92f5a8d4
TL
30# - Network libraries: Enable communication between processes on different
31# compute nodes. Depends on the network hardware in the supercomputer.
32# - Compute node libraries: Depends on the hardware on the targeted
33# compute nodes.
34# - Language extension libraries: Depends on the language extensions used
35# by the program (e.g. OpenMP, Unified Parallel C, et cetera).
7c673cae 36#
92f5a8d4
TL
37# Instead of forcing users to invoke the compiler with a bunch of
38# libraries listed on the command line, CCE decides what libraries to link
39# based on the environment. This is primarily controlled by loading and
40# unloading modules (with the `module` command) to create a cross
41# compiling and linking environment suitable for the particular hardware
42# on the targeted Cray supercomputer.
43#
44# CCE compilers come in two parts: the compiler itself, and the compiler
45# driver. Invoking a compiler directly is not supported. We must always
46# invoke the compiler through a compiler driver: either `cc` for C code,
47# `CC` for C++ code, or `ftn` for Fortran code. The compiler driver is
48# responsible for gathering information from the environment and invoking
49# the selected compiler with the appropriate command line options.
50#
51# For more information on CCE, search for Cray publication S-2529 on the
52# Cray publications website (https://pubs.cray.com).
53
54import "class" : new ;
55import common ;
56import feature ;
57import gcc ;
58import generators ;
59import os ;
60import regex ;
61import set ;
62import toolset ;
63import type ;
64import unix ;
65
66###
67### 'init'
68###
69
70rule init ( : : options * : requirements * )
71{
72
73 # User cannot specify a 'version' in their 'using' statement. Compiler
74 # version is always controlled by loading and unloading modules in the
75 # user's environment.
76
77 # User cannot specify a 'command' in their 'using' statement. Using a
78 # single 'command' argument only makes sense when a single executable can
79 # compile different types of code (e.g. gcc will compile C or C++ based on
80 # the file name extensions). In CCE, you have to invoke one of the three
81 # compiler drivers: cc for C code, CC for C++ code, or ftn for Fortran
82 # code. Each compiler driver compiles a single type of source code. It is
83 # possible to let the user pass in three 'command' arguments, one for each
84 # driver, but that seems like more effort that it's worth.
85
86 local toolset = cray ;
87
88 check-prgenv-module $(toolset) ;
89
90 local command-c = [ validate-command $(toolset) cc ] ;
91 local command-cxx = [ validate-command $(toolset) CC ] ;
92 local command-fortran = [ validate-command $(toolset) ftn ] ;
93
94 # Archive builder.
95 local command-ar = [ validate-command $(toolset) ar ] ;
96
97 # Archive indexer.
98 local command-ranlib = [ validate-command $(toolset) ranlib ] ;
99
100 # The 'command' variables always have one element, but they may contain
101 # spaces (e.g. if 'command' is an absolute path and some path components
102 # have spaces).
103
104 local version = ;
105 local developer-build = ;
106 {
107 local version-string = [ SHELL "\"$(command-cxx)\" -VV 2>&1" ] ;
108 local version-components = [ MATCH "Version ([0-9]+).([0-9]+).([a-zA-Z0-9]+)" : $(version-string) ] ;
109 if ! [ MATCH "([0-9]+)" : $(version-components[3]) ]
110 {
111
112 # The last component of the version is not a series of digits. This means
113 # we're probably using a developer build of CCE (i.e. a compiler built by
114 # a Cray employee). Developer builds report versions like '8.7.x'.
115
116 developer-build = true ;
117
118 # We want to treat developer builds as though they are the highest
119 # possible patch version of the release. Effectively, we want to turn
120 # '8.7.x' into '8.7.99'.
121
122 version-components = $(version-components[1]) $(version-components[2]) 99 ;
123
124 }
125
126 version = $(version-components:J=.) ;
127 }
128
129 local build = ;
130 if $(developer-build)
131 {
132
133 # If this is a developer build, we want to add the build subfeature to the
134 # compiler.
135
136 local version-string = [ SHELL "\"$(command-cxx)\" -VV 2>&1" ] ;
137 build = [ MATCH "[(][0-9]+_([0-9a-fA-F]+)[)]" : $(version-string) ] ;
138
139 # Truncate build hash to 7 characters
140 build = [ MATCH "(.......)................................." : $(build) ] ;
141 }
142
143 # IMPORTANT: 'set-cray-feature-defaults' causes the Boost.Build tests to
144 # fail. I tried using an 'init' argument called 'ignore-cray-defaults' and
145 # setting up 'test-config.jam' to pass 'ignore-cray-defaults' during
146 # testing, but I couldn't get the test to read my 'test-config.jam' file
147 # when running tests individually. So, I just comment out
148 # 'set-cray-feature-defaults' during testing.
149
150 set-cray-feature-defaults ;
151
152 {
153
154 # 'check-init-parameters' ensures that each time a toolset is initialized,
155 # it is initialized with a unique configuration. The return value is a
156 # Boost.Build property condition which uniquely identifies this
157 # configured instance of this toolset. Typically, toolsets use the
158 # returned condition as the conditional in a 'toolset.flags' call to set
159 # flags specific to this configuration of this toolset.
160
161 local identifying-condition = [ common.check-init-parameters $(toolset) $(requirements) : version $(version) : build $(build) ] ;
162
163 # 'handle-options' uses 'toolset.flags' to set 'CONFIG_COMMAND' variables
164 # on targets when this toolset is used. The 'CONFIG_COMMAND' variables
165 # specify the commands to call for compiling. This would be more relevant
166 # if our 'init' rule had arguments that might affect the command that is
167 # invoked (e.g. in many toolsets 'version' affects the name of the
168 # compiler command). For now, we'll do this because it is a common pattern
169 # in toolsets, and we may need it in the future.
170
171 handle-options
172 $(toolset)
173 : $(identifying-condition)
174 : $(command-c) $(command-cxx) $(command-fortran) $(command-ar) $(command-ranlib)
175 : $(options) ;
176
177 # Add compiler version to 'VERSION' variable on all targets. 'VERSION' is
178 # not used in any actions, but it is used in some updating rule
179 # procedures.
180
181 toolset.flags $(toolset) VERSION $(identifying-condition) : [ numeric-version $(version) ] ;
182 }
183}
184
185rule check-prgenv-module ( toolset )
186{
187
188 local compiler = [ os.environ PE_ENV ] ;
189 compiler = $(compiler:L) ;
190
191 # We could check that environment variable CRAY_PRGENV$PE_ENV is set to
192 # "loaded", but this seems unnecessary and redundant.
193
194 local default-compiler = cray ;
195
196 if ! $(compiler)
197 {
198 log-warning $(toolset) : no PrgEnv module loaded
199 : falling back to PrgEnv-$(default-compiler)
200 : please load the PrgEnv-$(default-compiler) module next time ;
201 compiler = $(default-compiler) ;
202 }
203
204 if $(compiler) != $(default-compiler)
205 {
206 log-error $(toolset) : compiler '$(compiler)' not supported
207 : toolset initialization failed
208 : please load the PrgEnv-$(default-compiler) module next time ;
209 # Do not abort, as suggested by:
210 # http://www.boost.org/build/doc/html/bbv2/extending/toolset_modules.html.
211 }
212}
213
214rule set-cray-feature-defaults ( )
215{
216
217 # CCE users expect that using the 'cray' toolset without any explicit
218 # options will give them the same result as invoking CCE without any
219 # explicit options. So, we set feature defaults to match the default CCE
220 # options.
221 #
222 # The decision to turn off <debug-symbols> by default was a tough one.
223 # When CCE produces debugging symbols, it disables all inlining. This
224 # causes a decrease in performance, which the user probably was not
225 # expecting since they thought they were compiling with default CCE
226 # options.
227
228 feature.set-default cxxstd-dialect : gnu ;
229 feature.set-default debug-symbols : off ;
230 feature.set-default optimization : default ;
231 feature.set-default inlining : default ;
232 feature.set-default vectorize : default ;
233}
234
235###
236### Command line options
237###
238
239if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
240{
241
242 # Check if '--debug-configuration' was passed on the command line. This is
243 # inspired by 'common.jam' and other modules.
244
245 # Variable names with a '.' prefix are intended to be globals.
246 #
247 # Refer to:
248 # https://github.com/boostorg/build/blob/develop/CONTRIBUTING.rst
249
250 # The Jam language uses dynamic scoping. Setting '.debug-configuration' in
251 # this module influences the behavior of methods called from this module.
7c673cae 252
92f5a8d4
TL
253 .debug-configuration = true ;
254}
255
256if [ MATCH (--debug-driver) : [ modules.peek : ARGV ] ]
257{
258
259 .debug-driver = true ;
260}
261
262###
263### Features
264###
7c673cae
FG
265
266feature.extend toolset : cray ;
267
92f5a8d4
TL
268# Typically, extending '<toolset>' with the value 'cray' would cause
269# 'cray' to be the default '<toolset>' as long as it is the first value
270# added to '<toolset>'. However, we already imported the 'gcc' toolset, so
271# 'cray' is not the first value added to '<toolset>'. Therefore, we need
272# to call 'feature.set-default'.
273#
274# If the build request specifies a '<toolset>' (e.g. on the command line),
275# then the '<toolset>' feature default is ignored. However, if the 'cray'
276# toolset is selected in 'user-config.jam' (e.g. with 'using cray ;'),
277# then the build request will use the '<toolset>' feature default.
278# Therefore, we must use 'feature.set-default' so that selecting the
279# 'cray' toolset in 'user-config.jam' works correctly.
280
281feature.set-default toolset : cray ;
282
283# CCE is different from other compilers in that it optimizes, inlines, and
284# vectorizes by default. Boost.Build assumes that 'off' is the default for
285# all compilers. However, for CCE, 'off' and 'default' have different
286# meanings. For CCE, 'off' requires an additional command line argument to
287# turn the feature off. 'default' will not include an additional command
288# line argument, but will do optimization, inlining, and vectorizing at
289# whatever default level CCE uses.
290
291feature.extend optimization : default ;
292feature.extend inlining : default ;
293feature.extend vectorize : default ;
294
295###
296### Flags
297###
298
299# Updating rules are named in a dotted hierarchy. For example:
300#
301# compile
302# \_ compile.c++
303# \_ compile.c++.preprocess
304# \_ compile.c
305# \_ compile.c.preprocess
306#
307# This naming convention allows us to apply flags to multiple children in
308# the hierarchy. For example, if we apply a flag to 'compile.c++', that
309# flag is also applied to its child 'compile.c++.preprocess'. If we apply
310# a flag to 'compile', then that flag is applied to all children under
311# 'compile'.
312
313toolset.flags cray.compile OPTIONS <link>shared : -h pic ;
314
315toolset.flags cray.compile OPTIONS <optimization>default ; # Blank.
316toolset.flags cray.compile OPTIONS <optimization>off : -O 0 ;
317toolset.flags cray.compile OPTIONS <optimization>speed : -O 3 ;
318toolset.flags cray.compile OPTIONS <optimization>space ; # Blank. CCE does not optimize for space.
319
320toolset.flags cray.compile OPTIONS <inlining>default ; # Blank.
321toolset.flags cray.compile OPTIONS <inlining>off : -h ipa0 ;
322toolset.flags cray.compile OPTIONS <inlining>on ; # Blank. CCE does inlining by default.
323toolset.flags cray.compile OPTIONS <inlining>full : -h ipa5 ;
324
325toolset.flags cray.compile OPTIONS <vectorize>default ; # Blank.
326toolset.flags cray.compile OPTIONS <vectorize>off : -h vector0 ;
327toolset.flags cray.compile OPTIONS <vectorize>on ; # Blank. CCE vectorizes by default.
328toolset.flags cray.compile OPTIONS <vectorize>full : -h vector3 ;
329
330toolset.flags cray.link FINDLIBS-SA <threading>multi : rt ; # Not sure if this is correct.
331
332toolset.flags cray.link OPTIONS <link>shared : -h pic ;
333
334{
335 #
336 # Link flags copied from 'gcc.jam'.
337 #
338
339 local toolset = cray ;
340 local generic-os = [ set.difference [ feature.values <target-os> ] : aix darwin vxworks solaris osf hpux ] ;
341 # Strip the binary when no debugging is needed. We use --strip-all flag
342 # as opposed to -s since icc (intel's compiler) is generally
343 # option-compatible with and inherits from the gcc toolset, but does not
344 # support -s.
345 toolset.flags $(toolset).link OPTIONS <target-os>$(generic-os)/<strip>on : -Wl,--strip-all ;
346 toolset.flags $(toolset).link RPATH <target-os>$(generic-os) : <dll-path> ;
347 toolset.flags $(toolset).link RPATH_OPTION <target-os>$(generic-os) : -rpath ;
348 toolset.flags $(toolset).link RPATH_LINK <target-os>$(generic-os) : <xdll-path> ;
349 toolset.flags $(toolset).link START-GROUP <target-os>$(generic-os) : -Wl,--start-group ;
350 toolset.flags $(toolset).link END-GROUP <target-os>$(generic-os) : -Wl,--end-group ;
351
352 # gnu ld has the ability to change the search behaviour for libraries
353 # referenced by the -l switch. These modifiers are -Bstatic and
354 # -Bdynamic and change search for -l switches that follow them. The
355 # following list shows the tried variants. Search stops at the first
356 # variant that has a match.
357 #
358 # *nix: -Bstatic -lxxx
359 # libxxx.a
360 #
361 # *nix: -Bdynamic -lxxx
362 # libxxx.so
363 # libxxx.a
364 #
365 # windows (mingw, cygwin) -Bstatic -lxxx
366 # libxxx.a
367 # xxx.lib
368 #
369 # windows (mingw, cygwin) -Bdynamic -lxxx
370 # libxxx.dll.a
371 # xxx.dll.a
372 # libxxx.a
373 # xxx.lib
374 # cygxxx.dll (*)
375 # libxxx.dll
376 # xxx.dll
377 # libxxx.a
378 #
379 # (*) This is for cygwin
380 # Please note that -Bstatic and -Bdynamic are not a guarantee that a
381 # static or dynamic lib indeed gets linked in. The switches only change
382 # search patterns!
383
384 # On *nix mixing shared libs with static runtime is not a good idea.
385 toolset.flags $(toolset).link FINDLIBS-ST-PFX <target-os>$(generic-os)/<runtime-link>shared : -Wl,-Bstatic ;
386 toolset.flags $(toolset).link FINDLIBS-SA-PFX <target-os>$(generic-os)/<runtime-link>shared : -Wl,-Bdynamic ;
387
388 toolset.flags $(toolset).link HAVE_SONAME <target-os>$(generic-os) : "" ;
389 toolset.flags $(toolset).link SONAME_OPTION <target-os>$(generic-os) : -h ;
390
391 # See note [1]
392 toolset.flags $(toolset).link OPTIONS <target-os>$(generic-os)/<runtime-link>static : -static ;
393
394 # [1]
395 # For <runtime-link>static we made sure there are no dynamic libraries in the
396 # link. On HP-UX not all system libraries exist as archived libraries (for
397 # example, there is no libunwind.a), so, on this platform, the -static option
398 # cannot be specified.
399}
400
401# Flags for 'free' features ('free' features are features that do not have
402# a pre-defined set of values).
403
404toolset.flags cray.compile USER_OPTIONS <cflags> ;
405toolset.flags cray.compile.c++ USER_OPTIONS <cxxflags> ;
406toolset.flags cray.compile.asm USER_OPTIONS <asmflags> ;
407toolset.flags cray.compile DEFINES <define> ;
408toolset.flags cray.compile INCLUDES <include> ;
409
410toolset.flags cray.link USER_OPTIONS <linkflags> ;
411toolset.flags cray.link LINKPATH <library-path> ;
412toolset.flags cray.link FINDLIBS-ST <find-static-library> ;
413toolset.flags cray.link FINDLIBS-SA <find-shared-library> ;
414toolset.flags cray.link LIBRARIES <library-file> ;
415
416toolset.flags cray.archive AROPTIONS <archiveflags> ;
417
418###
419### Actions
420###
421
422actions compile.c++
423{
424 "$(CONFIG_COMMAND_CXX)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -c -o "$(<)" "$(>)" $(DRIVER_OPTIONS)
425}
426
427actions compile.c
428{
429 "$(CONFIG_COMMAND_C)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -c -o "$(<)" "$(>)" $(DRIVER_OPTIONS)
430}
431
432actions compile.asm
433{
434 "$(CONFIG_COMMAND_CXX)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -c -o "$(<)" "$(>)" $(DRIVER_OPTIONS)
435}
436
437actions compile.c++.preprocess
438{
439 "$(CONFIG_COMMAND_CXX)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -E "$(>)" >"$(<)" $(DRIVER_OPTIONS)
440}
441
442actions compile.c.preprocess
443{
444 "$(CONFIG_COMMAND_C)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -E "$(>)" >"$(<)" $(DRIVER_OPTIONS)
445}
446
447# We don't want to invoke 'ld' (the linker) directly for 'link', since we
448# want to give the CCE compiler driver a chance to modify the command line
449# it passes to 'ld'.
450#
451# The question is: which CCE compiler driver do we use? The driver for C,
452# the driver for C++, or the driver for Fortran?
453#
454# Here are things that definitely do not work:
455#
456# - Using the driver for C doesn't work when linking C++ programs, because
457# things like 'std::cout' are not available in C, they are only
458# available in C++.
459#
460# We use the driver for C++ below since we are primarily interested in
461# compiling Boost, which is written in C++. Also, the C++ driver will
462# properly link C code as well.
463
464actions link bind LIBRARIES
465{
466 "$(CONFIG_COMMAND_CXX)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) $(DRIVER_OPTIONS)
467}
468
469actions link.dll bind LIBRARIES
470{
471 "$(CONFIG_COMMAND_CXX)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) $(DRIVER_OPTIONS)
472}
473
474actions piecemeal archive
475{
476 "$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)"
477 "$(.RANLIB)" "$(<)"
478}
479
480###
481### Updating rules
482###
483
484# These are the actual updating rules that apply the associated actions
485# when called.
486
487rule compile.c++ ( targets * : sources * : properties * )
488{
489 compile-c++-procedure $(targets) : $(sources) : $(properties) ;
490}
491
492rule compile.c ( targets * : sources * : properties * )
493{
494 compile-c-procedure $(targets) : $(sources) : $(properties) ;
495}
496
497rule compile.asm ( targets * : sources * : properties * )
498{
499 compile-asm-procedure $(targets) : $(sources) : $(properties) ;
500}
501
502rule compile.c++.preprocess ( targets * : sources * : properties * )
503{
504 compile-c++-preprocess-procedure $(targets) : $(sources) : $(properties) ;
505}
506
507rule compile.c.preprocess ( targets * : sources * : properties * )
508{
509 compile-c-preprocess-procedure $(targets) : $(sources) : $(properties) ;
510}
511
512rule link ( targets * : sources * : properties * )
513{
514 link-procedure $(targets) : $(sources) : $(properties) ;
515}
516
517rule link.dll ( targets * : sources * : properties * )
518{
519 link-dll-procedure $(targets) : $(sources) : $(properties) ;
520}
521
522rule archive ( targets * : sources * : properties * )
523{
524 archive-procedure $(targets) : $(sources) : $(properties) ;
525}
526
527# These are the procedure portions of the updating rules. Calling the
528# procedure portion may modify the targets, but it will not apply actions
529# to the targets. This allows us to reuse the procedure portions of the
530# updating rules without applying the same actions to targets.
531
532rule compile-c++-procedure ( targets * : sources * : properties * )
533{
534 set-cxxstd-procedure $(targets) : $(sources) : $(properties) ;
535 set-cxxstd-dialect-procedure $(targets) : $(sources) : $(properties) ;
536 set-debug-symbols-procedure $(targets) : $(sources) : $(properties) ;
537 add-space-procedure $(targets) : $(sources) : $(properties) ;
538 debug-driver-procedure $(targets) : $(sources) : $(properties) ;
539}
540
541rule compile-c-procedure ( targets * : sources * : properties * )
542{
543 set-debug-symbols-procedure $(targets) : $(sources) : $(properties) ;
544 add-space-procedure $(targets) : $(sources) : $(properties) ;
545 debug-driver-procedure $(targets) : $(sources) : $(properties) ;
546}
547
548rule compile-asm-procedure ( targets * : sources * : properties * )
549{
550 compile-c++-procedure $(targets) : $(sources) : $(properties) ;
551}
552
553rule compile-c++-preprocess-procedure ( targets * : sources * : properties * )
554{
555 compile-c++-procedure $(targets) : $(sources) : $(properties) ;
556}
557
558rule compile-c-preprocess-procedure ( targets * : sources * : properties * )
559{
560 compile-c-procedure $(targets) : $(sources) : $(properties) ;
561}
562
563rule link-procedure ( targets * : sources * : properties * )
564{
565 set-cxxstd-procedure $(targets) : $(sources) : $(properties) ;
566 set-cxxstd-dialect-procedure $(targets) : $(sources) : $(properties) ;
567 gcc-link-procedure $(targets) : $(sources) : $(properties) ;
568 debug-driver-procedure $(targets) : $(sources) : $(properties) ;
569
570 # CCE driver command line flags for linking executables.
571
572 local link = [ feature.get-values <link> : $(properties) ] ;
573 switch $(link)
574 {
575 case shared :
576 DRIVER_OPTIONS on $(<) += -dynamic ;
577 case static :
578 DRIVER_OPTIONS on $(<) += -static ;
579 }
580
581 # The link command line from the 'gcc' toolset includes:
582 #
583 # '$(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA)'
584 #
585 # The 'FINDLIBS-ST' and 'FINDLIBS-SA' variables are the libraries
586 # specified by the '<find-static-library>' and '<find-shared-library>'
587 # features, respectively. The 'FINDLIBS-ST-PFX' is typically
588 # '-Wl,-Bstatic'. The 'FINDLIBS-SA-PFX' is typically '-Wl,-Bdynamic'.
589 #
590 # The '-Bstatic' and '-Bdynamic' flags passed to the linker tell the
591 # linker how to link all of the following libraries. The flag is in effect
592 # until it is overridden by another '-B' flag on the command line.
593 #
594 # So, it makes sense that the 'gcc' toolset includes these flags, so the
595 # '<find-static-library>' and '<find-shared-library>' libraries are linked
596 # properly.
597 #
598 # The last flag that is set ('-Bdynamic') affects the link type for any
599 # other libraries on the command line. In the 'gcc' toolset, this is okay,
600 # since there are no other libraries specified on the command line after
601 # these flags. However, when the CCE compiler driver invokes the linker,
602 # it adds additional libraries to the command line based on what modules
603 # are loaded in the environment. So, the last '-B' flag on the CCE driver
604 # command line affects the link type for all libraries that CCE
605 # automatically appends.
606 #
607 # Therefore, we have to set the final '-B' flag to the link type we want
608 # the CCE libraries to be linked with. Appending to the 'OPTIONS' variable
609 # seems reasonable.
610
611 local link = [ feature.get-values <link> : $(properties) ] ;
612 switch $(link)
613 {
614 case shared :
615 OPTIONS on $(<) += -Wl,-Bdynamic ;
616 case static :
617 OPTIONS on $(<) += -Wl,-Bstatic ;
618 }
619}
620
621rule link-dll-procedure ( targets * : sources * : properties * )
622{
623 set-cxxstd-procedure $(targets) : $(sources) : $(properties) ;
624 set-cxxstd-dialect-procedure $(targets) : $(sources) : $(properties) ;
625 gcc-link-dll-procedure $(targets) : $(sources) : $(properties) ;
626 debug-driver-procedure $(targets) : $(sources) : $(properties) ;
627
628 # CCE driver command line flags for linking shared libraries.
629
630 DRIVER_OPTIONS on $(<) += -shared ;
631}
632
633rule archive-procedure ( targets * : sources * : properties * )
634{
635 gcc-archive-procedure $(targets) : $(sources) : $(properties) ;
636 debug-driver-procedure $(targets) : $(sources) : $(properties) ;
637}
638
639# Utility procedure rules intended to be called from updating rules.
640
641rule gcc-link-procedure ( targets * : sources * : properties * )
642{
643
644 # Copied from 'gcc.jam'.
645
646 SPACE on $(targets) = " " ;
647 # Serialize execution of the 'link' action, since running N links in
648 # parallel is just slower. For now, serialize only gcc links, it might be a
649 # good idea to serialize all links.
650 JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ;
651 gcc.quote-rpath $(targets) ;
652}
653
654rule gcc-link-dll-procedure ( targets * : sources * : properties * )
655{
656
657 # Copied from 'gcc.jam'.
658
659 SPACE on $(targets) = " " ;
660 JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ;
661 gcc.quote-rpath $(targets) ;
662}
663
664rule gcc-archive-procedure ( targets * : sources * : properties * )
665{
666
667 # Copied from 'gcc.jam'.
668
669 # Always remove archive and start again. Here is the rationale from
670 #
671 # Andre Hentz:
672 #
673 # I had a file, say a1.c, that was included into liba.a. I moved a1.c to
674 # a2.c, updated my Jamfiles and rebuilt. My program was crashing with absurd
675 # errors. After some debugging I traced it back to the fact that a1.o was
676 # *still* in liba.a
677 #
678 # Rene Rivera:
679 #
680 # Originally removing the archive was done by splicing an RM onto the
681 # archive action. That makes archives fail to build on NT when they have
682 # many files because it will no longer execute the action directly and blow
683 # the line length limit. Instead we remove the file in a different action,
684 # just before building the archive.
685 #
686 local clean.a = $(targets[1])(clean) ;
687 TEMPORARY $(clean.a) ;
688 NOCARE $(clean.a) ;
689 LOCATE on $(clean.a) = [ on $(targets[1]) return $(LOCATE) ] ;
690 DEPENDS $(clean.a) : $(sources) ;
691 DEPENDS $(targets) : $(clean.a) ;
692 common.RmTemps $(clean.a) : $(targets) ;
693}
694
695rule add-space-procedure ( targets * : sources * : properties * )
696{
697 SPACE on $(targets) = " " ;
698}
699
700rule set-cxxstd-procedure ( targets * : sources * : properties * )
701{
702
703 # Translate '<cxxstd>' into a standard recognized by CCE.
704
705 local version = [ on $(targets[1]) return $(VERSION) ] ;
706
707 local cxxstd = [ feature.get-values cxxstd : $(properties) ] ;
708 local cray-cxxstd = ;
709
710 local unsupported-values = 2a ; # I don't know what '2a' means.
711 if $(cxxstd) && $(cxxstd) in $(unsupported-values)
712 {
713
714 log-warning cray : ignoring unsupported property '<cxxstd>$(cxxstd)' ;
715
716 # Set to default value, or blank if default is unsupported.
717
718 local default-value = [ get-default-feature-value cxxstd ] ;
719 if $(default-value) in $(unsupported-values)
720 {
721 cxxstd = ;
722 }
723 else
724 {
725 cxxstd = $(default-value) ;
726 }
727 }
728
729 switch $(cxxstd)
730 {
731 case 98 : cray-cxxstd = 03 ;
732 case 03 : cray-cxxstd = 03 ;
733 case 0x : cray-cxxstd = 11 ;
734 case 11 : cray-cxxstd = 11 ;
735 case 1y : cray-cxxstd = 14 ;
736 case 14 : cray-cxxstd = 14 ;
737 case 1z : cray-cxxstd = 17 ;
738 case 17 : cray-cxxstd = 17 ;
739 case latest :
740 cray-cxxstd = [ latest-cray-cxxstd $(version) ] ;
741 }
742
743 # If the 'cray-cxxstd' is not supported by this compiler version, we just
744 # let the command line fail.
745
746 # If 'cxxstd' was blank, then 'cray-cxxstd' is also blank, and nothing is
747 # added to the command line. The compiler just uses it's default C++
748 # standard.
749
750 # Apply final options.
751 local space = " " ;
752 OPTIONS on $(targets) += -h$(space)std=c++$(cray-cxxstd) ;
753}
754
755rule set-cxxstd-dialect-procedure ( targets * : sources * : properties * )
756{
757
758 # Translate '<cxxstd-dialect>' into '-h [no]conform' and '-h [no]gnu'
759 # options.
760
761 local version = [ on $(targets[1]) return $(VERSION) ] ;
762
763 local cxxstd-dialect = [ feature.get-values cxxstd-dialect : $(properties) ] ;
764 local cray-conform = ;
765 local cray-gnu = ;
766
767 local unsupported-values = ms ;
768 if $(cxxstd-dialect) && $(cxxstd-dialect) in $(unsupported-values)
769 {
770
771 log-warning cray : ignoring unsupported property '<cxxstd-dialect>$(cxxstd-dialect)' ;
772
773 # Set to default value, or blank if default is unsupported.
774
775 local default-value = [ get-default-feature-value cxxstd-dialect ] ;
776 if $(default-value) in $(unsupported-values)
777 {
778 cxxstd-dialect = ;
779 }
780 else
781 {
782 cxxstd-dialect = $(default-value) ;
783 }
784 }
785
786 switch $(cxxstd-dialect)
787 {
788 case gnu : cray-conform = noconform ;
789 cray-gnu = gnu ;
790 case iso : cray-conform = conform ;
791 cray-gnu = nognu ;
792 }
793
794 if [ has-conform-option $(version) ] = false
795 {
796 # The '-h [no]conform' option is ignored in recent versions of CCE.
797 cray-conform = ;
798 }
799
800 # If 'cxxstd-dialect' was blank, then 'cray-conform' and 'cray-gnu' are
801 # also blank, and nothing is added to the command line. The compiler just
802 # uses it's default C++ dialect.
803
804 # Apply final options.
805 local space = " " ;
806 OPTIONS on $(targets) += -h$(space)$(cray-conform)
807 -h$(space)$(cray-gnu) ;
808}
809
810rule set-debug-symbols-procedure ( targets * : sources * : properties * )
811{
812
813 local debug-symbols = [ feature.get-values <debug-symbols> : $(properties) ] ;
814 if $(debug-symbols) = "on"
815 {
816 local optimization = [ feature.get-values <optimization> : $(properties) ] ;
817 local debug-option = ;
818 if $(optimization) = off
819 {
820 debug-option = 0 ;
821 }
822 else
823 {
824 debug-option = 3 ;
825 }
826
827 local space = " " ;
828 OPTIONS on $(targets) += -G$(space)$(debug-option) ;
829 }
830}
831
832rule debug-driver-procedure ( targets * : sources * : properties * )
833{
834 if $(.debug-driver)
835 {
836
837 # Passing '-vv' to the CCE driver causes it to output the command lines
838 # for the underlying tools that it invokes.
839
840 DRIVER_OPTIONS on $(<) += -vv ;
841 }
842}
843
844###
845### Generators
846###
847
848class cray-linking-generator : gcc-linking-generator
849{
850 rule action-class ( )
851 {
852 return action ;
853 }
854}
855
856# We reuse some generator classes from the 'unix' toolset. Specifically,
857# we are reusing generators for the following updating actions:
858#
859# - 'archive'
860# - 'searched-lib-generator'
861# - 'prebuilt'
862#
863# Inheriting these generators is like using the same generator classes as
864# the 'unix' toolset, but pointing them to the 'cray' updating rules.
865
866toolset.inherit-generators cray : unix : unix.link unix.link.dll ;
867
868# The 'C-compiling-generator' class adds source paths to the '<include>'
869# property.
870
871generators.register [ new C-compiling-generator
872 cray.compile.c++
873 : CPP
874 : OBJ
875 : <toolset>cray ] ;
876generators.register [ new C-compiling-generator
877 cray.compile.c
878 : C
879 : OBJ
880 : <toolset>cray ] ;
881generators.register [ new C-compiling-generator
882 cray.compile.asm
883 : ASM
884 : OBJ
885 : <toolset>cray ] ;
886generators.register [ new C-compiling-generator
887 cray.compile.c++.preprocess
888 : CPP
889 : PREPROCESSED_CPP
890 : <toolset>cray ] ;
891generators.register [ new C-compiling-generator
892 cray.compile.c.preprocess
893 : C
894 : PREPROCESSED_C
895 : <toolset>cray ] ;
896generators.register [ new cray-linking-generator
897 cray.link
898 : LIB OBJ
899 : EXE
900 : <toolset>cray ] ;
901generators.register [ new cray-linking-generator
902 cray.link.dll
903 : LIB OBJ
904 : SHARED_LIB
905 : <toolset>cray ] ;
906
907# Tell Boost.Build to prefer 'cray' generators over other valid
908# generators. This is used to resolve a tie when Boost.Build finds that
909# there is more than one viable generator for a particular build request.
7c673cae 910
7c673cae
FG
911generators.override cray.prebuilt : builtin.prebuilt ;
912generators.override cray.searched-lib-generator : searched-lib-generator ;
913
92f5a8d4
TL
914type.set-generated-target-suffix PREPROCESSED_CPP : <toolset>cray : i ;
915type.set-generated-target-suffix PREPROCESSED_C : <toolset>cray : i ;
916
917###
918### Utility rules
919###
920
921rule validate-command ( toolset command )
922{
923 local found-command = [ common.find-tool $(command) ] ;
924 if $(found-command) && $(.debug-configuration)
925 {
926 log-notice $(toolset) : command '$(command)' found at [ common.get-absolute-tool-path $(found-command) ] ;
927 }
928 if ! $(found-command)
929 {
930 log-warning $(toolset) : command '$(command)' not found ;
931 found-command = $(command) ;
932 }
933 return $(found-command) ;
934}
935
936local rule options-helper ( rule-or-module variable-name condition * : feature options * )
937{
938 toolset.flags $(rule-or-module) $(variable-name) $(condition) : [ feature.get-values $(feature) : $(options) ] : unchecked ;
939}
940
941rule handle-options (
942 toolset
943 : toolset-condition *
944 : command-c command-cxx command-fortran command-ar command-ranlib
945 : options *
946)
947{
948
949 # Configures some common 'toolset.flags' options. In particular, this rule
950 # sets the compiler command name to invoke. Inspired by
951 # 'common.handle-options'.
7c673cae 952
92f5a8d4
TL
953 # We cannot use a single 'CONFIG_COMMAND' variable because each CCE driver
954 # can only handle a single source code language. Therefore, we have to
955 # give actions a way to specify which driver they intend to use, and we
956 # accomplish this by providing multiple 'CONFIG_COMMAND' variables to the
957 # action. We cannot set the language through a flag in the 'OPTIONS'
958 # variable the way the 'gcc' toolset does.
959
960 toolset.flags $(toolset) CONFIG_COMMAND_C $(toolset-condition) : $(command-c) : unchecked ;
961 toolset.flags $(toolset) CONFIG_COMMAND_CXX $(toolset-condition) : $(command-cxx) : unchecked ;
962 toolset.flags $(toolset) CONFIG_COMMAND_FORTRAN $(toolset-condition) : $(command-fortran) : unchecked ;
963 toolset.flags $(toolset).archive .AR $(toolset-condition) : $(command-ar) : unchecked ;
964 toolset.flags $(toolset).archive .RANLIB $(toolset-condition) : $(command-ranlib) : unchecked ;
965
966 # The following flags are applied to all targets built by this
967 # configuration of this toolset. This particular configuration of this
968 # toolset is identified by '$(toolset-condition)'. This allows the user to
969 # specify 'options' in their 'using' statement, and those options will be
970 # applied to all targets built by this configuration of this toolset.
971
972 options-helper $(toolset).compile USER_OPTIONS $(toolset-condition) : <compileflags> $(options) ;
973 options-helper $(toolset).compile USER_OPTIONS $(toolset-condition) : <cflags> $(options) ;
974 options-helper $(toolset).compile.c++ USER_OPTIONS $(toolset-condition) : <cxxflags> $(options) ;
975 options-helper $(toolset).compile.fortran USER_OPTIONS $(toolset-condition) : <fflags> $(options) ;
976 options-helper $(toolset).compile.asm USER_OPTIONS $(toolset-condition) : <asmflags> $(options) ;
977 options-helper $(toolset).compile DEFINES $(toolset-condition) : <define> $(options) ;
978 options-helper $(toolset).compile INCLUDES $(toolset-condition) : <include> $(options) ;
979
980 options-helper $(toolset).link USER_OPTIONS $(toolset-condition) : <linkflags> $(options) ;
981 options-helper $(toolset).link LINKPATH $(toolset-condition) : <library-path> $(options) ;
982 options-helper $(toolset).link FINDLIBS-ST $(toolset-condition) : <find-static-library> $(options) ;
983 options-helper $(toolset).link FINDLIBS-SA $(toolset-condition) : <find-shared-library> $(options) ;
984 options-helper $(toolset).link LIBRARIES $(toolset-condition) : <library-file> $(options) ;
985
986 options-helper $(toolset).archive AROPTIONS $(toolset-condition) : <archiveflags> $(options) ;
987}
988
989rule latest-cray-cxxstd ( compiler-version )
990{
991 # Select latest 'cray-cxxstd' based on compiler version.
992
993 local cray-cxxstd = 03 ;
994
995 if $(compiler-version) >= [ numeric-version 8.6 ]
996 {
997 cray-cxxstd = 14 ;
998 }
999
1000 return $(cray-cxxstd) ;
1001}
1002
1003rule has-conform-option ( compiler-version )
7c673cae 1004{
92f5a8d4
TL
1005
1006 # Returns 'true' or 'false'. Returns empty list if the 'compiler-version'
1007 # is not supported.
1008
1009 local result = true ;
1010
1011 if $(compiler-version) >= [ numeric-version 8.6 ]
7c673cae 1012 {
92f5a8d4
TL
1013 result = false ;
1014 }
1015
1016 return $(result) ;
1017}
1018
1019local rule justify-right ( pad-char elements * )
1020{
1021
1022 # Returns a list of 'elements' where each 'element' is at least 2
1023 # characters long. If an 'element' is less than two characters long, pads
1024 # 'element' with 'pad-char' to make it 2 characters long.
7c673cae 1025
92f5a8d4
TL
1026 local result = ;
1027 local p = $(pad-char) ;
1028 for local e in $(elements)
1029 {
1030 switch $(e)
7c673cae 1031 {
92f5a8d4
TL
1032 case ?? : result += $(e) ;
1033 case ? : result += $(p)$(e) ;
1034 case * : result += $(p)$(p) ;
1035 }
1036 }
1037 return $(result) ;
1038}
7c673cae 1039
92f5a8d4 1040local rule list-justify-left ( pad-elem elements * )
7c673cae 1041{
92f5a8d4
TL
1042
1043 # Add 'pad-elem' to 'elements' list until it has 4 elements. If 'elements'
1044 # list already had 4 or more elements, returns the first 4 elements in
1045 # 'elements' list.
1046
1047 local tally = x ;
1048 local result = ;
1049 for local e in $(elements)
1050 {
1051 if $(tally) != xxxxx
1052 {
1053 result += $(e) ;
1054 tally = $(tally)x ;
1055 }
1056 }
1057
1058 while $(tally) != xxxxx
1059 {
1060 result += $(pad-elem) ;
1061 tally = $(tally)x ;
1062 }
1063
1064 return $(result) ;
7c673cae
FG
1065}
1066
92f5a8d4
TL
1067local rule numeric-version ( dotted-version )
1068{
1069
1070 # Returns a numeric representation of version that can be compared
1071 # directly with comparison operators.
7c673cae 1072
92f5a8d4
TL
1073 local result = [ regex.split $(dotted-version) "[.]" ] ;
1074 result = [ list-justify-left 0 $(result) ] ;
1075 result = [ justify-right 0 $(result) ] ;
1076 result = $(result:J="") ;
1077
1078 return $(result) ;
1079}
1080
1081local rule get-default-feature-value ( feature-name )
7c673cae 1082{
92f5a8d4
TL
1083 local default-property = [ feature.defaults $(feature-name) ] ;
1084 local default-value = [ feature.get-values $(feature-name) : $(default-property) ] ;
1085 return $(default-value) ;
7c673cae
FG
1086}
1087
92f5a8d4
TL
1088rule log ( log-level prefix ? : * )
1089{
1090 for local message-arg in 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
1091 {
1092 local message = $($(message-arg)) ;
1093 if $(message)
1094 {
1095 ECHO "$(log-level):" "$(prefix):" $(message) ;
1096 }
1097 }
1098}
7c673cae 1099
92f5a8d4 1100rule log-error ( prefix ? : * )
7c673cae 1101{
92f5a8d4 1102 log error $(prefix) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) : $(18) : $(19) : $(20) : $(21) : $(22) : $(23) : $(24) ;
7c673cae
FG
1103}
1104
92f5a8d4
TL
1105rule log-warning ( prefix ? : * )
1106{
1107 log warning $(prefix) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) : $(18) : $(19) : $(20) : $(21) : $(22) : $(23) : $(24) ;
1108}
7c673cae 1109
92f5a8d4 1110rule log-notice ( prefix ? : * )
7c673cae 1111{
92f5a8d4 1112 log notice $(prefix) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) : $(18) : $(19) : $(20) : $(21) : $(22) : $(23) : $(24) ;
7c673cae
FG
1113}
1114
92f5a8d4 1115rule __test__ ( )
7c673cae 1116{
92f5a8d4
TL
1117 import assert ;
1118
1119 assert.result 08060000 : numeric-version 8.6 ;
1120 assert.result 08061500 : numeric-version 8.6.15 ;
1121 assert.result 08061501 : numeric-version 8.6.15.1 ;
1122 assert.result 08061501 : numeric-version 8.6.15.1.2 ;
1123
1124 local a = [ numeric-version 8.6 ] ;
1125 local b = [ numeric-version 8.5.9 ] ;
1126
1127 # 'assert.equal x : y' forces the test to fail. It's like saying 'assert
1128 # false'.
1129
1130 if ! ( $(a) > $(b) )
1131 {
1132 assert.equal x : y ;
1133 }
1134
1135 if ! ( $(b) < $(a) )
1136 {
1137 assert.equal x : y ;
1138 }
1139
1140 if ! ( $(a) >= $(b) )
1141 {
1142 assert.equal x : y ;
1143 }
1144
1145 if ! ( $(a) >= $(a) )
1146 {
1147 assert.equal x : y ;
1148 }
1149
1150 if ! ( $(b) <= $(a) )
1151 {
1152 assert.equal x : y ;
1153 }
1154
1155 if ! ( $(b) <= $(b) )
1156 {
1157 assert.equal x : y ;
1158 }
1159
1160 if ! ( $(a) = $(a) )
1161 {
1162 assert.equal x : y ;
1163 }
1164
1165 if ! ( $(a) != $(b) )
1166 {
1167 assert.equal x : y ;
1168 }
7c673cae 1169}