![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /proc/self/root/usr/share/boost-build/src/tools/ |
Upload File : |
# Copyright 2001 David Abrahams # Copyright 2004, 2005 Markus Schoepflin # Copyright 2011 John Maddock # Copyright 2013, 2017-2018 Cray, Inc. # # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) # README.md # # This toolset is for the Cray Compiling Environment (CCE). # # The assembler, linker, and archiver are the same as those used in the # `gcc` toolset. Therefore, there is some duplication of code between the # `gcc` toolset and this toolset. # # # CCE Introduction # # Users want to compile and run massively parallel applications on Cray # supercomputers. Typically, the user compiles code on a login node of the # supercomputer and then runs the compiled program on multiple compute # nodes using a batch control system. This means the user is almost always # cross compiling. # # But, they're not just cross compiling. In order for a program to run on # a Cray supercomputer it has to link to particular libraries. There are # three general categories of libraries that user programs must link to: # # - Network libraries: Enable communication between processes on different # compute nodes. Depends on the network hardware in the supercomputer. # - Compute node libraries: Depends on the hardware on the targeted # compute nodes. # - Language extension libraries: Depends on the language extensions used # by the program (e.g. OpenMP, Unified Parallel C, et cetera). # # Instead of forcing users to invoke the compiler with a bunch of # libraries listed on the command line, CCE decides what libraries to link # based on the environment. This is primarily controlled by loading and # unloading modules (with the `module` command) to create a cross # compiling and linking environment suitable for the particular hardware # on the targeted Cray supercomputer. # # CCE compilers come in two parts: the compiler itself, and the compiler # driver. Invoking a compiler directly is not supported. We must always # invoke the compiler through a compiler driver: either `cc` for C code, # `CC` for C++ code, or `ftn` for Fortran code. The compiler driver is # responsible for gathering information from the environment and invoking # the selected compiler with the appropriate command line options. # # For more information on CCE, search for Cray publication S-2529 on the # Cray publications website (https://pubs.cray.com). import "class" : new ; import common ; import feature ; import gcc ; import generators ; import os ; import regex ; import set ; import toolset ; import type ; import unix ; ### ### 'init' ### rule init ( : : options * : requirements * ) { # User cannot specify a 'version' in their 'using' statement. Compiler # version is always controlled by loading and unloading modules in the # user's environment. # User cannot specify a 'command' in their 'using' statement. Using a # single 'command' argument only makes sense when a single executable can # compile different types of code (e.g. gcc will compile C or C++ based on # the file name extensions). In CCE, you have to invoke one of the three # compiler drivers: cc for C code, CC for C++ code, or ftn for Fortran # code. Each compiler driver compiles a single type of source code. It is # possible to let the user pass in three 'command' arguments, one for each # driver, but that seems like more effort that it's worth. local toolset = cray ; check-prgenv-module $(toolset) ; local command-c = [ validate-command $(toolset) cc ] ; local command-cxx = [ validate-command $(toolset) CC ] ; local command-fortran = [ validate-command $(toolset) ftn ] ; # Archive builder. local command-ar = [ validate-command $(toolset) ar ] ; # Archive indexer. local command-ranlib = [ validate-command $(toolset) ranlib ] ; # The 'command' variables always have one element, but they may contain # spaces (e.g. if 'command' is an absolute path and some path components # have spaces). local version = ; local developer-build = ; { local version-string = [ SHELL "\"$(command-cxx)\" -VV 2>&1" ] ; local version-components = [ MATCH "Version ([0-9]+).([0-9]+).([a-zA-Z0-9]+)" : $(version-string) ] ; if ! [ MATCH "([0-9]+)" : $(version-components[3]) ] { # The last component of the version is not a series of digits. This means # we're probably using a developer build of CCE (i.e. a compiler built by # a Cray employee). Developer builds report versions like '8.7.x'. developer-build = true ; # We want to treat developer builds as though they are the highest # possible patch version of the release. Effectively, we want to turn # '8.7.x' into '8.7.99'. version-components = $(version-components[1]) $(version-components[2]) 99 ; } version = $(version-components:J=.) ; } local build = ; if $(developer-build) { # If this is a developer build, we want to add the build subfeature to the # compiler. local version-string = [ SHELL "\"$(command-cxx)\" -VV 2>&1" ] ; build = [ MATCH "[(][0-9]+_([0-9a-fA-F]+)[)]" : $(version-string) ] ; # Truncate build hash to 7 characters build = [ MATCH "(.......)................................." : $(build) ] ; } # IMPORTANT: 'set-cray-feature-defaults' causes the Boost.Build tests to # fail. I tried using an 'init' argument called 'ignore-cray-defaults' and # setting up 'test-config.jam' to pass 'ignore-cray-defaults' during # testing, but I couldn't get the test to read my 'test-config.jam' file # when running tests individually. So, I just comment out # 'set-cray-feature-defaults' during testing. set-cray-feature-defaults ; { # 'check-init-parameters' ensures that each time a toolset is initialized, # it is initialized with a unique configuration. The return value is a # Boost.Build property condition which uniquely identifies this # configured instance of this toolset. Typically, toolsets use the # returned condition as the conditional in a 'toolset.flags' call to set # flags specific to this configuration of this toolset. local identifying-condition = [ common.check-init-parameters $(toolset) $(requirements) : version $(version) : build $(build) ] ; # 'handle-options' uses 'toolset.flags' to set 'CONFIG_COMMAND' variables # on targets when this toolset is used. The 'CONFIG_COMMAND' variables # specify the commands to call for compiling. This would be more relevant # if our 'init' rule had arguments that might affect the command that is # invoked (e.g. in many toolsets 'version' affects the name of the # compiler command). For now, we'll do this because it is a common pattern # in toolsets, and we may need it in the future. handle-options $(toolset) : $(identifying-condition) : $(command-c) $(command-cxx) $(command-fortran) $(command-ar) $(command-ranlib) : $(options) ; # Add compiler version to 'VERSION' variable on all targets. 'VERSION' is # not used in any actions, but it is used in some updating rule # procedures. toolset.flags $(toolset) VERSION $(identifying-condition) : [ numeric-version $(version) ] ; } } rule check-prgenv-module ( toolset ) { local compiler = [ os.environ PE_ENV ] ; compiler = $(compiler:L) ; # We could check that environment variable CRAY_PRGENV$PE_ENV is set to # "loaded", but this seems unnecessary and redundant. local default-compiler = cray ; if ! $(compiler) { log-warning $(toolset) : no PrgEnv module loaded : falling back to PrgEnv-$(default-compiler) : please load the PrgEnv-$(default-compiler) module next time ; compiler = $(default-compiler) ; } if $(compiler) != $(default-compiler) { log-error $(toolset) : compiler '$(compiler)' not supported : toolset initialization failed : please load the PrgEnv-$(default-compiler) module next time ; # Do not abort, as suggested by: # http://www.boost.org/build/doc/html/bbv2/extending/toolset_modules.html. } } rule set-cray-feature-defaults ( ) { # CCE users expect that using the 'cray' toolset without any explicit # options will give them the same result as invoking CCE without any # explicit options. So, we set feature defaults to match the default CCE # options. # # The decision to turn off <debug-symbols> by default was a tough one. # When CCE produces debugging symbols, it disables all inlining. This # causes a decrease in performance, which the user probably was not # expecting since they thought they were compiling with default CCE # options. feature.set-default cxxstd-dialect : gnu ; feature.set-default debug-symbols : off ; feature.set-default optimization : default ; feature.set-default inlining : default ; feature.set-default vectorize : default ; } ### ### Command line options ### if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] { # Check if '--debug-configuration' was passed on the command line. This is # inspired by 'common.jam' and other modules. # Variable names with a '.' prefix are intended to be globals. # # Refer to: # https://github.com/boostorg/build/blob/develop/CONTRIBUTING.rst # The Jam language uses dynamic scoping. Setting '.debug-configuration' in # this module influences the behavior of methods called from this module. .debug-configuration = true ; } if [ MATCH (--debug-driver) : [ modules.peek : ARGV ] ] { .debug-driver = true ; } ### ### Features ### feature.extend toolset : cray ; # Typically, extending '<toolset>' with the value 'cray' would cause # 'cray' to be the default '<toolset>' as long as it is the first value # added to '<toolset>'. However, we already imported the 'gcc' toolset, so # 'cray' is not the first value added to '<toolset>'. Therefore, we need # to call 'feature.set-default'. # # If the build request specifies a '<toolset>' (e.g. on the command line), # then the '<toolset>' feature default is ignored. However, if the 'cray' # toolset is selected in 'user-config.jam' (e.g. with 'using cray ;'), # then the build request will use the '<toolset>' feature default. # Therefore, we must use 'feature.set-default' so that selecting the # 'cray' toolset in 'user-config.jam' works correctly. feature.set-default toolset : cray ; # CCE is different from other compilers in that it optimizes, inlines, and # vectorizes by default. Boost.Build assumes that 'off' is the default for # all compilers. However, for CCE, 'off' and 'default' have different # meanings. For CCE, 'off' requires an additional command line argument to # turn the feature off. 'default' will not include an additional command # line argument, but will do optimization, inlining, and vectorizing at # whatever default level CCE uses. feature.extend optimization : default ; feature.extend inlining : default ; feature.extend vectorize : default ; ### ### Flags ### # Updating rules are named in a dotted hierarchy. For example: # # compile # \_ compile.c++ # \_ compile.c++.preprocess # \_ compile.c # \_ compile.c.preprocess # # This naming convention allows us to apply flags to multiple children in # the hierarchy. For example, if we apply a flag to 'compile.c++', that # flag is also applied to its child 'compile.c++.preprocess'. If we apply # a flag to 'compile', then that flag is applied to all children under # 'compile'. toolset.flags cray.compile OPTIONS <link>shared : -h pic ; toolset.flags cray.compile OPTIONS <optimization>default ; # Blank. toolset.flags cray.compile OPTIONS <optimization>off : -O 0 ; toolset.flags cray.compile OPTIONS <optimization>speed : -O 3 ; toolset.flags cray.compile OPTIONS <optimization>space ; # Blank. CCE does not optimize for space. toolset.flags cray.compile OPTIONS <inlining>default ; # Blank. toolset.flags cray.compile OPTIONS <inlining>off : -h ipa0 ; toolset.flags cray.compile OPTIONS <inlining>on ; # Blank. CCE does inlining by default. toolset.flags cray.compile OPTIONS <inlining>full : -h ipa5 ; toolset.flags cray.compile OPTIONS <vectorize>default ; # Blank. toolset.flags cray.compile OPTIONS <vectorize>off : -h vector0 ; toolset.flags cray.compile OPTIONS <vectorize>on ; # Blank. CCE vectorizes by default. toolset.flags cray.compile OPTIONS <vectorize>full : -h vector3 ; toolset.flags cray.link FINDLIBS-SA <threading>multi : rt ; # Not sure if this is correct. toolset.flags cray.link OPTIONS <link>shared : -h pic ; { # # Link flags copied from 'gcc.jam'. # local toolset = cray ; local generic-os = [ set.difference [ feature.values <target-os> ] : aix darwin vxworks solaris osf hpux ] ; # Strip the binary when no debugging is needed. We use --strip-all flag # as opposed to -s since icc (intel's compiler) is generally # option-compatible with and inherits from the gcc toolset, but does not # support -s. toolset.flags $(toolset).link OPTIONS <target-os>$(generic-os)/<strip>on : -Wl,--strip-all ; toolset.flags $(toolset).link RPATH <target-os>$(generic-os) : <dll-path> ; toolset.flags $(toolset).link RPATH_OPTION <target-os>$(generic-os) : -rpath ; toolset.flags $(toolset).link RPATH_LINK <target-os>$(generic-os) : <xdll-path> ; toolset.flags $(toolset).link START-GROUP <target-os>$(generic-os) : -Wl,--start-group ; toolset.flags $(toolset).link END-GROUP <target-os>$(generic-os) : -Wl,--end-group ; # gnu ld has the ability to change the search behaviour for libraries # referenced by the -l switch. These modifiers are -Bstatic and # -Bdynamic and change search for -l switches that follow them. The # following list shows the tried variants. Search stops at the first # variant that has a match. # # *nix: -Bstatic -lxxx # libxxx.a # # *nix: -Bdynamic -lxxx # libxxx.so # libxxx.a # # windows (mingw, cygwin) -Bstatic -lxxx # libxxx.a # xxx.lib # # windows (mingw, cygwin) -Bdynamic -lxxx # libxxx.dll.a # xxx.dll.a # libxxx.a # xxx.lib # cygxxx.dll (*) # libxxx.dll # xxx.dll # libxxx.a # # (*) This is for cygwin # Please note that -Bstatic and -Bdynamic are not a guarantee that a # static or dynamic lib indeed gets linked in. The switches only change # search patterns! # On *nix mixing shared libs with static runtime is not a good idea. toolset.flags $(toolset).link FINDLIBS-ST-PFX <target-os>$(generic-os)/<runtime-link>shared : -Wl,-Bstatic ; toolset.flags $(toolset).link FINDLIBS-SA-PFX <target-os>$(generic-os)/<runtime-link>shared : -Wl,-Bdynamic ; toolset.flags $(toolset).link HAVE_SONAME <target-os>$(generic-os) : "" ; toolset.flags $(toolset).link SONAME_OPTION <target-os>$(generic-os) : -h ; # See note [1] toolset.flags $(toolset).link OPTIONS <target-os>$(generic-os)/<runtime-link>static : -static ; # [1] # For <runtime-link>static we made sure there are no dynamic libraries in the # link. On HP-UX not all system libraries exist as archived libraries (for # example, there is no libunwind.a), so, on this platform, the -static option # cannot be specified. } # Flags for 'free' features ('free' features are features that do not have # a pre-defined set of values). toolset.flags cray.compile USER_OPTIONS <cflags> ; toolset.flags cray.compile.c++ USER_OPTIONS <cxxflags> ; toolset.flags cray.compile.asm USER_OPTIONS <asmflags> ; toolset.flags cray.compile DEFINES <define> ; toolset.flags cray.compile INCLUDES <include> ; toolset.flags cray.link USER_OPTIONS <linkflags> ; toolset.flags cray.link LINKPATH <library-path> ; toolset.flags cray.link FINDLIBS-ST <find-static-library> ; toolset.flags cray.link FINDLIBS-SA <find-shared-library> ; toolset.flags cray.link LIBRARIES <library-file> ; toolset.flags cray.archive AROPTIONS <archiveflags> ; ### ### Actions ### actions compile.c++ { "$(CONFIG_COMMAND_CXX)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -c -o "$(<)" "$(>)" $(DRIVER_OPTIONS) } actions compile.c { "$(CONFIG_COMMAND_C)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -c -o "$(<)" "$(>)" $(DRIVER_OPTIONS) } actions compile.asm { "$(CONFIG_COMMAND_CXX)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -c -o "$(<)" "$(>)" $(DRIVER_OPTIONS) } actions compile.c++.preprocess { "$(CONFIG_COMMAND_CXX)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -E "$(>)" >"$(<)" $(DRIVER_OPTIONS) } actions compile.c.preprocess { "$(CONFIG_COMMAND_C)" $(OPTIONS) $(USER_OPTIONS) -D$(SPACE)$(DEFINES) -I$(SPACE)"$(INCLUDES)" -E "$(>)" >"$(<)" $(DRIVER_OPTIONS) } # We don't want to invoke 'ld' (the linker) directly for 'link', since we # want to give the CCE compiler driver a chance to modify the command line # it passes to 'ld'. # # The question is: which CCE compiler driver do we use? The driver for C, # the driver for C++, or the driver for Fortran? # # Here are things that definitely do not work: # # - Using the driver for C doesn't work when linking C++ programs, because # things like 'std::cout' are not available in C, they are only # available in C++. # # We use the driver for C++ below since we are primarily interested in # compiling Boost, which is written in C++. Also, the C++ driver will # properly link C code as well. actions link bind LIBRARIES { "$(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) } actions link.dll bind LIBRARIES { "$(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) } actions piecemeal archive { "$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)" "$(.RANLIB)" "$(<)" } ### ### Updating rules ### # These are the actual updating rules that apply the associated actions # when called. rule compile.c++ ( targets * : sources * : properties * ) { compile-c++-procedure $(targets) : $(sources) : $(properties) ; } rule compile.c ( targets * : sources * : properties * ) { compile-c-procedure $(targets) : $(sources) : $(properties) ; } rule compile.asm ( targets * : sources * : properties * ) { compile-asm-procedure $(targets) : $(sources) : $(properties) ; } rule compile.c++.preprocess ( targets * : sources * : properties * ) { compile-c++-preprocess-procedure $(targets) : $(sources) : $(properties) ; } rule compile.c.preprocess ( targets * : sources * : properties * ) { compile-c-preprocess-procedure $(targets) : $(sources) : $(properties) ; } rule link ( targets * : sources * : properties * ) { link-procedure $(targets) : $(sources) : $(properties) ; } rule link.dll ( targets * : sources * : properties * ) { link-dll-procedure $(targets) : $(sources) : $(properties) ; } rule archive ( targets * : sources * : properties * ) { archive-procedure $(targets) : $(sources) : $(properties) ; } # These are the procedure portions of the updating rules. Calling the # procedure portion may modify the targets, but it will not apply actions # to the targets. This allows us to reuse the procedure portions of the # updating rules without applying the same actions to targets. rule compile-c++-procedure ( targets * : sources * : properties * ) { set-cxxstd-procedure $(targets) : $(sources) : $(properties) ; set-cxxstd-dialect-procedure $(targets) : $(sources) : $(properties) ; set-debug-symbols-procedure $(targets) : $(sources) : $(properties) ; add-space-procedure $(targets) : $(sources) : $(properties) ; debug-driver-procedure $(targets) : $(sources) : $(properties) ; } rule compile-c-procedure ( targets * : sources * : properties * ) { set-debug-symbols-procedure $(targets) : $(sources) : $(properties) ; add-space-procedure $(targets) : $(sources) : $(properties) ; debug-driver-procedure $(targets) : $(sources) : $(properties) ; } rule compile-asm-procedure ( targets * : sources * : properties * ) { compile-c++-procedure $(targets) : $(sources) : $(properties) ; } rule compile-c++-preprocess-procedure ( targets * : sources * : properties * ) { compile-c++-procedure $(targets) : $(sources) : $(properties) ; } rule compile-c-preprocess-procedure ( targets * : sources * : properties * ) { compile-c-procedure $(targets) : $(sources) : $(properties) ; } rule link-procedure ( targets * : sources * : properties * ) { set-cxxstd-procedure $(targets) : $(sources) : $(properties) ; set-cxxstd-dialect-procedure $(targets) : $(sources) : $(properties) ; gcc-link-procedure $(targets) : $(sources) : $(properties) ; debug-driver-procedure $(targets) : $(sources) : $(properties) ; # CCE driver command line flags for linking executables. local link = [ feature.get-values <link> : $(properties) ] ; switch $(link) { case shared : DRIVER_OPTIONS on $(<) += -dynamic ; case static : DRIVER_OPTIONS on $(<) += -static ; } # The link command line from the 'gcc' toolset includes: # # '$(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA)' # # The 'FINDLIBS-ST' and 'FINDLIBS-SA' variables are the libraries # specified by the '<find-static-library>' and '<find-shared-library>' # features, respectively. The 'FINDLIBS-ST-PFX' is typically # '-Wl,-Bstatic'. The 'FINDLIBS-SA-PFX' is typically '-Wl,-Bdynamic'. # # The '-Bstatic' and '-Bdynamic' flags passed to the linker tell the # linker how to link all of the following libraries. The flag is in effect # until it is overridden by another '-B' flag on the command line. # # So, it makes sense that the 'gcc' toolset includes these flags, so the # '<find-static-library>' and '<find-shared-library>' libraries are linked # properly. # # The last flag that is set ('-Bdynamic') affects the link type for any # other libraries on the command line. In the 'gcc' toolset, this is okay, # since there are no other libraries specified on the command line after # these flags. However, when the CCE compiler driver invokes the linker, # it adds additional libraries to the command line based on what modules # are loaded in the environment. So, the last '-B' flag on the CCE driver # command line affects the link type for all libraries that CCE # automatically appends. # # Therefore, we have to set the final '-B' flag to the link type we want # the CCE libraries to be linked with. Appending to the 'OPTIONS' variable # seems reasonable. local link = [ feature.get-values <link> : $(properties) ] ; switch $(link) { case shared : OPTIONS on $(<) += -Wl,-Bdynamic ; case static : OPTIONS on $(<) += -Wl,-Bstatic ; } } rule link-dll-procedure ( targets * : sources * : properties * ) { set-cxxstd-procedure $(targets) : $(sources) : $(properties) ; set-cxxstd-dialect-procedure $(targets) : $(sources) : $(properties) ; gcc-link-dll-procedure $(targets) : $(sources) : $(properties) ; debug-driver-procedure $(targets) : $(sources) : $(properties) ; # CCE driver command line flags for linking shared libraries. DRIVER_OPTIONS on $(<) += -shared ; } rule archive-procedure ( targets * : sources * : properties * ) { gcc-archive-procedure $(targets) : $(sources) : $(properties) ; debug-driver-procedure $(targets) : $(sources) : $(properties) ; } # Utility procedure rules intended to be called from updating rules. rule gcc-link-procedure ( targets * : sources * : properties * ) { # Copied from 'gcc.jam'. SPACE on $(targets) = " " ; # Serialize execution of the 'link' action, since running N links in # parallel is just slower. For now, serialize only gcc links, it might be a # good idea to serialize all links. JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ; gcc.quote-rpath $(targets) ; } rule gcc-link-dll-procedure ( targets * : sources * : properties * ) { # Copied from 'gcc.jam'. SPACE on $(targets) = " " ; JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ; gcc.quote-rpath $(targets) ; } rule gcc-archive-procedure ( targets * : sources * : properties * ) { # Copied from 'gcc.jam'. # Always remove archive and start again. Here is the rationale from # # Andre Hentz: # # I had a file, say a1.c, that was included into liba.a. I moved a1.c to # a2.c, updated my Jamfiles and rebuilt. My program was crashing with absurd # errors. After some debugging I traced it back to the fact that a1.o was # *still* in liba.a # # Rene Rivera: # # Originally removing the archive was done by splicing an RM onto the # archive action. That makes archives fail to build on NT when they have # many files because it will no longer execute the action directly and blow # the line length limit. Instead we remove the file in a different action, # just before building the archive. # local clean.a = $(targets[1])(clean) ; TEMPORARY $(clean.a) ; NOCARE $(clean.a) ; LOCATE on $(clean.a) = [ on $(targets[1]) return $(LOCATE) ] ; DEPENDS $(clean.a) : $(sources) ; DEPENDS $(targets) : $(clean.a) ; common.RmTemps $(clean.a) : $(targets) ; } rule add-space-procedure ( targets * : sources * : properties * ) { SPACE on $(targets) = " " ; } rule set-cxxstd-procedure ( targets * : sources * : properties * ) { # Translate '<cxxstd>' into a standard recognized by CCE. local version = [ on $(targets[1]) return $(VERSION) ] ; local cxxstd = [ feature.get-values cxxstd : $(properties) ] ; local cray-cxxstd = ; local unsupported-values = 2a ; # I don't know what '2a' means. if $(cxxstd) && $(cxxstd) in $(unsupported-values) { log-warning cray : ignoring unsupported property '<cxxstd>$(cxxstd)' ; # Set to default value, or blank if default is unsupported. local default-value = [ get-default-feature-value cxxstd ] ; if $(default-value) in $(unsupported-values) { cxxstd = ; } else { cxxstd = $(default-value) ; } } switch $(cxxstd) { case 98 : cray-cxxstd = 03 ; case 03 : cray-cxxstd = 03 ; case 0x : cray-cxxstd = 11 ; case 11 : cray-cxxstd = 11 ; case 1y : cray-cxxstd = 14 ; case 14 : cray-cxxstd = 14 ; case 1z : cray-cxxstd = 17 ; case 17 : cray-cxxstd = 17 ; case latest : cray-cxxstd = [ latest-cray-cxxstd $(version) ] ; } # If the 'cray-cxxstd' is not supported by this compiler version, we just # let the command line fail. # If 'cxxstd' was blank, then 'cray-cxxstd' is also blank, and nothing is # added to the command line. The compiler just uses it's default C++ # standard. # Apply final options. local space = " " ; OPTIONS on $(targets) += -h$(space)std=c++$(cray-cxxstd) ; } rule set-cxxstd-dialect-procedure ( targets * : sources * : properties * ) { # Translate '<cxxstd-dialect>' into '-h [no]conform' and '-h [no]gnu' # options. local version = [ on $(targets[1]) return $(VERSION) ] ; local cxxstd-dialect = [ feature.get-values cxxstd-dialect : $(properties) ] ; local cray-conform = ; local cray-gnu = ; local unsupported-values = ms ; if $(cxxstd-dialect) && $(cxxstd-dialect) in $(unsupported-values) { log-warning cray : ignoring unsupported property '<cxxstd-dialect>$(cxxstd-dialect)' ; # Set to default value, or blank if default is unsupported. local default-value = [ get-default-feature-value cxxstd-dialect ] ; if $(default-value) in $(unsupported-values) { cxxstd-dialect = ; } else { cxxstd-dialect = $(default-value) ; } } switch $(cxxstd-dialect) { case gnu : cray-conform = noconform ; cray-gnu = gnu ; case iso : cray-conform = conform ; cray-gnu = nognu ; } if [ has-conform-option $(version) ] = false { # The '-h [no]conform' option is ignored in recent versions of CCE. cray-conform = ; } # If 'cxxstd-dialect' was blank, then 'cray-conform' and 'cray-gnu' are # also blank, and nothing is added to the command line. The compiler just # uses it's default C++ dialect. # Apply final options. local space = " " ; OPTIONS on $(targets) += -h$(space)$(cray-conform) -h$(space)$(cray-gnu) ; } rule set-debug-symbols-procedure ( targets * : sources * : properties * ) { local debug-symbols = [ feature.get-values <debug-symbols> : $(properties) ] ; if $(debug-symbols) = "on" { local optimization = [ feature.get-values <optimization> : $(properties) ] ; local debug-option = ; if $(optimization) = off { debug-option = 0 ; } else { debug-option = 3 ; } local space = " " ; OPTIONS on $(targets) += -G$(space)$(debug-option) ; } } rule debug-driver-procedure ( targets * : sources * : properties * ) { if $(.debug-driver) { # Passing '-vv' to the CCE driver causes it to output the command lines # for the underlying tools that it invokes. DRIVER_OPTIONS on $(<) += -vv ; } } ### ### Generators ### class cray-linking-generator : gcc-linking-generator { rule action-class ( ) { return action ; } } # We reuse some generator classes from the 'unix' toolset. Specifically, # we are reusing generators for the following updating actions: # # - 'archive' # - 'searched-lib-generator' # - 'prebuilt' # # Inheriting these generators is like using the same generator classes as # the 'unix' toolset, but pointing them to the 'cray' updating rules. toolset.inherit-generators cray : unix : unix.link unix.link.dll ; # The 'C-compiling-generator' class adds source paths to the '<include>' # property. generators.register [ new C-compiling-generator cray.compile.c++ : CPP : OBJ : <toolset>cray ] ; generators.register [ new C-compiling-generator cray.compile.c : C : OBJ : <toolset>cray ] ; generators.register [ new C-compiling-generator cray.compile.asm : ASM : OBJ : <toolset>cray ] ; generators.register [ new C-compiling-generator cray.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>cray ] ; generators.register [ new C-compiling-generator cray.compile.c.preprocess : C : PREPROCESSED_C : <toolset>cray ] ; generators.register [ new cray-linking-generator cray.link : LIB OBJ : EXE : <toolset>cray ] ; generators.register [ new cray-linking-generator cray.link.dll : LIB OBJ : SHARED_LIB : <toolset>cray ] ; # Tell Boost.Build to prefer 'cray' generators over other valid # generators. This is used to resolve a tie when Boost.Build finds that # there is more than one viable generator for a particular build request. generators.override cray.prebuilt : builtin.prebuilt ; generators.override cray.searched-lib-generator : searched-lib-generator ; type.set-generated-target-suffix PREPROCESSED_CPP : <toolset>cray : i ; type.set-generated-target-suffix PREPROCESSED_C : <toolset>cray : i ; ### ### Utility rules ### rule validate-command ( toolset command ) { local found-command = [ common.find-tool $(command) ] ; if $(found-command) && $(.debug-configuration) { log-notice $(toolset) : command '$(command)' found at [ common.get-absolute-tool-path $(found-command) ] ; } if ! $(found-command) { log-warning $(toolset) : command '$(command)' not found ; found-command = $(command) ; } return $(found-command) ; } local rule options-helper ( rule-or-module variable-name condition * : feature options * ) { toolset.flags $(rule-or-module) $(variable-name) $(condition) : [ feature.get-values $(feature) : $(options) ] : unchecked ; } rule handle-options ( toolset : toolset-condition * : command-c command-cxx command-fortran command-ar command-ranlib : options * ) { # Configures some common 'toolset.flags' options. In particular, this rule # sets the compiler command name to invoke. Inspired by # 'common.handle-options'. # We cannot use a single 'CONFIG_COMMAND' variable because each CCE driver # can only handle a single source code language. Therefore, we have to # give actions a way to specify which driver they intend to use, and we # accomplish this by providing multiple 'CONFIG_COMMAND' variables to the # action. We cannot set the language through a flag in the 'OPTIONS' # variable the way the 'gcc' toolset does. toolset.flags $(toolset) CONFIG_COMMAND_C $(toolset-condition) : $(command-c) : unchecked ; toolset.flags $(toolset) CONFIG_COMMAND_CXX $(toolset-condition) : $(command-cxx) : unchecked ; toolset.flags $(toolset) CONFIG_COMMAND_FORTRAN $(toolset-condition) : $(command-fortran) : unchecked ; toolset.flags $(toolset).archive .AR $(toolset-condition) : $(command-ar) : unchecked ; toolset.flags $(toolset).archive .RANLIB $(toolset-condition) : $(command-ranlib) : unchecked ; # The following flags are applied to all targets built by this # configuration of this toolset. This particular configuration of this # toolset is identified by '$(toolset-condition)'. This allows the user to # specify 'options' in their 'using' statement, and those options will be # applied to all targets built by this configuration of this toolset. options-helper $(toolset).compile USER_OPTIONS $(toolset-condition) : <compileflags> $(options) ; options-helper $(toolset).compile USER_OPTIONS $(toolset-condition) : <cflags> $(options) ; options-helper $(toolset).compile.c++ USER_OPTIONS $(toolset-condition) : <cxxflags> $(options) ; options-helper $(toolset).compile.fortran USER_OPTIONS $(toolset-condition) : <fflags> $(options) ; options-helper $(toolset).compile.asm USER_OPTIONS $(toolset-condition) : <asmflags> $(options) ; options-helper $(toolset).compile DEFINES $(toolset-condition) : <define> $(options) ; options-helper $(toolset).compile INCLUDES $(toolset-condition) : <include> $(options) ; options-helper $(toolset).link USER_OPTIONS $(toolset-condition) : <linkflags> $(options) ; options-helper $(toolset).link LINKPATH $(toolset-condition) : <library-path> $(options) ; options-helper $(toolset).link FINDLIBS-ST $(toolset-condition) : <find-static-library> $(options) ; options-helper $(toolset).link FINDLIBS-SA $(toolset-condition) : <find-shared-library> $(options) ; options-helper $(toolset).link LIBRARIES $(toolset-condition) : <library-file> $(options) ; options-helper $(toolset).archive AROPTIONS $(toolset-condition) : <archiveflags> $(options) ; } rule latest-cray-cxxstd ( compiler-version ) { # Select latest 'cray-cxxstd' based on compiler version. local cray-cxxstd = 03 ; if $(compiler-version) >= [ numeric-version 8.6 ] { cray-cxxstd = 14 ; } return $(cray-cxxstd) ; } rule has-conform-option ( compiler-version ) { # Returns 'true' or 'false'. Returns empty list if the 'compiler-version' # is not supported. local result = true ; if $(compiler-version) >= [ numeric-version 8.6 ] { result = false ; } return $(result) ; } local rule justify-right ( pad-char elements * ) { # Returns a list of 'elements' where each 'element' is at least 2 # characters long. If an 'element' is less than two characters long, pads # 'element' with 'pad-char' to make it 2 characters long. local result = ; local p = $(pad-char) ; for local e in $(elements) { switch $(e) { case ?? : result += $(e) ; case ? : result += $(p)$(e) ; case * : result += $(p)$(p) ; } } return $(result) ; } local rule list-justify-left ( pad-elem elements * ) { # Add 'pad-elem' to 'elements' list until it has 4 elements. If 'elements' # list already had 4 or more elements, returns the first 4 elements in # 'elements' list. local tally = x ; local result = ; for local e in $(elements) { if $(tally) != xxxxx { result += $(e) ; tally = $(tally)x ; } } while $(tally) != xxxxx { result += $(pad-elem) ; tally = $(tally)x ; } return $(result) ; } local rule numeric-version ( dotted-version ) { # Returns a numeric representation of version that can be compared # directly with comparison operators. local result = [ regex.split $(dotted-version) "[.]" ] ; result = [ list-justify-left 0 $(result) ] ; result = [ justify-right 0 $(result) ] ; result = $(result:J="") ; return $(result) ; } local rule get-default-feature-value ( feature-name ) { local default-property = [ feature.defaults $(feature-name) ] ; local default-value = [ feature.get-values $(feature-name) : $(default-property) ] ; return $(default-value) ; } rule log ( log-level prefix ? : * ) { 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 { local message = $($(message-arg)) ; if $(message) { ECHO "$(log-level):" "$(prefix):" $(message) ; } } } rule log-error ( prefix ? : * ) { 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) ; } rule log-warning ( prefix ? : * ) { 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) ; } rule log-notice ( prefix ? : * ) { 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) ; } rule __test__ ( ) { import assert ; assert.result 08060000 : numeric-version 8.6 ; assert.result 08061500 : numeric-version 8.6.15 ; assert.result 08061501 : numeric-version 8.6.15.1 ; assert.result 08061501 : numeric-version 8.6.15.1.2 ; local a = [ numeric-version 8.6 ] ; local b = [ numeric-version 8.5.9 ] ; # 'assert.equal x : y' forces the test to fail. It's like saying 'assert # false'. if ! ( $(a) > $(b) ) { assert.equal x : y ; } if ! ( $(b) < $(a) ) { assert.equal x : y ; } if ! ( $(a) >= $(b) ) { assert.equal x : y ; } if ! ( $(a) >= $(a) ) { assert.equal x : y ; } if ! ( $(b) <= $(a) ) { assert.equal x : y ; } if ! ( $(b) <= $(b) ) { assert.equal x : y ; } if ! ( $(a) = $(a) ) { assert.equal x : y ; } if ! ( $(a) != $(b) ) { assert.equal x : y ; } }