From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- Jambase | 4541 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4541 insertions(+) create mode 100644 Jambase (limited to 'Jambase') 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 .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 + + + + + CFBundleName + $(<:BS) + CFBundlePackageType + APPL + CFBundleVersion + 59 + CFBundleShortVersionString + 1.1 + CFBundleSignature + none + + +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) ; + -- cgit v1.2.3