summaryrefslogtreecommitdiff
path: root/Jambase
diff options
context:
space:
mode:
Diffstat (limited to 'Jambase')
-rw-r--r--Jambase4541
1 files changed, 4541 insertions, 0 deletions
diff --git a/Jambase b/Jambase
new file mode 100644
index 0000000..6ee19eb
--- /dev/null
+++ b/Jambase
@@ -0,0 +1,4541 @@
+#
+# /+\
+# +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+# \+/
+#
+# This file is part of Jam - see jam.c for Copyright information.
+#
+
+# The Copyright information in jam.c reads:
+#
+#/*
+# * /+\
+# * +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+# * \+/
+# *
+# * This file is part of jam.
+# *
+# * License is hereby granted to use this software and distribute it
+# * freely, as long as this copyright notice is retained and modifications
+# * are clearly marked.
+# *
+# * ALL WARRANTIES ARE HEREBY DISCLAIMED.
+# */
+
+# MODIFIDED version of jam 2.5 Jambase, for the ArgyllCMS project by Graeme W. Gill.
+# These modifications are herebye licensed under the same conditions
+# as as the rest of Jam, as detailed above.
+# Moved to a "Normalized" scheme, where Jamfile UNIX style target paths
+# are converted to platform specific, Jamfile relative, Gristed/SEARCH/LOCATE
+# form internally. Creating the tree is simplified by eliminating the SubDir
+# rule. Better support for MingW, OS X. More comprehensive ruleset.
+# Renamed Jamrules to Jamtop.
+#
+# JAMBASE - jam 2.5 ruleset providing make(1)-like functionality
+#
+# Supports UNIX, NT, and VMS.
+#
+# Special targets defined in this file:
+#
+# all - parent of first, shell, files, lib, exe
+# first - first dependent of 'all', for potential initialization
+# shell - parent of all Shell targets
+# files - parent of all File targets
+# lib - parent of all Library targets
+# exe - parent of all Main targets
+# dirs - parent of all MkDir targets
+# install - parent of all Install targets
+# clean - removes all Shell, File, Library, and Main targets
+# uninstall - removes all Install targets
+#
+
+# Rules defined by this file:
+#
+# As obj : source.s ; .s -> .o
+# Bulk dir : files ; populate directory with many files
+# Cc obj : src.c : flags : defines : hdrpaths
+# .c -> .o
+# C++ obj : src.cc : flags : defines : hdrpaths
+# .cc -> .o
+# Clean clean : sources ; remove sources with 'jam clean'
+# File dest : source ; copy file
+# FileNoClean dest : source ; copy file, but don't delete dest during clean
+# FakeFile dest : source ; Fudge to say dest is created with source
+# Fortran obj.o : source.f ; .f -> .o
+# GenFile target : program args ; make custom file
+# GenFileND target : program args : extra_dependecies ;
+# make custom file, program dependent & args not
+# GenFileNND target : program args : extra_dependecies ;
+# make custom file, program & args not dependent
+# CatToFile dest : strings ; save the arguments to the file
+# GuiBin image ; Mark executable as GUI applications
+# (Needs to go before other declarations of image)
+# HardLink target : source ; make link from source to target
+# HdrRule source : headers ; handle #includes
+# InstallInto dir : sources ; install any files
+# InstallBin dir : sources ; install binaries
+# InstallLib dir : sources ; install files
+# InstallShLib dir : sources ; install files
+# InstallFile dir : sources ; install files
+# InstallMan dir : sources ; install man pages
+# InstallShell dir : sources ; install shell scripts
+# Lex source.c : source.l ; .l -> .c
+# Library library : sources : flags : defines : hdrpaths : objects
+# static library from compiled sources
+# LibraryFromLibraries lib : libs ; static library from static libraries
+# LibraryFromObjects lib : objects ; static library from objects
+# LinkLibraries images : libraries ; add static libraries onto Mains
+# LinkObjects images : objects ; add objects onto Mains
+# LinkShLibraries images : shlibraries ; add shared libraries onto Mains
+# Main image : sources : flags : defines : hdrpaths : objects : libs : shlibs ;
+# create exe from compiled sources
+# MainsFromSources sources ; create exes each from their source
+# MainFromObjects image : objects : libs : shlibs ;
+# create executable from objects
+# MainVariant image : sources : flags : defines : hdrpaths : objects : libs : shlibs ;
+# create exe from compiled sources with separate named objs
+# MainLinkFlags mains : flags ; add linker flags for object
+# MkDir dir ; make a directory, if not there
+# Mod target : mode ; sets mode of file
+# NDepends dest : source ; make Normalized dependency
+# NNoUpdate targ ; create Normalized target if needed but never update it
+# NIncludes dest : source ; make Normalized co-dependency
+# Object object : sources : flags : defines : hdrpaths ; compile object from source
+# ObjectCcFlags objects : flags ; add compiler flags for object
+# ObjectPrefCcFlags objects : flags ; add preference compiler flags for object (overridable)
+# ObjectC++Flags objects : flags ; add compiler flags for object
+# ObjectPrefC++Flags objects : flags ; add preference compiler flags for object (overridable)
+# ObjectDefines objects : defines ; add defines for object
+# ObjectHdrs objects : dirs ; add include directories for object
+# ObjectKeep objects ; mark objects to be kept after library build
+# Objects sources : flags : defines : hdrpaths compile sources
+# PeerInclude dir ; include peer Jamfile
+# FindTop ; Set TOP by locating JAMTOP file above SUBDIR
+# ProjTop d1 d2 .. ; Set project TOP
+# RmTemps target : sources ; remove temp sources after target made
+# Setuid images ; mark executables Setuid
+# set SHLINKDEFFILE on for Windows to define exports using .def file.
+# set SHLINKSEARCHEXEPATH true on UNIX to have applications search exeutable location for it
+# ShLibrary shlib : source ; link shared library from compiled sources
+# ShLibraryFromObjects shlib : objects ; link shared library from objects
+# ShLibraryLibraries shlib : libraries ; add static libraries onto shared libraries link
+# ShLibraryObjects shlib : objects ; add objects onto shared libraries link
+# ShLibraryShLibraries shlib : shlibraries ; add shared libraries onto shared libraries link
+# SoftLink target : source ; make symlink from source to target
+# SubInclude dir ; include sub Jamfile
+# Shell exe : source ; make a shell executable
+# Undefines images : symbols ; save undef's for linking
+# UserObject object : source ; handle unknown suffixes for Object
+# Yacc source.c : source.y ; .y -> .c
+# Aswig : source.i ; .i -> .h _i.c .hpp
+#
+# Utility rules
+#
+# val = geton var : varname ; return the value of varname on var
+# paths = NormPaths paths [ : dir ] ; normalize a set of paths relative to SUBDIR or dir
+# paths = NormSrcPaths paths [ : dir ] ; NormPaths with SRCDIR
+# paths = NormDstPaths paths [ : dir ] ; NormPaths with DSTDIR
+# paths = NormSrcTargets paths [ : dir ] ; normalize source targets, set Grist NOMLOC SEARCH
+# paths = NormDstTargets paths [ : dir ] ; normalize destination targets, set Grist NOMLOC LOCATE
+# paths = NormISrcTargets paths [ : dir ] ; Same as NormSrcTargets but ignore SRCDIR
+# paths = NormIDstTargets paths [ : dir ] ; Same as NormDstTargets but ignore DSTDIR
+#
+# More utility rules that have no side effects :
+#
+# FAppendSuffix f1 f2 ... : $(SUF) ; return $(<) with suffixes if no current suffixes
+# FStripCommon v1 : v2 ; strip common initial parts of v1 v2
+# FReverse a1 a2 ... ; return ... a2 a1
+# FDelEmpty a1 a2 ... ; return a1 a2 ... with any empty elements deleted
+#
+# Variables:
+#
+# Sub-Jamfile build variables, optionaly set in each Sub-Jamfile. They will
+# be picked up by subsequent rules that set target relationships and
+# creation rules. They are added to any Parent-Jamfile variables,
+# and become the Parent-Jamfile variables of any SubIncludes.
+# Relative file/path variables are anchored by the Jamfile location.
+#
+# ASFLAGS - Flags for the assembler.
+# CCFLAGS - Flags for the C compiler.
+# C++FLAGS - Flags for the C++ compiler.
+# LINKFLAGS - Flags for the executable linker.
+# SHLINKFLAGS - Flags for the shared library linker.
+# HDRS - Complile header search directories
+# DEFINES - Compile defines
+# LINKOBJS - Link extra objects
+# LINKLIBS - Link extra libraries
+# LINKSHLIBS - Link extra shared libraries
+# SHLINKOBJS - ShLibrary Linker extra objects
+# SHLINKLIBS - ShLibrary Linker extra libraries
+# SHLINKSHLIBS - ShLibrary Linker extra shared libraries
+#
+# Sub-directory preferred build flags, e.g. optimizations etc. These will only
+# have effect if not set by a parent Jamfile (ie. involked from a leaf Jamfile).
+#
+# PREF_ASFLAGS
+# PREF_CCFLAGS
+# PREF_C++FLAGS
+# PREF_LINKFLAGS
+# PREF_SHLINKFLAGS
+#
+# Parent-Jamfile build variables. These are the accumulated
+# values from any Parent Jamfiles, and will be added to any
+# Sub-Jamfile variables when a rule picks them up.
+# File/path variables will have been normalized.
+#
+# P_ASFLAGS - Flags for the assembler.
+# P_CCFLAGS - Flags for the C compiler.
+# P_C++FLAGS - Flags for the C++ compiler.
+# P_LINKFLAGS - Flags for the executable linker.
+# P_SHLINKFLAGS - Flags for the shared library linker.
+# P_HDRS - Complile header search directories
+# P_DEFINES - Compile defines
+# P_LINKOBJS - Link extra objects
+# P_LINKLIBS - Link extra libraries
+# P_LINKSHLIBS - Link extra shared libraries
+# P_SHLINKOBJS - ShLibrary Linker extra objects
+# P_SHLINKLIBS - ShLibrary Linker extra libraries
+# P_SHLINKSHLIBS - ShLibrary Linker extra shared libraries
+#
+# Pre-defined values
+#
+# Pre-packaged flags that conceal platform dependence,
+# and are used to set CCFLAGS/C++FLAGS/LINKFLAGS/SHLINLFLAGS etc.
+#
+# CCOPTFLAG - CC/C++ flag for optimization
+# CCDEBUGFLAG - CC/C++ flag for debug
+# CCPROFFLAG - CC/C++ flag for performance profiling
+# CCSHOBJFLAG - CC/C++ flag for compiling for a shared library (UNIX)
+#
+# LINKOPTFLAG - LINK flag for optimization of the binary/shared library
+# LINKDEBUGFLAG - LINK flag to support debugging
+# LINKPROFFLAG - LINK flag to support performance profiling
+# LINKSTRIPFLAG - LINK flag to strip binary of any symbols
+#
+# Location variables:
+#
+# DSTDIR - puts all products in a subdirectory of their nominated location.
+# Useful for storing variants in their own areas.
+#
+# SRCDIR - Looks for all sources and Jamfiles in an alternate top level source
+# location. Useful for accessing a read only source repository, or
+# building a variant without copying all the sources.
+# Note that at least the project Jamtop must be in the location
+# that is the target for the build, and will most likely be where
+# SRCDIR is set. SRCDIR is the location of the sources relative
+# to where it is declared.
+# (Not currently useful for a shadow build repository where the source
+# is spread between the SRCDIR and the build dir, because Jam 2.5 fails
+# to look at SEARCH if LOCATE is set).
+#
+# =========================================================================
+# ArgyllCMS Normalize mods:
+#
+# The main change is to locate and identify targets using their nominated location in the
+# filesystem. This eliminates the need to create Grist, or manipulate SEARCH, LOCATE etc.
+# when setting up a herachy of Jamfiles.
+#
+# Whenever a path is provided as an argument to one of the public rules, its path is assumed
+# to be relative to the Jamfile that it is declared in. [ The NormPaths/NormTargets rules do this. ]
+# Naturally absolute paths are not affected by this.
+# During execution this means that all files are translated to paths that are
+# in a normalized form, with either an absolute path or one that is relative to
+# the directory that Jam was involked in. For simplicity it is assumed that
+# the Jamfile contains UNIX style paths, and these are converted to the
+# platform specific form on normalization.
+#
+# For a target, the normalized directory is then stripped from the name and
+# set as the Grist (path elements separated by !), and also set in the NOMLOC,
+# LOCATE and SEARCH variables "on" the target. This gives a target a unique
+# identity for the whole of the build, determined by its nominated file system location.
+# The NOMLOC variable is a way of recovering it's location without having the reverse
+# the Grist strings. The actual location of the target can then be varied by
+# augmenting it's LOCATE and/or SEARCH variables.
+#
+# Any include file discovered by header scanning is searched for using the
+# search path that is expected to be used during compilation, and
+# its nominated location resolved this way. Any headers that are not
+# located this way or who's location isn't declared by another rule (the
+# latter being typical when headers are being generated) will be marked as
+# being in an __unknown__ directory and will not be scaned. Normally any
+# header files located in the STDHDRS directories will not be scanned either.
+#
+# [ Typically headers will be __unknown__ if the STDHDRS directories do
+# not reflect the default paths actually searched by the compiler, or if a
+# header is not actually going to be #included because it is protected
+# by an #ifdef. ]
+
+# Argyll Jambase internal implementation rules:
+
+# IDs = _TargetIDs targpaths ; return target ID's (gristed) from normalized paths
+# path = DeNormTargs target ; return the original path
+# CopyTarget dest : source ; duplicate a targets on NOMLOC LOCATE SEARCH variables.
+# NotTargets vars ; ensure variables aren't treated as LOCATE etc targets
+
+# d1 d2 ... file = _SepPath path ; separate a path into its components
+# path = _DirName d1 d2 ... ; combine components into a path
+# d1 d2 .. = _RatPath d1 d2 .. rationalize a path
+# d1 d2 .. = _RootPath d1 d2 .. : p1 p2 ... re-root a path
+# paths = RatPaths paths ; rationalize a set of paths
+# paths = RootPaths dir : paths ; re-root a set of paths
+# targs = CreateIDstTargets targs : dir ; create dest targets by locating targets in dir
+# paths1/paths = CatPaths path1 : paths ; concatenate paths separated by a /
+# found = FindToRoot starting_dir : file ; Try and locate file from directory up to root.
+
+# FindTop ; # Look for a default project file
+
+# DoInit ; Do subdir initialization (done by JAMBASE)
+
+# public write/read Variables:
+#
+# TRACESTDHDRS # Normally false, set to true to trace system path #include file dependenicies
+
+# public read only Variables:
+#
+# SUBDIR d1/d2/d3 # Current path from PWD to Jamfile
+# TOP d1/d2/d3 # Current path from PWD to the project Jamtop
+
+# internal variables
+#
+# _SUBDIR d1 d2 d3 ... # Current path from PWD to Jamfile
+# _TOP d1 d2 d3 # Current path from PWD to the project Jamtop
+
+# - - - - - - - - - - - - - - -
+
+# NOTE: Cross compiling support :-
+# To fix this to support cross compilation, the setup needs to be
+# modularised into 3 parts, making them all rules that can be re-involked:
+# 1) OS/Platform setup. System tools like copy, delete etc.
+# 2) Compiler setup. Basic compiler syntax etc.
+# 3) Target setup. Make this a rule, and allow switching
+# target by involking the rule. This will be simpler to
+# get working that per target 'on' variable (some
+# things are currently broken for 'on' variables, such
+# as library members, and it will be easier to do
+# things such as switch compilers.
+
+# - - - - - - - - - - - - - - -
+
+
+# Brief review of the jam language:
+#
+# Statements:
+# rule RULE - statements to process a rule
+# actions RULE - system commands to carry out target update
+#
+# Modifiers on actions:
+# together - multiple instances of same rule on target get executed
+# once with their sources ($(>)) concatenated
+# updated - refers to updated sources ($(>)) only
+# ignore - ignore return status of command
+# quietly - don't trace its execution unless verbose
+# piecemeal - iterate command each time with a small subset of $(>)
+# existing - refers to currently existing sources ($(>)) only
+# bind vars - subject to binding before expanding in actions
+#
+# Special rules:
+# Always - always build a target
+# Depends - builds the dependency graph
+# NOTE: can have only one $(<), or parallel builds stuff up!!
+# Use FakeFile to work around the problem.
+# Echo - blurt out targets on stdout
+# Exit - blurt out targets and exit
+# Includes - marks sources as headers for target (a codependency)
+# NoCare - don't panic if the target can't be built
+# NoUpdate - create the target if needed but never update it
+# NotFile - ignore the timestamp of the target (it's not a file)
+# Temporary - target need not be present if sources haven't changed
+#
+# Special variables set by jam:
+# $(<) - targets of a rule (to the left of the :)
+# $(>) - sources of a rule (to the right of the :)
+# $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC)
+# $(OS) - name of OS - varies wildly
+# $(JAMVERSION) - version number (2.5)
+#
+# Special variables used by jam:
+# SEARCH - where to find something (used during binding and actions)
+# LOCATE - where to plop something not found with SEARCH
+# HDRRULE - rule to call to handle include files
+# HDRSCAN - egrep regex to extract include files
+#
+# Special targets:
+# all - default if none given on command line
+#
+
+# for perforce use -- jambase version
+
+JAMBASEDATE = 2008.03.26 ;
+
+# Initialize variables
+#
+
+# ===========================================================
+#
+# OS specific variable settings
+#
+
+if $(NT)
+{
+ MV ?= move /y ;
+ CP ?= copy ;
+ RM ?= del /f/q ;
+ RMDIR ?= rmdir /s/q ;
+ SLASH ?= \\ ;
+ SUFLIB ?= .lib ;
+ SUFSHLIB ?= .dll ;
+ SUFIMPLIB ?= .lib ;
+ SUFOBJ ?= .obj ;
+ SUFEXE ?= .exe ;
+ SUFSH ?= .bat ;
+ CCSHOBJFLAG ?= ;
+
+ if $(BCCROOT)
+ {
+ AR ?= tlib /C /P64 ;
+ CC ?= bcc32 ;
+ CCFLAGS ?= -v -w- -q -DWIN -tWR -tWM -tWC ;
+ C++ ?= $(CC) ;
+ C++FLAGS ?= $(CCFLAGS) -P ;
+ LINK ?= $(CC) ;
+ LINKFLAGS ?= ;
+ STDLIBPATH ?= $(BCCROOT)\\lib ;
+ STDHDRS ?= $(BCCROOT)\\include ;
+ NOARSCAN ?= true ;
+ }
+ else if $(MingW) || $(MINGW)
+ {
+ # We need to do something about adding -Wl,-subsystem,windows
+ # if WinMain is being used ? (it defaults to console)
+
+ MINGW ?= $(MingW) ;
+ TPFX = "" ;
+
+ if [ GLOB $(MINGW)/bin : x86_64-w64-mingw32-gcc.exe ] {
+ MINGW64 = $(MINGW) ;
+ }
+
+ # This doesn't work on a 32 bit system because we're cross
+ # compiling and need to create build system exe's
+ # (tiff/mkversion.exe, imdi/imdi_make.exe
+ # Will using -m32 for local exe's fix this ?
+ # What is multi-lib option ???
+ if $(MINGW64) {
+ ECHO "Compiler is MingW for 64 bit target" ;
+ TARGET64 = true ;
+ TPFX = x86_64-w64-mingw32- ;
+ MINGW64_LIB32 = $(MINGW)/mingw/lib32 ;
+ } else {
+ ECHO "Compiler is MingW for 32 bit target" ;
+ }
+
+
+ # Basic C/C++ tools
+ AR ?= $(TPFX)ar rusc ;
+ AS ?= $(TPFX)as ;
+ CC ?= $(TPFX)gcc ;
+ CCFLAGS ?= -DNT -mwin32 -pipe ;
+ C++ ?= $(CC) ;
+ C++FLAGS ?= $(CCFLAGS) ;
+
+ OLELIBS ?= -loleaut32 -luuid ;
+ BASELIBS ?= -lstdc++ -lgcc -lodbc32 -lwsock32 ;
+# WINLIBS ?= -lwinspool -lwinmm -lshell32 -lcomctl32 -lctl3d32
+# -lodbc32 -ladvapi32 -lodbc32 -lwsock32 -lopengl32
+# -lglu32 -lshlwapi -lsetupapi ;
+ WINLIBS ?= -lshlwapi -lsetupapi -lole32 -lws2_32 -lpsapi ;
+ GUILIBS ?= -lgdi32 -lmscms ;
+
+ LINK ?= $(TPFX)g++ ; # In case we link to C++ files
+ LINKFLAGS ?= -static ;
+ SHLINKFLAGS ?= ;
+ STDLIBS ?= -lm $(OLELIBS) $(WINLIBS) $(GUILIBS) ;
+ SHSTDLIBS ?= $(STDLIBS) ;
+
+ STDHDRS ?= $(MINGW)\\include ;
+
+ # Not sure whether linker -mconsole or -mwindow are needed ??
+
+ # Allow setting of flags, independent of compiler
+ DEFFLAG ?= -D ;
+ UNDEFFLAG ?= -U ;
+ CCOPTFLAG ?= -O3 ;
+ if $(PROCESSOR_LEVEL) = 15
+ { # -mtune seems faster than -march !!!
+# CCOPTFLAG += -mtune=pentium4 ;
+# CCOPTFLAG += -mtune=prescott ;
+ CCOPTFLAG += -mtune=nocona ; # portable code for Pentium4 640
+# CCOPTFLAG += -march=nocona -mfpmath=sse -msse3 ; # non-portable
+
+ }
+
+ CCDEBUGFLAG ?= -g ; # default (TABS? DWARF2 ?) format
+ CCPROFFLAG ?= -pg ;
+ LINKDEBUGFLAG ?= -g ;
+ LINKPROFFLAG ?= -pg ;
+ LINKOPTFLAG ?= -s -O ; # Affects creating .so's ??
+ LINKSTRIPFLAG ?= -s ;
+
+ # Other tools
+ AWK ?= awk ;
+ SED ?= sed ;
+
+# YACC ?= yacc ;
+# YACCFLAGS ?= -d ;
+# YACCFILES ?= y.tab ;
+
+ YACC ?= bison -y ;
+ YACCGEN ?= .c ;
+ YACCFILES ?= y.tab ;
+ YACCFLAGS ?= -d ;
+ }
+ else if $(MSVC) #
+ {
+ ECHO "Compiler is VC++ 16 bit" ;
+ AR ?= lib /nologo ;
+ CC ?= cl /nologo ;
+ CCFLAGS ?= /D \"WIN\" ;
+ C++ ?= $(CC) ;
+ C++FLAGS ?= $(CCFLAGS) ;
+ LINK ?= $(CC) ;
+ LINKFLAGS ?= ;
+ STDLIBS ?=
+ $(MSVC)\\lib\\mlibce.lib
+ $(MSVC)\\lib\\oldnames.lib
+ ;
+ NOARSCAN ?= true ;
+ STDHDRS ?= $(MSVC)\\include ;
+ DEFFLAG ?= /D ;
+ UNDEFFLAG ?= "/u _" ;
+ }
+ else if $(MSVCNT) || $(MSVCDIR) || $(MSVCDir) || $(VCINSTALLDIR)
+ {
+ # Visual C++ 8.0/9.0 uses VCINSTALLDIR
+ # We assume VC++ Express + XP32 SDK has been setup
+
+ # Visual C++ 6.0 uses MSVCDIR
+
+ if $(VCINSTALLDIR) {
+ MSVCNT ?= $(VCINSTALLDIR) ;
+ } else if $(MSVCDir) {
+ MSVCNT ?= $(MSVCDir) ;
+ } else {
+ MSVCNT ?= $(MSVCDIR) ;
+ }
+
+ if $(COMPILER) = MSVCPP10 {
+ ECHO "Compiler is VC++10 32 bit" ;
+ MSVCVER = 10 ;
+ } else if $(COMPILER) = MSVCPP9 {
+ ECHO "Compiler is VC++9 32 bit" ;
+ MSVCVER = 9 ;
+ } else if $(COMPILER) = MSVCPP8 {
+ ECHO "Compiler is VC++8 32 bit" ;
+ MSVCVER = 8 ;
+ } else {
+ ECHO "Compiler is VC++ 32 bit" ;
+ MSVCVER = 6 ;
+ }
+
+ # Add the SDK include and lib if it is present
+ if $(MSSdk) {
+ MSNTSDK ?= $(MSSdk) ;
+ } else if $(MSSDK) {
+ MSNTSDK ?= $(MSSDK) ;
+ } else if $(MSVCNT) {
+ MSNTSDK ?= $(MSVCNT) ;
+ }
+
+ # bury IA64 in the path for the SDK ???
+ # (but MSSDK already has this ?
+# local I ; if $(CPU) = "IA64" { I = ia64\\ ; } else { I = "" ; }
+ local I ; I = "" ;
+
+ AR ?= lib /NOLOGO ;
+ AS ?= masm386 ;
+ CC ?= cl /nologo ;
+ CCFLAGS ?= /DNT /MD ; # DLL compatible build by default
+ if $(MSVCVER) >= 8 {
+ CCFLAGS += /D_CRT_SECURE_NO_DEPRECATE=1
+ /D_CRT_NONSTDC_NO_DEPRECATE=1 ;
+ }
+ C++ ?= $(CC) ;
+ C++FLAGS ?= $(CCFLAGS) /GX ; # GX enables syncronous exception handling
+ LINK ?= link /nologo ;
+ LINKOUTFLAG ?= /out: ;
+ LINKFLAGS ?= /INCREMENTAL:NO /LIBPATH:$(MSNTSDK)\\lib\\$(I) ;
+ SHLINKFLAGS ?= ;
+
+ STDLIBS ?=
+ oldnames.lib
+ kernel32.lib
+ advapi32.lib
+ user32.lib
+ mscms.lib
+ gdi32.lib
+ shlwapi.lib
+ shell32.lib
+ setupapi.lib
+ ole32.lib
+ oleaut32.lib
+ ws2_32.lib
+ Wbemuuid.lib
+ ;
+ SHSTDLIBS ?= $(STDLIBS) ;
+ LINKFLAG ?= ;
+ STDHDRS ?= $(MSNTSDK)\\Include ;
+ DEFFLAG ?= /D ;
+ UNDEFFLAG ?= /U ;
+ CCOPTFLAG ?= /Ox ; # MSVC9 doesn't understamd GB, G6 ?
+ if $(MSVCVER) = 6 {
+ CCDEBUGFLAG ?= /Od /Z7 ; # Include debugging into in each object
+ CCPROFFLAG ?= /Od /Z7 ;
+ LINKDEBUGFLAG ?= /DEBUGTYPE:BOTH /DEBUG /PDB:NONE ;
+ } else {
+ CCDEBUGFLAG ?= /Od /Zi ; # /Zi creates debugging database
+ CCPROFFLAG ?= /Od /Zi ;
+ LINKDEBUGFLAG ?= /DEBUG ;
+ }
+ LINKPROFFLAG ?= /PROFILE $(LINKDEBUGFLAG) ;
+ LINKOPTFLAG ?= /OPT:REF ;
+ LINKSTRIPFLAG ?= ;
+ YACC ?= bison -y ;
+ YACCGEN ?= .c ;
+ YACCFILES ?= y.tab ;
+ YACCFLAGS ?= -d ;
+ }
+ else
+ {
+ EXIT On NT, set BCCROOT, MINGW, MSVCDIR, MSVCNT, MSVC or VCINSTALLDIR to the root
+ of the Borland, GCC or Microsoft directories. ;
+ }
+}
+else if $(OS2)
+{
+ WATCOM ?= $(watcom) ;
+
+ if ! $(WATCOM)
+ {
+ Exit On OS2, set WATCOM to the root of the Watcom directory. ;
+ }
+
+ AR ?= wlib ;
+ BINDIR ?= \\os2\\apps ;
+ CC ?= wcc386 ;
+ CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet
+ C++ ?= wpp386 ;
+ C++FLAGS ?= $(CCFLAGS) ;
+ CP ?= copy ;
+ DOT ?= . ;
+ DOTDOT ?= .. ;
+ LINK ?= wcl386 ;
+ LINKFLAGS ?= /zq ; # zq=quiet
+ STDLIBS ?= ;
+ MV ?= move ;
+ NOARSCAN ?= true ;
+ RM ?= del /f ;
+ SLASH ?= \\ ;
+ STDHDRS ?= $(WATCOM)\\h ;
+ SUFEXE ?= .exe ;
+ SUFSH ?= .bat ;
+ SUFLIB ?= .lib ;
+ SUFOBJ ?= .obj ;
+ DEFFLAG ?= /D ;
+ UNDEFFLAG ?= "/u _" ;
+
+}
+else if $(VMS)
+{
+ C++ ?= cxx ;
+ C++FLAGS ?= ;
+ CC ?= cc ;
+ CCFLAGS ?= ;
+ CHMOD ?= set file/prot= ;
+ CP ?= copy/replace ;
+ CRELIB ?= true ;
+ DOT ?= [] ;
+ DOTDOT ?= [-] ;
+ EXEMODE ?= (w:e) ;
+ FILEMODE ?= (w:r) ;
+ HDRS ?= ;
+ LINK ?= link ;
+ LINKFLAGS ?= "" ;
+ STDLIBS ?= ;
+ MKDIR ?= create/dir ;
+ MV ?= rename ;
+ RM ?= delete ;
+ RUNVMS ?= mcr ;
+ SHELLMODE ?= (w:er) ;
+ SLASH ?= . ;
+ STDHDRS ?= decc$library_include ;
+ SUFEXE ?= .exe ;
+ SUFSH ?= .bat ;
+ SUFLIB ?= .olb ;
+ SUFOBJ ?= .obj ;
+
+ switch $(OS)
+ {
+ case OPENVMS : CCFLAGS ?= /stand=vaxc ;
+ case VMS : STDLIBS ?= sys$library:vaxcrtl.olb/lib ;
+ }
+}
+else if $(MAC)
+{
+ local OPT ;
+
+ CW ?= "{CW}" ;
+
+ MACHDRS ?=
+ "$(UMACHDRS):Universal:Interfaces:CIncludes"
+ "$(CW):MSL:MSL_C:MSL_Common:Include"
+ "$(CW):MSL:MSL_C:MSL_MacOS:Include" ;
+
+ MACLIBS ?=
+ "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib"
+ "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ;
+
+ MPWLIBS ?=
+ "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
+ "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ;
+
+ MPWNLLIBS ?=
+ "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
+ "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ;
+
+ SIOUXHDRS ?= ;
+
+ SIOUXLIBS ?=
+ "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib"
+ "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib"
+ "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ;
+
+ C++ ?= mwcppc ;
+ C++FLAGS ?= -w off ;
+ CC ?= mwcppc ;
+ CCFLAGS ?= -w off ;
+ CP ?= duplicate -y ;
+ DOT ?= ":" ;
+ DOTDOT ?= "::" ;
+ HDRS ?= $(MACHDRS) $(MPWHDRS) ;
+ LINK ?= mwlinkppc ;
+ LINKFLAGS ?= -mpwtool -warn ;
+ STDLIBS ?= $(MACLIBS) $(MPWLIBS) ;
+ SHSTDLIBS ?= $(STDLIBS) ;
+ MKDIR ?= newfolder ;
+ MV ?= rename -y ;
+ NOARSCAN ?= true ;
+ RM ?= delete -y ;
+ SLASH ?= ":" ;
+ STDHDRS ?= ;
+ SUFLIB ?= .lib ;
+ SUFOBJ ?= .o ;
+}
+else if $(OS) = BEOS && $(OSPLAT) = PPC
+{
+ AR ?= mwld -xml -o ;
+ BINDIR ?= /boot/home/config/bin ;
+ CC ?= mwcc ;
+ CCFLAGS ?= -nosyspath ;
+ C++ ?= $(CC) ;
+ C++FLAGS ?= -nosyspath ;
+ CHMOD ?= chmod ;
+ CHGRP ?= chgrp ;
+ CHOWN ?= chown ;
+ FORTRAN ?= "" ;
+ LEX ?= flex ;
+ LIBDIR ?= /boot/home/config/lib ;
+ LINK ?= mwld ;
+ LINKFLAGS ?= "" ;
+ MANDIR ?= /boot/home/config/man ;
+ NOARSCAN ?= true ;
+ RANLIB ?= ranlib ;
+ STDHDRS ?= /boot/develop/headers/posix ;
+ YACC ?= bison -y ;
+ YACCGEN ?= .c ;
+ YACCFILES ?= y.tab ;
+ YACCFLAGS ?= -d ;
+}
+else if $(OS) = BEOS
+{
+ BINDIR ?= /boot/home/config/bin ;
+ CC ?= gcc ;
+ C++ ?= $(CC) ;
+ CHMOD ?= chmod ;
+ CHGRP ?= chgrp ;
+ CHOWN ?= chown ;
+ FORTRAN ?= "" ;
+ LEX ?= flex ;
+ LIBDIR ?= /boot/home/config/lib ;
+ LINK ?= gcc ;
+ MANDIR ?= /boot/home/config/man ;
+ NOARSCAN ?= true ;
+ RANLIB ?= ranlib ;
+ STDHDRS ?= /boot/develop/headers/posix ;
+ YACC ?= bison -y ;
+ YACCGEN ?= .c ;
+ YACCFILES ?= y.tab ;
+ YACCFLAGS ?= -d ;
+}
+else if $(UNIX)
+{
+ switch $(OS)
+ {
+ case AIX :
+ STDLIBS ?= -lbsd ;
+
+ case AMIGA :
+ CC ?= gcc ;
+ YACC ?= bison -y ;
+
+ case CYGWIN :
+ CC ?= gcc ;
+ CCFLAGS += -D__cygwin__ ;
+ LEX ?= flex ;
+ JAMSHELL ?= sh -c ;
+ RANLIB ?= "" ;
+ SUFEXE ?= .exe ;
+ YACC ?= bison -y ;
+
+ case DGUX :
+ RANLIB ?= "" ;
+ RELOCATE ?= true ;
+
+ case HPUX :
+ RANLIB ?= "" ;
+
+ case INTERIX :
+ CC ?= gcc ;
+ JAMSHELL ?= sh -c ;
+ RANLIB ?= "" ;
+
+ case IRIX :
+ RANLIB ?= "" ;
+
+ case MPEIX :
+ CC ?= gcc ;
+ C++ ?= gcc ;
+ CCFLAGS += -D_POSIX_SOURCE ;
+ HDRS += /usr/include ;
+ RANLIB ?= "" ;
+ NOARSCAN ?= true ;
+ NOARUPDATE ?= true ;
+
+ case MVS :
+ RANLIB ?= "" ;
+
+ case NEXT :
+ AR ?= libtool -o ;
+ RANLIB ?= "" ;
+
+ case MACOSX :
+# AR ?= libtool -o ;
+ AR ?= ar rusc ;
+ C++ ?= c++ ;
+ MANDIR ?= /usr/local/share/man ;
+ RANLIB ?= "" ;
+ SUFSHLIB ?= .dylib ;
+ SUFIMPLIB ?= .dylib ;
+
+ case NCR :
+ RANLIB ?= "" ;
+
+ case PTX :
+ RANLIB ?= "" ;
+
+ case QNX :
+ AR ?= wlib ;
+ CC ?= cc ;
+ CCFLAGS ?= -Q ; # quiet
+ C++ ?= $(CC) ;
+ C++FLAGS ?= -Q ; # quiet
+ LINK ?= $(CC) ;
+ LINKFLAGS ?= -Q ; # quiet
+ NOARSCAN ?= true ;
+ RANLIB ?= "" ;
+
+ case SCO :
+ RANLIB ?= "" ;
+ RELOCATE ?= true ;
+
+ case SINIX :
+ RANLIB ?= "" ;
+
+ case SOLARIS :
+ RANLIB ?= "" ;
+ AR ?= "/usr/ccs/bin/ar ru" ;
+
+ case UNICOS :
+ NOARSCAN ?= true ;
+ CCOPTFLAG ?= -O0 ;
+
+ case UNIXWARE :
+ RANLIB ?= "" ;
+ RELOCATE ?= true ;
+ }
+
+ # UNIX defaults
+
+ CCFLAGS ?= -DUNIX -D_THREAD_SAFE -pipe ;
+ CCOPTFLAG ?= -O2 ;
+ CCDEBUGFLAG ?= -g ;
+ CCPROFFLAG ?= ;
+ CCSHOBJFLAG ?= -fPIC ; # Position independent is better for ShLibrary
+ C++FLAGS ?= $(CCFLAGS) ;
+ CHMOD ?= chmod ;
+ CHGRP ?= chgrp ;
+ CHOWN ?= chown ;
+ LEX ?= lex ;
+ LINKFLAGS ?= ;
+ LINKOPTFLAG ?= -O ; # Affects creating .so's
+ LINKSTRIPFLAG ?= -s ;
+ LINKDEBUGFLAG ?= ;
+ LINKPROFFLAG ?= ;
+ SHLINKFLAGS ?= ; # Flags for creation of shared library
+ STDLIBS ?= -lm -lpthread ;
+ SHSTDLIBS ?= $(STDLIBS) ;
+ LINKFLAG ?= -l ;
+ RANLIB ?= "" ;
+ YACC ?= yacc ;
+ YACCGEN ?= .c ;
+ YACCFILES ?= y.tab ;
+ YACCFLAGS ?= -d ;
+
+ HDRS ?= /usr/local/include ;
+
+ # Add some good defaults for OS X
+ if $(OS) = MACOSX {
+ CCFLAGS += -Wno-sign-compare ; # supress new gcc4 warnings ?
+ CCFLAGS += -fpascal-strings ; # for compatibility with the OSX API
+ LINKFLAGS += -framework Carbon ; # default for .c
+ LINKFLAGS += -framework Cocoa ; # default for .m
+ }
+
+ # Make things work on 64 bit Linux
+ # Note that HOSTTYPE needs to be exported by the shell!
+ if $(HOSTTYPE) = x86_64
+ || $(HOSTTYPE) = x86_64-linux {
+ ECHO "We're on a 64 bit host" ;
+ HOST64 = true ;
+ CCFLAGS += -m64 ;
+ C++FLAGS += -m64 ;
+ }
+
+ # Adding --hash-style=sysv to the compiler options
+ # might improve Linux compatibility with FC5 ?
+}
+
+#
+# General defaults; a lot like UNIX
+#
+
+ AR ?= ar rusc ;
+ AS ?= as ;
+ ASFLAGS ?= ;
+ AWK ?= awk ;
+ BINDIR ?= /usr/local/bin ;
+ C++ ?= cc ;
+ C++FLAGS ?= ;
+ CC ?= cc ;
+ CCFLAGS ?= ;
+ CP ?= cp -f ;
+ CRELIB ?= ;
+ DOT ?= . ;
+ DOTDOT ?= .. ;
+ EXEMODE ?= 711 ;
+ FILEMODE ?= 644 ;
+ FORTRAN ?= f77 ;
+ FORTRANFLAGS ?= ;
+ HDRS ?= ;
+ INSTALLGRIST ?= installed ;
+ JAMFILE ?= Jamfile ;
+ JAMTOP ?= Jamtop ;
+ LEX ?= ;
+ LIBDIR ?= /usr/local/lib ;
+ LINK ?= $(CC) ;
+ LINKFLAGS ?= ;
+ SHLINKFLAGS ?= ;
+ STDLIBS ?= ;
+ SHSTDLIBS ?= $(STDLIBS) ;
+ LINKOUTFLAG ?= "-o " ;
+ LN ?= ln ;
+ MANDIR ?= /usr/local/man ;
+ MKDIR ?= mkdir ;
+ MV ?= mv -f ;
+ RCP ?= rcp ;
+ RM ?= rm -f ;
+ RMDIR ?= $(RM) ;
+ RSH ?= rsh ;
+ SED ?= sed ;
+ SHELLHEADER ?= "#!/bin/sh" ;
+ SHELLMODE ?= 755 ;
+ SLASH ?= / ;
+ STDHDRS ?= /usr/include ;
+ SUFEXE ?= "" ;
+ SUFSH ?= .sh ;
+ SUFLIB ?= .a ;
+ SUFSHLIB ?= .so ;
+ SUFIMPLIB ?= .so ;
+ SUFOBJ ?= .o ;
+
+ DEFFLAG ?= -D ;
+ UNDEFFLAG ?= -U ;
+ YACC ?= ;
+ YACCGEN ?= ;
+ YACCFILES ?= ;
+ YACCFLAGS ?= ;
+
+ HDRPATTERN =
+ "^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ;
+
+ OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
+
+
+# ===========================================================
+
+#
+# Base dependencies - first for "bootstrap" kinds of rules
+#
+
+Depends all : shell files lib exe obj ;
+Depends all shell files lib exe obj install : first ;
+NotFile all first shell files lib exe obj dirs clean install uninstall ;
+Always clean uninstall ;
+
+# ===========================================================
+# ArgyllCMS Jambase building blocks:
+
+# Allow returning of a targets "on" variable
+# Only the first variable in the list "on" variable is retrieved
+# ret = geton target : variable ;
+rule noop { return $(<) ; }
+rule geton {
+ local _rv ;
+ _rv = [ on $(<[1]) noop $($(>)) ] ;
+ return $(_rv) ;
+}
+
+# Separate a single path into it's components, irrespective of
+# whether a MSWindows or UNIX path separator is used.
+# d1 d2 ... file = _SepPath path ;
+rule _SepPath
+{
+#Echo "_SepPath called with = '" $(<[1]) "'" ;
+
+ local _in = /$(<[1]) ; # leading / is to detect absolute path
+ local split = true ;
+ local _out = ;
+
+ if ! $(<) {
+#Echo "_SepPath returning '" "" "'" ;
+ return $(<) ;
+ }
+
+ split = [ MATCH (.*)[/\\](.*) : $(_in) ] ;
+ while $(split) {
+#Echo "Split = '" $(split[1]) "' and '" $(split[2]) "'" ;
+ _out = $(split[2]) $(_out) ;
+ _in = $(split[1]) ;
+ split = [ MATCH (.*)[/\\](.*) : $(_in) ] ;
+ }
+#Echo "After slplitting got '" $(_in) "' out '" $(_out) "'" ;
+
+ if $(_in) != "" { # No leading /
+#Echo "Setting _out to '" $(_in) "' plus '" $(_out) "'" ;
+ _out = $(_in) $(_out) ;
+ }
+
+#Echo "_SepPath initial sep =" $(_out) ;
+
+ # Deal with DOS drive letters
+ if $(NT) {
+ switch $(_out[1]) {
+ case *:* : {
+ split = [ MATCH (.*)[:](.*) : $(_out[1]) ] ;
+ if $(split[2]) != "" {
+ _out = $(split[1]): $(split[2]) $(_out[2-]) ;
+ } else {
+ _out = $(split[1]): $(SLASH) $(_out[2-]) ;
+ }
+ }
+ }
+#Echo "_SepPath after DOS letters _out =" $(_out) ;
+ }
+
+ # Make sure leading / is in the correct form
+ if $(_out[1]) = "/" || $(_out[1]) = "\\" {
+ _out = $(SLASH) $(_out[2-]) ;
+ }
+
+#Echo "_SepPath returning _out =" $(_out) ;
+
+ return $(_out) ;
+}
+
+# Turn a sequence of directories into a directory path.
+# Opposite of _SepPath
+# path = _DirName d1 d2 ... ;
+rule _DirName
+{
+ local _in = $(<) ;
+ local _out = "" ;
+
+#Echo "_DirName got '" $(_in) "'" ;
+
+ # Deal with DOS drive letters
+ if $(NT) {
+ switch $(_in[1]) {
+ case *:* : {
+#Echo "_DirName match x:" ;
+ _out = $(_in[1]) ;
+ _in = $(_in[2-]) ;
+ }
+ }
+#Echo "_DirName _in = '" $(_in) "' out = '" $(_out) "'" ;
+ }
+
+ # Deal with absolute path
+ if $(_in[1]) = "/" || $(_in[1]) = "\\" {
+ _out = $(_out)$(SLASH) ;
+ _in = $(_in[2-]) ;
+#Echo "_DirName abs in = '" $(_in) "' out = '" $(_out) "'" ;
+ }
+
+ while $(_in) {
+ _out = $(_out)$(_in[1]) ;
+ _in = $(_in[2-]) ;
+#Echo "_DirName in = '" $(_in) "' out = '" $(_out) "'" ;
+ if $(_in) {
+ _out = $(_out)$(SLASH) ;
+ }
+#Echo "_DirName sep in = '" $(_in) "' out = '" $(_out) "'" ;
+ }
+
+#Echo "_DirName returning '" $(_out) "'" ;
+ return $(_out) ;
+}
+
+# Rationalize a path (ie. cancell dirs & .. )
+# Currently paths that cancel out return " ".
+# d1 d2 .. file = _RatPath d1 d2 .. file ;
+rule _RatPath
+{
+ local _in = $(<) ;
+ local _rio = ; # reversed intermediate output
+ local _out = ;
+ local _gotdot = ; # There was at a dot in the input path
+ local _first = ; # Fixed first elements
+
+#Echo "_RatPath called with '" $(_in) "'" ;
+
+ # Deal with DOS drive letters
+ if $(NT) {
+ switch $(_in[1]) {
+ case *:* : {
+ _first = $(_first) $(_in[1]) ;
+ _in = $(_in[2-]) ;
+ }
+ }
+#Echo "_RatPath got first '" $(_first) "' in = '" $(_in) "'" ;
+ }
+
+ # Deal with absolute path or single dot
+ if $(_in[1]) = / || $(_in[1]) = \\ {
+ _first = $(_first) $(SLASH) ;
+ _in = $(_in[2-]) ;
+#Echo "_RatPath got first '" $(_first) "' in = '" $(_in) "'" ;
+ } else {
+ if $(_in[1]) = $(DOT) && ! $(_in[2-]) {
+ _first = $(_first) $(DOT) ;
+ _in = $(_in[2-]) ;
+#Echo "_RatPath got first '" $(_first) "' in = '" $(_in) "'" ;
+ }
+ }
+ while $(_in) {
+#Echo "Next = " $(_in[1]) " and last = " $(_rio[1]) ;
+ if $(_in[1]) = $(DOT) {
+ _gotdot = true ;
+ }
+ # if the .. will cancel out the previous directory
+ if $(_in[1]) = $(DOTDOT) && $(_rio[1]) && $(_rio[1] != $(DOTDOT) {
+ _rio = $(_rio[2-]) ; # Remove previous
+#Echo "Found .. so removed previous and got _rio = " $(_rio) ;
+ } else { # Add next
+ # If we're decending with a directory
+ if $(_in[1]) != $(DOT) {
+ _rio = $(_in[1]) $(_rio) ;
+#Echo "Adding so _rio = " $(_rio) ;
+ } else {
+#Echo "Found . so ignoring got _rio = " $(_rio) ;
+ }
+ }
+ _in = $(_in[2-]) ;
+ }
+ # Make sure that a single dot is preserved
+ if $(_gotdot) && ! $(_rio) {
+ _rio = $(DOT) ;
+ }
+#Echo "Final _rio = " $(_rio) ;
+ # Reverse it
+ for _i in $(_rio) {
+ _out = $(_i) $(_out) ;
+ }
+
+ # Preprent with first */
+ _out = $(_first) $(_out) ;
+
+#Echo "_RatPath rationalized to '" $(_out) "'" ;
+#Echo ;
+
+ return $(_out) ;
+}
+
+# Re-root a directory path by pre-pending the given path.
+# Don't do this if the path is absolute
+# Don't return anything if the path is empty.
+# p1 p2 .. file = _RootPath d1 d2 .. : p1 p2 ... file ;
+rule _RootPath
+{
+ local _i _out = ;
+
+#Echo "_RootPath called with '" $(<) "' and '" $(>) "'" ;
+
+ if ! $(>[1]) {
+#Echo "_RootPath no RHS returning '" $(<) "'" ;
+ return $(<) ;
+ }
+
+ if $(>[1]) = "/" || $(>[1]) = "\\" {
+#Echo "_RootPath RHS = / returning '" $(<) "'" ;
+ return $(>) ;
+ }
+ if $(NT) {
+ switch $(>[1]) {
+ case *:* : {
+#Echo "_RootPath RHS = drive: returning '" $(<) "'" ;
+ return $(>) ;
+ }
+ }
+ }
+
+#Echo "_RootPath returning '" $(<) $(>) "'" ;
+ return $(<) $(>) ;
+
+}
+
+# Re-root a set of directory paths by pre-pending the given path.
+# Don't do this if the path is absolute
+# Don't return anything if the path is empty.
+# paths = RootPaths dir : paths ;
+rule RootPaths
+{
+ local _d = [ _SepPath $(<[1]) ] ;
+ local _i _t ;
+ local _out = ;
+
+#Echo "RootPaths got dir '" $(<[1]) "' and paths '" $(>) "'" ;
+ for _i in $(>)
+ {
+ _t = [ _SepPath $(_i) ] ;
+ _t = [ _RootPath $(_d) : $(_t) ] ;
+ _t = [ _RatPath $(_t) ] ;
+ _out += [ _DirName $(_t) ] ;
+ }
+
+#Echo "RootPaths returns to '" $(_out) "'" ;
+
+ return $(_out) ;
+}
+
+# - - - - - - - - - - - - - -
+
+# Rationalize a set of paths (ie. cancell dirs & .. )
+# paths = RatPaths paths ;
+rule RatPaths
+{
+ local _i _t ;
+ local _out = ;
+
+#Echo "RatPaths got '" $(<) "'" ;
+ for _i in $(<)
+ {
+ _t = [ _SepPath $(_i) ] ;
+ _t = [ _RatPath $(_t) ] ;
+ _out += [ _DirName $(_t) ] ;
+ }
+
+#Echo "RatPaths returns to '" $(_out) "'" ;
+
+ return $(_out) ;
+}
+
+# Normalize a set of paths. This resolves the
+# paths location with respect to SUBDIR, and so
+# accounting for the location of the Jamfile
+# the path is declared, and rationalizes the result.
+# If the optional dir is present, use it to
+# locate their targets rather than SUBDIR.
+# If paths is empty, nothing is returned.
+# SRCDIR and DSTDIR are ignored.
+# paths = NormPaths paths : [ dir ] ;
+rule NormPaths
+{
+ return [ _NormPaths $(<) : $(>) : "none" ] ;
+}
+
+# Normalize a set of Source paths. This resolves the
+# paths location with respect to SUBDIR, and so
+# accounting for the location of the Jamfile
+# the path is declared, and rationalizes the result.
+# If the optional dir is present, use it to
+# locate thie targets rather than SUBDIR.
+# If paths is empty, nothing is returned.
+# paths = NormPaths paths : [ dir ] ;
+rule NormSrcPaths
+{
+ return [ _NormPaths $(<) : $(>) : "src" ] ;
+}
+
+# Normalize a set of destination paths. This resolves the
+# paths location with respect to SUBDIR, and so
+# accounting for the location of the Jamfile
+# the path is declared, and rationalizes the result.
+# If the optional dir is present, use it to
+# locate thie targets rather than SUBDIR.
+# If paths is empty, nothing is returned.
+# paths = NormPaths paths : [ dir ] ;
+rule NormDstPaths
+{
+ return [ _NormPaths $(<) : $(>) : "dst" ] ;
+}
+
+# Normalize a set of paths. This resolves the
+# paths location with respect to SUBDIR, and so
+# accounting for the location of the Jamfile
+# the path is declared, and rationalizes the result.
+# If the optional dir is present, use it to
+# locate thie targets rather than SUBDIR.
+# If paths is empty, nothing is returned.
+# paths = NormPaths paths : dir : type ;
+# (This and the other rules it calls, is probably a good candidate for speed optimization!)
+rule _NormPaths
+{
+ local _p _i _t ;
+ local _out = ;
+ local _src _dst ;
+
+ if $(>) {
+ _p = [ _SepPath $(>[1]) ] ;
+ _p = [ _RatPath $(_p) ] ;
+ } else {
+ _p = $(_SUBDIR) ;
+ }
+
+ _src = [ _SepPath $(SRCDIR) ] ;
+ _dst = [ _SepPath $(DSTDIR) ] ;
+
+#Echo "_NormPaths got '" $(<) "' dir '" $(_p) "' type '" $(3) "'srcdir "' $(_src) "' dstdir '" $(_dst) "'" ;
+ for _i in $(<)
+ {
+#Echo "_i = '" $(_i) "'" ;
+ _t = [ _SepPath $(_i) ] ;
+#Echo "_SepPath _i = '" $(_i) "'" ;
+ _t = [ _RootPath $(_p) : $(_t) ] ;
+#Echo "_RootPath _t = '" $(_t) "'" ;
+
+ if $(_src) && $(3) = "src" {
+ _t = [ _RootPath $(_src) : $(_t) ] ;
+#Echo "_src += _t = '" $(_i) "'" ;
+
+ } else if $(_dst) && $(3) = "dst" {
+ local _f ;
+ _t = [ _DirName $(_t) ] ;
+ _f = [ _SepPath $(_t:BS) ] ;
+ _t = $(_t:D) ;
+ if ! $(_t) {
+ _t = $(DOT) ;
+ }
+ _t = [ _RootPath [ _SepPath $(_t) ] : $(_dst) ] $(_f) ;
+#Echo " _t += _dst = '" $(_t) "'" ;
+ }
+ _t = [ _RatPath $(_t) ] ;
+#Echo "_RatPath _t = '" $(_t) "'" ;
+ # Special case of complete cancelation that can occure for a pure
+ # directory path (?)
+ if $(_t) = "" {
+ _t = "." ;
+ }
+ _t = [ _DirName $(_t) ] ;
+ _out += $(_t) ;
+#Echo "_out += '" $(_t) "'" ;
+ }
+
+#Echo "_NormPaths returns '" $(_out) "'" ;
+ return $(_out) ;
+}
+
+# Normalize a set of targets.
+# This is the same as NormPaths except it
+# then strips the path out and uses it to set the
+# Grist, NOMLOC, LOCATE and SEARCH on the target.
+# If the optional dir is present, use it to
+# locate the targets rather than SUBDIR.
+# Ignore SRCDIR if present.
+# paths = NormTargets paths [ : dir ] ;
+rule NormISrcTargets
+{
+ return [ _NormTargets $(<) : $(>) : "isrc" ] ;
+}
+
+# Normalize a set of targets.
+# This is the same as NormPaths except it
+# then strips the path out and uses it to set the
+# Grist, NOMLOC, LOCATE and SEARCH on the target.
+# If the optional dir is present, use it to
+# locate the targets rather than SUBDIR.
+# se DSTDIR if present.
+# paths = NormTargets paths [ : dir ] ;
+rule NormIDstTargets
+{
+ return [ _NormTargets $(<) : $(>) : "idst" ] ;
+}
+
+# Normalize a set of targets.
+# This is the same as NormPaths except it
+# then strips the path out and uses it to set the
+# Grist, NOMLOC, LOCATE and SEARCH on the target.
+# If the optional dir is present, use it to
+# locate the targets rather than SUBDIR.
+# Use SRCDIR if present.
+# paths = NormTargets paths [ : dir ] ;
+rule NormSrcTargets
+{
+ return [ _NormTargets $(<) : $(>) : "src" ] ;
+}
+
+# Normalize a set of targets.
+# This is the same as NormPaths except it
+# then strips the path out and uses it to set the
+# Grist, NOMLOC, LOCATE and SEARCH on the target.
+# If the optional dir is present, use it to
+# locate the targets rather than SUBDIR.
+# Use DSTDIR if present.
+# paths = NormTargets paths [ : dir ] ;
+rule NormDstTargets
+{
+ return [ _NormTargets $(<) : $(>) : "dst" ] ;
+}
+
+# Normalize a set of targets.
+# This is the same as NormPaths except it
+# then strips the path out and uses it to set the
+# Grist, NOMLOC, LOCATE and SEARCH on the target.
+# If the optional dir is present, use it to
+# locate the targets rather than SUBDIR.
+# paths = NormTargets paths : dir : type ;
+rule _NormTargets
+{
+ local _p _i _t _d _ds ;
+ local _out = ;
+ local _src _dst ;
+
+ if $(>) {
+ _p = [ _SepPath $(>[1]) ] ;
+ } else {
+ _p = $(_SUBDIR) ;
+ }
+
+ if $(3) = "src" || $(3) = "dst" {
+ _src = [ _SepPath $(SRCDIR) ] ;
+ _dst = [ _SepPath $(DSTDIR) ] ;
+ }
+
+#Echo ;
+#Echo "_NormTargets got '" $(<) "' base = '" $(_p) "' type '" $(3) "' srcdir = '" $(_src) "' dstdirr = '" $(_dst) "'" ;
+ for _i in $(<)
+ {
+ _t = [ _SepPath $(_i) ] ;
+#Echo " _t = '" $(_t) "'" ;
+ _t = [ _RootPath $(_p) : $(_t) ] ;
+#Echo " _t = '" $(_t) "'" ;
+ _t = [ _RatPath $(_t) ] ;
+#Echo " _t = '" $(_t) "'" ;
+ _t = [ _DirName $(_t) ] ;
+#Echo " _t = '" $(_t) "'" ;
+ _d = $(_t:D) ;
+#Echo " _d = '" $(_d) "'" ;
+ _ds = [ _SepPath $(_d) ] ;
+#Echo " _ds = '" $(_ds) "'" ;
+ _t = $(_t:D=) ;
+#Echo " _t = '" $(_t) "'" ;
+ _t = $(_t:G=$(_ds:J=!)) ;
+#Echo " _t = '" $(_t) "'" ;
+
+ # dst trumps all the others
+ if $(3) = "dst" {
+ if $($(_t)-target) != "dst" {
+ NOMLOC on $(_t) = $(_d) ;
+ if $(_dst) {
+ if ! $(_ds) {
+ _ds = $(DOT) ;
+ }
+ _d = [ _DirName [ _RootPath $(_ds) : $(_dst) ] ] ;
+ }
+ if $(_d) = "/" || $(_d) = "\\" { # Jam has a bug when locating in root
+ _d = $(_d). ;
+ }
+ LOCATE on $(_t) = $(_d) ;
+ $(_t)-target = "dst" ;
+ }
+
+ # idst trumps src and isrc
+ } else if $(3) = "idst" {
+ if $($(_t)-target) != "dst" && $($(_t)-target) != "idst" {
+ NOMLOC on $(_t) = $(_d) ;
+ if $(_d) = "/" || $(_d) = "\\" { # Jam has a bug when locating in root
+ _d = $(_d). ;
+ }
+ LOCATE on $(_t) = $(_d) ;
+ $(_t)-target = "idst" ;
+ }
+
+ # src trumps isrc
+ } else if $(3) = "src" {
+ if $($(_t)-target) != "dst" && $($(_t)-target) != "idst"
+ && $($(_t)-target) != "src" {
+ local _d1 _d2 ;
+ NOMLOC on $(_t) = $(_d) ;
+ if $(_src) {
+ _d1 = [ _DirName [ _RootPath $(_src) : $(_ds) ] ] ;
+ } else {
+ _d1 = $(_d) ;
+ }
+ if $(_dst) {
+ if ! $(_ds) {
+ _ds = $(DOT) ;
+ }
+ _d2 = [ _DirName [ _RootPath $(_ds) : $(_dst) ] ] ;
+ }
+ if $(_d1) = "/" || $(_d1) = "\\" { # Jam has a bug when locating in root
+ _d1 = $(_d1). ;
+ }
+ if $(_d2) = "/" || $(_d2) = "\\" { # Jam has a bug when locating in root
+ _d2 = $(_d2). ;
+ }
+ # We assume that if we've got a DSTDIR here, then
+ # it may apply to this source, even if it is never
+ # gets labelled this way. - ie. it may be a dst of a
+ # Jamfile with the same DSTDIR that's not in scope.
+ SEARCH on $(_t) = $(_d2) $(_d1) ;
+ $(_t)-target = "src" ;
+ }
+
+ # isrc is lowest priority
+ } else if $(3) = "isrc" && ! $($(_t)-target) {
+ if $(_d) = "/" || $(_d) = "\\" { # Jam has a bug when locating in root
+ _d = $(_d). ;
+ }
+ NOMLOC on $(_t) = $(_d) ;
+ SEARCH on $(_t) = $(_d) ;
+ $(_t)-target = "isrc" ;
+ }
+
+#Echo "On '" $(_t) "' set LOCATE = '" [ geton $(_t) : LOCATE ] "' SEARCH = '" [ geton $(_t) : SEARCH ] "' NOMLOC = '" [ geton $(_t) : NOMLOC ] "'" ;
+ _out += $(_t) ;
+ }
+
+#Echo "_NormTargets returns to '" $(_out) "'" ;
+ return $(_out) ;
+}
+
+# Given a set of normalized paths, return the Target ID's for
+# them (ie. Gristed version of path)
+# IDs = _TargetIDs targpaths ;
+rule _TargetIDs
+{
+ local _i _t _d _ds ;
+ local _out = ;
+
+#Echo "_TargetIDs got '" $(<) "'" ;
+ for _i in $(<)
+ {
+ _d = $(_i:D) ;
+ _ds = [ _SepPath $(_d) ] ;
+ _t = $(_i:D=) ;
+ _t = $(_t:G=$(_ds:J=!)) ;
+ _out += $(_t) ;
+ }
+
+#Echo "_TargetIDs returning '" $(_out) "'" ;
+ return $(_out) ;
+}
+
+
+# Copy the target related "on" variables from one
+# target to another.
+#rule CopyTarget dest : source ;
+rule CopyTarget
+{
+ NOMLOC on $(<) = [ geton $(>) : NOMLOC ] ;
+ LOCATE on $(<) = [ geton $(>) : LOCATE ] ;
+ SEARCH on $(<) = [ geton $(>) : SEARCH ] ;
+}
+
+# Make sure a non-target isn't LOCATED or SEARCH'd by
+# setting LOCATE, SEARCH and NOMLOC to ""
+#rule NotTargets vars ;
+rule NotTargets
+{
+ NOMLOC on $(<) = "" ;
+ LOCATE on $(<) = "" ;
+ SEARCH on $(<) = "" ;
+}
+
+# Create a destination target by locating
+# the given files in the given directory.
+# The dir is assumed to be normalized.
+# SRCDIR and DSTDIR are ignored.
+# targs = SetTargetsLoc targs : dir ;
+rule CreateIDstTargets
+{
+ local _o ;
+#Echo "CreateIDstTargets got '" $(<) "' and '" $(>) "'" ;
+ _o = [ NormIDstTargets $(<:BS) : $(>[1]) ] ;
+#Echo "CreateIDstTargets returning '" $(_o) "'" ;
+ return $(_o) ;
+}
+
+# Given a normalized target, return the
+# orgiginal path to it.
+# (We use NOMLOC to do this.)
+# path = DeNormTargs target ;
+rule DeNormTargs
+{
+ local _i _t _p _out = ;
+
+ for _i in $(<) {
+ _p = [ geton $(_i) : NOMLOC ] ;
+ _t = $(_i:G=) ;
+ _out += $(_t:D=$(_p)) ;
+ }
+
+ return $(_out) ;
+}
+
+# Given a list of directories and a list of files,
+# simply concatenate them in combination separated by a /
+# paths1/paths = CatPaths path1 : paths ;
+rule CatPaths
+{
+ return $(<)$(SLASH)$(>) ;
+}
+
+# Try and locate a given file pattern starting from the current
+# directory and working towards the root.
+# We use a heuristic to figure out when to stop, since
+# Jam doesn't have pwd :-(
+# found = FindRoot starting_dir : file ;
+rule FindToRoot
+{
+ local dir = $(<[1]) ;
+ local dir_list, prev_list = ;
+ local dir_list;
+ local found = ;
+
+#Echo "FindToRoot got starting_dir '" $(<) "' file '" $(>) "'" ;
+ found = [ GLOB $(dir) : $(>[1]) ] ;
+
+ if $(found) {
+ return $(found) ;
+ }
+
+#Echo "dir_list = " $(dir_list) ;
+
+ dir_list = [ GLOB $(dir) : * ] ;
+ while $(dir_list:D="") != $(prev_list:D="") {
+ dir = $(dir)$(SLASH)$(DOTDOT) ;
+#Echo "dir = " $(dir) ;
+ found = [ GLOB $(dir) : $(>[1]) ] ;
+
+ if $(found) {
+ return $(found) ;
+ }
+
+ prev_list = $(dir_list) ;
+ dir_list = [ GLOB $(dir) : * ] ;
+#Echo "dir_list = " $(dir_list) ;
+ }
+#Echo "returning " $(found) ;
+ return $(found) ;
+}
+
+# -----------------------------------------
+
+rule DoInit
+{
+ if ! $(DONEANCHORINIT) {
+
+ SUBDIR ?= $(DOT) ;
+ _SUBDIR ?= $(DOT) ;
+
+ # initial "parent" settings
+ P_ASFLAGS = ;
+ P_CCFLAGS = ;
+ P_C++FLAGS = ;
+ P_LINKFLAGS = ;
+ P_SHLINKFLAGS = ;
+ P_HDRS = ;
+ P_DEFINES = ;
+
+ P_PREF_ASFLAGS = ;
+ P_PREF_CCFLAGS = ;
+ P_PREF_C++FLAGS = ;
+ P_PREF_LINKFLAGS = ;
+ P_PREF_SHLINKFLAGS = ;
+
+ FindTop ; # Look for a default project file
+
+ TRACESTDHDRS = false ; # don't trace system path #include file dependenicies
+ DONEANCHORINIT = true ;
+ }
+}
+
+# Set the project top for this Jamfile and all sub Jamfiles
+# until another top is set or we return.
+# ProjTop d1 d2 .. ;
+rule ProjTop
+{
+#Echo "ProjTop got '" $(<) "'" ;
+
+ _TOP = [ _RatPath $(<) ] ;
+ TOP = [ _DirName $(_TOP) ] ;
+
+#Echo "ProjTop set TOP to '" $(TOP) "'" ;
+
+ if ! $($(TOP)-SET) { # Not tried to read the project file
+
+ local found = [ GLOB $(_top) : $(JAMFILE) ] ;
+
+ if $(found) {
+ local save__SUBDIR = $(_SUBDIR) ;
+ local save__INVSUBDIR = $(_INVSUBDIR) ;
+ local save_SUBDIR = $(SUBDIR) ;
+
+ _SUBDIR = $(_TOP) ;
+ _INVSUBDIR = [ _InvertPath $(_SUBDIR) ] ;
+ SUBDIR = [ _DirName $(_SUBDIR) ] ;
+#Echo "_SUBDIR = '" $(_SUBDIR) "'" ;
+#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ;
+
+ # Translate SRCDIR for new SUBDIR
+ if $(SRCDIR) {
+#Echo "SRCDIR olddir '" $(SRCDIR) "'" ;
+ SRCDIR = [ _SepPath $(SRCDIR) ] ;
+ SRCDIR = [ _RootPath $(_INVSUBDIR) : [ _RootPath $(SRCDIR) : $(_SUBDIR) ] ] ;
+ SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ;
+#Echo "SRCDIR newdir '" $(SRCDIR) "'" ;
+ }
+
+#Echo "About to include Jamtop '" $(found) "'" ;
+ include $(found) ;
+
+ # Un Translate SRCDIR, in case it was set in the rules directory
+ if $(SRCDIR) {
+#Echo "_SUBDIR = '" $(_SUBDIR) "'" ;
+#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ;
+#Echo "SRCDIR newdir '" $(SRCDIR) "'" ;
+ SRCDIR = [ _SepPath $(SRCDIR) ] ;
+ SRCDIR = [ _RootPath $(_SUBDIR) : [ _RootPath $(SRCDIR) : $(_INVSUBDIR) ] ] ;
+ SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ;
+#Echo "SRCDIR olddir '" $(SRCDIR) "'" ;
+ }
+
+ # Restore things
+ _SUBDIR = $(save__SUBDIR) ;
+ _INVSUBDIR = $(save__INVSUBDIR) ;
+ SUBDIR = $(save_SUBDIR) ;
+ } else {
+ Echo "WARNING :- no project " $(TOP) "Jamtop found" ;
+ }
+
+ $(TOP)-SET = true ;
+ }
+}
+
+# Search for the project top by looking for the Jamtop
+# starting at $(SUBDIR) and lookup upwards.
+# FindTop ;
+rule FindTop
+{
+#Echo ;
+#Echo "FindTop called SUBDIR = '" $(SUBDIR) "'" ;
+
+ local _JRF = [ FindToRoot $(SUBDIR) : $(JAMTOP) ] ;
+
+#Echo "FindTop found '" $(_JRF) "'" ;
+ if $(_JRF) {
+
+ _TOP = [ _RatPath [ _SepPath $(_JRF:D) ] ] ;
+ TOP = [ _DirName $(_TOP) ] ;
+#Echo "ProjTop set TOP to '" $(TOP) "'" ;
+
+ if ! $($(TOP)-SET) { # Not tried to read the project file
+ local save__SUBDIR = $(_SUBDIR) ;
+ local save__INVSUBDIR = $(_INVSUBDIR) ;
+ local save_SUBDIR = $(SUBDIR) ;
+
+ _SUBDIR = $(_TOP) ;
+ _INVSUBDIR = [ _InvertPath $(_SUBDIR) ] ;
+ SUBDIR = [ _DirName $(_SUBDIR) ] ;
+#Echo "_SUBDIR = '" $(_SUBDIR) "'" ;
+#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ;
+
+ # Translate SRCDIR for new SUBDIR
+ if $(SRCDIR) {
+#Echo "SRCDIR olddir '" $(SRCDIR) "'" ;
+ SRCDIR = [ _SepPath $(SRCDIR) ] ;
+ SRCDIR = [ _RootPath $(_INVSUBDIR) : [ _RootPath $(SRCDIR) : $(_SUBDIR) ] ] ;
+ SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ;
+#Echo "SRCDIR newdir '" $(SRCDIR) "'" ;
+ }
+
+#Echo "About to include Jamtop '" $(_JRF) "'" ;
+ include $(_JRF) ;
+ $(TOP)-SET = true ;
+
+ # Un Translate SRCDIR, in case it was set in the ruls directory
+ if $(SRCDIR) {
+#Echo "_SUBDIR = '" $(_SUBDIR) "'" ;
+#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ;
+#Echo "SRCDIR newdir '" $(SRCDIR) "'" ;
+ SRCDIR = [ _SepPath $(SRCDIR) ] ;
+ SRCDIR = [ _RootPath $(_SUBDIR) : [ _RootPath $(SRCDIR) : $(_INVSUBDIR) ] ] ;
+ SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ;
+#Echo "SRCDIR olddir '" $(SRCDIR) "'" ;
+ }
+
+ # Restore things
+ _SUBDIR = $(save__SUBDIR) ;
+ _INVSUBDIR = $(save__INVSUBDIR) ;
+ SUBDIR = $(save_SUBDIR) ;
+ }
+ } else {
+ Echo "WARNING :- no project Jamtop found, no TOP set !" ;
+
+ if ! $(TOP) {
+ TOP = $(DOT) ; # set a default TOP
+ _TOP = $(DOT) ;
+ }
+ }
+}
+
+# Given a path relative to CWD, return the inverse direction
+# path. Return nothing if the path is absolute.
+# [ we're using a hack here, since Jam 2.5 doesn't have
+# any functions that will simply resolve a path relative
+# to CWD into an absolute path. ]
+# d1 d2 .. = _InvertPath d1 d2 ..
+rule _InvertPath
+{
+ local _i _o _d ;
+#Echo "_InvertPath got '" $(<) "'" ;
+ if $(<[1]) = "/" || $(<[1]) = "\\" {
+#Echo "_InvertPath returning nothing" ;
+ return "" ;
+ }
+ if $(NT) {
+ switch $(<[1]) {
+ case *:* : {
+#Echo "_InvertPath returning nothing" ;
+ return "" ;
+ }
+ }
+ }
+
+ for _i in $(<) {
+#Echo "_InvertPath _i = '" $(_i) "' _o = '" $(_o) "'" ;
+ # Ignore .
+ if $(_i) = $(DOT) {
+ continue ;
+ }
+ # The hard one. Look amongst all the
+ # sub directories for one that has the same
+ # contents as the directory we came from.
+ # Too bad if two directories have the same contents...
+ if $(_i) = $(DOTDOT) {
+ local _j;
+ local _d1 _d2 _l1, _l2 _l3 ;
+
+#Echo "_InvertPath inverting '" $(_i) "'" ;
+
+ _d1 = [ _DirName $(_d) ] ;
+ _l1 = [ GLOB $(_d1) : * ] ;
+#Echo "_d1 = '" $(_d1) "'" ;
+ _d += $(_i) ;
+ _d2 = [ _DirName $(_d) ] ;
+#Echo "_d2 = '" $(_d2) "'" ;
+ _l2 = [ GLOB $(_d2) : * ] ;
+
+ for _j in $(_l2) {
+ if $(_j) = $(DOT) || $(_j) = $(DOTDOT) {
+ continue ;
+ }
+#Echo "Checking _j = '" $(_j) "'" ;
+ _l3 = [ GLOB $(_j) : * ] ;
+#Echo "_l1 = '" $(_l1) "'" ;
+#Echo "_l3 = '" $(_l3:BS) "'" ;
+ if $(_l3:BS) = $(_l1) {
+#Echo "Found reverse = '" $(_j) "'" ;
+ _o = $(_j:BS) $(_o) ;
+ break ;
+ }
+ }
+
+ # The easy one. the opposite of a directory
+ # is ..
+ } else {
+ _o = $(DOTDOT) $(_o) ;
+ _d += $(_i) ;
+ }
+ }
+ if ! $(_o) {
+ _o = $(DOT) ;
+ }
+
+#Echo "_InvertPath returning '" $(_o) "'" ;
+ return $(_o) ;
+}
+
+# Variables containing (possible) relative paths that are to remain
+# anchored to where they were declared. This is to prevent
+# NormPath in a sub-Jamfile assuming they are relative to that Jamfile.
+# (This is a bit messy. How could it be avoided ? If there were
+# a simple way of making paths absolute, rather than computing eveything
+# relative to the invokation directory, it could help.)
+ANCHORED_PATH_VARS = ;
+
+# Variables to save before starting a new Jamfile, then
+# restore once it's finished.
+
+SUBDIR_VARS = SUBDIR _SUBDIR TOP _TOP SRCDIR DSTDIR
+ P_ASFLAGS P_CCFLAGS P_C++FLAGS P_LINKFLAGS P_SHLINKFLAGS
+ ASFLAGS CCFLAGS C++FLAGS LINKFLAGS SHLINKFLAGS
+ P_PREF_ASFLAGS P_PREF_CCFLAGS P_PREF_C++FLAGS P_PREF_LINKFLAGS
+ PREF_ASFLAGS PREF_CCFLAGS PREF_C++FLAGS PREF_LINKFLAGS PREF_SHLINKFLAGS
+ P_HDRS HDRS
+ P_DEFINES DEFINES
+ P_LINKOBJS LINKOBJS
+ P_LINKLIBS LINKLIBS
+ P_LINKSHLIBS LINKSHLIBS
+ P_SHLINKOBJS SHLINKOBJS
+ P_SHLINKLIBS SHLINKLIBS
+ P_SHLINKSHLIBS SHLINKSHLIBS
+ ;
+
+# Implement including a Jamfile from a sub or peer directory,
+# Sub includes cause flags/headers/options to be inhereted
+# from the calling Jamfile, while Peer includes do not.
+# The global _JAMINCLUDE_PEER variable controls whether
+# this is a sub or peer include.
+# _JamInclude dir ;
+rule _JamInclude
+{
+#Echo "_JamInclude called with '" $(<) "' SUBDIR '" $(SUBDIR) "' and _JAMINCLUDE_PEER '" $(_JAMINCLUDE_PEER) "'" ;
+
+ # Save certain variables so that sub-Jamfiles don't affect them
+ local _jamfile ;
+ local _SUBDIR_VARS = $(SUBDIR_VARS) $(ANCHORED_PATH_VARS) ;
+ local _i parent_$(_SUBDIR_VARS) ;
+
+ for _i in $(_SUBDIR_VARS) {
+ parent_$(_i) = $($(_i)) ;
+ }
+
+ if $(_JAMINCLUDE_PEER) != "true" {
+ # Incorporate this levels extra flags & header paths into the base
+ P_ASFLAGS += $(ASFLAGS) ;
+ P_CCFLAGS += $(CCFLAGS) ;
+ P_C++FLAGS += $(C++FLAGS) ;
+ P_LINKFLAGS += $(LINKFLAGS) ;
+ P_SHLINKFLAGS += $(SHLINKFLAGS) ;
+ P_HDRS = [ NormPaths $(HDRS) ] $(P_HDRS) ;
+ P_DEFINES += $(DEFINES) ;
+ P_LINKOBJS = [ NormPaths $(LINKOBJS) ] $(P_LINKOBJS) ;
+ P_LINKLIBS = [ NormPaths $(LINKLIBS) ] $(P_LINKLIBS) ;
+ P_LINKSHLIBS = [ NormPaths $(LINKSHLIBS) ] $(P_LINKSHLIBS) ;
+ P_SHLINKOBJS = [ NormPaths $(SHLINKOBJS) ] $(P_SHLINKOBJS) ;
+ P_SHLINKLIBS = [ NormPaths $(SHLINKLIBS) ] $(P_SHLINKLIBS) ;
+ P_SHLINKSHLIBS = [ NormPaths $(SHLINKSHLIBS) ] $(P_SHLINKSHLIBS) ;
+
+ # Set parent flags no existing parent flags
+ if ! $(P_PREF_ASFLAGS) {
+ P_PREF_ASFLAGS = $(PREF_ASFLAGS) ; }
+ if ! $(P_PREF_CCFLAGS) {
+ P_PREF_CCFLAGS = $(PREF_CCFLAGS) ; }
+ if ! $(P_PREF_C++FLAGS) {
+ P_PREF_C++FLAGS = $(PREF_C++FLAGS) ; }
+ if ! $(P_PREF_LINKFLAGS) {
+ P_PREF_LINKFLAGS = $(PREF_LINKFLAGS) ; }
+ if ! $(P_PREF_SHLINKFLAGS) {
+ P_PREF_SHLINKFLAGS = $(PREF_SHLINKFLAGS) ; }
+ }
+
+ # Set default for new Jamfile extra and preferred flags
+ ASFLAGS = ;
+ CCFLAGS = ;
+ C++FLAGS = ;
+ LINKFLAGS = ;
+ SHLINKFLAGS = ;
+ HDRS = ;
+ DEFINES = ;
+ LINKOBJS = ;
+ LINKLIBS = ;
+ LINKSHLIBS = ;
+ SHLINKOBJS = ;
+ SHLINKLIBS = ;
+ SHLINKSHLIBS = ;
+
+ PREF_ASFLAGS = ;
+ PREF_CCFLAGS = ;
+ PREF_C++FLAGS = ;
+ PREF_LINKFLAGS = ;
+ PREF_SHLINKFLAGS = ;
+
+ _SUBDIR = [ _RatPath [ _RootPath $(_SUBDIR) : [ _SepPath $(<) ] ] ] ;
+ _INVSUBDIR = [ _InvertPath $(_SUBDIR) ] ;
+ SUBDIR = [ _DirName $(_SUBDIR) ] ;
+
+#Echo "new _SUBDIR =" $(_SUBDIR) ;
+#Echo "new _INVSUBDIR =" $(_INVSUBDIR) ;
+
+ if $(_INVSUBDIR) != "." {
+ # Keep paths relative to where they were defined, so that
+ # NormPaths doesn't think they are relative to the sub-Jamfile.
+#Echo "Before ANCHORED_PATH_VARS = $(ANCHORED_PATH_VARS) vals $($(ANCHORED_PATH_VARS))" ;
+ for _i in $(ANCHORED_PATH_VARS) {
+ $(_i) = [ RootPaths $(_INVSUBDIR) : $($(_i)) ] ;
+ }
+#Echo "After ANCHORED_PATH_VARS = $(ANCHORED_PATH_VARS) vals $($(ANCHORED_PATH_VARS))" ;
+ }
+
+ # Translate SRCDIR for new SUBDIR
+#Echo "SRCDIR olddir '" $(SRCDIR) "'" ;
+ if $(SRCDIR) {
+ local subdir = $(_SUBDIR[2-]) ;
+ local invsubdir = [ FReverse $(_INVSUBDIR) ] ;
+ invsubdir = [ FReverse $(invsubdir[2-]) ] ;
+#Echo "subdir-1 =" $(subdir) ;
+#Echo "invsubdir-1 =" $(invsubdir) ;
+ SRCDIR = [ _SepPath $(SRCDIR) ] ;
+ SRCDIR = [ _RootPath $(invsubdir) : [ _RootPath $(SRCDIR) : $(subdir) ] ] ;
+ SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ;
+#Echo "SRCDIR newdir '" $(SRCDIR) "'" ;
+ }
+
+ _jamfile = [ NormSrcPaths $(JAMFILE) ] ;
+
+#Echo "About to include " $(_jamfile) ;
+ include $(_jamfile) ;
+
+ # Restore variable before returning
+ for _i in $(_SUBDIR_VARS) {
+ $(_i) = $(parent_$(_i)) ;
+ }
+
+#Echo "Done include " $(JAMFILE:D=$(_subdir)) ;
+#Echo "restored SUBDIR =" $(SUBDIR) ;
+#Echo "_JamInclude done" ;
+}
+
+# Invoke a Jamfile as a sub Jamfile
+# SubInclude dir ;
+rule SubInclude
+{
+#Echo "### SubInclude called with '" $(<[1]) "' and SUBDIR = '" $(SUBDIR) "'" ;
+ _JAMINCLUDE_PEER = "false" ; # This is a sub include
+ return [ _JamInclude $(<) ] ;
+}
+
+# Invoke a Jamfile in as a peer Jamfile
+# PeerInclude dir ;
+rule PeerInclude
+{
+#Echo "### PeerInclude called with '" $(<[1]) "' and SUBDIR = '" $(SUBDIR) "'" ;
+ _JAMINCLUDE_PEER = "true" ; # This is a peer include
+ return [ _JamInclude $(<) ] ;
+}
+
+# ===========================================================
+#
+# Rules
+#
+
+# Public As
+# As obj : source.s ; .s -> .o
+rule As
+{
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ;
+ local _s = [ NormSrcTargets $(>) ] ;
+
+ Depends $(_t) : $(_s) ;
+ Depends obj : $(_t) ;
+ MakeLocate $(_t) ;
+
+ HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ;
+}
+
+# Internal As
+rule As_
+{
+ local pref_asflags = $(P_PREF_ASFLAGS) ;
+ pref_asflags ?= $(PREF_ASFLAGS) ;
+ ASFLAGS1 on $(<) = $(P_ASFLAGS) $(ASFLAGS) ;
+ ASFLAGS2 on $(<) = $(pref_asflags) ;
+ ASFLAGS on $(<) = [ geton $(<) : ASFLAGS1 ] [ geton $(<) : ASFLAGS2 ] ;
+ ASHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
+}
+
+# copies sources into directory.
+# SRCDIR and DSTDIR will be ignored.
+# Bulk directory : sources ;
+rule Bulk
+{
+#Echo "Bulk got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+ local _is _it ; # individual source and target
+
+ for _is in $(_s)
+ {
+ _it = $(_t[1]) ;
+ _t = $(_t[2-]) ; # Track _is
+
+ Depends files : $(_it) ;
+ Depends $(_it) : $(_is) ;
+ MakeLocate $(_it) ;
+ File_ $(_it) : $(_is) ;
+ MODE on $(_it) = $(FILEMODE) ;
+ Chmod_ $(_it) ;
+ }
+}
+
+# Cc object : source : flags : defines : hdrpaths ;
+rule Cc
+{
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Depends $(_t) : $(_s) ;
+ Depends obj : $(_t) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+
+ HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ;
+ SOURCE on $(_t) = $(_s) ;
+
+ HDRRULE on $(_s) = HdrRule ;
+ HDRSCAN on $(_s) = $(HDRPATTERN) ;
+ # Construct HDRSEARCH so that we can know where to look for headers
+ local _dot = [ geton $(_>) : NOMLOC ] ;
+ if ! $(_dot) { _dot = $(DOT) ; }
+ HDRSEARCH1 on $(_s) = $(_dot) ;
+ HDRSEARCH2 on $(_s) = [ NormPaths $(HDRS) ] $(P_HDRS) ;
+ HDRSEARCH3 on $(_s) = [ NormPaths $(STDHDRS) ] ;
+ HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ]
+ [ geton $(_s) : HDRSEARCH3 ] ;
+#Echo "Cc set HDRSEARCH on '" $(_s) "' to '" [ geton $(_s) : HDRSEARCH ] "'" ;
+
+ # propagate target specific-defines
+
+ DEFINES on $(_t) = $(P_DEFINES) $(DEFINES) ;
+
+ Cc_ $(_t) : $(_s) : $(3) ;
+
+ if $(3) {
+ ObjectCcFlags $(<) : $(3) ;
+ }
+ if $(4) {
+ ObjectDefines $(<) : $(4) ;
+ }
+ if $(5) {
+ ObjectHdrs $(<) : $(5) ;
+ }
+}
+
+# Internal Cc
+# Cc_ object : sources ;
+rule Cc_
+{
+ # If the compiler's -o flag doesn't work, relocate the .o
+ if $(RELOCATE)
+ {
+ CcMv $(<) : $(>) ;
+ }
+
+ local pref_ccflags = $(P_PREF_CCFLAGS) ;
+ pref_ccflags ?= $(PREF_CCFLAGS) ;
+ # Make sure we incorporate any CCFLAGS[12] on object into total
+ CCFLAGS1 on $(<) += $(P_CCFLAGS) $(CCFLAGS) ;
+ CCFLAGS2 on $(<) += $(pref_ccflags) ;
+ CCFLAGS on $(<) = [ geton $(<) : CCFLAGS1 ] [ geton $(<) : CCFLAGS2 ] ;
+
+#Echo "Cc object '" $(<) "' got CCFLAGS1 '" [ geton $(<) : CCFLAGS1 ] "' and CCFLAGS2 '" [ geton $(<) : CCFLAGS2 ] "' for total CCFLAGS '" [ geton $(<) : CCFLAGS ] "'" ;
+
+ # Make sure the CCHDRS and CCDEFS are formatter correctly
+ CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
+ CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
+}
+
+# C++ object : source : flags : defines : hdrpaths ;
+rule C++
+{
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Depends $(_t) : $(_s) ;
+ Depends obj : $(_t) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+
+ HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ;
+ SOURCE on $(_t) = $(_s) ;
+
+ HDRRULE on $(_s) = HdrRule ;
+ HDRSCAN on $(_s) = $(HDRPATTERN) ;
+ # Construct HDRSEARCH so that we can know where to look for headers
+ local _dot = [ geton $(_>) : NOMLOC ] ;
+ if ! $(_dot) { _dot = $(DOT) ; }
+ HDRSEARCH1 on $(_s) = $(_dot) ;
+ HDRSEARCH2 on $(_s) = [ NormPaths $(HDRS) ] $(P_HDRS) ;
+ HDRSEARCH3 on $(_s) = [ NormPaths $(STDHDRS) ] ;
+ HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ]
+ [ geton $(_s) : HDRSEARCH3 ] ;
+
+ # propagate target specific-defines
+
+ DEFINES on $(_t) = $(P_DEFINES) $(DEFINES) ;
+
+ C++_ $(_t) : $(_s) ;
+
+ if $(3) {
+ ObjectC++Flags $(<) : $(3) ;
+ }
+ if $(4) {
+ ObjectDefines $(<) : $(4) ;
+ }
+ if $(5) {
+ ObjectHdrs $(<) : $(5) ;
+ }
+}
+
+# Internal C++
+# C++_ object : sources ;
+rule C++_
+{
+ # If the compiler's -o flag doesn't work, relocate the .o
+ if $(RELOCATE)
+ {
+ CcMv $(<) : $(>) ;
+ }
+
+ local pref_c++flags = $(P_PREF_C++FLAGS) ;
+ pref_c++flags ?= $(PREF_C++FLAGS) ;
+ # Make sure we incorporate any C++FLAGS[12] on object into total
+ C++FLAGS1 on $(<) += $(P_C++FLAGS) $(C++FLAGS) ;
+ C++FLAGS2 on $(<) += $(pref_c++flags) ;
+ C++FLAGS on $(<) = [ geton $(<) : C++FLAGS1 ] [ geton $(<) : C++FLAGS2 ] ;
+
+ # Make sure the CCHDRS and CCDEFS are formatter correctly
+ CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
+ CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
+}
+
+rule Chmod_
+{
+#Echo "Chmod_ on '" $(<) "' with MODE = '" [ geton $(<) : MODE ] "'" ;
+ if $(CHMOD) { Chmod1 $(<) ; }
+}
+
+# Public use Depends that does normalisation of its targets
+# (non-normalizing Depends is a built in)
+# NDepends dest : source ; make dependency
+rule NDepends {
+ local _t _s ;
+ local _p = ;
+
+#Echo "NDepends got '" $(<) "' and '" $(>) "'" ;
+
+ # Don't anchor psuedo targets
+ switch $(<)
+ {
+ case all : _p = true ;
+ case first : _p = true ;
+ case shell : _p = true ;
+ case files : _p = true ;
+ case lib : _p = true ;
+ case exe : _p = true ;
+ case obj : _p = true ;
+ case dirs : _p = true ;
+ case clean : _p = true ;
+ case install : _p = true ;
+ case uninstall : _p = true ;
+ }
+
+ # Normalize target names and set Grist LOCATE and SOURCE
+ if ! $(_p) {
+ _t = [ NormDstTargets $(<) ] ;
+ } else {
+ _t = $(<) ;
+ }
+ _s = [ NormSrcTargets $(>) ] ;
+
+#Echo "Passing Depends '" $(_t) "' and '" $(_s) "'" ;
+
+ Depends $(_t) : $(_s) ;
+}
+
+# Public use NoUpdate that does normalisation of its targets
+# (non-normalizing NoUpdate is a built in)
+# NNoUpdate dest ; Make sure created, but don't update
+rule NNoUpdate {
+ local _t ;
+ local _p = ;
+
+#Echo "NNoUpdate got '" $(<) "'" ;
+
+ # Don't anchor psuedo targets
+ switch $(<)
+ {
+ case all : _p = true ;
+ case first : _p = true ;
+ case shell : _p = true ;
+ case files : _p = true ;
+ case lib : _p = true ;
+ case exe : _p = true ;
+ case obj : _p = true ;
+ case dirs : _p = true ;
+ case clean : _p = true ;
+ case install : _p = true ;
+ case uninstall : _p = true ;
+ }
+
+ # Normalize target names and set Grist LOCATE and SOURCE
+ if ! $(_p) {
+ _t = [ NormDstTargets $(<) ] ;
+ } else {
+ _t = $(<) ;
+ }
+ _s = [ NormSrcTargets $(>) ] ;
+
+#Echo "Passing NoUpdate '" $(_t) "'" ;
+
+ NoUpdate $(_t) ;
+}
+
+# Public use Includes that does normalisation of its targets
+# (non-normalizing Includes is a built in)
+# NDepends dest : source ; make dependency
+rule NIncludes {
+ local _t _s ;
+ local _p = ;
+
+#Echo "NIncludes got '" $(<) "' and '" $(>) "'" ;
+
+ # Normalize target names and set Grist LOCATE and SOURCE
+ _t = [ NormDstTargets $(<) ] ;
+ _s = [ NormSrcTargets $(>) ] ;
+
+#Echo "Passing Includes '" $(_t) "' and '" $(_s) "'" ;
+
+ Includes $(_t) : $(_s) ;
+}
+
+# sets mode of file
+# Mod target : mode ;
+rule Mod
+{
+ local _t = [ NormIDstTargets $(<[1]) ] ;
+ MODE on $(_t) = $(>) ;
+ Chmod_ $(_t) ;
+}
+
+# copies source onto target.
+# SRCDIR and DSTDIR will be ignored.
+# File target : source ;
+rule File
+{
+ local _t = [ NormIDstTargets $(<[1]) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Depends files : $(_t) ;
+ Depends $(_t) : $(_s) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+ File_ $(_t) : $(_s) ;
+ MODE on $(_t) = $(FILEMODE) ;
+ Chmod_ $(_t) ;
+}
+
+# copies source onto target, but doesn't clean source.
+# SRCDIR and DSTDIR will be ignored.
+# File target : source ;
+rule FileNoClean
+{
+ local _t = [ NormIDstTargets $(<[1]) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Depends files : $(_t) ;
+ Depends $(_t) : $(_s) ;
+ MakeLocate $(_t) ;
+ File_ $(_t) : $(_s) ;
+ MODE on $(_t) = $(FILEMODE) ;
+ Chmod_ $(_t) ;
+}
+
+# Fake file copy. Creates a dependence to work around
+# problem that Jam doesn't understand two products from one action.
+# FakeFile target : source ;
+rule FakeFile
+{
+ local _t = [ NormIDstTargets $(<[1]) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ FakeFile_ $(_t) : $(_s) ;
+}
+
+rule FakeFile_
+{
+ local _t = $(<) ;
+ local _s = $(>) ;
+
+ Depends files : $(_t) ;
+ Depends $(_t) : $(_s) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+}
+
+
+# Compile Fortran source file into object
+# Fortran object : source ;
+rule Fortran
+{
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Depends $(_t) : $(_s) ;
+ Depends obj : $(_t) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+
+ Fortran_ $(_t) : $(_s) ;
+}
+
+# Internal Fortran
+rule Fortran_
+{
+}
+
+
+# NOTE! Perhaps GenFileND and GenFileNND could be replaced by a GenFile
+# with a $(3) for the dependecies ?
+
+# All > are assumed to be files that < is dependent on
+# with >[1] being an executable
+# SRCDIR and DSTDIR are ignored.
+rule GenFile
+{
+#Echo "GenFile got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormIDstTargets $(<) ] ;
+ local _s = [ NormISrcTargets $(>[1]:S=$(SUFEXE)) ] ;
+ local _a = [ NormISrcTargets $(>[2-]) ] ;
+
+#Echo "GenFile normed '" $(_t) "' and '" $(_s) "' plus '" $(_a) "'" ;
+
+ Depends $(_t) : $(_s) $(_a) ;
+ if ! $(_s[1]:G) { # In case PATH doesn't have . in it.
+ _s = $(DOT)$(SLASH)$(_s[1]:G=) $(_s[2-]) ;
+ NotTargets $(_s) ;
+ NoCare $(_s) ;
+ NotFile $(_s) ;
+ }
+ GenFile1 $(_t) : $(_s) $(_a) ;
+ Clean clean : $(_t) ;
+}
+
+rule GenFile1
+{
+ MakeLocate $(<) ;
+}
+
+# Only >[1] is assumed to be an executable that < is dependent on.
+# $(3) are optional extra dependecies
+# SRCDIR and DSTDIR are ignored.
+rule GenFileND
+{
+#Echo "GenFileND got '$(<)' and '$(>)' and src targets '$(_d)'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormIDstTargets $(<[1]) ] ;
+ local _s = [ NormISrcTargets $(>[1]:S=$(SUFEXE)) ] ;
+ local _a = $(>[2-]) ;
+ _a = $(_a:J=" ") ;
+ local _d = [ NormSrcTargets $(3) ] ;
+
+#Echo "GenFileND normed '$(_t)' and '$(_s)' plus '$(_a)' and src targets '$(_d)'" ;
+
+ NotTargets $(_a) ;
+ NoCare $(_a) ;
+ NotFile $(_a) ; # Supresses "independent target", but may mark a directory wrongly
+ Depends $(_t) : $(_s) $(_d) ;
+#Echo "GenFileND set Depends '$(_t)' and '$(_s)' and '$(_d)'" ;
+
+ if ! $(_s[1]:G) { # In case PATH doesn't have . in it.
+ _s = $(DOT)$(SLASH)$(_s[1]) $(_s[2-]) ;
+ NotTargets $(_s) ;
+ NoCare $(_s) ;
+ NotFile $(_s) ;
+ }
+ GenFileND1 $(_t) : $(_s) $(_a) ;
+
+ Clean clean : $(_t) ;
+}
+
+rule GenFileND1
+{
+ MakeLocate $(<) ;
+}
+
+# GenFileNND target : program args : extra_dependecies ;
+# None of > is assumed to be a file.
+# $(3) are optional extra dependecies
+# SRCDIR and DSTDIR are ignored.
+rule GenFileNND
+{
+#Echo "GenFileNND got '$(<)' and '$(>)' and src targets '$(3)' " ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormIDstTargets $(<) ] ;
+ local _a = $(>) ;
+ _a = $(_a:J=" ") ; # Split up by space delimeter ?
+ local _d = [ NormSrcTargets $(3) ] ;
+
+#Echo "GenFileNND normed '$(_t)' plus '$(_a)' and src targets '$(_d)'" ;
+
+ Depends files : $(_t) ;
+ Depends $(_t) : $(_d) ;
+
+ NotTargets $(_a) ;
+ NoCare $(_a) ;
+ NotFile $(_a) ; # Supresses "independent target", but may mark a directory wrongly
+
+ GenFileNND1 $(_t) : $(_a) ;
+ Clean clean : $(_t) ;
+}
+
+rule GenFileNND1
+{
+#Echo "GenFileNND1 got "' $(<) "' and "' $(>) "'" ;
+ MakeLocate $(<) ;
+}
+
+# Concatenate all the argument to the file
+# Each argument to a separate line
+# If no arguments, create empty file
+# SRCDIR and DSTDIR are ignored.
+rule CatToFile
+{
+#Echo "CatToFile got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormIDstTargets $(<) ] ;
+
+ MakeLocate $(_t) ;
+ Depends files : $(_t) ;
+ NotFile $(2) $(3) $(4) $(5) $(6) $(7) $(8) $(9) ;
+
+ Clean clean : $(_t) ;
+
+ if ! $(>) {
+ CreateCatFile_ $(_t) ;
+
+ } else {
+ if $(2) {
+ CatToFile_ $(_t) : $(2) ;
+ }
+ if $(3) {
+ CatToFile_ $(_t) : $(3) ;
+ }
+ if $(4) {
+ CatToFile_ $(_t) : $(4) ;
+ }
+ if $(5) {
+ CatToFile_ $(_t) : $(5) ;
+ }
+ if $(6) {
+ CatToFile_ $(_t) : $(6) ;
+ }
+ if $(7) {
+ CatToFile_ $(_t) : $(7) ;
+ }
+ if $(8) {
+ CatToFile_ $(_t) : $(8) ;
+ }
+ if $(9) {
+ CatToFile_ $(_t) : $(9) ;
+ }
+ }
+}
+
+rule HardLink
+{
+ local _t = [ NormDstTargets $(<) ] ;
+ local _s = [ NormSrcTargets $(>) ] ;
+
+ Depends files : $(_t) ;
+ Depends $(_t) : $(_s) ;
+
+ HardLink_ $(_t) : $(_s) ;
+}
+
+# Mark executable as GUI applications (ie. OS X Bundle)
+# GuiImages images ;
+rule GuiBin
+{
+ local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ;
+ GUIAPP on $(_t) = "true" ;
+}
+
+rule GUIAPP
+{
+}
+
+# /HdrMacroFile
+#
+# this rule is specific to FT-Jam. It is used to indicate that a given file
+# contains definitions for filename macros (e.g. "#define MYFILE_H <myfile>.h")
+# that can later be used in #include statements in the rest of the source
+#
+# these files must be parsed before any make is tried.
+#
+rule HdrMacroFile
+{
+ HDRMACRO $(<) ;
+}
+
+# Handle #includes that are found.
+# Try and locate them to asociate them with declared targets, as
+# well as tracing any further #includes they may have.
+# HdrRule NormedSource : headers ;
+rule HdrRule
+{
+ # N.B. This rule is called during binding, potentially after
+ # the fate of many targets has been determined, and must be
+ # used with caution: don't add dependencies to unrelated
+ # targets, and don't set variables on $(<).
+
+#Echo "HdrRule got '" $(<) "' and '" $(>) "'" ;
+
+ local _d = [ geton $(<) : NOMLOC ] ; # Directory location of source file
+ local _schpath = [ geton $(<) : HDRSEARCH ] ; # Search path used to find these
+ local _s _ts ; # include source targets, sources to trace
+
+#Echo "HDRSEARCH on '" $(<) "' is = '" $(_schpath) "'" ;
+
+ # See if we can locate the header amongst the generated files.
+#Echo "Checking for matches of known targets" ;
+ local _i _j _k _ss _sp _n ;
+ local _stdhdrs = [ NormPaths $(STDHDRS) ] ;
+ _st = ;
+ for _j in $(>) {
+ _sp = ; # Search path
+ _ss = ; # Resolved source target
+#Echo "Checking include '" $(_j) "'" ;
+ for _k in $(_schpath) "__unknown__" { # search path and plain
+ _n = [ NormPaths $(_j) : $(_k) ] ; # Normalized path for that search path
+ _i = [ _TargetIDs $(_n) ] ; # Target ID/name if it exitsts
+#Echo "Checking target ID '" $(_i)-target "' value '" $($(_i)-target) "'" ;
+ if $($(_i)-target) { # Target exists
+ _ss = $(_i) ;
+ _s += $(_ss) ;
+#Echo "Found existing target '" $(_ss) "'" ;
+ break ;
+ } else if ! $($(_i)-target) { # unknown state
+#Echo "Unknown statis target '" $(_i) "'" ;
+ _sp += [ NormPaths $(_j:D) : $(_k) ] ; # paths to search
+ }
+ }
+ if ! $(_ss) && $(_sp) { # We've not seen that target
+ local _found = ;
+#Echo "Searching for '" $(_j) "' in paths '" $(_sp) "'" ;
+ # See if we can find the header
+ _found = [ GLOB $(_sp) : $(_j:BS) ] ;
+
+ # Hmm. This sort of works around Windows problem of std include files being upper case.
+ # It won't solve the problem of tracing them if TRACESTDHDRS is true though.
+ if $(NT) && ! $(_found) {
+ _found = [ GLOB $(_sp) : $(_j:UBS) ] ;
+ _found = $(_found:D)\\$(_found:LBS) ;
+ }
+ if $(_found) {
+ _ss = [ NormSrcTargets $(_found[1]) ] ; # Add it to our list
+#Echo "Using new found target '" $(_ss) "'" ;
+ _s += $(_ss) ;
+ }
+ # Mark off not found targets
+ for _k in $(_schpath) {
+ _n = [ NormPaths $(_j) : $(_k) ] ; # Normalized path for that search path
+ _i = [ _TargetIDs $(_n) ] ; # Target ID/name if it exitsts
+ if $(_i) = $(_ss) {
+ break ; # The one we found
+ }
+#Echo "marking off '" $(_i) "' as non-existant" ;
+ $(_i)-target = "false" ; # That combination doesn't exist
+ }
+ if ! $(_found) {
+ _k = "__unknown__" ;
+ _ss = [ NormSrcTargets $(_j) : $(_k) ] ;
+ # ~~99 This would make good warning information ?
+#Echo "Include unresolved: '" $(_ss) "'" ;
+ _s += $(_ss) ; # Use plain header name as target ID
+ }
+ }
+ # We're left with $(_ss_) being the target and $(_k) being the search path
+
+ # Add this to our list that will also be scanned for #includes
+#Echo "Dealt with'" $(_j) "', _ss = '" $(_ss) "' and _k = '" $(_k) "'" ;
+ if ( ! $(_k) in "__unknown__" )
+ && ( $(TRACESTDHDRS) = true || ! $(_k) in $(_stdhdrs) ) {
+ _st += $(_ss) ;
+ }
+ }
+
+#Echo "Normalized includes = '" $(_s) "'" ;
+#Echo "Includes to be traced = '" $(_st) "'" ;
+
+ # Propagate on $(<) to $(>)
+ # Compute header search path for any #includes in these #includes
+
+ if $(_st) {
+ HDRSEARCH2 on $(_st) = [ geton $(<) : HDRSEARCH2 ] ;
+ HDRSEARCH3 on $(_st) = [ geton $(<) : HDRSEARCH3 ] ;
+ for _i in $(_st) {
+ # Replace file dot/HDRSEARCH1 with one for this file
+ local _dot = [ geton $(_i) : NOMLOC ] ;
+ if ! $(_dot) { _dot = $(DOT) ; }
+ HDRSEARCH1 on $(_i) = $(_dot) ;
+ HDRSEARCH on $(_i) = [ geton $(_i) : HDRSEARCH1 ] [ geton $(_i) : HDRSEARCH2 ]
+ [ geton $(_i) : HDRSEARCH3 ] ;
+ }
+ HDRSCAN on $(_st) = [ geton $(<) : HDRSCAN ] ;
+ HDRRULE on $(_st) = [ geton $(<) : HDRRULE ] ;
+ HDRGRIST on $(_st) = [ geton $(<) : HDRGRIST ] ;
+#Echo "HdrRule SEARCH on '" $(_st) "' set to '" [ geton $(_st) : SEARCH ] "'" ;
+#Echo "HdrRule HDRSEARCH on '" $(_st) "' set to '" [ geton $(_st) : HDRSEARCH ] "'" ;
+#Echo "HdrRule HDRSCAN on '" $(_st) "' set to '" [ geton $(_st) : HDRSCAN ] "'" ;
+#Echo "HdrRule HDRRULE on '" $(_st) "' set to '" [ geton $(_st) : HDRRULE ] "'" ;
+ }
+
+ # Tell Jam that anything depending on $(<) also depends on $(>),
+ # set SEARCH so Jam can find the headers, but then say we don't
+ # care if we can't actually find the headers (they may have been
+ # within ifdefs),
+
+ NoCare $(_s) ;
+ SEARCH on $(_s) = $(_schpath) ; # Use search path used to find these #includes as Jam SEARCH path.
+ Includes $(<) : $(_s) ;
+}
+
+# Public InstallInto
+# InstallInto dir : sources ; install any files
+rule InstallInto
+{
+#Echo "InstallInto got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+ _InstallInto $(_t) : $(_s) ;
+}
+
+# Private InstallInto
+# Note that the install rules ignore SRDDIR and DSTDIR.
+# InstallInto destinations : sources ; install any files
+rule _InstallInto
+{
+#Echo "_InstallInto got '" $(<) "' and '" $(>) "'" ;
+
+ local _t = $(<) ; # targets
+ local _s = $(>) ; # sources
+ local _is _it ; # individual source and target
+
+ # Arrange for jam install
+ # Arrange for jam uninstall
+ # targets are in dir
+
+ Depends install : $(_t) ;
+ Clean uninstall : $(_t) ;
+ MakeLocate $(_t) ; # create directories
+
+ # For each source, Install, Chmod, Chown, and Chgrp
+
+ for _is in $(_s)
+ {
+ _it = $(_t[1]) ;
+ _t = $(_t[2-]) ; # Track _is
+
+#Echo "_InstallInto installing target '" $(_it) "' from src '" $(_is) "'" ;
+ Depends $(_it) : $(_is) ;
+ Install $(_it) : $(_is) ;
+ Chmod_ $(_it) ;
+
+ if $(OWNER) && $(CHOWN)
+ {
+ Chown_ $(_it) ;
+ OWNER on $(_it) = $(OWNER) ;
+ }
+
+ if $(GROUP) && $(CHGRP)
+ {
+ Chgrp_ $(_it) ;
+ GROUP on $(_it) = $(GROUP) ;
+ }
+ }
+}
+
+# InstallBin dir : sources ; install binaries
+rule InstallBin
+{
+#Echo "InstallBin got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>:S=$(SUFEXE)) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+#Echo "InstallBin norm '" $(_d) "' and '" $(_s) "' and '" $(_t) "'" ;
+ MODE on $(_t) = $(EXEMODE) ;
+ _InstallInto $(_t) : $(_s) ;
+#Echo "InstallBin done " ;
+}
+
+# InstallFile dir : sources ; install files
+rule InstallFile
+{
+#Echo "InstallFile got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+#Echo "InstallFile normed targ '" $(_t) "' src '" $(_s) "' and dir '" $(_d) "'" ;
+ MODE on $(_t) = $(FILEMODE) ;
+ _InstallInto $(_t) : $(_s) ;
+}
+
+# InstallLib dir : sources ; install static library files
+rule InstallLib
+{
+#Echo "InstallLib got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+ MODE on $(_t) = $(FILEMODE) ;
+ _InstallInto $(_t) : $(_s) ;
+}
+
+# InstallShLib dir : sources ; install shared library files
+rule InstallShLib
+{
+#Echo "InstallShLib got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>:S=$(SUFSHLIB)) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+ MODE on $(_t) = $(FILEMODE) ;
+ _InstallInto $(_t) : $(_s) ;
+}
+
+# InstallShell dir : sources ; install files
+rule InstallShell
+{
+#Echo "InstallShell got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+ MODE on $(_t) = $(SHELLMODE) ;
+ _InstallInto $(_t) : $(_s) ;
+}
+
+# InstallMan dir : sources ; install files
+rule InstallMan
+{
+#Echo "InstallMan got '" $(<) "' and '" $(>) "'" ;
+ local _d = [ NormPaths $(<) ] ; # Directory
+ local _s = [ NormSrcTargets $(>) ] ; # Sources
+ local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir
+
+ # Really this just strips the . from the suffix
+
+ local _is _it _tt _s _id ;
+
+ _tt = $(_t) ;
+ for _is in $(_s)
+ {
+ _it = $(_tt[1]) ;
+ _tt = $(_tt[2-]) ;
+
+ switch $(_is:S)
+ {
+ case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
+ case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
+ case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
+ case .n : s = n ; case .man : s = 1 ;
+ }
+
+ _id = [ RootPaths $(_d) : man$(_s) ] ;
+ CreateIDstTargets $(_it) : $(_id) ;
+ MODE on $(_it) = $(FILEMODE) ;
+ _InstallInto $(_it) : $(_is) ;
+ }
+}
+
+# Lex
+# Lex source.c : source.l ;
+rule Lex
+{
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<[1]) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Depends $(_t) : $(_s) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+
+ Lex_ $(_t) : $(_s) ;
+}
+
+# Internal Lex
+rule Lex_
+{
+ LexMv_ $(<) : $(>) ;
+}
+
+# Library - create a static library from sources.
+# Library library : sources : flags : defines : hdrpaths : objects ;
+rule Library
+{
+ LibraryFromObjects $(<) : $(>) $(6) ;
+ Objects $(>) : $(3) : $(4) : $(5) ;
+}
+
+# LibraryFromObjects - create a static library from object files.
+# LibraryFromObjects library : objects ;
+rule LibraryFromObjects
+{
+ local _i ;
+
+#Echo "LibraryFromObjects got " $(<) "and" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _l = [ NormDstTargets $(<[1]:S=$(SUFLIB)) ] ;
+ local _s = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ;
+#Echo "LibraryFromObjects nomed = " $(_l) "and" $(_s) ;
+
+ Depends lib : $(_l) ;
+
+ MakeLocate $(_l) ;
+
+ if $(NOARSCAN)
+ {
+ # If we can't scan the library to timestamp its contents,
+ # we have to just make the library depend directly on the
+ # on-disk object files.
+
+ Depends $(_l) : $(_s) ;
+ }
+ else
+ {
+ # If we can scan the library, we make the library depend
+ # on its members and each member depend on the on-disk
+ # object file.
+
+ for _i in $(_s)
+ {
+ local _m ;
+ _m = $(_l:M=$(_i:BS)) ;
+ CopyTarget $(_m) : $(_l) ; # Transfer LOCATE, SEARCH, NOMLOC
+ Depends $(_l) : $(_m) ;
+ Depends $(_m) : $(_i) ;
+ }
+ }
+
+ Clean clean : $(_l) ;
+
+ if $(CRELIB) {
+ CreLib $(_l) : $(_s[1]) ;
+ }
+
+ Archive $(_l) : $(_s) ;
+
+ if $(RANLIB) {
+ Ranlib $(_l) ;
+ }
+
+ # If we can't scan the library, we have to leave the .o's around.
+ if ! ( $(NOARSCAN) || $(NOARUPDATE) ) {
+ local _ds ;
+ for _i in $(_s) {
+ # Don't delete any objects that we've marked with KEEPOBJS
+ if ! [ geton $(_i) : KEEPOBJS ] {
+ _ds += $(_i) ;
+ }
+ }
+ if $(_ds) {
+ RmTemps_ $(_l) : $(_ds) ;
+ }
+ }
+}
+
+# LibraryFromLibraries - create a static library from object files and static libraries.
+# LibraryFromLibraries library : libraries ;
+rule LibraryFromLibraries
+{
+ local _i ;
+
+#Echo "LibraryFromLibraries got " $(<) "and" $(>) ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _l = [ NormDstTargets $(<[1]:S=$(SUFLIB)) ] ;
+ local _s = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ;
+#Echo "LibraryFromObjects nomed = " $(_l) "and" $(_s) ;
+
+ Depends lib : $(_l) ;
+ Depends $(_l) : $(_s) ;
+
+ MakeLocate $(_l) ;
+
+ Clean clean : $(_l) ;
+
+ if $(CRELIB) {
+ CreLib $(_l) : $(_s[1]) ;
+ }
+
+ ArchiveArchive $(_l) : $(_s) ;
+}
+
+# ShLibrary - create a shared library from sources.
+# ShLibrary library : sources : flags : defines : hdrpaths : objects : libs : shlibs ;
+rule ShLibrary
+{
+ ShLibraryFromObjects $(<) : $(>) $(6) : $(7) : $(8) ;
+ Objects $(>) : $(CCSHOBJFLAG) $(3) : $(4) : $(5) ;
+}
+
+# ShLibraryFromObjects - create a shared library from object files.
+# Both the import (if used on the system) and shared library will be created.
+# ShLibraryFromObjects shlib : objects : libs : shlibs ;
+rule ShLibraryFromObjects
+{
+ local _i _l ;
+
+#Echo "ShLibraryFromObjects got " $(<) "and" $(>) ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _sl = [ NormDstTargets $(<[1]:S=$(SUFSHLIB)) ] ;
+ if $(NT) {
+ _l = [ NormDstTargets $(<[1]:S=$(SUFIMPLIB)) ] ;
+ }
+ local _s = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ;
+#Echo "ShLibraryFromObjects nomed =" $(_sl) "and" $(_l) "and" $(_s) ;
+
+ Depends lib : $(_sl) ;
+# Depends lib : $(_l) ;
+ MakeLocate $(_sl) ;
+
+ Depends $(_sl) : $(_s) ;
+ Clean clean : $(_sl) $(_l) ;
+
+ if $(_l) {
+ Depends $(_l) : $(_s) ;
+ Clean clean : $(_l:S=.exp) ;
+ }
+
+#Echo "ShLibraryFromObjects SHLINKFLAGS = '" $(SHLINKFLAGS) "' and P_SHLINKFLAGS ='" $(P_LSHINKFLAGS) "'" ;
+
+ if $(SHLINKFLAGS) || $(P_SHLINKFLAGS)
+ || $(PREF_SHLINKFLAGS) || $(P_PREF_SHLINKFLAGS) {
+ local pref_shlinkflags = $(P_PREF_SHLINKFLAGS) ;
+ pref_shlinkflags ?= $(PREF_SHLINKFLAGS) ;
+ SHLINKFLAGS on $(_sl) += $(P_SHLINKFLAGS) $(SHLINKFLAGS) $(pref_shlinkflags) ;
+ }
+
+#Echo "ShLibraryFromObjects SHLINKOBJS = '" $(SHLINKOBJS) "' and P_SHLINKOBJS ='" $(P_SHLINKOBJS) "'" ;
+ if $(SHLINKOBJS) || $(P_SHLINKOBJS) {
+ local _o = [ NormSrcTargets $(SHLINKOBJS:S=$(SUFOBJ)) ] $(P_SHLINKOBJS:S=$(SUFOBJ)) ;
+ Depends $(_t) : $(_o) ;
+ SHLINKOBJS on $(_t) += $(_o) ;
+ }
+
+#Echo "ShLibraryFromObjects SHLINKLIBS = '" $(SHLINKLIBS) "' and P_SHLINKLIBS ='" $(P_SHLINKLIBS) "'" ;
+ if $(SHLINKLIBS) || $(P_SHLINKLIBS) {
+ local _l = [ NormSrcTargets $(SHLINKLIBS:S=$(SUFLIB)) ] $(P_SHLINKLIBS:S=$(SUFLIB)) ;
+ Depends $(_t) : $(_l) ;
+ SHLINKLIBS on $(_t) += $(_l) ;
+ }
+
+#Echo "ShLibraryFromObjects SHLINKSHLIBS = '" $(SHLINKSHLIBS) "' and P_SHLINKSHLIBS ='" $(P_SHLINKSHLIBS) "'" ;
+ if $(SHLINKSHLIBS) || $(P_SHLINKSHLIBS) {
+ local _l = [ NormSrcTargets $(SHLINKSHLIBS:S=$(SUFSHLIB)) ] $(P_SHLINKSHLIBS:S=$(SUFSHLIB)) ;
+ Depends $(_t) : $(_l) ;
+ SHLINKSHLIBS on $(_t) += $(_l) ;
+ }
+
+ if $(SHLINKDEFFILE) { # Windows special option
+ SHLINKDEFFILE on $(_sl) $(_l) = [ NormSrcTargets $(SHLINKDEFFILE) ] ;
+ Depends $(_sl) : [ geton $(_sl) : SHLINKDEFFILE ] ;
+ FakeFile_ $(_l) : $(_sl) ; # .lib is created with .dll
+ ShLinkDef_ $(_sl) $(_l) : $(_s) ;
+ } else {
+ if (SHLINKSEARCHEXEPATH) { # UNIX special option
+
+ if $(OS) = MACOSX { # OS X version of ld
+ SHLINKSEARCHEXEPATH = @executable_path/ ;
+ } else {
+# SHLINKSEARCHEXEPATH = \\$PATH/ ;
+ SHLINKSEARCHEXEPATH = \\$ORIGIN/ ;
+ }
+ }
+ ShLink_ $(_sl) $(_l) : $(_s) ;
+ }
+
+ # Try and make sure the objects are build with the correct flag
+ ObjectCcFlags $(>) : $(CCSHOBJFLAG) ;
+ ObjectC++Flags $(>) : $(CCSHOBJFLAG) ;
+
+ if $(3) {
+ ShLibraryLibraries $(<) : $(3) ;
+ }
+ if $(4) {
+ ShLibraryShLibraries $(<) : $(4) ;
+ }
+}
+
+# Internal link
+rule Link_
+{
+ MODE on $(<) = $(EXEMODE) ;
+ Chmod_ $(<) ;
+}
+
+# Make the shared library link with the given objects.
+# This is just a way of adding common object files to many shlibs.
+# ShLibraryObjects shlib : objects ;
+rule ShLibraryObjects
+{
+#Echo "ShLibraryObjects got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<:S=$(SUFSHLIB)) ] ;
+ local _o = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ;
+
+ Depends $(_t) : $(_o) ;
+
+ SHLINKOBJS on $(_t) += $(_o) ;
+}
+
+# Make the executables link with the given static libraries.
+# ShLibraryLibraries shlib : libraries ;
+rule ShLibraryLibraries
+{
+#Echo "ShLibraryLibraries got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<:S=$(SUFSHLIB)) ] ;
+ local _l = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ;
+
+ Depends $(_t) : $(_l) ;
+
+ SHLINKLIBS on $(_t) += $(_l) ;
+}
+
+# Make the executables link with the given shared libraries.
+# ShLibraryShLibraries shlib : shlibraries ;
+rule ShLibraryShLibraries
+{
+#Echo "ShLibraryShLibraries got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<:S=$(SUFSHLIB)) ] ;
+ local _l = [ NormSrcTargets $(>:S=$(SUFSHIMPLIB)) ] ;
+
+ Depends $(_t) : $(_l) ;
+
+ SHLINKSHLIBS on $(_t) += $(_l) ;
+}
+
+# Add extra LINKFLAGS to mains
+# MainLinkFlags mains : flags ;
+rule MainLinkFlags
+{
+#Echo "MainLinkFlags got '" $(<) "' and '" $(>) "'" ;
+ local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ;
+ local _i ;
+
+ for _i in $(_t) {
+ LINKFLAGS on $(_i) += $(>) ;
+#Echo "exes '" $(_i) "' got LINKFLAGS '" [ geton $(_i) : LINKFLAGS ] "'" ;
+ }
+}
+
+# Make an executable from sources
+# Main image : sources : flags : defines : hdrpaths : objects : libs : shlibs ;
+rule Main
+{
+ MainFromObjects $(<) : $(>) $(6) : $(7) : $(8) ;
+ Objects $(>) : $(3) : $(4) : $(5) ;
+}
+
+# Make a variant executable from sources
+# Objects are distiguished by appending "_image"
+# MainVariant image : sources : flags : defines : hdrpaths : objects : libs : shlibs ;
+rule MainVariant
+{
+ local _i _t _o ;
+
+#Echo "MainVariant got '" $(<) "' and '" $(>) "'" ;
+ for _i in $(>) {
+ _t = $(_i:DB)_$(<[1]) ;
+ Object $(_t) : $(_i) : $(3) : $(4) : $(5) ;
+#Echo "MainVariant object '" $(_t) "' and src '" $(_i) "'" ;
+ _o += $(_t) ;
+ }
+#Echo "MainVariant image '" $(<) "' and objs '" $(_o) "'" ;
+ MainFromObjects $(<) : $(_o) $(6) : $(7) : $(8) ;
+}
+
+# Make an executable from objects
+# MainFromObjects image : objects : libs : shlibs ;
+rule MainFromObjects
+{
+#Echo "MainFromObjects got" $(<) "and" $(>) ;
+
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<[1]:S=$(SUFEXE)) ] ;
+ local _s = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ;
+
+#Echo "MainFromObjects _t" $(_t) "and _s" $(_s) ;
+
+ # so 'jam foo' works when it's really foo.exe
+ if $(_t:S=) != $(_t)
+ {
+ Depends $(_t:S=) : $(_t) ;
+ NotFile $(_t:S=) ;
+ }
+
+ # make compiled sources a dependency of target
+
+ Depends exe : $(_t) ;
+ Depends $(_t) : $(_s) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+
+ if $(3) {
+ LinkLibraries $(<) : $(3) ;
+ }
+ if $(4) {
+ LinkShLibraries $(<) : $(4) ;
+ }
+
+#Echo "MainFromObjects LINKFLAGS = '" $(LINKFLAGS) "' and P_LINKFLAGS ='" $(P_LINKFLAGS) "'" ;
+#Echo " PREF_LINKFLAGS = '" $(PREF_LINKFLAGS) "' and P_PREF_LINKFLAGS ='" $(P_PREF_LINKFLAGS) "'" ;
+ if $(LINKFLAGS) || $(P_LINKFLAGS)
+ || $(PREF_LINKFLAGS) || $(P_PREF_LINKFLAGS) {
+ local pref_linkflags = $(P_PREF_LINKFLAGS) ;
+ pref_linkflags ?= $(PREF_LINKFLAGS) ;
+ LINKFLAGS on $(_t) += $(P_LINKFLAGS) $(LINKFLAGS) $(pref_linkflags) ;
+#Echo "LINKFLAGS on $(_t) = '" [ geton $(_t) : LINKFLAGS ] "'" ;
+ }
+
+#Echo "MainFromObjects LINKOBJS = '" $(LINKOBJS) "' and P_LINKOBJS ='" $(P_LINKOBJS) "'" ;
+ if $(LINKOBJS) || $(P_LINKOBJS) {
+ local _o = [ NormSrcTargets $(LINKOBJS:S=$(SUFOBJ)) ] $(P_LINKOBJS:S=$(SUFOBJ)) ;
+ Depends $(_t) : $(_o) ;
+ LINKOBJS on $(_t) += $(_o) ;
+ }
+
+#Echo "MainFromObjects LINKLIBS = '" $(LINKLIBS) "' and P_LINKLIBS ='" $(P_LINKLIBS) "'" ;
+ if $(LINKLIBS) || $(P_LINKLIBS) {
+ local _l = [ NormSrcTargets $(LINKLIBS:S=$(SUFLIB)) ] $(P_LINKLIBS:S=$(SUFLIB)) ;
+ Depends $(_t) : $(_l) ;
+ LINKLIBS on $(_t) += $(_l) ;
+ }
+
+#Echo "MainFromObjects LINKSHLIBS = '" $(LINKSHLIBS) "' and P_LINKSHLIBS ='" $(P_LINKSHLIBS) "'" ;
+ if $(LINKSHLIBS) || $(P_LINKSHLIBS) {
+ local _l = [ NormSrcTargets $(LINKSHLIBS:S=$(SUFIMPLIB)) ] $(P_LINKSHLIBS:S=$(SUFIMPLIB)) ;
+ Depends $(_t) : $(_l) ;
+ LINKSHLIBS on $(_t) += $(_l) ;
+ }
+
+ Link_ $(_t) : $(_s) ;
+
+ # Some OS's need to post process GUI apps to work (ie. OS X bundle)
+ if [ geton $(_t) : GUIAPP ] = "true" {
+ GUIAPP $(_t) ;
+ }
+#Echo "MainFromObjects done" ;
+}
+
+# A rule to make several mains from each of their single source files.
+# MainsFromSources executables ;
+rule MainsFromSources
+{
+ local _i ;
+ for _i in $(<) {
+ Main $(_i) : $(_i) ;
+ }
+}
+
+# Make the executables link with the given objects.
+# This is just a way of adding common object files to many mains.
+# LinkObjects image : objects ;
+rule LinkObjects
+{
+#Echo "LinkObjects got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ;
+ local _o = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ;
+
+ Depends $(_t) : $(_o) ;
+
+ LINKOBJS on $(_t) += $(_o) ;
+}
+
+# Make the executables link with the given static libraries.
+# LinkLibraries image : libraries ;
+rule LinkLibraries
+{
+#Echo "LinkLibraries got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ;
+ local _l = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ;
+
+ Depends $(_t) : $(_l) ;
+
+ LINKLIBS on $(_t) += $(_l) ;
+}
+
+# Make the executables link with the given shared libraries.
+# LinkShLibraries image : shlibraries ;
+rule LinkShLibraries
+{
+#Echo "LinkShLibraries got '" $(<) "' and '" $(>) "'" ;
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ;
+ local _l = [ NormSrcTargets $(>:S=$(SUFSHIMPLIB)) ] ;
+
+ Depends $(_t) : $(_l) ;
+
+ LINKSHLIBS on $(_t) += $(_l) ;
+}
+
+# Ensure that each targets directories are created
+# Makelocate targets ;
+rule MakeLocate
+{
+#Echo "MakeLocate got '" $(<) "'" ;
+ local _i ;
+ # Uses special variable LOCATE of targets, and arranges
+ # with MkDir to create target directory.
+ # The directory itself becomes a target
+
+ for _i in $(<) {
+ local _t = [ geton $(_i) : LOCATE ] ;
+ if $(_t) {
+ MkDir_ $(_t) : $(_i) ;
+ }
+ }
+}
+
+# Make the directories and all their parent directories.
+# MkDir directories ;
+rule MkDir
+{
+#Echo "MkDir got '" $(<) "'" ;
+ # Ignore timestamps on directories: we only care if they exist.
+ local _t= [ NormPaths $(<) ] ;
+ local _i ;
+
+ for _i in $(_t) {
+ MkDir_ $(_i) ;
+ }
+}
+
+# Internal MkDir
+# MkDir dir [ : dependency ]
+rule MkDir_
+{
+#Echo "MkDir_ got '" $(<) "' : '" $(>) "'" ;
+
+ if ! $(<:BS) {
+ return ;
+ }
+
+ local _t ;
+ local _d = $(<:D) ; # Form target id from path + last directory
+ if ! $(_d) {
+ _d = $(DOT) ;
+ }
+ local _t = [ NormIDstTargets $(<:BS) : $(_d) ] ;
+
+#Echo "MkDir_ target = '" $(_t) "' dependant = '" $(>) "'" ;
+
+ if $(>) { # Thing that depends on this directory
+ Depends $(>) : $(_t) ;
+ }
+ NoUpdate $(_t) ;
+
+ # Don't create . or any directory already created.
+
+ if $(_t) != $(DOT) && ! $($(_t)-mkdir)
+ {
+ # Cheesy gate to prevent multiple invocations on same dir
+ # Arrange for jam dirs
+ # MkDir1 has the actions
+
+#Echo "Making '" $(_t) "'" ;
+ $(_t)-mkdir = true ;
+ Depends dirs : $(_t) ;
+ MkDir1 $(_t) ;
+
+ # Recursively make parent directories.
+ # $(_t:P) = $(_t)'s parent, & we recurse until root
+
+ local _s = $(<:P) ;
+#Echo "parent = '" $(_s) "'" ;
+
+ # Don't try to create A: or A:\ on windows
+
+ if $(NT)
+ {
+ switch $(_s)
+ {
+ case *: : _s = ;
+ case *:\\ : _s = ;
+ case *:/ : _s = ;
+ }
+ }
+
+#Echo "parent now = '" $(_s) "'" ;
+ if $(_s) = $(SLASH) # Hmm. Was $(_s) = $(<). How could that work ?
+ {
+#Echo "At root, ignore '" $(_s) "' = '" $(<) "'" ;
+ # The parent is the same as the dir.
+ # We're at the root, which some OS's can't stat, so we mark
+ # it as NotFile.
+
+ NotFile $(_s) ;
+ }
+ else if $(_s)
+ {
+ # There's a parent; recurse.
+
+#Echo "Doing Depends '" $(_t) "' with '" [ _TargetIDs $(_s) ] "'" ;
+ Depends $(_t) : [ _TargetIDs $(_s) ] ;
+#Echo "Recursing with parent '" $(_s) "'" ;
+ MkDir_ $(_s) ;
+ }
+ } else {
+#Echo "Not making '" $(_t) "' because it's dot, or it's been made before" ;
+ }
+}
+
+# Deal with a single source to object.
+# Object object : sources : flags : defines : hdrpaths
+rule Object
+{
+#Echo "Object got " $(<) "and" $(>) "' flags '" $(3) "' defs '" $(4) "' hds '" $(5) "'" ;
+
+ # Normalize target names and set Grist LOCATE and SOURCE
+ local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+ local _dot ;
+
+#Echo "Object norms " $(_t) "and" $(_s) ;
+
+ Depends $(_t) : $(_s) ;
+ Depends obj : $(_t) ;
+ Clean clean : $(_t) ;
+ MakeLocate $(_t) ;
+
+ # HDRS is used to provide the -I$(HDRS) options on compile.
+
+#Echo "Object sets HDRS on '" $(_t) "' to HDRS '" $(HDRS) "' and P_HDRS '" $(P_HDRS) "'" ;
+ HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ;
+#Echo "HDRS on '" $(_t) "' is now '" [ geton $(_t) : HDRS ] "'" ;
+
+ # we need to mark what the associated source is so
+ # that if we want to change HDRS we can propogate
+ # it to the #include files.
+
+ SOURCE on $(_t) = $(_s) ; # ~~99 should check source is the same as any previous ?
+
+ # handle #includes for source: Jam scans for headers with
+ # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
+ # with the scanned file as the target and the found headers
+ # as the sources. HDRSEARCH is the value of SEARCH used for
+ # the found header files.
+
+ HDRRULE on $(_s) = HdrRule ;
+ HDRSCAN on $(_s) = $(HDRPATTERN) ;
+
+ # Construct HDRSEARCH so that we can latter add to HDRS
+ local _dot = [ geton $(_s) : NOMLOC ] ;
+ if ! $(_dot) { _dot = $(DOT) ; }
+ HDRSEARCH1 on $(_s) = $(_dot) ;
+ HDRSEARCH2 on $(_s) = [ NormPaths $(HDRS) ] $(P_HDRS) ;
+ HDRSEARCH3 on $(_s) = [ NormPaths $(STDHDRS) ] ;
+ HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ]
+ [ geton $(_s) : HDRSEARCH3 ] ;
+#Echo "Object: HDRSEARCH on '" $(_s) "' set to '" [ geton $(_s) : HDRSEARCH ] "'" ;
+
+ # propagate target specific-defines
+
+ DEFINES on $(_t) = $(P_DEFINES) $(DEFINES) ;
+
+ # if source is not .c, generate .c with specific rule
+
+ switch $(_s:S)
+ {
+ case .asm : As_ $(_t) : $(_s) ;
+
+ case .c : Cc_ $(_t) : $(_s) ;
+
+ case .C : C++_ $(_t) : $(_s) ;
+ case .cc : C++_ $(_t) : $(_s) ;
+ case .cpp : C++_ $(_t) : $(_s) ;
+ case .cxx : C++_ $(_t) : $(_s) ;
+
+ case .m : Cc_ $(_t) : $(_s) ;
+
+ case .f : Fortran_ $(_t) : $(_s) ;
+
+ case .l : {
+ local _c = $(_t:S=.c) ;
+ CopyTarget $(_c) : $(_t) ; # Transfer LOCATE, SEARCH, NOMLOC
+ Lex_ $(_c) : $(_s) ;
+ Cc_ $(_t) : $(_c) ;
+ }
+
+ case .s : As_ $(_t) : $(_s) ;
+
+ case .y : {
+ local _c = $(_t:S=$(YACCGEN)) ;
+ CopyTarget $(_c) : $(_t) ; # Transfer LOCATE, SEARCH, NOMLOC
+ Yacc_ $(_c) : $(_s) ;
+ Cc_ $(_t) : $(_c) ;
+ }
+ # Note user object gets normalized target and source
+ case * : UserObject $(_t) : $(_s) : $(3) : $(4) : $(5) ;
+ }
+#Echo ;
+
+ if $(3) {
+ ObjectCcFlags $(<) : $(3) ;
+ switch $(_s:S)
+ {
+ case .c : ObjectCcFlags $(_t) : $(3) ;
+
+ case .C : ObjectC++Flags $(_t) : $(3) ;
+ case .cc : ObjectC++Flags $(_t) : $(3) ;
+ case .cpp : ObjectC++Flags $(_t) : $(3) ;
+ case .cxx : ObjectC++Flags $(_t) : $(3) ;
+
+ case .l : ObjectCcFlags $(_t) : $(3) ;
+ case .y : ObjectCcFlags $(_t) : $(3) ;
+ }
+ }
+ if $(4) {
+ ObjectDefines $(<) : $(4) ;
+ }
+ if $(5) {
+ ObjectHdrs $(<) : $(5) ;
+ }
+}
+
+# Add extra CCFLAGS to objects
+# ObjectCcFlags objects : flags ;
+rule ObjectCcFlags
+{
+#Echo "ObjectCcFLags got '" $(<) "' and '" $(>) "'" ;
+ local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ;
+ local _i ;
+
+ for _i in $(_t) {
+ CCFLAGS1 on $(_i) += $(>) ;
+ CCFLAGS on $(_i) = [ geton $(_i) : CCFLAGS1 ] [ geton $(_i) : CCFLAGS2 ] ;
+#Echo "object '" $(_i) "' got CCFLAGS1 '" [ geton $(_i) : CCFLAGS1 ] "' and CCFLAGS2 '" [ geton $(_i) : CCFLAGS2 ] "' for total CCFLAGS '" [ geton $(_i) : CCFLAGS ] "'" ;
+ }
+}
+
+# Add extra PREF_CCFLAGS to objects
+# ObjectPrefCcFlags objects : flags ;
+rule ObjectPrefCcFlags
+{
+#Echo "ObjectPrefCcFLags got '" $(<) "' and '" $(>) "'" ;
+ if ! $(P_PREF_CCFLAGS) {
+ local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ;
+ local _i ;
+
+ for _i in $(_t) {
+ CCFLAGS2 on $(_i) += $(>) ;
+ CCFLAGS on $(_i) = [ geton $(_i) : CCFLAGS1 ] [ geton $(_i) : CCFLAGS2 ] ;
+#Echo "object '" $(_i) "' got CCFLAGS1 '" [ geton $(_i) : CCFLAGS1 ] "' and CCFLAGS2 '" [ geton $(_i) : CCFLAGS2 ] "' for total CCFLAGS '" [ geton $(_i) : CCFLAGS ] "'" ;
+ }
+ }
+}
+
+# Add extra C++FLAGS to objects
+# ObjectC++Flags objects : flags ;
+rule ObjectC++Flags
+{
+#Echo "ObjectC++FLags got '" $(<) "' and '" $(>) "'" ;
+ local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ;
+ local _i ;
+
+ for _i in $(_t) {
+ C++FLAGS1 on $(_i) += $(>) ;
+ C++FLAGS on $(_i) = [ geton $(_i) : C++FLAGS1 ] [ geton $(_i) : C++FLAGS2 ] ;
+ }
+}
+
+# Add extra PREF_C++FLAGS to objects
+# ObjectPrefC++Flags objects : flags ;
+rule ObjectPrefC++Flags
+{
+#Echo "ObjectPrefC++FLags got '" $(<) "' and '" $(>) "'" ;
+ if ! $(P_PREF_C++FLAGS) {
+ local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ;
+ local _i ;
+
+ for _i in $(_t) {
+ C++FLAGS2 on $(_i) += $(>) ;
+ C++FLAGS on $(_i) = [ geton $(_i) : C++FLAGS1 ] [ geton $(_i) : C++FLAGS2 ] ;
+ }
+ }
+}
+
+# Add extra DEFINES to objects
+# ObjectDefines objects : defines ;
+rule ObjectDefines
+{
+ # must reformat CCDEFS according to current defines
+
+ local s = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ;
+
+ DEFINES on $(s) += $(>) ;
+ CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;
+}
+
+# Add extra header search paths to objects.
+# ObjectHdrs objects : dirs ;
+rule ObjectHdrs
+{
+#Echo "ObjectHdrs HDRS got '" $(<) "' and '" $(>) "'" ;
+ # Add to HDRS for CCHDRS benefit.
+ local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ;
+ local _h = [ NormSrcPaths $(>) ] ;
+ local _i _s ;
+
+#Echo "ObjectHdrs changed HDRS on '" $(_t) "' from '" [ geton $(_t) : HDRS ] "'" ;
+ HDRS on $(_t) += $(_h) ;
+#Echo " to '" [ geton $(_t) : HDRS ] "'" ;
+ for _i in $(_t) {
+ _s = [ geton $(_i) : SOURCE ] ;
+#Echo " obj '" $(_i) "' has source '" $(_s) "'" ;
+#Echo " ObjectHdrs changed HDRSEARCH on '" $(_s) "' from '" [ geton $(_s) : HDRSEARCH ] "'" ;
+ HDRSEARCH2 on $(_s) += $(_h) ;
+ HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ]
+ [ geton $(_s) : HDRSEARCH3 ] ;
+#Echo " to '" [ geton $(_s) : HDRSEARCH ] "'" ;
+ CCHDRS on $(_i) = [ on $(_i) FIncludes $(HDRS) ] ;
+ }
+}
+
+# Set KEEPOBJS on the given headers
+# ObjectKeep objects ;
+rule ObjectKeep
+{
+#Echo "ObjectKeep got '" $(<) "" ;
+ local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ;
+
+ KEEPOBJS on $(_t) = "true" ;
+#Echo "ObjectHdrs changed KEEPOBJS on '" $(_t) "' to '" [ geton $(_t[1]) : KEEPOBJS ] "'" ;
+}
+
+# Create object files from sources.
+# Objects sources : flags : defines : hdrpaths ;
+rule Objects
+{
+#Echo "Objects got src '" $(<) "' flags '" $(2) "' def '" $(3) "' hdrs '" $(4) "'" ;
+ local _i ;
+
+ for _i in $(<) {
+ Object $(_i) : $(_i) : $(2) : $(3) : $(4) ;
+ }
+}
+
+# Marks sources as temporary with the TEMPORARY rule, and deletes sources once targets are built.
+# Must be the last rule invoked on targets.
+# RmTemps targets : sources ;
+rule RmTemps
+{
+ local _s = [ NormPaths $(>) ] ;
+ if $(_s) {
+ RmTemps_ $(<) : $(_s) ;
+ }
+}
+
+# internal RmTemps
+rule RmTemps_
+{
+ Temporary $(>) ;
+}
+
+# Setuid
+rule Setuid
+{
+ local _t = [ NormPaths $(>:S=$(SUFEXE)) ] ;
+ MODE on $(_t) = 4711 ;
+}
+
+# Shell
+rule Shell
+{
+ local _t = [ NormTargs $(>:S=$(SUFSH)) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+ Shell_ $(_t) : $(_s) ;
+}
+
+# internal Shell
+rule Shell_
+{
+ Depends shell : $(<) ;
+ Depends $(<) : $(>) ;
+ MODE on $(<) = $(SHELLMODE) ;
+ Clean clean : $(<) ;
+ Chmod_ $(<) ;
+}
+
+# SoftLink
+rule SoftLink
+{
+ local _t = [ NormDstTargets $(<) ] ;
+ local _s = [ NormSrcTargets $(>) ] ;
+
+ SoftLink_ $(_t) : $(_s) ;
+}
+
+# internal SoftLink
+rule SoftLink_
+{
+ Depends files : $(<) ;
+ Depends $(<) : $(>) ;
+ Clean clean : $(<) ;
+}
+
+#Adds flags to mark symbols as undefined on link command for images
+rule Undefines
+{
+ local _t = [ NormDstTargets $(<) ] ;
+ UNDEFS on [ $(_t:S=$(SUFEXE)) ] += $(UNDEFFLAG)$(>) ;
+}
+
+# User routine to handle objects. Note that
+# targets and sources are in normalized form.
+rule UserObject
+{
+ Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
+}
+
+# Yacc source.c : source.y ;
+rule Yacc
+{
+ local _t = [ NormDstTargets $(<[1]) ] ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Yacc_ $(_t) : $(_s) ;
+}
+
+# internal Yacc
+rule Yacc_
+{
+ local _h ;
+
+ _h = $(<:S=.h) ;
+ CopyTarget $(_h) : $(<) ; # Transfer LOCATE, SEARCH, NOMLOC
+
+ # Some places don't have a yacc.
+
+ MakeLocate $(<) $(_h) ;
+
+ if $(YACC)
+ {
+ Depends $(<) : $(>) ;
+ FakeFile_ $(_h) : $(<) ; # .h is created with .c
+ Yacc1_ $(<) $(_h) : $(>) ;
+ YaccMv_ $(<) $(_h) ;
+ Clean clean : $(<) $(_h) ;
+ }
+
+ # make sure someone includes $(_h) else it will be
+ # a deadly independent target
+
+ Includes $(<) : $(_h) ;
+}
+
+# Aswig : source.i ;
+# Argyll C class generator. Creates C class declaration source.h,
+# C class partial implementation source_i.c, C++ class wrapper
+# declaration & implementation source.hpp.
+rule Aswig
+{
+#Echo "Aswig called with $(>) " ;
+ local _s = [ NormSrcTargets $(>[1]) ] ;
+
+ Aswig_ : $(_s) ;
+}
+
+# internal Aswig
+rule Aswig_
+{
+#Echo "Aswig_ called with $(>)" ;
+ local _i = $(>[1]) ;
+ local _h = $(_i:S=.h) ;
+ CopyTarget $(_h) : $(_i) ; # Transfer LOCATE, SEARCH, NOMLOC
+ local _c = $(_i:B=$(_i:B)_i:S=.c) ;
+ CopyTarget $(_c) : $(_i) ; # Transfer LOCATE, SEARCH, NOMLOC
+ local _hpp = $(_i:S=.hpp) ;
+ CopyTarget $(_hpp) : $(_i) ; # Transfer LOCATE, SEARCH, NOMLOC
+
+#Echo "Aswig_ creates $(_h) $(_c) $(_hpp) from $(_i) " ;
+
+ MakeLocate $(_h) $(_c) $(_hpp) ;
+
+ Depends $(_h) : $(_i) ;
+ FakeFile_ $(_c) : $(_h) ; # _i.c is created with .h
+ FakeFile_ $(_hpp) : $(_h) ; # _.hpp is created with .h
+ Aswig1_ $(_h) : $(_i) ;
+ Clean clean : $(_h) $(_c) $(_hpp) ;
+}
+
+#
+# Utility rules; no side effects on these
+#
+
+# FReverse a1 a2 a3 ... ;
+# return ... a3 a2 a1 ;
+rule FReverse
+{
+
+ local _i _o = ;
+ for _i in $(1)
+ {
+ _o = $(_i) $(_o) ;
+ }
+ return $(_o) ;
+}
+
+# Strip common initial elements of variables v1 and v2.
+# Modifies the variable values themselves.
+# FStripCommon v1 : v2 ;
+rule FStripCommon
+{
+
+ if $($(<)[1]) && $($(<)[1]) = $($(>)[1])
+ {
+ $(<) = $($(<)[2-]) ;
+ $(>) = $($(>)[2-]) ;
+ FStripCommon $(<) : $(>) ;
+ }
+}
+
+# Append suffix if there is not already one
+# E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
+# returns (yacc,lex,foo.bat) on Unix and
+# (yacc.exe,lex.exe,foo.bat) on NT.
+# FAppendSuffix files : suffix ;
+rule FAppendSuffix
+{
+
+ if $(>)
+ {
+ local _i _o ;
+
+ for _i in $(<)
+ {
+ if $(_i:S)
+ {
+ _o += $(_i) ;
+ }
+ else
+ {
+ _o += $(_i:S=$(>)) ;
+ }
+ }
+ return $(_o) ;
+ }
+ else
+ {
+ return $(<) ;
+ }
+}
+
+# return a1 a2 ... with any empty elements deleted
+# FDelEmpty a1 a2 ... ;
+rule FDelEmpty
+{
+
+ local _i _o = ;
+ for _i in $(<)
+ {
+ if $(_i) {
+ _o += $(_i) ;
+ }
+ }
+ return $(_o) ;
+}
+
+#
+# Operating system specific utility rules
+# First, the (generic) UNIX versions
+#
+
+rule FQuote { return \\\"$(<)\\\" ; }
+rule FDefines { local _t = [ FDelEmpty $(<) ] ; return -D$(_t) ; }
+rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return -I$(_t) ; }
+
+if $(OS2)
+{
+ rule FQuote { return \"$(<)\" ; }
+ rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return /I$(_t) ; }
+}
+
+else if $(NT)
+{
+ if ! $(MINGW) {
+ rule FDefines { local _t = [ FDelEmpty $(<) ] ; return /D$(_t) ; }
+ rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return /I$(_t) ; }
+ }
+}
+
+else if $(MAC)
+{
+ rule FQuote { return \"$(<)\" ; }
+ rule FDefines { local _t = [ FDelEmpty $(<) ] ; return "-define '$(_t)'" ; }
+ rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return \"$(_t:J=,)\" ; }
+}
+
+else if $(VMS)
+{
+ rule FQuote { return \"\"\"$(<)\"\"\" ; }
+ rule FDefines { local _t = [ FDelEmpty $(<) ] ; return "/define=( $(_t:J=,) )" ; }
+ rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return "/inc=( $(_t:J=,) )" ; }
+
+ rule FDirName
+ {
+ local _s _i ;
+
+ # Turn individual elements in $(<) into a usable path.
+
+ if ! $(<)
+ {
+ _s = $(DOT) ;
+ }
+ else
+ {
+ # This handles the following cases:
+ # a -> [.a]
+ # a b c -> [.a.b.c]
+ # x: -> x:
+ # x: a -> x:[a]
+ # x:[a] b -> x:[a.b]
+
+ switch $(<[1])
+ {
+ case *:* : _s = $(<[1]) ;
+ case \\[*\\] : _s = $(<[1]) ;
+ case * : _s = [.$(<[1])] ;
+ }
+
+ for _i in [.$(<[2-])]
+ {
+ _s = $(_i:R=$(_s)) ;
+ }
+ }
+
+ return $(_s) ;
+ }
+}
+
+#
+# Actions
+#
+
+#
+# First the defaults
+#
+
+actions updated together piecemeal Archive
+{
+ $(AR) $(<) $(>)
+}
+
+actions together ArchiveArchive
+{
+ mkdir .jamArchiveArchive$PPID
+ cp $(>) .jamArchiveArchive$PPID
+ cd .jamArchiveArchive$PPID
+ for i in $(>:BS)
+ do
+ ar -xo $i
+ done
+ cd ..
+ ar -r $(<) .jamArchiveArchive$PPID/*.o
+ rm -rf .jamArchiveArchive$PPID
+}
+
+actions As
+{
+ $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
+}
+
+actions C++_
+{
+ $(C++) -c -o $(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
+}
+
+actions Cc_
+{
+ $(CC) -c -o $(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
+}
+
+actions Chgrp_
+{
+ $(CHGRP) $(GROUP) $(<)
+}
+
+actions Chmod1
+{
+ $(CHMOD) $(MODE) $(<)
+}
+
+actions Chown_
+{
+ $(CHOWN) $(OWNER) $(<)
+}
+
+actions piecemeal together existing Clean
+{
+ $(RM) $(>)
+}
+
+actions File_
+{
+ $(CP) $(>) $(<)
+}
+
+#actions FakeFile_ { }
+
+actions GenFile1
+{
+ $(>[1]) $(<) $(>[2-])
+}
+
+actions GenFileND1
+{
+ $(>)
+}
+
+actions GenFileNND1
+{
+ $(>)
+}
+
+actions CreateCatFile_
+{
+ $(CP) /Y nul $(<) > nul
+}
+
+actions CatToFile_
+{
+ echo $(>) >> $(<)
+}
+
+actions Fortran_
+{
+ $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)
+}
+
+actions HardLink_
+{
+ $(RM) $(<) && $(LN) $(>) $(<)
+}
+
+actions Install
+{
+ $(CP) $(>) $(<)
+}
+
+actions Lex_
+{
+ $(LEX) $(>)
+}
+
+actions LexMv_
+{
+ $(MV) lex.yy.c $(<)
+}
+
+# Old: $(LINK) $(LINKFLAGS) $(LINKOUTFLAG)$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS)
+# $(LINK) $(LINKOUTFLAG)$(<) $(UNDEFS) $(>) $(LINKFLAGS) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS)
+actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS
+{
+ $(LINK) $(LINKOUTFLAG)$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(LINKFLAGS) $(STDLIBS)
+}
+
+if $(OS) = MACOSX { # OS X version of ld
+
+ # Link .o and .a into a .dylib
+ # gcc -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.0,-current_version,1.0,-install_name,/usr/local/lib/libfoo.1.dylib -o libfoo.1.dylib $(OBJ)
+ # -Wl,-install_name,@executable_path ???
+ actions ShLink_
+ {
+ $(LINK) -dynamiclib -Wl,-undefined,dynamic_lookup,-install_name,$(SHLINKSEARCHEXEPATH)$(<[1]:BS) $(LINKOUTFLAG)$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHLINKFLAGS) $(SHSTDLIBS)
+ }
+
+} else { # General gcc
+
+ # Link .o and .a into a .so
+ # To set .so search path: -Wl,-rpath,$(LINKSHLIBS:D)
+ # or set LD_LIBRARY_PATH
+ # or set /etc/ld.so.conf.d/*.conf
+ # To set .so search path (after flag): -Wl,-soname=$(<[1]:BS)
+# Old: $(LINK) -shared -Wl,-soname=$(SHLINKSEARCHEXEPATH)$(<[1]:BS) $(SHLINKFLAGS) $(LINKOUTFLAG)$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS)
+ actions ShLink_
+ {
+ $(LINK) -shared -Wl,-soname=$(SHLINKSEARCHEXEPATH)$(<[1]:BS) $(LINKOUTFLAG)$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHLINKFLAGS) $(SHSTDLIBS)
+ }
+}
+
+actions MkDir1
+{
+ $(MKDIR) $(<)
+}
+
+actions together Ranlib
+{
+ $(RANLIB) $(<)
+}
+
+actions quietly updated piecemeal together RmTemps_
+{
+ $(RM) $(>)
+}
+
+actions Shell_
+{
+ $(AWK) '
+ NR == 1 { print "$(SHELLHEADER)" }
+ NR == 1 && /^[#:]/ { next }
+ /^##/ { next }
+ { print }
+ ' < $(>) > $(<)
+}
+
+actions SoftLink_
+{
+ $(RM) $(<) && $(LN) -s $(>) $(<)
+}
+
+actions Yacc1_
+{
+ $(YACC) $(YACCFLAGS) $(>)
+}
+
+actions YaccMv_
+{
+ $(MV) $(YACCFILES).c $(<[1])
+ $(MV) $(YACCFILES).h $(<[2])
+}
+
+actions Aswig1_
+{
+ aswig $(ASWIGFLAGS) -c++ -a2c $(>)
+}
+
+#
+# RELOCATE - for compilers with broken -o flags
+#
+
+if $(RELOCATE)
+{
+ actions C++_
+ {
+ $(C++) -c $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions Cc_
+ {
+ $(CC) -c $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions ignore CcMv
+ {
+ [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
+ }
+}
+
+#
+# NOARUPDATE - can't update an archive
+#
+
+if $(NOARUPDATE)
+{
+ actions Archive
+ {
+ $(AR) $(<) $(>)
+ }
+}
+
+#
+# UNIX specific actions
+#
+
+if $(UNIX)
+{
+ actions GenFile1
+ {
+ PATH="$PATH:."
+ $(>[1]) $(<) $(>[2-])
+ }
+
+ actions CreateCatFile_
+ {
+ $(CP) /dev/null $(<)
+ }
+
+ actions CatToFile_
+ {
+ echo "$(>)" >> $(<)
+ }
+
+ # Make OS X GUI apps work
+ if $(OS) = MACOSX
+ {
+
+ # Used to use /Developer/Tools/Rez -t APPL Carbon.r -o $(<)
+ # but this no longer works in OS X 10.5, and we don't need this
+ # stuff with TransformProcessType()
+ # Another alternative is to use link option "-sectcreate __TEXT __info_plist Info.plist" ???
+ # to embed the plist in the executable, but not sure what should be in plist.
+ # Pure GUI app
+ actions GUIAPP
+ {
+ rm -rf $(<).app
+ mkdir -p $(<).app
+ mkdir $(<).app/Contents
+ mkdir $(<).app/Contents/Resources
+ mkdir $(<).app/Contents/MacOS
+ echo APPLnone > $(<).app/Contents/PkgInfo
+ mv $(<) $(<).app/Contents/MacOS
+ chmod 755 $(<).app/Contents/MacOS/$(<:BS)
+ cat << EOF > $(<).app/Contents/info.plist
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleName</key>
+ <string>$(<:BS)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleVersion</key>
+ <string>59</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.1</string>
+ <key>CFBundleSignature</key>
+ <string>none</string>
+</dict>
+</plist>
+EOF
+ cat << EOF > $(<)
+#!/bin/sh
+\$0.app/Contents/MacOS/$(<:BS)
+EOF
+ chmod 755 $(<)
+ }
+ }
+}
+
+#
+# NT specific actions
+#
+
+if $(NT)
+{
+ # Ensure timestamp is updated
+
+ actions File_
+ {
+ $(CP) /b $(>) + nul $(<) > nul
+ }
+
+ actions Install
+ {
+ $(CP) /b $(>) + nul $(<) > nul
+ }
+}
+
+if $(NT) && $(MSVCNT)
+{
+# actions updated together piecemeal Archive
+# {
+# if exist $(<) set _$(<:B)_=$(<)
+# $(AR) /out:$(<) %_$(<:B)_% $(>)
+# }
+
+ # This is slightly dodgy if you've got multiple
+ # libraries with the same name in different directories with
+ # jam -j n, or you have .obj's distinguished only by their directory
+ # being combined into the same library, but it overcomes
+ # the problem of lib not updating a library properly if
+ # jam is involked from different directories.
+ actions updated together piecemeal Archive
+ {
+ if exist $(<:BS)_ RMDIR /S/Q $(<:BS)_
+ MKDIR $(<:BS)_
+ for %%i in ( $(>) ) do COPY %%i $(<:BS)_ 1>nul
+ if exist $(<) set _$(<:B)_=$(<)
+ $(AR) /out:$(<) %_$(<:B)_% $(<:BS)_\*
+ DEL /F/S/Q $(<:BS)_\* 1>nul
+ RMDIR /Q $(<:BS)_
+ }
+
+ actions together ArchiveArchive
+ {
+ $(AR) /out:$(<) $(>)
+ }
+
+ actions As
+ {
+ $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;
+ }
+
+ actions Cc_
+ {
+ $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>)
+ }
+
+ actions C++_
+ {
+ $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp $(>)
+ }
+
+ actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS
+ {
+ $(LINK) $(LINKFLAGS) $(P_LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS)
+ }
+
+ # Create DLL using export attribute
+ actions ShLink_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS
+ {
+ $(LINK) /DLL $(SHLINKFLAGS) /out:$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS)
+ }
+
+ # Create DLL using .def file
+ actions ShLinkDef_ bind SHLINKDEFFILE SHLINKOBJS SHLINKLIBS SHLINKSHLIBS
+ {
+ $(LINK) /DLL /DEF:$(SHLINKDEFFILE) $(SHLINKFLAGS) /out:$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS)
+ }
+}
+else if $(NT) && $(MSVC)
+{
+ actions updated together piecemeal Archive
+ {
+ $(AR) $(<) -+$(>)
+ }
+
+ actions Cc_
+ {
+ $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions C++_
+ {
+ $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /Tp $(>)
+ }
+
+ actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS
+ {
+ $(LINK) $(LINKFLAGS) $(P_LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS)
+ }
+}
+else if $(NT) && $(BCCROOT)
+{
+ actions updated together piecemeal Archive
+ {
+ $(AR) $(<) -+$(>)
+ }
+
+ actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS
+ {
+ $(LINK) -e$(<) $(LINKFLAGS) $(P_LINKFLAGS) $(UNDEFS) -L$(STDLIBS) $(LINKLIBS) $(LINKSHLIBS) $(>) $(LINKOBJS)
+ }
+
+ actions C++_
+ {
+ $(C++) -c -o$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions Cc_
+ {
+ $(CC) -c -o$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+}
+
+else if $(NT) && $(MINGW) {
+
+ # Create DLL using export attribute
+ actions ShLink_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS
+ {
+ $(LINK) -shared $(SHLINKFLAGS) $(LINKOUTFLAG)$(<[1]) -Wl,--out-implib,$(<[2]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS)
+ }
+ # Create DLL using .def file
+ actions ShLinkDef_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS SHLINKDEFFILE
+ {
+ $(LINK) -shared $(SHLINKFLAGS) $(LINKOUTFLAG)$(<[1]) -Wl,--out-implib,$(<[2]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS) $(SHLINKDEFFILE)
+ }
+}
+
+#
+# OS2 specific actions
+#
+
+else if $(OS2) && $(WATCOM)
+{
+ actions together piecemeal Archive
+ {
+ $(AR) $(<) +-$(>)
+ }
+
+ actions Cc_
+ {
+ $(CC) /Fo=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions C++_
+ {
+ $(C++) /Fo=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS
+ {
+ $(LINK) $(LINKFLAGS) $(P_LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS)
+ }
+
+ actions Shell_
+ {
+ $(CP) $(>) $(<)
+ }
+}
+
+#
+# VMS specific actions
+#
+
+else if $(VMS)
+{
+ actions updated together piecemeal Archive
+ {
+ lib/replace $(<) $(>[1]) ,$(>[2-])
+ }
+
+ actions Cc_
+ {
+ $(CC)/obj=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions C++_
+ {
+ $(C++)/obj=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
+ }
+
+ actions piecemeal together existing Clean
+ {
+ $(RM) $(>[1]);* ,$(>[2-]);*
+ }
+
+ actions together quietly CreLib
+ {
+ if f$search("$(<)") .eqs. "" then lib/create $(<)
+ }
+
+ actions GenFile1
+ {
+ mcr $(>[1]) $(<) $(>[2-])
+ }
+
+ actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS
+ {
+ $(LINK)/exe=$(<) $(LINKFLAGS) $(P_LINKFLAGS) $(>:J=,) ,$(LINKOBJS:J=,) ,$(LINKLIBS)/lib ,$(LINKSHLIBS)/lib ,$(STDLIBS)
+ }
+
+ actions quietly updated piecemeal together RmTemps_
+ {
+ $(RM) $(>[1]);* ,$(>[2-]);*
+ }
+
+ actions Shell_
+ {
+ $(CP) $(>) $(<)
+ }
+}
+
+#
+# Mac specifc actions
+#
+
+else if $(MAC)
+{
+ actions together Archive
+ {
+ $(LINK) -library -o $(<) $(>)
+ }
+
+ actions Cc_
+ {
+ set -e MWCincludes $(CCHDRS)
+ $(CC) -o $(<) $(CCFLAGS) $(CCDEFS) $(>)
+ }
+
+ actions C++_
+ {
+ set -e MWCincludes $(CCHDRS)
+ $(CC) -o $(<) $(C++FLAGS) $(CCDEFS) $(>)
+ }
+
+ actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS
+ {
+ $(LINK) -o $(<) $(LINKOBJS) $(LINKFLAGS) $(P_LINKFLAGS) $(>) $(LINKLIBS) $(LINKSHLIBS) "$(STDLIBS)"
+ }
+}
+
+if $(WIN98)
+{
+ actions existing Clean
+ {
+ del $(>)
+ }
+}
+
+# =========================================
+
+# Now do Argyll init and read default Jamtop
+DoInit ;
+
+#
+# Now include the user's Jamfile.
+#
+
+#PeerInclude $(DOT) ;
+SubInclude $(DOT) ;
+