1# 2# /+\ 3# +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. 4# \+/ 5# 6# This file is part of Jam - see jam.c for Copyright information. 7# 8 9# The Copyright information in jam.c reads: 10# 11#/* 12# * /+\ 13# * +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. 14# * \+/ 15# * 16# * This file is part of jam. 17# * 18# * License is hereby granted to use this software and distribute it 19# * freely, as long as this copyright notice is retained and modifications 20# * are clearly marked. 21# * 22# * ALL WARRANTIES ARE HEREBY DISCLAIMED. 23# */ 24 25# MODIFIDED version of jam 2.5 Jambase, for the ArgyllCMS project by Graeme W. Gill. 26# These modifications are herebye licensed under the same conditions 27# as as the rest of Jam, as detailed above. 28# Moved to a "Normalized" scheme, where Jamfile UNIX style target paths 29# are converted to platform specific, Jamfile relative, Gristed/SEARCH/LOCATE 30# form internally. Creating the tree is simplified by eliminating the SubDir 31# rule. Better support for MingW, OS X. More comprehensive ruleset. 32# Renamed Jamrules to Jamtop. 33# 34# JAMBASE - jam 2.5 ruleset providing make(1)-like functionality 35# 36# Supports UNIX, NT, and VMS. 37# 38# Special targets defined in this file: 39# 40# all - parent of first, shell, files, lib, exe 41# first - first dependent of 'all', for potential initialization 42# shell - parent of all Shell targets 43# files - parent of all File targets 44# lib - parent of all Library targets 45# exe - parent of all Main targets 46# dirs - parent of all MkDir targets 47# install - parent of all Install targets 48# clean - removes all Shell, File, Library, and Main targets 49# uninstall - removes all Install targets 50# 51 52# Rules defined by this file: 53# 54# As obj : source.s ; .s -> .o 55# Bulk dir : files ; populate directory with many files 56# Cc obj : src.c : flags : defines : hdrpaths 57# .c -> .o 58# C++ obj : src.cc : flags : defines : hdrpaths 59# .cc -> .o 60# Clean clean : sources ; remove sources with 'jam clean' 61# File dest : source ; copy file 62# FileNoClean dest : source ; copy file, but don't delete dest during clean 63# FakeFile dest : source ; Fudge to say dest is created with source 64# Fortran obj.o : source.f ; .f -> .o 65# GenFile target : program args ; make custom file 66# GenFileND target : program args : extra_dependecies ; 67# make custom file, program dependent & args not 68# GenFileNND target : program args : extra_dependecies ; 69# make custom file, program & args not dependent 70# GenFileNNDnc target : program args : extra_dependecies ; 71# Same as GenFileNND but don't clean the target. 72# CatToFile dest : strings ; save the arguments to the file 73# GuiBin image ; Mark executable as GUI applications 74# (Needs to go before other declarations of image) 75# HardLink target : source ; make link from source to target 76# HdrRule source : headers ; handle #includes 77# InstallInto dir : sources ; install any files 78# InstallBin dir : sources ; install binaries 79# InstallLib dir : sources ; install files 80# InstallShLib dir : sources ; install files 81# InstallFile dir : sources ; install files 82# InstallMan dir : sources ; install man pages 83# InstallShell dir : sources ; install shell scripts 84# Lex source.c : source.l ; .l -> .c 85# Library library : sources : flags : defines : hdrpaths : objects 86# static library from compiled sources 87# LibraryFromLibraries lib : libs ; static library from static libraries 88# LibraryFromObjects lib : objects ; static library from objects 89# LinkLibraries images : libraries ; add static libraries onto Mains 90# LinkObjects images : objects ; add objects onto Mains 91# LinkShLibraries images : shlibraries ; add shared libraries onto Mains 92# Main image : sources : flags : defines : hdrpaths : objects : libs : shlibs ; 93# create exe from compiled sources 94# MainsFromSources sources ; create exes each from their source 95# MainFromObjects image : objects : libs : shlibs ; 96# create executable from objects 97# MainVariant image : sources : flags : defines : hdrpaths : objects : libs : shlibs ; 98# create exe from compiled sources with separate named objs 99# MainLinkFlags mains : flags ; add linker flags for object 100# MkDir dir ; make a directory, if not there 101# Mod target : mode ; sets mode of file 102# NDepends dest : source ; make Normalized dependency 103# NNoUpdate targ ; create Normalized target if needed but never update it 104# NIncludes dest : source ; make Normalized co-dependency 105# Object object : sources : flags : defines : hdrpaths ; compile object from source 106# ObjectCcFlags objects : flags ; add compiler flags for object 107# ObjectPrefCcFlags objects : flags ; add preference compiler flags for object (overridable) 108# ObjectC++Flags objects : flags ; add compiler flags for object 109# ObjectPrefC++Flags objects : flags ; add preference compiler flags for object (overridable) 110# ObjectDefines objects : defines ; add defines for object 111# ObjectHdrs objects : dirs ; add include directories for object 112# ObjectKeep objects ; mark objects to be kept after library build 113# Objects sources : flags : defines : hdrpaths compile sources 114# PeerInclude dir ; include peer Jamfile 115# FindTop ; Set TOP by locating JAMTOP file above SUBDIR 116# ProjTop d1 d2 .. ; Set project TOP 117# RmTemps target : sources ; remove temp sources after target made 118# Setuid images ; mark executables Setuid 119# set SHLINKDEFFILE on for Windows to define exports using .def file. 120# set SHLINKSEARCHEXEPATH true on UNIX/OSX to have applications search exeutable location for it 121# ShLibrary shlib : source ; link shared library from compiled sources 122# ShLibraryFromObjects shlib : objects ; link shared library from objects 123# ShLibraryLibraries shlib : libraries ; add static libraries onto shared libraries link 124# ShLibraryObjects shlib : objects ; add objects onto shared libraries link 125# ShLibraryShLibraries shlib : shlibraries ; add shared libraries onto shared libraries link 126# SoftLink target : source ; make symlink from source to target 127# SubInclude dir ; include sub Jamfile 128# Shell exe : source ; make a shell executable 129# Undefines images : symbols ; save undef's for linking 130# UserObject object : source ; handle unknown suffixes for Object 131# Yacc source.c : source.y ; .y -> .c 132# Aswig : source.i ; .i -> .h _i.c .hpp 133# 134# Utility rules 135# 136# val = geton var : varname ; return the value of varname on var 137# paths = NormPaths paths [ : dir ] ; normalize a set of paths relative to SUBDIR or dir 138# paths = NormSrcPaths paths [ : dir ] ; NormPaths with SRCDIR 139# paths = NormDstPaths paths [ : dir ] ; NormPaths with DSTDIR 140# paths = NormSrcTargets paths [ : dir ] ; normalize source targets, set Grist NOMLOC SEARCH 141# paths = NormDstTargets paths [ : dir ] ; normalize destination targets, set Grist NOMLOC LOCATE 142# paths = NormISrcTargets paths [ : dir ] ; Same as NormSrcTargets but ignore SRCDIR 143# paths = NormIDstTargets paths [ : dir ] ; Same as NormDstTargets but ignore DSTDIR 144# 145# More utility rules that have no side effects : 146# 147# FAppendSuffix f1 f2 ... : $(SUF) ; return $(<) with suffixes if no current suffixes 148# FStripCommon v1 : v2 ; strip common initial parts of v1 v2 149# FReverse a1 a2 ... ; return ... a2 a1 150# FDelEmpty a1 a2 ... ; return a1 a2 ... with any empty elements deleted 151# 152# Variables: 153# 154# Sub-Jamfile build variables, optionaly set in each Sub-Jamfile. They will 155# be picked up by subsequent rules that set target relationships and 156# creation rules. They are added to any Parent-Jamfile variables, 157# and become the Parent-Jamfile variables of any SubIncludes. 158# Relative file/path variables are anchored by the Jamfile location. 159# 160# ASFLAGS - Flags for the assembler. 161# CCFLAGS - Flags for the C compiler. 162# C++FLAGS - Flags for the C++ compiler. 163# LINKFLAGS - Flags for the executable linker. 164# SHLINKFLAGS - Flags for the shared library linker. 165# HDRS - Complile header search directories 166# DEFINES - Compile defines 167# LINKOBJS - Link extra objects 168# LINKLIBS - Link extra libraries 169# LINKSHLIBS - Link extra shared libraries 170# SHLINKOBJS - ShLibrary Linker extra objects 171# SHLINKLIBS - ShLibrary Linker extra libraries 172# SHLINKSHLIBS - ShLibrary Linker extra shared libraries 173# 174# Sub-directory preferred build flags, e.g. optimizations etc. These will only 175# have effect if not set by a parent Jamfile (ie. involked from a leaf Jamfile). 176# 177# PREF_ASFLAGS 178# PREF_CCFLAGS 179# PREF_C++FLAGS 180# PREF_LINKFLAGS 181# PREF_SHLINKFLAGS 182# 183# Parent-Jamfile build variables. These are the accumulated 184# values from any Parent Jamfiles, and will be added to any 185# Sub-Jamfile variables when a rule picks them up. 186# File/path variables will have been normalized. 187# 188# P_ASFLAGS - Flags for the assembler. 189# P_CCFLAGS - Flags for the C compiler. 190# P_C++FLAGS - Flags for the C++ compiler. 191# P_LINKFLAGS - Flags for the executable linker. 192# P_SHLINKFLAGS - Flags for the shared library linker. 193# P_HDRS - Complile header search directories 194# P_DEFINES - Compile defines 195# P_LINKOBJS - Link extra objects 196# P_LINKLIBS - Link extra libraries 197# P_LINKSHLIBS - Link extra shared libraries 198# P_SHLINKOBJS - ShLibrary Linker extra objects 199# P_SHLINKLIBS - ShLibrary Linker extra libraries 200# P_SHLINKSHLIBS - ShLibrary Linker extra shared libraries 201# 202# Pre-defined values 203# 204# Pre-packaged flags that conceal platform dependence, 205# and are used to set CCFLAGS/C++FLAGS/LINKFLAGS/SHLINLFLAGS etc. 206# 207# CCOPTFLAG - CC/C++ flag for optimization 208# CCDEBUGFLAG - CC/C++ flag for debug 209# CCPROFFLAG - CC/C++ flag for performance profiling 210# CCSHOBJFLAG - CC/C++ flag for compiling for a shared library (UNIX) 211# 212# LINKOPTFLAG - LINK flag for optimization of the binary/shared library 213# LINKDEBUGFLAG - LINK flag to support debugging 214# LINKPROFFLAG - LINK flag to support performance profiling 215# LINKSTRIPFLAG - LINK flag to strip binary of any symbols 216# 217# Location variables: 218# 219# DSTDIR - puts all products in a subdirectory of their nominated location. 220# Useful for storing variants in their own areas. 221# 222# SRCDIR - Looks for all sources and Jamfiles in an alternate top level source 223# location. Useful for accessing a read only source repository, or 224# building a variant without copying all the sources. 225# Note that at least the project Jamtop must be in the location 226# that is the target for the build, and will most likely be where 227# SRCDIR is set. SRCDIR is the location of the sources relative 228# to where it is declared. 229# (Not currently useful for a shadow build repository where the source 230# is spread between the SRCDIR and the build dir, because Jam 2.5 fails 231# to look at SEARCH if LOCATE is set). 232# 233# ========================================================================= 234# ArgyllCMS Normalize mods: 235# 236# The main change is to locate and identify targets using their nominated location in the 237# filesystem. This eliminates the need to create Grist, or manipulate SEARCH, LOCATE etc. 238# when setting up a herachy of Jamfiles. 239# 240# Whenever a path is provided as an argument to one of the public rules, its path is assumed 241# to be relative to the Jamfile that it is declared in. [ The NormPaths/NormTargets rules do this. ] 242# Naturally absolute paths are not affected by this. 243# During execution this means that all files are translated to paths that are 244# in a normalized form, with either an absolute path or one that is relative to 245# the directory that Jam was involked in. For simplicity it is assumed that 246# the Jamfile contains UNIX style paths, and these are converted to the 247# platform specific form on normalization. 248# 249# For a target, the normalized directory is then stripped from the name and 250# set as the Grist (path elements separated by !), and also set in the NOMLOC, 251# LOCATE and SEARCH variables "on" the target. This gives a target a unique 252# identity for the whole of the build, determined by its nominated file system location. 253# The NOMLOC variable is a way of recovering it's location without having the reverse 254# the Grist strings. The actual location of the target can then be varied by 255# augmenting it's LOCATE and/or SEARCH variables. 256# 257# Any include file discovered by header scanning is searched for using the 258# search path that is expected to be used during compilation, and 259# its nominated location resolved this way. Any headers that are not 260# located this way or who's location isn't declared by another rule (the 261# latter being typical when headers are being generated) will be marked as 262# being in an __unknown__ directory and will not be scaned. Normally any 263# header files located in the STDHDRS directories will not be scanned either. 264# 265# [ Typically headers will be __unknown__ if the STDHDRS directories do 266# not reflect the default paths actually searched by the compiler, or if a 267# header is not actually going to be #included because it is protected 268# by an #ifdef. ] 269 270# Argyll Jambase internal implementation rules: 271 272# IDs = _TargetIDs targpaths ; return target ID's (gristed) from normalized paths 273# path = DeNormTargs target ; return the original path 274# CopyTarget dest : source ; duplicate a targets on NOMLOC LOCATE SEARCH variables. 275# NotTargets vars ; ensure variables aren't treated as LOCATE etc targets 276 277# d1 d2 ... file = _SepPath path ; separate a path into its components 278# path = _DirName d1 d2 ... ; combine components into a path 279# d1 d2 .. = _RatPath d1 d2 .. rationalize a path 280# d1 d2 .. = _RootPath d1 d2 .. : p1 p2 ... re-root a path 281# paths = RatPaths paths ; rationalize a set of paths 282# paths = RootPaths dir : paths ; re-root a set of paths 283# targs = CreateIDstTargets targs : dir ; create dest targets by locating targets in dir 284# paths1/paths = CatPaths path1 : paths ; concatenate paths separated by a / 285# found = FindToRoot starting_dir : file ; Try and locate file from directory up to root. 286 287# FindTop ; # Look for a default project file 288 289# DoInit ; Do subdir initialization (done by JAMBASE) 290 291# public write/read Variables: 292# 293# TRACESTDHDRS # Normally false, set to true to trace system path #include file dependenicies 294 295# public read only Variables: 296# 297# SUBDIR d1/d2/d3 # Current path from PWD to Jamfile 298# TOP d1/d2/d3 # Current path from PWD to the project Jamtop 299 300# internal variables 301# 302# _SUBDIR d1 d2 d3 ... # Current path from PWD to Jamfile 303# _TOP d1 d2 d3 # Current path from PWD to the project Jamtop 304 305# - - - - - - - - - - - - - - - 306 307# NOTE: Cross compiling support :- 308# To fix this to support cross compilation, the setup needs to be 309# modularised into 3 parts, making them all rules that can be re-involked: 310# 1) OS/Platform setup. System tools like copy, delete etc. 311# 2) Compiler setup. Basic compiler syntax etc. 312# 3) Target setup. Make this a rule, and allow switching 313# target by involking the rule. This will be simpler to 314# get working that per target 'on' variable (some 315# things are currently broken for 'on' variables, such 316# as library members, and it will be easier to do 317# things such as switch compilers. 318 319# - - - - - - - - - - - - - - - 320 321 322# Brief review of the jam language: 323# 324# Statements: 325# rule RULE - statements to process a rule 326# actions RULE - system commands to carry out target update 327# 328# Modifiers on actions: 329# together - multiple instances of same rule on target get executed 330# once with their sources ($(>)) concatenated 331# updated - refers to updated sources ($(>)) only 332# ignore - ignore return status of command 333# quietly - don't trace its execution unless verbose 334# piecemeal - iterate command each time with a small subset of $(>) 335# existing - refers to currently existing sources ($(>)) only 336# bind vars - subject to binding before expanding in actions 337# 338# Special rules: 339# Always - always build a target 340# Depends - builds the dependency graph 341# NOTE: can have only one $(<), or parallel builds stuff up!! 342# Use FakeFile to work around the problem. 343# Echo - blurt out targets on stdout 344# Exit - blurt out targets and exit 345# Includes - marks sources as headers for target (a codependency) 346# NoCare - don't panic if the target can't be built 347# NoUpdate - create the target if needed but never update it 348# NotFile - ignore the timestamp of the target (it's not a file) 349# Temporary - target need not be present if sources haven't changed 350# 351# Special variables set by jam: 352# $(<) - targets of a rule (to the left of the :) 353# $(>) - sources of a rule (to the right of the :) 354# $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC) 355# $(OS) - name of OS - varies wildly 356# $(JAMVERSION) - version number (2.5) 357# 358# Special variables used by jam: 359# SEARCH - where to find something (used during binding and actions) 360# LOCATE - where to plop something not found with SEARCH 361# HDRRULE - rule to call to handle include files 362# HDRSCAN - egrep regex to extract include files 363# 364# Special targets: 365# all - default if none given on command line 366# 367 368# for perforce use -- jambase version 369 370JAMBASEDATE = 2008.03.26 ; 371 372# Initialize variables 373# 374 375# =========================================================== 376# 377# OS specific variable settings 378# 379 380if $(NT) 381{ 382 MV ?= move /y ; 383 CP ?= copy ; 384 RM ?= del /f/q ; 385 RMDIR ?= rmdir /s/q ; 386 SLASH ?= \\ ; 387 SUFLIB ?= .lib ; 388 SUFSHLIB ?= .dll ; 389 SUFIMPLIB ?= .lib ; 390 SUFOBJ ?= .obj ; 391 SUFEXE ?= .exe ; 392 SUFSH ?= .bat ; 393 CCSHOBJFLAG ?= ; 394 395 if $(BCCROOT) 396 { 397 AR ?= tlib /C /P64 ; 398 CC ?= bcc32 ; 399 CCFLAGS ?= -v -w- -q -DWIN -tWR -tWM -tWC ; 400 C++ ?= $(CC) ; 401 C++FLAGS ?= $(CCFLAGS) -P ; 402 LINK ?= $(CC) ; 403 LINKFLAGS ?= ; 404 STDLIBPATH ?= $(BCCROOT)\\lib ; 405 STDHDRS ?= $(BCCROOT)\\include ; 406 NOARSCAN ?= true ; 407 } 408 else if $(MingW) || $(MINGW) 409 { 410 # We need to do something about adding -Wl,-subsystem,windows 411 # if WinMain is being used ? (it defaults to console) 412 413 MINGW ?= $(MingW) ; 414 TPFX = "" ; 415 416 if [ GLOB $(MINGW)/bin : x86_64-w64-mingw32-gcc.exe ] { 417 MINGW64 = $(MINGW) ; 418 } 419 420 # This doesn't work on a 32 bit system because we're cross 421 # compiling and need to create build system exe's 422 # (tiff/mkversion.exe, imdi/imdi_make.exe 423 # Will using -m32 for local exe's fix this ? 424 # What is multi-lib option ??? 425 if $(MINGW64) { 426 ECHO "Compiler is MingW for 64 bit target" ; 427 TARGET64 = true ; 428 TPFX = x86_64-w64-mingw32- ; 429 MINGW64_LIB32 = $(MINGW)/mingw/lib32 ; 430 } else { 431 ECHO "Compiler is MingW for 32 bit target" ; 432 } 433 434 435 # Basic C/C++ tools 436 AR ?= $(TPFX)ar rusc ; 437 AS ?= $(TPFX)as ; 438 CC ?= $(TPFX)gcc ; 439 CCFLAGS ?= -DNT -mwin32 -pipe ; 440 C++ ?= $(CC) ; 441 C++FLAGS ?= $(CCFLAGS) ; 442 443 OLELIBS ?= -loleaut32 -luuid ; 444 BASELIBS ?= -lstdc++ -lgcc -lodbc32 -lwsock32 ; 445# WINLIBS ?= -lwinspool -lwinmm -lshell32 -lcomctl32 -lctl3d32 446# -lodbc32 -ladvapi32 -lodbc32 -lwsock32 -lopengl32 447# -lglu32 -lshlwapi -lsetupapi ; 448 WINLIBS ?= -lshlwapi -lsetupapi -lole32 -lws2_32 -lpsapi -lversion ; 449 GUILIBS ?= -lgdi32 -lmscms ; 450 451 LINK ?= $(TPFX)g++ ; # In case we link to C++ files 452 LINKFLAGS ?= -static ; 453 SHLINKFLAGS ?= ; 454 STDLIBS ?= -lm $(OLELIBS) $(WINLIBS) $(GUILIBS) ; 455 SHSTDLIBS ?= $(STDLIBS) ; 456 457 STDHDRS ?= $(MINGW)\\include ; 458 459 # Not sure whether linker -mconsole or -mwindow are needed ?? 460 461 # Allow setting of flags, independent of compiler 462 DEFFLAG ?= -D ; 463 UNDEFFLAG ?= -U ; 464 CCOPTFLAG ?= -O3 ; 465 if $(PROCESSOR_LEVEL) = 15 466 { # -mtune seems faster than -march !!! 467# CCOPTFLAG += -mtune=pentium4 ; 468# CCOPTFLAG += -mtune=prescott ; 469 CCOPTFLAG += -mtune=nocona ; # portable code for Pentium4 640 470# CCOPTFLAG += -march=nocona -mfpmath=sse -msse3 ; # non-portable 471 472 } 473 474 CCDEBUGFLAG ?= -g ; # default (TABS? DWARF2 ?) format 475 CCPROFFLAG ?= -pg ; 476 LINKDEBUGFLAG ?= -g ; 477 LINKPROFFLAG ?= -pg ; 478 LINKOPTFLAG ?= -s -O ; # Affects creating .so's ?? 479 LINKSTRIPFLAG ?= -s ; 480 481 # Other tools 482 AWK ?= awk ; 483 SED ?= sed ; 484 485# YACC ?= yacc ; 486# YACCFLAGS ?= -d ; 487# YACCFILES ?= y.tab ; 488 489 YACC ?= bison -y ; 490 YACCGEN ?= .c ; 491 YACCFILES ?= y.tab ; 492 YACCFLAGS ?= -d ; 493 } 494 else if $(MSVC) # 495 { 496 ECHO "Compiler is VC++ 16 bit" ; 497 AR ?= lib /nologo ; 498 CC ?= cl /nologo ; 499 CCFLAGS ?= /D \"WIN\" ; 500 C++ ?= $(CC) ; 501 C++FLAGS ?= $(CCFLAGS) ; 502 LINK ?= $(CC) ; 503 LINKFLAGS ?= ; 504 STDLIBS ?= 505 $(MSVC)\\lib\\mlibce.lib 506 $(MSVC)\\lib\\oldnames.lib 507 ; 508 NOARSCAN ?= true ; 509 STDHDRS ?= $(MSVC)\\include ; 510 DEFFLAG ?= /D ; 511 UNDEFFLAG ?= "/u _" ; 512 } 513 else if $(TARGET_ARCH) 514 { 515 # Intel C++ compiler (ICL) 516 517 # No IA64 dir 518 local I ; I = "" ; 519 520 AR ?= lib /NOLOGO ; 521 AS ?= masm386 ; 522 CC ?= icl /nologo ; 523 CCFLAGS ?= /DNT /MD ; # DLL compatible build by default 524 525 C++ ?= $(CC) ; 526 C++FLAGS ?= $(CCFLAGS) /GX ; # GX enables syncronous exception handling 527 LINK ?= xilink /nologo ; 528 LINKOUTFLAG ?= /out: ; 529 LINKFLAGS ?= ; # iclvars.bat [arch] sets this up 530 531 SHLINKFLAGS ?= ; 532 533 STDLIBS ?= 534 oldnames.lib 535 kernel32.lib 536 advapi32.lib 537 user32.lib 538 mscms.lib 539 gdi32.lib 540 shlwapi.lib 541 shell32.lib 542 setupapi.lib 543 ole32.lib 544 oleaut32.lib 545 ws2_32.lib 546 Wbemuuid.lib 547 ; 548 SHSTDLIBS ?= $(STDLIBS) ; 549 LINKFLAG ?= ; 550 STDHDRS ?= $(ICPP_COMPILER14)\\Include ; 551 DEFFLAG ?= /D ; 552 UNDEFFLAG ?= /U ; 553 CCOPTFLAG ?= /O3 ; 554 555 if $(MSVCVER) = 6 { 556 CCDEBUGFLAG ?= /Od /Z7 ; # Include debugging into in each object 557 CCPROFFLAG ?= /Od /Z7 ; 558 LINKDEBUGFLAG ?= /DEBUGTYPE:BOTH /DEBUG /PDB:NONE ; 559 } else { 560 CCDEBUGFLAG ?= /Od /Zi ; # /Zi creates debugging database 561 CCPROFFLAG ?= /Od /Zi ; 562 LINKDEBUGFLAG ?= /DEBUG ; 563 } 564 LINKPROFFLAG ?= /PROFILE $(LINKDEBUGFLAG) ; 565 LINKOPTFLAG ?= /OPT:REF ; 566 LINKSTRIPFLAG ?= ; 567 YACC ?= bison -y ; 568 YACCGEN ?= .c ; 569 YACCFILES ?= y.tab ; 570 YACCFLAGS ?= -d ; 571 } 572 else if $(MSVCNT) || $(MSVCDIR) || $(MSVCDir) || $(VCINSTALLDIR) 573 { 574 # Visual C++ 8.0/9.0/10.0/11.0/12.0 uses VCINSTALLDIR 575 # We assume VC++ Express + XP32 SDK has been setup 576 577 if $(VCINSTALLDIR) { 578 MSVCNT ?= $(VCINSTALLDIR) ; 579 } else if $(MSVCDir) { 580 MSVCNT ?= $(MSVCDir) ; 581 } else { # Visual C++ 6.0 uses MSVCDIR 582 MSVCNT ?= $(MSVCDIR) ; 583 } 584 585 if [ MATCH 12\\.(.*) : $(VisualStudioVersion) ] { 586 ECHO "Compiler is VC++12 32 bit" ; 587 MSVCVER = 12 ; 588 } else if [ MATCH 11\\.(.*) : $(VisualStudioVersion) ] { 589 ECHO "Compiler is VC++11 32 bit" ; 590 MSVCVER = 11 ; 591 } else if [ MATCH (.*)VC\\+\\+10(.*) : $(MSVCNT) ] { 592 ECHO "Compiler is VC++10 32 bit" ; 593 MSVCVER = 10 ; 594 } else if [ MATCH (.*)VC\\+\\+9(.*) : $(MSVCNT) ] { 595 ECHO "Compiler is VC++9 32 bit" ; 596 MSVCVER = 9 ; 597 } else if [ MATCH (.*)VC\\+\\+8(.*) : $(MSVCNT) ] { 598 ECHO "Compiler is VC++8 32 bit" ; 599 MSVCVER = 8 ; 600 } else { 601 ECHO "Compiler is VC++6 32 bit" ; 602 MSVCVER = 6 ; 603 } 604 605 # Add the SDK include and lib if it is present 606 if $(MSSdk) { 607 MSNTSDK ?= $(MSSdk) ; 608 } else if $(MSSDK) { 609 MSNTSDK ?= $(MSSDK) ; 610 } else if $(MSVCNT) { 611 MSNTSDK ?= $(MSVCNT) ; 612 } 613 614 # bury IA64 in the path for the SDK ??? 615 # (but MSSDK already has this ? 616# local I ; if $(CPU) = "IA64" { I = ia64\\ ; } else { I = "" ; } 617 local I ; I = "" ; 618 619 AR ?= lib /NOLOGO ; 620 AS ?= masm386 ; 621 CC ?= cl /nologo ; 622 CCFLAGS ?= /DNT /MD ; # DLL compatible build by default 623 if $(MSVCVER) >= 8 { 624 CCFLAGS += /D_CRT_SECURE_NO_DEPRECATE=1 625 /D_CRT_NONSTDC_NO_DEPRECATE=1 ; 626 } 627 C++ ?= $(CC) ; 628 C++FLAGS ?= $(CCFLAGS) /GX ; # GX enables syncronous exception handling 629 LINK ?= link /nologo ; 630 LINKOUTFLAG ?= /out: ; 631 LINKFLAGS ?= /INCREMENTAL:NO /LIBPATH:$(MSNTSDK)\\lib\\$(I) ; 632 SHLINKFLAGS ?= ; 633 634 STDLIBS ?= 635 oldnames.lib 636 kernel32.lib 637 advapi32.lib 638 user32.lib 639 mscms.lib 640 gdi32.lib 641 shlwapi.lib 642 shell32.lib 643 setupapi.lib 644 ole32.lib 645 oleaut32.lib 646 ws2_32.lib 647 Wbemuuid.lib 648 Version.lib 649 ; 650 SHSTDLIBS ?= $(STDLIBS) ; 651 LINKFLAG ?= ; 652 STDHDRS ?= $(MSNTSDK)\\Include ; 653 DEFFLAG ?= /D ; 654 UNDEFFLAG ?= /U ; 655 CCOPTFLAG ?= /Ox ; # MSVC9 doesn't understamd GB, G6 ? 656 if $(MSVCVER) = 6 { 657 CCDEBUGFLAG ?= /Od /Z7 ; # Include debugging into in each object 658 CCPROFFLAG ?= /Od /Z7 ; 659 LINKDEBUGFLAG ?= /DEBUGTYPE:BOTH /DEBUG /PDB:NONE ; 660 } else { 661 CCDEBUGFLAG ?= /Od /Zi ; # /Zi creates debugging database 662 CCPROFFLAG ?= /Od /Zi ; 663 LINKDEBUGFLAG ?= /DEBUG ; 664 } 665 LINKPROFFLAG ?= /PROFILE $(LINKDEBUGFLAG) ; 666 LINKOPTFLAG ?= /OPT:REF ; 667 LINKSTRIPFLAG ?= ; 668 YACC ?= bison -y ; 669 YACCGEN ?= .c ; 670 YACCFILES ?= y.tab ; 671 YACCFLAGS ?= -d ; 672 } 673 else 674 { 675 EXIT On NT, set BCCROOT, MINGW, MSVCDIR, MSVCNT, MSVC or VCINSTALLDIR to the root 676 of the Borland, GCC or Microsoft directories. ; 677 } 678} 679else if $(OS2) 680{ 681 WATCOM ?= $(watcom) ; 682 683 if ! $(WATCOM) 684 { 685 Exit On OS2, set WATCOM to the root of the Watcom directory. ; 686 } 687 688 AR ?= wlib ; 689 BINDIR ?= \\os2\\apps ; 690 CC ?= wcc386 ; 691 CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet 692 C++ ?= wpp386 ; 693 C++FLAGS ?= $(CCFLAGS) ; 694 CP ?= copy ; 695 DOT ?= . ; 696 DOTDOT ?= .. ; 697 LINK ?= wcl386 ; 698 LINKFLAGS ?= /zq ; # zq=quiet 699 STDLIBS ?= ; 700 MV ?= move ; 701 NOARSCAN ?= true ; 702 RM ?= del /f ; 703 SLASH ?= \\ ; 704 STDHDRS ?= $(WATCOM)\\h ; 705 SUFEXE ?= .exe ; 706 SUFSH ?= .bat ; 707 SUFLIB ?= .lib ; 708 SUFOBJ ?= .obj ; 709 DEFFLAG ?= /D ; 710 UNDEFFLAG ?= "/u _" ; 711 712} 713else if $(VMS) 714{ 715 C++ ?= cxx ; 716 C++FLAGS ?= ; 717 CC ?= cc ; 718 CCFLAGS ?= ; 719 CHMOD ?= set file/prot= ; 720 CP ?= copy/replace ; 721 CRELIB ?= true ; 722 DOT ?= [] ; 723 DOTDOT ?= [-] ; 724 EXEMODE ?= (w:e) ; 725 FILEMODE ?= (w:r) ; 726 HDRS ?= ; 727 LINK ?= link ; 728 LINKFLAGS ?= "" ; 729 STDLIBS ?= ; 730 MKDIR ?= create/dir ; 731 MV ?= rename ; 732 RM ?= delete ; 733 RUNVMS ?= mcr ; 734 SHELLMODE ?= (w:er) ; 735 SLASH ?= . ; 736 STDHDRS ?= decc$library_include ; 737 SUFEXE ?= .exe ; 738 SUFSH ?= .bat ; 739 SUFLIB ?= .olb ; 740 SUFOBJ ?= .obj ; 741 742 switch $(OS) 743 { 744 case OPENVMS : CCFLAGS ?= /stand=vaxc ; 745 case VMS : STDLIBS ?= sys$library:vaxcrtl.olb/lib ; 746 } 747} 748else if $(MAC) 749{ 750 local OPT ; 751 752 CW ?= "{CW}" ; 753 754 MACHDRS ?= 755 "$(UMACHDRS):Universal:Interfaces:CIncludes" 756 "$(CW):MSL:MSL_C:MSL_Common:Include" 757 "$(CW):MSL:MSL_C:MSL_MacOS:Include" ; 758 759 MACLIBS ?= 760 "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" 761 "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ; 762 763 MPWLIBS ?= 764 "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" 765 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ; 766 767 MPWNLLIBS ?= 768 "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" 769 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ; 770 771 SIOUXHDRS ?= ; 772 773 SIOUXLIBS ?= 774 "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib" 775 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib" 776 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ; 777 778 C++ ?= mwcppc ; 779 C++FLAGS ?= -w off ; 780 CC ?= mwcppc ; 781 CCFLAGS ?= -w off ; 782 CP ?= duplicate -y ; 783 DOT ?= ":" ; 784 DOTDOT ?= "::" ; 785 HDRS ?= $(MACHDRS) $(MPWHDRS) ; 786 LINK ?= mwlinkppc ; 787 LINKFLAGS ?= -mpwtool -warn ; 788 STDLIBS ?= $(MACLIBS) $(MPWLIBS) ; 789 SHSTDLIBS ?= $(STDLIBS) ; 790 MKDIR ?= newfolder ; 791 MV ?= rename -y ; 792 NOARSCAN ?= true ; 793 RM ?= delete -y ; 794 SLASH ?= ":" ; 795 STDHDRS ?= ; 796 SUFLIB ?= .lib ; 797 SUFOBJ ?= .o ; 798} 799else if $(OS) = BEOS && $(OSPLAT) = PPC 800{ 801 AR ?= mwld -xml -o ; 802 BINDIR ?= /boot/home/config/bin ; 803 CC ?= mwcc ; 804 CCFLAGS ?= -nosyspath ; 805 C++ ?= $(CC) ; 806 C++FLAGS ?= -nosyspath ; 807 CHMOD ?= chmod ; 808 CHGRP ?= chgrp ; 809 CHOWN ?= chown ; 810 FORTRAN ?= "" ; 811 LEX ?= flex ; 812 LIBDIR ?= /boot/home/config/lib ; 813 LINK ?= mwld ; 814 LINKFLAGS ?= "" ; 815 MANDIR ?= /boot/home/config/man ; 816 NOARSCAN ?= true ; 817 RANLIB ?= ranlib ; 818 STDHDRS ?= /boot/develop/headers/posix ; 819 YACC ?= bison -y ; 820 YACCGEN ?= .c ; 821 YACCFILES ?= y.tab ; 822 YACCFLAGS ?= -d ; 823} 824else if $(OS) = BEOS 825{ 826 BINDIR ?= /boot/home/config/bin ; 827 CC ?= gcc ; 828 C++ ?= $(CC) ; 829 CHMOD ?= chmod ; 830 CHGRP ?= chgrp ; 831 CHOWN ?= chown ; 832 FORTRAN ?= "" ; 833 LEX ?= flex ; 834 LIBDIR ?= /boot/home/config/lib ; 835 LINK ?= gcc ; 836 MANDIR ?= /boot/home/config/man ; 837 NOARSCAN ?= true ; 838 RANLIB ?= ranlib ; 839 STDHDRS ?= /boot/develop/headers/posix ; 840 YACC ?= bison -y ; 841 YACCGEN ?= .c ; 842 YACCFILES ?= y.tab ; 843 YACCFLAGS ?= -d ; 844} 845else if $(UNIX) 846{ 847 switch $(OS) 848 { 849 case AIX : 850 STDLIBS ?= -lbsd ; 851 852 case AMIGA : 853 CC ?= gcc ; 854 YACC ?= bison -y ; 855 856 case CYGWIN : 857 CC ?= gcc ; 858 CCFLAGS += -D__cygwin__ ; 859 LEX ?= flex ; 860 JAMSHELL ?= sh -c ; 861 RANLIB ?= "" ; 862 SUFEXE ?= .exe ; 863 YACC ?= bison -y ; 864 865 case DGUX : 866 RANLIB ?= "" ; 867 RELOCATE ?= true ; 868 869 case HPUX : 870 RANLIB ?= "" ; 871 872 case INTERIX : 873 CC ?= gcc ; 874 JAMSHELL ?= sh -c ; 875 RANLIB ?= "" ; 876 877 case IRIX : 878 RANLIB ?= "" ; 879 880 case MPEIX : 881 CC ?= gcc ; 882 C++ ?= gcc ; 883 CCFLAGS += -D_POSIX_SOURCE ; 884 HDRS += /usr/include ; 885 RANLIB ?= "" ; 886 NOARSCAN ?= true ; 887 NOARUPDATE ?= true ; 888 889 case MVS : 890 RANLIB ?= "" ; 891 892 case NEXT : 893 AR ?= libtool -o ; 894 RANLIB ?= "" ; 895 896 case MACOSX : 897# AR ?= libtool -o ; 898 AR ?= ar rusc ; 899 C++ ?= c++ ; 900 MANDIR ?= /usr/local/share/man ; 901 RANLIB ?= "" ; 902 SUFSHLIB ?= .dylib ; 903 SUFIMPLIB ?= .dylib ; 904 905 case NCR : 906 RANLIB ?= "" ; 907 908 case PTX : 909 RANLIB ?= "" ; 910 911 case QNX : 912 AR ?= wlib ; 913 CC ?= cc ; 914 CCFLAGS ?= -Q ; # quiet 915 C++ ?= $(CC) ; 916 C++FLAGS ?= -Q ; # quiet 917 LINK ?= $(CC) ; 918 LINKFLAGS ?= -Q ; # quiet 919 NOARSCAN ?= true ; 920 RANLIB ?= "" ; 921 922 case SCO : 923 RANLIB ?= "" ; 924 RELOCATE ?= true ; 925 926 case SINIX : 927 RANLIB ?= "" ; 928 929 case SOLARIS : 930 RANLIB ?= "" ; 931 AR ?= "/usr/ccs/bin/ar ru" ; 932 933 case UNICOS : 934 NOARSCAN ?= true ; 935 CCOPTFLAG ?= -O0 ; 936 937 case UNIXWARE : 938 RANLIB ?= "" ; 939 RELOCATE ?= true ; 940 } 941 942 # UNIX defaults 943 944 CCFLAGS ?= -DUNIX -D__FreeBSD__ -D_THREAD_SAFE -pipe -DZ_HAVE_UNISTD_H ; 945 CCOPTFLAG ?= -O2 ; 946 CCDEBUGFLAG ?= -g ; 947 CCPROFFLAG ?= ; 948 CCSHOBJFLAG ?= -fPIC ; # Position independent is better for ShLibrary 949 C++FLAGS ?= $(CCFLAGS) ; 950 CHMOD ?= chmod ; 951 CHGRP ?= chgrp ; 952 CHOWN ?= chown ; 953 LEX ?= lex ; 954 LINKFLAGS ?= ; 955 LINKOPTFLAG ?= -O ; # Affects creating .so's 956 LINKSTRIPFLAG ?= -s ; 957 LINKDEBUGFLAG ?= ; 958 LINKPROFFLAG ?= ; 959 SHLINKFLAGS ?= ; # Flags for creation of shared library 960 STDLIBS ?= -lm -lpthread ; 961 SHSTDLIBS ?= $(STDLIBS) ; 962 LINKFLAG ?= -l ; 963 RANLIB ?= "" ; 964 YACC ?= yacc ; 965 YACCGEN ?= .c ; 966 YACCFILES ?= y.tab ; 967 YACCFLAGS ?= -d ; 968 969 HDRS ?= $(LOCALBASE)/include ; 970 971 # Add some good defaults for OS X 972 if $(OS) = MACOSX { 973 CCFLAGS += -Wno-sign-compare ; # supress new gcc4 warnings ? 974 CCFLAGS += -fpascal-strings ; # for compatibility with the OSX API 975 LINKFLAGS += -framework Carbon ; # default for .c 976 LINKFLAGS += -framework Cocoa ; # default for .m 977 } 978 979 # Make things work on 64 bit Linux 980 # Because HOSTTYPE is not normally exported, check the uname() result 981 if ! $(HOSTTYPE) { 982 HOSTTYPE = $(JAMUNAME[1]) ; 983 } 984 985 if $(HOSTTYPE) = x86_64 986 || $(HOSTTYPE) = x86_64-linux 987 || $(HOSTTYPE) = amd64 { 988 ECHO "We're on a 64 bit host" ; 989 HOST64 = true ; 990 CCFLAGS += -m64 ; 991 C++FLAGS += -m64 ; 992 } 993 994 # Adding --hash-style=sysv to the compiler options 995 # might improve Linux compatibility with FC5 ? 996} 997 998# 999# General defaults; a lot like UNIX 1000# 1001 1002 if ! $(AR) { 1003 AR = ar rusc ; 1004 } else { 1005 AR += rusc ; 1006 } 1007 AS ?= as ; 1008 ASFLAGS ?= ; 1009 AWK ?= awk ; 1010 BINDIR ?= /usr/local/bin ; 1011 C++ ?= cc ; 1012 C++FLAGS ?= ; 1013 CC ?= cc ; 1014 CCFLAGS ?= ; 1015 CP ?= cp -f ; 1016 CRELIB ?= ; 1017 DOT ?= . ; 1018 DOTDOT ?= .. ; 1019 EXEMODE ?= 755 ; 1020 FILEMODE ?= 644 ; 1021 FORTRAN ?= f77 ; 1022 FORTRANFLAGS ?= ; 1023 HDRS ?= ; 1024 INSTALLGRIST ?= installed ; 1025 JAMFILE ?= Jamfile ; 1026 JAMTOP ?= Jamtop ; 1027 LEX ?= ; 1028 LIBDIR ?= /usr/local/lib ; 1029 LINK ?= $(CC) ; 1030 LINKFLAGS ?= ; 1031 SHLINKFLAGS ?= ; 1032 STDLIBS ?= ; 1033 SHSTDLIBS ?= $(STDLIBS) ; 1034 LINKOUTFLAG ?= "-o " ; 1035 LN ?= ln ; 1036 MANDIR ?= /usr/local/man ; 1037 MKDIR ?= mkdir ; 1038 MV ?= mv -f ; 1039 RCP ?= rcp ; 1040 RM ?= rm -f ; 1041 RMDIR ?= $(RM) ; 1042 RSH ?= rsh ; 1043 SED ?= sed ; 1044 SHELLHEADER ?= "#!/bin/sh" ; 1045 SHELLMODE ?= 755 ; 1046 SLASH ?= / ; 1047 STDHDRS ?= /usr/include ; 1048 SUFEXE ?= "" ; 1049 SUFSH ?= .sh ; 1050 SUFLIB ?= .a ; 1051 SUFSHLIB ?= .so ; 1052 SUFIMPLIB ?= .so ; 1053 SUFOBJ ?= .o ; 1054 1055 DEFFLAG ?= -D ; 1056 UNDEFFLAG ?= -U ; 1057 YACC ?= ; 1058 YACCGEN ?= ; 1059 YACCFILES ?= ; 1060 YACCFLAGS ?= ; 1061 1062 HDRPATTERN = 1063 "^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ; 1064 1065 OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; 1066 1067 1068# =========================================================== 1069 1070# 1071# Base dependencies - first for "bootstrap" kinds of rules 1072# 1073 1074Depends all : shell files lib exe obj ; 1075Depends all shell files lib exe obj install : first ; 1076NotFile all first shell files lib exe obj dirs clean install uninstall ; 1077Always clean uninstall ; 1078 1079# =========================================================== 1080# ArgyllCMS Jambase building blocks: 1081 1082# Allow returning of a targets "on" variable 1083# Only the first variable in the list "on" variable is retrieved 1084# ret = geton target : variable ; 1085rule noop { return $(<) ; } 1086rule geton { 1087 local _rv ; 1088 _rv = [ on $(<[1]) noop $($(>)) ] ; 1089 return $(_rv) ; 1090} 1091 1092# Separate a single path into it's components, irrespective of 1093# whether a MSWindows or UNIX path separator is used. 1094# d1 d2 ... file = _SepPath path ; 1095rule _SepPath 1096{ 1097#Echo "_SepPath called with = '" $(<[1]) "'" ; 1098 1099 local _in = /$(<[1]) ; # leading / is to detect absolute path 1100 local split = true ; 1101 local _out = ; 1102 1103 if ! $(<) { 1104#Echo "_SepPath returning '" "" "'" ; 1105 return $(<) ; 1106 } 1107 1108 split = [ MATCH (.*)[/\\](.*) : $(_in) ] ; 1109 while $(split) { 1110#Echo "Split = '" $(split[1]) "' and '" $(split[2]) "'" ; 1111 _out = $(split[2]) $(_out) ; 1112 _in = $(split[1]) ; 1113 split = [ MATCH (.*)[/\\](.*) : $(_in) ] ; 1114 } 1115#Echo "After slplitting got '" $(_in) "' out '" $(_out) "'" ; 1116 1117 if $(_in) != "" { # No leading / 1118#Echo "Setting _out to '" $(_in) "' plus '" $(_out) "'" ; 1119 _out = $(_in) $(_out) ; 1120 } 1121 1122#Echo "_SepPath initial sep =" $(_out) ; 1123 1124 # Deal with DOS drive letters 1125 if $(NT) { 1126 switch $(_out[1]) { 1127 case *:* : { 1128 split = [ MATCH (.*)[:](.*) : $(_out[1]) ] ; 1129 if $(split[2]) != "" { 1130 _out = $(split[1]): $(split[2]) $(_out[2-]) ; 1131 } else { 1132 _out = $(split[1]): $(SLASH) $(_out[2-]) ; 1133 } 1134 } 1135 } 1136#Echo "_SepPath after DOS letters _out =" $(_out) ; 1137 } 1138 1139 # Make sure leading / is in the correct form 1140 if $(_out[1]) = "/" || $(_out[1]) = "\\" { 1141 _out = $(SLASH) $(_out[2-]) ; 1142 } 1143 1144#Echo "_SepPath returning _out =" $(_out) ; 1145 1146 return $(_out) ; 1147} 1148 1149# Turn a sequence of directories into a directory path. 1150# Opposite of _SepPath 1151# path = _DirName d1 d2 ... ; 1152rule _DirName 1153{ 1154 local _in = $(<) ; 1155 local _out = "" ; 1156 1157#Echo "_DirName got '" $(_in) "'" ; 1158 1159 # Deal with DOS drive letters 1160 if $(NT) { 1161 switch $(_in[1]) { 1162 case *:* : { 1163#Echo "_DirName match x:" ; 1164 _out = $(_in[1]) ; 1165 _in = $(_in[2-]) ; 1166 } 1167 } 1168#Echo "_DirName _in = '" $(_in) "' out = '" $(_out) "'" ; 1169 } 1170 1171 # Deal with absolute path 1172 if $(_in[1]) = "/" || $(_in[1]) = "\\" { 1173 _out = $(_out)$(SLASH) ; 1174 _in = $(_in[2-]) ; 1175#Echo "_DirName abs in = '" $(_in) "' out = '" $(_out) "'" ; 1176 } 1177 1178 while $(_in) { 1179 _out = $(_out)$(_in[1]) ; 1180 _in = $(_in[2-]) ; 1181#Echo "_DirName in = '" $(_in) "' out = '" $(_out) "'" ; 1182 if $(_in) { 1183 _out = $(_out)$(SLASH) ; 1184 } 1185#Echo "_DirName sep in = '" $(_in) "' out = '" $(_out) "'" ; 1186 } 1187 1188#Echo "_DirName returning '" $(_out) "'" ; 1189 return $(_out) ; 1190} 1191 1192# Rationalize a path (ie. cancell dirs & .. ) 1193# Currently paths that cancel out return " ". 1194# d1 d2 .. file = _RatPath d1 d2 .. file ; 1195rule _RatPath 1196{ 1197 local _in = $(<) ; 1198 local _rio = ; # reversed intermediate output 1199 local _out = ; 1200 local _gotdot = ; # There was a dot in the input path 1201 local _first = ; # Fixed first elements 1202 1203#Echo "_RatPath called with '" $(_in) "'" ; 1204 1205 # Deal with DOS drive letters 1206 if $(NT) { 1207 switch $(_in[1]) { 1208 case *:* : { 1209 _first = $(_first) $(_in[1]) ; 1210 _in = $(_in[2-]) ; 1211 } 1212 } 1213#Echo "_RatPath got first '" $(_first) "' in = '" $(_in) "'" ; 1214 } 1215 1216 # Deal with absolute path or single dot 1217 if $(_in[1]) = / || $(_in[1]) = \\ { 1218 _first = $(_first) $(SLASH) ; 1219 _in = $(_in[2-]) ; 1220#Echo "_RatPath got first '" $(_first) "' in = '" $(_in) "'" ; 1221 } else { 1222 if $(_in[1]) = $(DOT) && ! $(_in[2-]) { 1223 _first = $(_first) $(DOT) ; 1224 _in = $(_in[2-]) ; 1225#Echo "_RatPath got first '" $(_first) "' in = '" $(_in) "'" ; 1226 } 1227 } 1228 while $(_in) { 1229#Echo "Next = " $(_in[1]) " and last = " $(_rio[1]) ; 1230 if $(_in[1]) = $(DOT) { 1231 _gotdot = true ; 1232 } 1233 # if the .. will cancel out the previous directory 1234 if $(_in[1]) = $(DOTDOT) && $(_rio[1]) && $(_rio[1] != $(DOTDOT) { 1235 _rio = $(_rio[2-]) ; # Remove previous 1236#Echo "Found .. so removed previous and got _rio = " $(_rio) ; 1237 } else { # Add next 1238 # If we're decending with a directory 1239 if $(_in[1]) != $(DOT) { 1240 _rio = $(_in[1]) $(_rio) ; 1241#Echo "Adding so _rio = " $(_rio) ; 1242 } else { 1243#Echo "Found . so ignoring got _rio = " $(_rio) ; 1244 } 1245 } 1246 _in = $(_in[2-]) ; 1247 } 1248 # Make sure that a single dot is preserved 1249 if $(_gotdot) && ! $(_rio) { 1250 _rio = $(DOT) ; 1251 } 1252#Echo "Final _rio = " $(_rio) ; 1253 # Reverse it 1254 for _i in $(_rio) { 1255 _out = $(_i) $(_out) ; 1256 } 1257 1258 # Preprent with first */ 1259 _out = $(_first) $(_out) ; 1260 1261#Echo "_RatPath rationalized to '" $(_out) "'" ; 1262#Echo ; 1263 1264 return $(_out) ; 1265} 1266 1267# Re-root a directory path by pre-pending the given path. 1268# Don't do this if the path is absolute 1269# Don't return anything if the path is empty. 1270# p1 p2 .. file = _RootPath d1 d2 .. : p1 p2 ... file ; 1271rule _RootPath 1272{ 1273 local _i _out = ; 1274 1275#Echo "_RootPath called with '" $(<) "' and '" $(>) "'" ; 1276 1277 if ! $(>[1]) { 1278#Echo "_RootPath no RHS returning '" $(<) "'" ; 1279 return $(<) ; 1280 } 1281 1282 if $(>[1]) = "/" || $(>[1]) = "\\" { 1283#Echo "_RootPath RHS = / returning '" $(<) "'" ; 1284 return $(>) ; 1285 } 1286 if $(NT) { 1287 switch $(>[1]) { 1288 case *:* : { 1289#Echo "_RootPath RHS = drive: returning '" $(<) "'" ; 1290 return $(>) ; 1291 } 1292 } 1293 } 1294 1295#Echo "_RootPath returning '" $(<) $(>) "'" ; 1296 return $(<) $(>) ; 1297 1298} 1299 1300# Re-root a set of directory paths by pre-pending the given path. 1301# Don't do this if the path is absolute 1302# Don't return anything if the path is empty. 1303# paths = RootPaths dir : paths ; 1304rule RootPaths 1305{ 1306 local _d = [ _SepPath $(<[1]) ] ; 1307 local _i _t ; 1308 local _out = ; 1309 1310#Echo "RootPaths got dir '" $(<[1]) "' and paths '" $(>) "'" ; 1311 for _i in $(>) 1312 { 1313 _t = [ _SepPath $(_i) ] ; 1314 _t = [ _RootPath $(_d) : $(_t) ] ; 1315 _t = [ _RatPath $(_t) ] ; 1316 _out += [ _DirName $(_t) ] ; 1317 } 1318 1319#Echo "RootPaths returns to '" $(_out) "'" ; 1320 1321 return $(_out) ; 1322} 1323 1324# - - - - - - - - - - - - - - 1325 1326# Rationalize a set of paths (ie. cancell dirs & .. ) 1327# paths = RatPaths paths ; 1328rule RatPaths 1329{ 1330 local _i _t ; 1331 local _out = ; 1332 1333#Echo "RatPaths got '" $(<) "'" ; 1334 for _i in $(<) 1335 { 1336 _t = [ _SepPath $(_i) ] ; 1337 _t = [ _RatPath $(_t) ] ; 1338 _out += [ _DirName $(_t) ] ; 1339 } 1340 1341#Echo "RatPaths returns to '" $(_out) "'" ; 1342 1343 return $(_out) ; 1344} 1345 1346# Normalize a set of paths. This resolves the 1347# paths location with respect to SUBDIR, and so 1348# accounting for the location of the Jamfile 1349# the path is declared, and rationalizes the result. 1350# If the optional dir is present, use it to 1351# locate their targets rather than SUBDIR. 1352# If paths is empty, nothing is returned. 1353# SRCDIR and DSTDIR are ignored. 1354# paths = NormPaths paths : [ dir ] ; 1355rule NormPaths 1356{ 1357 return [ _NormPaths $(<) : $(>) : "none" ] ; 1358} 1359 1360# Normalize a set of Source paths. This resolves the 1361# paths location with respect to SUBDIR, and so 1362# accounting for the location of the Jamfile 1363# the path is declared, and rationalizes the result. 1364# If the optional dir is present, use it to 1365# locate thie targets rather than SUBDIR. 1366# If paths is empty, nothing is returned. 1367# paths = NormPaths paths : [ dir ] ; 1368rule NormSrcPaths 1369{ 1370 return [ _NormPaths $(<) : $(>) : "src" ] ; 1371} 1372 1373# Normalize a set of destination paths. This resolves the 1374# paths location with respect to SUBDIR, and so 1375# accounting for the location of the Jamfile 1376# the path is declared, and rationalizes the result. 1377# If the optional dir is present, use it to 1378# locate thie targets rather than SUBDIR. 1379# If paths is empty, nothing is returned. 1380# paths = NormPaths paths : [ dir ] ; 1381rule NormDstPaths 1382{ 1383 return [ _NormPaths $(<) : $(>) : "dst" ] ; 1384} 1385 1386# Normalize a set of paths. This resolves the 1387# paths location with respect to SUBDIR, and so 1388# accounting for the location of the Jamfile 1389# the path is declared, and rationalizes the result. 1390# If the optional dir is present, use it to 1391# locate thie targets rather than SUBDIR. 1392# If paths is empty, nothing is returned. 1393# paths = NormPaths paths : dir : type ; 1394# (This and the other rules it calls, is probably a good candidate for speed optimization!) 1395# 1396# ~~~~~ This isn't working correctly - 1397# i.e. given "." where . = ccast and "../ccast", 1398# it still returns "../ccast". 1399rule _NormPaths 1400{ 1401 local _p _i _t ; 1402 local _out = ; 1403 local _src _dst ; 1404 1405 if $(>) { 1406 _p = [ _SepPath $(>[1]) ] ; 1407 _p = [ _RatPath $(_p) ] ; 1408 } else { 1409 _p = $(_SUBDIR) ; 1410 } 1411 1412 _src = [ _SepPath $(SRCDIR) ] ; 1413 _dst = [ _SepPath $(DSTDIR) ] ; 1414 1415#Echo "_NormPaths got '" $(<) "' dir '" $(_p) "' type '" $(3) "'srcdir "' $(_src) "' dstdir '" $(_dst) "'" ; 1416 for _i in $(<) 1417 { 1418#Echo "_i = '" $(_i) "'" ; 1419 _t = [ _SepPath $(_i) ] ; 1420#Echo "_SepPath _i = '" $(_t) "'" ; 1421 _t = [ _RootPath $(_p) : $(_t) ] ; 1422#Echo "_RootPath _t = '" $(_t) "'" ; 1423 1424 if $(_src) && $(3) = "src" { 1425 _t = [ _RootPath $(_src) : $(_t) ] ; 1426#Echo "_src += _t = '" $(_i) "'" ; 1427 1428 } else if $(_dst) && $(3) = "dst" { 1429 local _f ; 1430 _t = [ _DirName $(_t) ] ; 1431 _f = [ _SepPath $(_t:BS) ] ; 1432 _t = $(_t:D) ; 1433 if ! $(_t) { 1434 _t = $(DOT) ; 1435 } 1436 _t = [ _RootPath [ _SepPath $(_t) ] : $(_dst) ] $(_f) ; 1437#Echo " _t += _dst = '" $(_t) "'" ; 1438 } 1439 _t = [ _RatPath $(_t) ] ; 1440#Echo "_RatPath _t = '" $(_t) "'" ; 1441 # Special case of complete cancelation that can occure for a pure 1442 # directory path (?) 1443 if $(_t) = "" { 1444 _t = "." ; 1445 } 1446 _t = [ _DirName $(_t) ] ; 1447 _out += $(_t) ; 1448#Echo "_out += '" $(_t) "'" ; 1449 } 1450 1451#Echo "_NormPaths returns '" $(_out) "'" ; 1452 return $(_out) ; 1453} 1454 1455# Normalize a set of targets. 1456# This is the same as NormPaths except it 1457# then strips the path out and uses it to set the 1458# Grist, NOMLOC, LOCATE and SEARCH on the target. 1459# If the optional dir is present, use it to 1460# locate the targets rather than SUBDIR. 1461# Ignore SRCDIR if present. 1462# paths = NormTargets paths [ : dir ] ; 1463rule NormISrcTargets 1464{ 1465 return [ _NormTargets $(<) : $(>) : "isrc" ] ; 1466} 1467 1468# Normalize a set of targets. 1469# This is the same as NormPaths except it 1470# then strips the path out and uses it to set the 1471# Grist, NOMLOC, LOCATE and SEARCH on the target. 1472# If the optional dir is present, use it to 1473# locate the targets rather than SUBDIR. 1474# se DSTDIR if present. 1475# paths = NormTargets paths [ : dir ] ; 1476rule NormIDstTargets 1477{ 1478 return [ _NormTargets $(<) : $(>) : "idst" ] ; 1479} 1480 1481# Normalize a set of targets. 1482# This is the same as NormPaths except it 1483# then strips the path out and uses it to set the 1484# Grist, NOMLOC, LOCATE and SEARCH on the target. 1485# If the optional dir is present, use it to 1486# locate the targets rather than SUBDIR. 1487# Use SRCDIR if present. 1488# paths = NormTargets paths [ : dir ] ; 1489rule NormSrcTargets 1490{ 1491 return [ _NormTargets $(<) : $(>) : "src" ] ; 1492} 1493 1494# Normalize a set of targets. 1495# This is the same as NormPaths except it 1496# then strips the path out and uses it to set the 1497# Grist, NOMLOC, LOCATE and SEARCH on the target. 1498# If the optional dir is present, use it to 1499# locate the targets rather than SUBDIR. 1500# Use DSTDIR if present. 1501# paths = NormTargets paths [ : dir ] ; 1502rule NormDstTargets 1503{ 1504 return [ _NormTargets $(<) : $(>) : "dst" ] ; 1505} 1506 1507# Normalize a set of targets. 1508# This is the same as NormPaths except it 1509# then strips the path out and uses it to set the 1510# Grist, NOMLOC, LOCATE and SEARCH on the target. 1511# If the optional dir is present, use it to 1512# locate the targets rather than SUBDIR. 1513# paths = NormTargets paths : dir : type ; 1514rule _NormTargets 1515{ 1516 local _p _i _t _d _ds ; 1517 local _out = ; 1518 local _src _dst ; 1519 1520 if $(>) { 1521 _p = [ _SepPath $(>[1]) ] ; 1522 } else { 1523 _p = $(_SUBDIR) ; 1524 } 1525 1526 if $(3) = "src" || $(3) = "dst" { 1527 _src = [ _SepPath $(SRCDIR) ] ; 1528 _dst = [ _SepPath $(DSTDIR) ] ; 1529 } 1530 1531#Echo ; 1532#Echo "_NormTargets got '" $(<) "' base = '" $(_p) "' type '" $(3) "' srcdir = '" $(_src) "' dstdirr = '" $(_dst) "'" ; 1533 for _i in $(<) 1534 { 1535 _t = [ _SepPath $(_i) ] ; 1536#Echo " _t = '" $(_t) "'" ; 1537 _t = [ _RootPath $(_p) : $(_t) ] ; 1538#Echo " _t = '" $(_t) "'" ; 1539 _t = [ _RatPath $(_t) ] ; 1540#Echo " _t = '" $(_t) "'" ; 1541 _t = [ _DirName $(_t) ] ; 1542#Echo " _t = '" $(_t) "'" ; 1543 _d = $(_t:D) ; 1544#Echo " _d = '" $(_d) "'" ; 1545 _ds = [ _SepPath $(_d) ] ; 1546#Echo " _ds = '" $(_ds) "'" ; 1547 _t = $(_t:D=) ; 1548#Echo " _t = '" $(_t) "'" ; 1549 _t = $(_t:G=$(_ds:J=!)) ; 1550#Echo " _t = '" $(_t) "'" ; 1551 1552 # dst trumps all the others 1553 if $(3) = "dst" { 1554 if $($(_t)-target) != "dst" { 1555 NOMLOC on $(_t) = $(_d) ; 1556 if $(_dst) { 1557 if ! $(_ds) { 1558 _ds = $(DOT) ; 1559 } 1560 _d = [ _DirName [ _RootPath $(_ds) : $(_dst) ] ] ; 1561 } 1562 if $(_d) = "/" || $(_d) = "\\" { # Jam has a bug when locating in root 1563 _d = $(_d). ; 1564 } 1565 LOCATE on $(_t) = $(_d) ; 1566 $(_t)-target = "dst" ; 1567 } 1568 1569 # idst trumps src and isrc 1570 } else if $(3) = "idst" { 1571 if $($(_t)-target) != "dst" && $($(_t)-target) != "idst" { 1572 NOMLOC on $(_t) = $(_d) ; 1573 if $(_d) = "/" || $(_d) = "\\" { # Jam has a bug when locating in root 1574 _d = $(_d). ; 1575 } 1576 LOCATE on $(_t) = $(_d) ; 1577 $(_t)-target = "idst" ; 1578 } 1579 1580 # src trumps isrc 1581 } else if $(3) = "src" { 1582 if $($(_t)-target) != "dst" && $($(_t)-target) != "idst" 1583 && $($(_t)-target) != "src" { 1584 local _d1 _d2 ; 1585 NOMLOC on $(_t) = $(_d) ; 1586 if $(_src) { 1587 _d1 = [ _DirName [ _RootPath $(_src) : $(_ds) ] ] ; 1588 } else { 1589 _d1 = $(_d) ; 1590 } 1591 if $(_dst) { 1592 if ! $(_ds) { 1593 _ds = $(DOT) ; 1594 } 1595 _d2 = [ _DirName [ _RootPath $(_ds) : $(_dst) ] ] ; 1596 } 1597 if $(_d1) = "/" || $(_d1) = "\\" { # Jam has a bug when locating in root 1598 _d1 = $(_d1). ; 1599 } 1600 if $(_d2) = "/" || $(_d2) = "\\" { # Jam has a bug when locating in root 1601 _d2 = $(_d2). ; 1602 } 1603 # We assume that if we've got a DSTDIR here, then 1604 # it may apply to this source, even if it is never 1605 # gets labelled this way. - ie. it may be a dst of a 1606 # Jamfile with the same DSTDIR that's not in scope. 1607 SEARCH on $(_t) = $(_d2) $(_d1) ; 1608 $(_t)-target = "src" ; 1609 } 1610 1611 # isrc is lowest priority 1612 } else if $(3) = "isrc" && ! $($(_t)-target) { 1613 if $(_d) = "/" || $(_d) = "\\" { # Jam has a bug when locating in root 1614 _d = $(_d). ; 1615 } 1616 NOMLOC on $(_t) = $(_d) ; 1617 SEARCH on $(_t) = $(_d) ; 1618 $(_t)-target = "isrc" ; 1619 } 1620 1621#Echo "On '" $(_t) "' set LOCATE = '" [ geton $(_t) : LOCATE ] "' SEARCH = '" [ geton $(_t) : SEARCH ] "' NOMLOC = '" [ geton $(_t) : NOMLOC ] "'" ; 1622 _out += $(_t) ; 1623 } 1624 1625#Echo "_NormTargets returns to '" $(_out) "'" ; 1626 return $(_out) ; 1627} 1628 1629# Given a set of normalized paths, return the Target ID's for 1630# them (ie. Gristed version of path) 1631# IDs = _TargetIDs targpaths ; 1632rule _TargetIDs 1633{ 1634 local _i _t _d _ds ; 1635 local _out = ; 1636 1637#Echo "_TargetIDs got '" $(<) "'" ; 1638 for _i in $(<) 1639 { 1640 _d = $(_i:D) ; 1641 _ds = [ _SepPath $(_d) ] ; 1642 _t = $(_i:D=) ; 1643 _t = $(_t:G=$(_ds:J=!)) ; 1644 _out += $(_t) ; 1645 } 1646 1647#Echo "_TargetIDs returning '" $(_out) "'" ; 1648 return $(_out) ; 1649} 1650 1651 1652# Copy the target related "on" variables from one 1653# target to another. 1654#rule CopyTarget dest : source ; 1655rule CopyTarget 1656{ 1657 NOMLOC on $(<) = [ geton $(>) : NOMLOC ] ; 1658 LOCATE on $(<) = [ geton $(>) : LOCATE ] ; 1659 SEARCH on $(<) = [ geton $(>) : SEARCH ] ; 1660} 1661 1662# Make sure a non-target isn't LOCATED or SEARCH'd by 1663# setting LOCATE, SEARCH and NOMLOC to "" 1664#rule NotTargets vars ; 1665rule NotTargets 1666{ 1667 NOMLOC on $(<) = "" ; 1668 LOCATE on $(<) = "" ; 1669 SEARCH on $(<) = "" ; 1670} 1671 1672# Create a destination target by locating 1673# the given files in the given directory. 1674# The dir is assumed to be normalized. 1675# SRCDIR and DSTDIR are ignored. 1676# targs = SetTargetsLoc targs : dir ; 1677rule CreateIDstTargets 1678{ 1679 local _o ; 1680#Echo "CreateIDstTargets got '" $(<) "' and '" $(>) "'" ; 1681 _o = [ NormIDstTargets $(<:BS) : $(>[1]) ] ; 1682#Echo "CreateIDstTargets returning '" $(_o) "'" ; 1683 return $(_o) ; 1684} 1685 1686# Given a normalized target, return the 1687# orgiginal path to it. 1688# (We use NOMLOC to do this.) 1689# path = DeNormTargs target ; 1690rule DeNormTargs 1691{ 1692 local _i _t _p _out = ; 1693 1694 for _i in $(<) { 1695 _p = [ geton $(_i) : NOMLOC ] ; 1696 _t = $(_i:G=) ; 1697 _out += $(_t:D=$(_p)) ; 1698 } 1699 1700 return $(_out) ; 1701} 1702 1703# Given a list of directories and a list of files, 1704# simply concatenate them in combination separated by a / 1705# paths1/paths = CatPaths path1 : paths ; 1706rule CatPaths 1707{ 1708 return $(<)$(SLASH)$(>) ; 1709} 1710 1711# Try and locate a given file pattern starting from the current 1712# directory and working towards the root. 1713# We use a heuristic to figure out when to stop, since 1714# Jam doesn't have pwd :-( 1715# found = FindRoot starting_dir : file ; 1716rule FindToRoot 1717{ 1718 local dir = $(<[1]) ; 1719 local dir_list, prev_list = ; 1720 local dir_list; 1721 local found = ; 1722 1723#Echo "FindToRoot got starting_dir '" $(<) "' file '" $(>) "'" ; 1724 found = [ GLOB $(dir) : $(>[1]) ] ; 1725 1726 if $(found) { 1727 return $(found) ; 1728 } 1729 1730#Echo "dir_list = " $(dir_list) ; 1731 1732 dir_list = [ GLOB $(dir) : * ] ; 1733 while $(dir_list:D="") != $(prev_list:D="") { 1734 dir = $(dir)$(SLASH)$(DOTDOT) ; 1735#Echo "dir = " $(dir) ; 1736 found = [ GLOB $(dir) : $(>[1]) ] ; 1737 1738 if $(found) { 1739 return $(found) ; 1740 } 1741 1742 prev_list = $(dir_list) ; 1743 dir_list = [ GLOB $(dir) : * ] ; 1744#Echo "dir_list = " $(dir_list) ; 1745 } 1746#Echo "returning " $(found) ; 1747 return $(found) ; 1748} 1749 1750# ----------------------------------------- 1751 1752rule DoInit 1753{ 1754 if ! $(DONEANCHORINIT) { 1755 1756 SUBDIR ?= $(DOT) ; 1757 _SUBDIR ?= $(DOT) ; 1758 1759 # initial "parent" settings 1760 P_ASFLAGS = ; 1761 P_CCFLAGS = ; 1762 P_C++FLAGS = ; 1763 P_LINKFLAGS = ; 1764 P_SHLINKFLAGS = ; 1765 P_HDRS = ; 1766 P_DEFINES = ; 1767 1768 P_PREF_ASFLAGS = ; 1769 P_PREF_CCFLAGS = ; 1770 P_PREF_C++FLAGS = ; 1771 P_PREF_LINKFLAGS = ; 1772 P_PREF_SHLINKFLAGS = ; 1773 1774 FindTop ; # Look for a default project file 1775 1776 TRACESTDHDRS = false ; # don't trace system path #include file dependenicies 1777 DONEANCHORINIT = true ; 1778 } 1779} 1780 1781# Set the project top for this Jamfile and all sub Jamfiles 1782# until another top is set or we return. 1783# ProjTop d1 d2 .. ; 1784rule ProjTop 1785{ 1786#Echo "ProjTop got '" $(<) "'" ; 1787 1788 _TOP = [ _RatPath $(<) ] ; 1789 TOP = [ _DirName $(_TOP) ] ; 1790 1791#Echo "ProjTop set TOP to '" $(TOP) "'" ; 1792 1793 if ! $($(TOP)-SET) { # Not tried to read the project file 1794 1795 local found = [ GLOB $(_top) : $(JAMFILE) ] ; 1796 1797 if $(found) { 1798 local save__SUBDIR = $(_SUBDIR) ; 1799 local save__INVSUBDIR = $(_INVSUBDIR) ; 1800 local save_SUBDIR = $(SUBDIR) ; 1801 1802 _SUBDIR = $(_TOP) ; 1803 _INVSUBDIR = [ _InvertPath $(_SUBDIR) ] ; 1804 SUBDIR = [ _DirName $(_SUBDIR) ] ; 1805#Echo "_SUBDIR = '" $(_SUBDIR) "'" ; 1806#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ; 1807 1808 # Translate SRCDIR for new SUBDIR 1809 if $(SRCDIR) { 1810#Echo "SRCDIR olddir '" $(SRCDIR) "'" ; 1811 SRCDIR = [ _SepPath $(SRCDIR) ] ; 1812 SRCDIR = [ _RootPath $(_INVSUBDIR) : [ _RootPath $(SRCDIR) : $(_SUBDIR) ] ] ; 1813 SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ; 1814#Echo "SRCDIR newdir '" $(SRCDIR) "'" ; 1815 } 1816 1817#Echo "About to include Jamtop '" $(found) "'" ; 1818 include $(found) ; 1819 1820 # Un Translate SRCDIR, in case it was set in the rules directory 1821 if $(SRCDIR) { 1822#Echo "_SUBDIR = '" $(_SUBDIR) "'" ; 1823#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ; 1824#Echo "SRCDIR newdir '" $(SRCDIR) "'" ; 1825 SRCDIR = [ _SepPath $(SRCDIR) ] ; 1826 SRCDIR = [ _RootPath $(_SUBDIR) : [ _RootPath $(SRCDIR) : $(_INVSUBDIR) ] ] ; 1827 SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ; 1828#Echo "SRCDIR olddir '" $(SRCDIR) "'" ; 1829 } 1830 1831 # Restore things 1832 _SUBDIR = $(save__SUBDIR) ; 1833 _INVSUBDIR = $(save__INVSUBDIR) ; 1834 SUBDIR = $(save_SUBDIR) ; 1835 } else { 1836 Echo "WARNING :- no project " $(TOP) "Jamtop found" ; 1837 } 1838 1839 $(TOP)-SET = true ; 1840 } 1841} 1842 1843# Search for the project top by looking for the Jamtop 1844# starting at $(SUBDIR) and lookup upwards. 1845# FindTop ; 1846rule FindTop 1847{ 1848#Echo ; 1849#Echo "FindTop called SUBDIR = '" $(SUBDIR) "'" ; 1850 1851 local _JRF = [ FindToRoot $(SUBDIR) : $(JAMTOP) ] ; 1852 1853#Echo "FindTop found '" $(_JRF) "'" ; 1854 if $(_JRF) { 1855 1856 _TOP = [ _RatPath [ _SepPath $(_JRF:D) ] ] ; 1857 TOP = [ _DirName $(_TOP) ] ; 1858#Echo "ProjTop set TOP to '" $(TOP) "'" ; 1859 1860 if ! $($(TOP)-SET) { # Not tried to read the project file 1861 local save__SUBDIR = $(_SUBDIR) ; 1862 local save__INVSUBDIR = $(_INVSUBDIR) ; 1863 local save_SUBDIR = $(SUBDIR) ; 1864 1865 _SUBDIR = $(_TOP) ; 1866 _INVSUBDIR = [ _InvertPath $(_SUBDIR) ] ; 1867 SUBDIR = [ _DirName $(_SUBDIR) ] ; 1868#Echo "_SUBDIR = '" $(_SUBDIR) "'" ; 1869#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ; 1870 1871 # Translate SRCDIR for new SUBDIR 1872 if $(SRCDIR) { 1873#Echo "SRCDIR olddir '" $(SRCDIR) "'" ; 1874 SRCDIR = [ _SepPath $(SRCDIR) ] ; 1875 SRCDIR = [ _RootPath $(_INVSUBDIR) : [ _RootPath $(SRCDIR) : $(_SUBDIR) ] ] ; 1876 SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ; 1877#Echo "SRCDIR newdir '" $(SRCDIR) "'" ; 1878 } 1879 1880#Echo "About to include Jamtop '" $(_JRF) "'" ; 1881 include $(_JRF) ; 1882 $(TOP)-SET = true ; 1883 1884 # Un Translate SRCDIR, in case it was set in the ruls directory 1885 if $(SRCDIR) { 1886#Echo "_SUBDIR = '" $(_SUBDIR) "'" ; 1887#Echo "_INVSUBDIR = '" $(_INVSUBDIR) "'" ; 1888#Echo "SRCDIR newdir '" $(SRCDIR) "'" ; 1889 SRCDIR = [ _SepPath $(SRCDIR) ] ; 1890 SRCDIR = [ _RootPath $(_SUBDIR) : [ _RootPath $(SRCDIR) : $(_INVSUBDIR) ] ] ; 1891 SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ; 1892#Echo "SRCDIR olddir '" $(SRCDIR) "'" ; 1893 } 1894 1895 # Restore things 1896 _SUBDIR = $(save__SUBDIR) ; 1897 _INVSUBDIR = $(save__INVSUBDIR) ; 1898 SUBDIR = $(save_SUBDIR) ; 1899 } 1900 } else { 1901 Echo "WARNING :- no project Jamtop found, no TOP set !" ; 1902 1903 if ! $(TOP) { 1904 TOP = $(DOT) ; # set a default TOP 1905 _TOP = $(DOT) ; 1906 } 1907 } 1908} 1909 1910# Given a path relative to CWD, return the inverse direction 1911# path. Return nothing if the path is absolute. 1912# [ we're using a hack here, since Jam 2.5 doesn't have 1913# any functions that will simply resolve a path relative 1914# to CWD into an absolute path. ] 1915# d1 d2 .. = _InvertPath d1 d2 .. 1916rule _InvertPath 1917{ 1918 local _i _o _d ; 1919#Echo "_InvertPath got '" $(<) "'" ; 1920 if $(<[1]) = "/" || $(<[1]) = "\\" { 1921#Echo "_InvertPath returning nothing" ; 1922 return "" ; 1923 } 1924 if $(NT) { 1925 switch $(<[1]) { 1926 case *:* : { 1927#Echo "_InvertPath returning nothing" ; 1928 return "" ; 1929 } 1930 } 1931 } 1932 1933 for _i in $(<) { 1934#Echo "_InvertPath _i = '" $(_i) "' _o = '" $(_o) "'" ; 1935 # Ignore . 1936 if $(_i) = $(DOT) { 1937 continue ; 1938 } 1939 # The hard one. Look amongst all the 1940 # sub directories for one that has the same 1941 # contents as the directory we came from. 1942 # Too bad if two directories have the same contents... 1943 if $(_i) = $(DOTDOT) { 1944 local _j; 1945 local _d1 _d2 _l1, _l2 _l3 ; 1946 1947#Echo "_InvertPath inverting '" $(_i) "'" ; 1948 1949 _d1 = [ _DirName $(_d) ] ; 1950 _l1 = [ GLOB $(_d1) : * ] ; 1951#Echo "_d1 = '" $(_d1) "'" ; 1952 _d += $(_i) ; 1953 _d2 = [ _DirName $(_d) ] ; 1954#Echo "_d2 = '" $(_d2) "'" ; 1955 _l2 = [ GLOB $(_d2) : * ] ; 1956 1957 for _j in $(_l2) { 1958 if $(_j) = $(DOT) || $(_j) = $(DOTDOT) { 1959 continue ; 1960 } 1961#Echo "Checking _j = '" $(_j) "'" ; 1962 _l3 = [ GLOB $(_j) : * ] ; 1963#Echo "_l1 = '" $(_l1) "'" ; 1964#Echo "_l3 = '" $(_l3:BS) "'" ; 1965 if $(_l3:BS) = $(_l1) { 1966#Echo "Found reverse = '" $(_j) "'" ; 1967 _o = $(_j:BS) $(_o) ; 1968 break ; 1969 } 1970 } 1971 1972 # The easy one. the opposite of a directory 1973 # is .. 1974 } else { 1975 _o = $(DOTDOT) $(_o) ; 1976 _d += $(_i) ; 1977 } 1978 } 1979 if ! $(_o) { 1980 _o = $(DOT) ; 1981 } 1982 1983#Echo "_InvertPath returning '" $(_o) "'" ; 1984 return $(_o) ; 1985} 1986 1987# Variables containing (possible) relative paths that are to remain 1988# anchored to where they were declared. This is to prevent 1989# NormPath in a sub-Jamfile assuming they are relative to that Jamfile. 1990# (This is a bit messy. How could it be avoided ? If there were 1991# a simple way of making paths absolute, rather than computing eveything 1992# relative to the invokation directory, it could help.) 1993ANCHORED_PATH_VARS = ; 1994 1995# Variables to save before starting a new Jamfile, then 1996# restore once it's finished. 1997 1998SUBDIR_VARS = SUBDIR _SUBDIR TOP _TOP SRCDIR DSTDIR 1999 P_ASFLAGS P_CCFLAGS P_C++FLAGS P_LINKFLAGS P_SHLINKFLAGS 2000 ASFLAGS CCFLAGS C++FLAGS LINKFLAGS SHLINKFLAGS 2001 P_PREF_ASFLAGS P_PREF_CCFLAGS P_PREF_C++FLAGS P_PREF_LINKFLAGS 2002 PREF_ASFLAGS PREF_CCFLAGS PREF_C++FLAGS PREF_LINKFLAGS PREF_SHLINKFLAGS 2003 P_HDRS HDRS 2004 P_DEFINES DEFINES 2005 P_LINKOBJS LINKOBJS 2006 P_LINKLIBS LINKLIBS 2007 P_LINKSHLIBS LINKSHLIBS 2008 P_SHLINKOBJS SHLINKOBJS 2009 P_SHLINKLIBS SHLINKLIBS 2010 P_SHLINKSHLIBS SHLINKSHLIBS 2011 ; 2012 2013# Implement including a Jamfile from a sub or peer directory, 2014# Sub includes cause flags/headers/options to be inhereted 2015# from the calling Jamfile, while Peer includes do not. 2016# The global _JAMINCLUDE_PEER variable controls whether 2017# this is a sub or peer include. 2018# _JamInclude dir ; 2019rule _JamInclude 2020{ 2021#Echo "_JamInclude called with '" $(<) "' SUBDIR '" $(SUBDIR) "' and _JAMINCLUDE_PEER '" $(_JAMINCLUDE_PEER) "'" ; 2022 2023 # Save certain variables so that sub-Jamfiles don't affect them 2024 local _jamfile ; 2025 local _SUBDIR_VARS = $(SUBDIR_VARS) $(ANCHORED_PATH_VARS) ; 2026 local _i parent_$(_SUBDIR_VARS) ; 2027 2028 for _i in $(_SUBDIR_VARS) { 2029 parent_$(_i) = $($(_i)) ; 2030 } 2031 2032 if $(_JAMINCLUDE_PEER) != "true" { 2033 # Incorporate this levels extra flags & header paths into the base 2034 P_ASFLAGS += $(ASFLAGS) ; 2035 P_CCFLAGS += $(CCFLAGS) ; 2036 P_C++FLAGS += $(C++FLAGS) ; 2037 P_LINKFLAGS += $(LINKFLAGS) ; 2038 P_SHLINKFLAGS += $(SHLINKFLAGS) ; 2039 P_HDRS = [ NormPaths $(HDRS) ] $(P_HDRS) ; 2040 P_DEFINES += $(DEFINES) ; 2041 P_LINKOBJS = [ NormPaths $(LINKOBJS) ] $(P_LINKOBJS) ; 2042 P_LINKLIBS = [ NormPaths $(LINKLIBS) ] $(P_LINKLIBS) ; 2043 P_LINKSHLIBS = [ NormPaths $(LINKSHLIBS) ] $(P_LINKSHLIBS) ; 2044 P_SHLINKOBJS = [ NormPaths $(SHLINKOBJS) ] $(P_SHLINKOBJS) ; 2045 P_SHLINKLIBS = [ NormPaths $(SHLINKLIBS) ] $(P_SHLINKLIBS) ; 2046 P_SHLINKSHLIBS = [ NormPaths $(SHLINKSHLIBS) ] $(P_SHLINKSHLIBS) ; 2047 2048 # Set parent flags no existing parent flags 2049 if ! $(P_PREF_ASFLAGS) { 2050 P_PREF_ASFLAGS = $(PREF_ASFLAGS) ; } 2051 if ! $(P_PREF_CCFLAGS) { 2052 P_PREF_CCFLAGS = $(PREF_CCFLAGS) ; } 2053 if ! $(P_PREF_C++FLAGS) { 2054 P_PREF_C++FLAGS = $(PREF_C++FLAGS) ; } 2055 if ! $(P_PREF_LINKFLAGS) { 2056 P_PREF_LINKFLAGS = $(PREF_LINKFLAGS) ; } 2057 if ! $(P_PREF_SHLINKFLAGS) { 2058 P_PREF_SHLINKFLAGS = $(PREF_SHLINKFLAGS) ; } 2059 } 2060 2061 # Set default for new Jamfile extra and preferred flags 2062 ASFLAGS = ; 2063 CCFLAGS = ; 2064 C++FLAGS = ; 2065 LINKFLAGS = ; 2066 SHLINKFLAGS = ; 2067 HDRS = ; 2068 DEFINES = ; 2069 LINKOBJS = ; 2070 LINKLIBS = ; 2071 LINKSHLIBS = ; 2072 SHLINKOBJS = ; 2073 SHLINKLIBS = ; 2074 SHLINKSHLIBS = ; 2075 2076 PREF_ASFLAGS = ; 2077 PREF_CCFLAGS = ; 2078 PREF_C++FLAGS = ; 2079 PREF_LINKFLAGS = ; 2080 PREF_SHLINKFLAGS = ; 2081 2082 _SUBDIR = [ _RatPath [ _RootPath $(_SUBDIR) : [ _SepPath $(<) ] ] ] ; 2083 _INVSUBDIR = [ _InvertPath $(_SUBDIR) ] ; 2084 SUBDIR = [ _DirName $(_SUBDIR) ] ; 2085 2086#Echo "new _SUBDIR =" $(_SUBDIR) ; 2087#Echo "new _INVSUBDIR =" $(_INVSUBDIR) ; 2088 2089 if $(_INVSUBDIR) != "." { 2090 # Keep paths relative to where they were defined, so that 2091 # NormPaths doesn't think they are relative to the sub-Jamfile. 2092#Echo "Before ANCHORED_PATH_VARS = $(ANCHORED_PATH_VARS) vals $($(ANCHORED_PATH_VARS))" ; 2093 for _i in $(ANCHORED_PATH_VARS) { 2094 $(_i) = [ RootPaths $(_INVSUBDIR) : $($(_i)) ] ; 2095 } 2096#Echo "After ANCHORED_PATH_VARS = $(ANCHORED_PATH_VARS) vals $($(ANCHORED_PATH_VARS))" ; 2097 } 2098 2099 # Translate SRCDIR for new SUBDIR 2100#Echo "SRCDIR olddir '" $(SRCDIR) "'" ; 2101 if $(SRCDIR) { 2102 local subdir = $(_SUBDIR[2-]) ; 2103 local invsubdir = [ FReverse $(_INVSUBDIR) ] ; 2104 invsubdir = [ FReverse $(invsubdir[2-]) ] ; 2105#Echo "subdir-1 =" $(subdir) ; 2106#Echo "invsubdir-1 =" $(invsubdir) ; 2107 SRCDIR = [ _SepPath $(SRCDIR) ] ; 2108 SRCDIR = [ _RootPath $(invsubdir) : [ _RootPath $(SRCDIR) : $(subdir) ] ] ; 2109 SRCDIR = [ _DirName [ _RatPath $(SRCDIR) ] ] ; 2110#Echo "SRCDIR newdir '" $(SRCDIR) "'" ; 2111 } 2112 2113 _jamfile = [ NormSrcPaths $(JAMFILE) ] ; 2114 2115#Echo "About to include " $(_jamfile) ; 2116 include $(_jamfile) ; 2117 2118 # Restore variable before returning 2119 for _i in $(_SUBDIR_VARS) { 2120 $(_i) = $(parent_$(_i)) ; 2121 } 2122 2123#Echo "Done include " $(JAMFILE:D=$(_subdir)) ; 2124#Echo "restored SUBDIR =" $(SUBDIR) ; 2125#Echo "_JamInclude done" ; 2126} 2127 2128# Invoke a Jamfile as a sub Jamfile 2129# SubInclude dir ; 2130rule SubInclude 2131{ 2132#Echo "### SubInclude called with '" $(<[1]) "' and SUBDIR = '" $(SUBDIR) "'" ; 2133 _JAMINCLUDE_PEER = "false" ; # This is a sub include 2134 return [ _JamInclude $(<) ] ; 2135} 2136 2137# Invoke a Jamfile in as a peer Jamfile 2138# PeerInclude dir ; 2139rule PeerInclude 2140{ 2141#Echo "### PeerInclude called with '" $(<[1]) "' and SUBDIR = '" $(SUBDIR) "'" ; 2142 _JAMINCLUDE_PEER = "true" ; # This is a peer include 2143 return [ _JamInclude $(<) ] ; 2144} 2145 2146# =========================================================== 2147# 2148# Rules 2149# 2150 2151# Public As 2152# As obj : source.s ; .s -> .o 2153rule As 2154{ 2155 # Normalize target names and set Grist LOCATE and SOURCE 2156 local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ; 2157 local _s = [ NormSrcTargets $(>) ] ; 2158 2159 Depends $(_t) : $(_s) ; 2160 Depends obj : $(_t) ; 2161 MakeLocate $(_t) ; 2162 2163 HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ; 2164} 2165 2166# Internal As 2167rule As_ 2168{ 2169 local pref_asflags = $(P_PREF_ASFLAGS) ; 2170 pref_asflags ?= $(PREF_ASFLAGS) ; 2171 ASFLAGS1 on $(<) = $(P_ASFLAGS) $(ASFLAGS) ; 2172 ASFLAGS2 on $(<) = $(pref_asflags) ; 2173 ASFLAGS on $(<) = [ geton $(<) : ASFLAGS1 ] [ geton $(<) : ASFLAGS2 ] ; 2174 ASHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; 2175} 2176 2177# copies sources into directory. 2178# SRCDIR and DSTDIR will be ignored. 2179# Bulk directory : sources ; 2180rule Bulk 2181{ 2182#Echo "Bulk got '" $(<) "' and '" $(>) "'" ; 2183 local _d = [ NormPaths $(<) ] ; # Directory 2184 local _s = [ NormSrcTargets $(>) ] ; # Sources 2185 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2186 local _is _it ; # individual source and target 2187 2188 for _is in $(_s) 2189 { 2190 _it = $(_t[1]) ; 2191 _t = $(_t[2-]) ; # Track _is 2192 2193 Depends files : $(_it) ; 2194 Depends $(_it) : $(_is) ; 2195 MakeLocate $(_it) ; 2196 File_ $(_it) : $(_is) ; 2197 MODE on $(_it) = $(FILEMODE) ; 2198 Chmod_ $(_it) ; 2199 } 2200} 2201 2202# Cc object : source : flags : defines : hdrpaths ; 2203rule Cc 2204{ 2205 # Normalize target names and set Grist LOCATE and SOURCE 2206 local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ; 2207 local _s = [ NormSrcTargets $(>[1]) ] ; 2208 2209 Depends $(_t) : $(_s) ; 2210 Depends obj : $(_t) ; 2211 Clean clean : $(_t) ; 2212 MakeLocate $(_t) ; 2213 2214 HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ; 2215 SOURCE on $(_t) = $(_s) ; 2216 2217 HDRRULE on $(_s) = HdrRule ; 2218 HDRSCAN on $(_s) = $(HDRPATTERN) ; 2219 # Construct HDRSEARCH so that we can know where to look for headers 2220 local _dot = [ geton $(_>) : NOMLOC ] ; 2221 if ! $(_dot) { _dot = $(DOT) ; } 2222 HDRSEARCH1 on $(_s) = $(_dot) ; 2223 HDRSEARCH2 on $(_s) = [ NormPaths $(HDRS) ] $(P_HDRS) ; 2224 HDRSEARCH3 on $(_s) = [ NormPaths $(STDHDRS) ] ; 2225 HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ] 2226 [ geton $(_s) : HDRSEARCH3 ] ; 2227#Echo "Cc set HDRSEARCH on '" $(_s) "' to '" [ geton $(_s) : HDRSEARCH ] "'" ; 2228 2229 # propagate target specific-defines 2230 2231 DEFINES on $(_t) = $(P_DEFINES) $(DEFINES) ; 2232 2233 Cc_ $(_t) : $(_s) : $(3) ; 2234 2235 if $(3) { 2236 ObjectCcFlags $(<) : $(3) ; 2237 } 2238 if $(4) { 2239 ObjectDefines $(<) : $(4) ; 2240 } 2241 if $(5) { 2242 ObjectHdrs $(<) : $(5) ; 2243 } 2244} 2245 2246# Internal Cc 2247# Cc_ object : sources ; 2248rule Cc_ 2249{ 2250 # If the compiler's -o flag doesn't work, relocate the .o 2251 if $(RELOCATE) 2252 { 2253 CcMv $(<) : $(>) ; 2254 } 2255 2256 local pref_ccflags = $(P_PREF_CCFLAGS) ; 2257 pref_ccflags ?= $(PREF_CCFLAGS) ; 2258 # Make sure we incorporate any CCFLAGS[12] on object into total 2259 CCFLAGS1 on $(<) += $(P_CCFLAGS) $(CCFLAGS) ; 2260 CCFLAGS2 on $(<) += $(pref_ccflags) ; 2261 CCFLAGS on $(<) = [ geton $(<) : CCFLAGS1 ] [ geton $(<) : CCFLAGS2 ] ; 2262 2263#Echo "Cc object '" $(<) "' got CCFLAGS1 '" [ geton $(<) : CCFLAGS1 ] "' and CCFLAGS2 '" [ geton $(<) : CCFLAGS2 ] "' for total CCFLAGS '" [ geton $(<) : CCFLAGS ] "'" ; 2264 2265 # Make sure the CCHDRS and CCDEFS are formatter correctly 2266 CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; 2267 CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; 2268} 2269 2270# C++ object : source : flags : defines : hdrpaths ; 2271rule C++ 2272{ 2273 # Normalize target names and set Grist LOCATE and SOURCE 2274 local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ; 2275 local _s = [ NormSrcTargets $(>[1]) ] ; 2276 2277 Depends $(_t) : $(_s) ; 2278 Depends obj : $(_t) ; 2279 Clean clean : $(_t) ; 2280 MakeLocate $(_t) ; 2281 2282 HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ; 2283 SOURCE on $(_t) = $(_s) ; 2284 2285 HDRRULE on $(_s) = HdrRule ; 2286 HDRSCAN on $(_s) = $(HDRPATTERN) ; 2287 # Construct HDRSEARCH so that we can know where to look for headers 2288 local _dot = [ geton $(_>) : NOMLOC ] ; 2289 if ! $(_dot) { _dot = $(DOT) ; } 2290 HDRSEARCH1 on $(_s) = $(_dot) ; 2291 HDRSEARCH2 on $(_s) = [ NormPaths $(HDRS) ] $(P_HDRS) ; 2292 HDRSEARCH3 on $(_s) = [ NormPaths $(STDHDRS) ] ; 2293 HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ] 2294 [ geton $(_s) : HDRSEARCH3 ] ; 2295 2296 # propagate target specific-defines 2297 2298 DEFINES on $(_t) = $(P_DEFINES) $(DEFINES) ; 2299 2300 C++_ $(_t) : $(_s) ; 2301 2302 if $(3) { 2303 ObjectC++Flags $(<) : $(3) ; 2304 } 2305 if $(4) { 2306 ObjectDefines $(<) : $(4) ; 2307 } 2308 if $(5) { 2309 ObjectHdrs $(<) : $(5) ; 2310 } 2311} 2312 2313# Internal C++ 2314# C++_ object : sources ; 2315rule C++_ 2316{ 2317 # If the compiler's -o flag doesn't work, relocate the .o 2318 if $(RELOCATE) 2319 { 2320 CcMv $(<) : $(>) ; 2321 } 2322 2323 local pref_c++flags = $(P_PREF_C++FLAGS) ; 2324 pref_c++flags ?= $(PREF_C++FLAGS) ; 2325 # Make sure we incorporate any C++FLAGS[12] on object into total 2326 C++FLAGS1 on $(<) += $(P_C++FLAGS) $(C++FLAGS) ; 2327 C++FLAGS2 on $(<) += $(pref_c++flags) ; 2328 C++FLAGS on $(<) = [ geton $(<) : C++FLAGS1 ] [ geton $(<) : C++FLAGS2 ] ; 2329 2330 # Make sure the CCHDRS and CCDEFS are formatter correctly 2331 CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; 2332 CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; 2333} 2334 2335rule Chmod_ 2336{ 2337#Echo "Chmod_ on '" $(<) "' with MODE = '" [ geton $(<) : MODE ] "'" ; 2338 if $(CHMOD) { Chmod1 $(<) ; } 2339} 2340 2341# Public use Depends that does normalisation of its targets 2342# (non-normalizing Depends is a built in) 2343# NDepends dest : source ; make dependency 2344rule NDepends { 2345 local _t _s ; 2346 local _p = ; 2347 2348#Echo "NDepends got '" $(<) "' and '" $(>) "'" ; 2349 2350 # Don't anchor psuedo targets 2351 switch $(<) 2352 { 2353 case all : _p = true ; 2354 case first : _p = true ; 2355 case shell : _p = true ; 2356 case files : _p = true ; 2357 case lib : _p = true ; 2358 case exe : _p = true ; 2359 case obj : _p = true ; 2360 case dirs : _p = true ; 2361 case clean : _p = true ; 2362 case install : _p = true ; 2363 case uninstall : _p = true ; 2364 } 2365 2366 # Normalize target names and set Grist LOCATE and SOURCE 2367 if ! $(_p) { 2368 _t = [ NormDstTargets $(<) ] ; 2369 } else { 2370 _t = $(<) ; 2371 } 2372 _s = [ NormSrcTargets $(>) ] ; 2373 2374#Echo "Passing Depends '" $(_t) "' and '" $(_s) "'" ; 2375 2376 Depends $(_t) : $(_s) ; 2377} 2378 2379# Public use NoUpdate that does normalisation of its targets 2380# (non-normalizing NoUpdate is a built in) 2381# NNoUpdate dest ; Make sure created, but don't update 2382rule NNoUpdate { 2383 local _t ; 2384 local _p = ; 2385 2386#Echo "NNoUpdate got '" $(<) "'" ; 2387 2388 # Don't anchor psuedo targets 2389 switch $(<) 2390 { 2391 case all : _p = true ; 2392 case first : _p = true ; 2393 case shell : _p = true ; 2394 case files : _p = true ; 2395 case lib : _p = true ; 2396 case exe : _p = true ; 2397 case obj : _p = true ; 2398 case dirs : _p = true ; 2399 case clean : _p = true ; 2400 case install : _p = true ; 2401 case uninstall : _p = true ; 2402 } 2403 2404 # Normalize target names and set Grist LOCATE and SOURCE 2405 if ! $(_p) { 2406 _t = [ NormDstTargets $(<) ] ; 2407 } else { 2408 _t = $(<) ; 2409 } 2410 _s = [ NormSrcTargets $(>) ] ; 2411 2412#Echo "Passing NoUpdate '" $(_t) "'" ; 2413 2414 NoUpdate $(_t) ; 2415} 2416 2417# Public use Includes that does normalisation of its targets 2418# (non-normalizing Includes is a built in) 2419# NDepends dest : source ; make dependency 2420rule NIncludes { 2421 local _t _s ; 2422 local _p = ; 2423 2424#Echo "NIncludes got '" $(<) "' and '" $(>) "'" ; 2425 2426 # Normalize target names and set Grist LOCATE and SOURCE 2427 _t = [ NormDstTargets $(<) ] ; 2428 _s = [ NormSrcTargets $(>) ] ; 2429 2430#Echo "Passing Includes '" $(_t) "' and '" $(_s) "'" ; 2431 2432 Includes $(_t) : $(_s) ; 2433} 2434 2435# sets mode of file 2436# Mod target : mode ; 2437rule Mod 2438{ 2439 local _t = [ NormIDstTargets $(<[1]) ] ; 2440 MODE on $(_t) = $(>) ; 2441 Chmod_ $(_t) ; 2442} 2443 2444# copies source onto target. 2445# SRCDIR and DSTDIR will be ignored. 2446# File target : source ; 2447rule File 2448{ 2449 local _t = [ NormIDstTargets $(<[1]) ] ; 2450 local _s = [ NormSrcTargets $(>[1]) ] ; 2451 2452 Depends files : $(_t) ; 2453 Depends $(_t) : $(_s) ; 2454 Clean clean : $(_t) ; 2455 MakeLocate $(_t) ; 2456 File_ $(_t) : $(_s) ; 2457 MODE on $(_t) = $(FILEMODE) ; 2458 Chmod_ $(_t) ; 2459} 2460 2461# copies source onto target, but doesn't clean source. 2462# SRCDIR and DSTDIR will be ignored. 2463# File target : source ; 2464rule FileNoClean 2465{ 2466 local _t = [ NormIDstTargets $(<[1]) ] ; 2467 local _s = [ NormSrcTargets $(>[1]) ] ; 2468 2469 Depends files : $(_t) ; 2470 Depends $(_t) : $(_s) ; 2471 MakeLocate $(_t) ; 2472 File_ $(_t) : $(_s) ; 2473 MODE on $(_t) = $(FILEMODE) ; 2474 Chmod_ $(_t) ; 2475} 2476 2477# Fake file copy. Creates a dependence to work around 2478# problem that Jam doesn't understand two products from one action. 2479# FakeFile target : source ; 2480rule FakeFile 2481{ 2482 local _t = [ NormIDstTargets $(<[1]) ] ; 2483 local _s = [ NormSrcTargets $(>[1]) ] ; 2484 2485 FakeFile_ $(_t) : $(_s) ; 2486} 2487 2488rule FakeFile_ 2489{ 2490 local _t = $(<) ; 2491 local _s = $(>) ; 2492 2493 Depends files : $(_t) ; 2494 Depends $(_t) : $(_s) ; 2495 Clean clean : $(_t) ; 2496 MakeLocate $(_t) ; 2497} 2498 2499 2500# Compile Fortran source file into object 2501# Fortran object : source ; 2502rule Fortran 2503{ 2504 # Normalize target names and set Grist LOCATE and SOURCE 2505 local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ; 2506 local _s = [ NormSrcTargets $(>[1]) ] ; 2507 2508 Depends $(_t) : $(_s) ; 2509 Depends obj : $(_t) ; 2510 Clean clean : $(_t) ; 2511 MakeLocate $(_t) ; 2512 2513 Fortran_ $(_t) : $(_s) ; 2514} 2515 2516# Internal Fortran 2517rule Fortran_ 2518{ 2519} 2520 2521 2522# NOTE! Perhaps GenFileND and GenFileNND could be replaced by a GenFile 2523# with a $(3) for the dependecies ? 2524 2525# All > are assumed to be files that < is dependent on 2526# with >[1] being an executable 2527# SRCDIR and DSTDIR are ignored. 2528rule GenFile 2529{ 2530#Echo "GenFile got '" $(<) "' and '" $(>) "'" ; 2531 # Normalize target names and set Grist LOCATE and SOURCE 2532 local _t = [ NormIDstTargets $(<) ] ; 2533 local _s = [ NormISrcTargets $(>[1]:S=$(SUFEXE)) ] ; 2534 local _a = [ NormISrcTargets $(>[2-]) ] ; 2535 2536#Echo "GenFile normed '" $(_t) "' and '" $(_s) "' plus '" $(_a) "'" ; 2537 2538 Depends $(_t) : $(_s) $(_a) ; 2539 if ! $(_s[1]:G) { # In case PATH doesn't have . in it. 2540 _s = $(DOT)$(SLASH)$(_s[1]:G=) $(_s[2-]) ; 2541 NotTargets $(_s) ; 2542 NoCare $(_s) ; 2543 NotFile $(_s) ; 2544 } 2545 GenFile1 $(_t) : $(_s) $(_a) ; 2546 Clean clean : $(_t) ; 2547} 2548 2549rule GenFile1 2550{ 2551 MakeLocate $(<) ; 2552} 2553 2554# Only >[1] is assumed to be an executable that < is dependent on. 2555# $(3) are optional extra dependecies 2556# SRCDIR and DSTDIR are ignored. 2557rule GenFileND 2558{ 2559#Echo "GenFileND got '$(<)' and '$(>)' and src targets '$(_d)'" ; 2560 # Normalize target names and set Grist LOCATE and SOURCE 2561 local _t = [ NormIDstTargets $(<[1]) ] ; 2562 local _s = [ NormISrcTargets $(>[1]:S=$(SUFEXE)) ] ; 2563 local _a = $(>[2-]) ; 2564 _a = $(_a:J=" ") ; 2565 local _d = [ NormSrcTargets $(3) ] ; 2566 2567#Echo "GenFileND normed '$(_t)' and '$(_s)' plus '$(_a)' and src targets '$(_d)'" ; 2568 2569 NotTargets $(_a) ; 2570 NoCare $(_a) ; 2571 NotFile $(_a) ; # Supresses "independent target", but may mark a directory wrongly 2572 Depends $(_t) : $(_s) $(_d) ; 2573#Echo "GenFileND set Depends '$(_t)' and '$(_s)' and '$(_d)'" ; 2574 2575 if ! $(_s[1]:G) { # In case PATH doesn't have . in it. 2576 _s = $(DOT)$(SLASH)$(_s[1]) $(_s[2-]) ; 2577 NotTargets $(_s) ; 2578 NoCare $(_s) ; 2579 NotFile $(_s) ; 2580 } 2581 GenFileND1 $(_t) : $(_s) $(_a) ; 2582 2583 Clean clean : $(_t) ; 2584} 2585 2586rule GenFileND1 2587{ 2588 MakeLocate $(<) ; 2589} 2590 2591# GenFileNND target : program args : extra_dependecies ; 2592# None of > is assumed to be a file. 2593# $(3) are optional extra dependecies 2594# SRCDIR and DSTDIR are ignored. 2595rule GenFileNND 2596{ 2597#Echo "GenFileNND got '$(<)' and '$(>)' and src targets '$(3)' " ; 2598 # Normalize target names and set Grist LOCATE and SOURCE 2599 local _t = [ NormIDstTargets $(<) ] ; 2600 local _a = $(>) ; 2601 _a = $(_a:J=" ") ; # Split up by space delimeter ? 2602 local _d = [ NormSrcTargets $(3) ] ; 2603 2604#Echo "GenFileNND normed '$(_t)' plus '$(_a)' and src targets '$(_d)'" ; 2605 2606 Depends files : $(_t) ; 2607 Depends $(_t) : $(_d) ; 2608 2609 NotTargets $(_a) ; 2610 NoCare $(_a) ; 2611 NotFile $(_a) ; # Supresses "independent target", but may mark a directory wrongly 2612 2613 GenFileNND1 $(_t) : $(_a) ; 2614 Clean clean : $(_t) ; 2615} 2616 2617rule GenFileNND1 2618{ 2619#Echo "GenFileNND1 got "' $(<) "' and "' $(>) "'" ; 2620 MakeLocate $(<) ; 2621} 2622 2623# GenFileNNDnc target : program args : extra_dependecies ; 2624# Same as GenFileNND but don't clean the target. 2625# None of > is assumed to be a file. 2626# $(3) are optional extra dependecies 2627# SRCDIR and DSTDIR are ignored. 2628rule GenFileNNDnc 2629{ 2630#Echo "GenFileNNDnc got '$(<)' and '$(>)' and src targets '$(3)' " ; 2631 # Normalize target names and set Grist LOCATE and SOURCE 2632 local _t = [ NormIDstTargets $(<) ] ; 2633 local _a = $(>) ; 2634 _a = $(_a:J=" ") ; # Split up by space delimeter ? 2635 local _d = [ NormSrcTargets $(3) ] ; 2636 2637#Echo "GenFileNNDnc normed '$(_t)' plus '$(_a)' and src targets '$(_d)'" ; 2638 2639 Depends files : $(_t) ; 2640 Depends $(_t) : $(_d) ; 2641 2642 NotTargets $(_a) ; 2643 NoCare $(_a) ; 2644 NotFile $(_a) ; # Supresses "independent target", but may mark a directory wrongly 2645 2646 GenFileNND1 $(_t) : $(_a) ; 2647} 2648 2649# Concatenate all the argument to the file 2650# Each argument to a separate line 2651# If no arguments, create empty file 2652# SRCDIR and DSTDIR are ignored. 2653rule CatToFile 2654{ 2655#Echo "CatToFile got '" $(<) "' and '" $(>) "'" ; 2656 # Normalize target names and set Grist LOCATE and SOURCE 2657 local _t = [ NormIDstTargets $(<) ] ; 2658 2659 MakeLocate $(_t) ; 2660 Depends files : $(_t) ; 2661 NotFile $(2) $(3) $(4) $(5) $(6) $(7) $(8) $(9) ; 2662 2663 Clean clean : $(_t) ; 2664 2665 if ! $(>) { 2666 CreateCatFile_ $(_t) ; 2667 2668 } else { 2669 if $(2) { 2670 CatToFile_ $(_t) : $(2) ; 2671 } 2672 if $(3) { 2673 CatToFile_ $(_t) : $(3) ; 2674 } 2675 if $(4) { 2676 CatToFile_ $(_t) : $(4) ; 2677 } 2678 if $(5) { 2679 CatToFile_ $(_t) : $(5) ; 2680 } 2681 if $(6) { 2682 CatToFile_ $(_t) : $(6) ; 2683 } 2684 if $(7) { 2685 CatToFile_ $(_t) : $(7) ; 2686 } 2687 if $(8) { 2688 CatToFile_ $(_t) : $(8) ; 2689 } 2690 if $(9) { 2691 CatToFile_ $(_t) : $(9) ; 2692 } 2693 } 2694} 2695 2696rule HardLink 2697{ 2698 local _t = [ NormDstTargets $(<) ] ; 2699 local _s = [ NormSrcTargets $(>) ] ; 2700 2701 Depends files : $(_t) ; 2702 Depends $(_t) : $(_s) ; 2703 2704 HardLink_ $(_t) : $(_s) ; 2705} 2706 2707# Mark executable as GUI applications (ie. OS X Bundle) 2708# GuiImages images ; 2709rule GuiBin 2710{ 2711 local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ; 2712 GUIAPP on $(_t) = "true" ; 2713} 2714 2715rule GUIAPP 2716{ 2717} 2718 2719# /HdrMacroFile 2720# 2721# this rule is specific to FT-Jam. It is used to indicate that a given file 2722# contains definitions for filename macros (e.g. "#define MYFILE_H <myfile>.h") 2723# that can later be used in #include statements in the rest of the source 2724# 2725# these files must be parsed before any make is tried. 2726# 2727rule HdrMacroFile 2728{ 2729 HDRMACRO $(<) ; 2730} 2731 2732# Handle #includes that are found. 2733# Try and locate them to asociate them with declared targets, as 2734# well as tracing any further #includes they may have. 2735# HdrRule NormedSource : headers ; 2736rule HdrRule 2737{ 2738 # N.B. This rule is called during binding, potentially after 2739 # the fate of many targets has been determined, and must be 2740 # used with caution: don't add dependencies to unrelated 2741 # targets, and don't set variables on $(<). 2742 2743#Echo "HdrRule got '" $(<) "' and '" $(>) "'" ; 2744 2745 local _d = [ geton $(<) : NOMLOC ] ; # Directory location of source file 2746 local _schpath = [ geton $(<) : HDRSEARCH ] ; # Search path used to find these 2747 local _s _ts ; # include source targets, sources to trace 2748 2749#Echo "HDRSEARCH on '" $(<) "' is = '" $(_schpath) "'" ; 2750 2751 # See if we can locate the header amongst the generated files. 2752#Echo "Checking for matches of known targets" ; 2753 local _i _j _k _ss _sp _n ; 2754 local _stdhdrs = [ NormPaths $(STDHDRS) ] ; 2755 _st = ; 2756 for _j in $(>) { 2757 _sp = ; # Search path 2758 _ss = ; # Resolved source target 2759#Echo "Checking include '" $(_j) "'" ; 2760 for _k in $(_schpath) "__unknown__" { # search path and plain 2761 _n = [ NormPaths $(_j) : $(_k) ] ; # Normalized path for that search path 2762 _i = [ _TargetIDs $(_n) ] ; # Target ID/name if it exitsts 2763#Echo "Checking target ID '" $(_i)-target "' value '" $($(_i)-target) "'" ; 2764 if $($(_i)-target) { # Target exists 2765 _ss = $(_i) ; 2766 _s += $(_ss) ; 2767#Echo "Found existing target '" $(_ss) "'" ; 2768 break ; 2769 } else if ! $($(_i)-target) { # unknown state 2770#Echo "Unknown statis target '" $(_i) "'" ; 2771 _sp += [ NormPaths $(_j:D) : $(_k) ] ; # paths to search 2772 } 2773 } 2774 if ! $(_ss) && $(_sp) { # We've not seen that target 2775 local _found = ; 2776#Echo "Searching for '" $(_j) "' in paths '" $(_sp) "'" ; 2777 # See if we can find the header 2778 _found = [ GLOB $(_sp) : $(_j:BS) ] ; 2779 2780 # Hmm. This sort of works around Windows problem of std include files being upper case. 2781 # It won't solve the problem of tracing them if TRACESTDHDRS is true though. 2782 if $(NT) && ! $(_found) { 2783 _found = [ GLOB $(_sp) : $(_j:UBS) ] ; 2784 _found = $(_found:D)\\$(_found:LBS) ; 2785 } 2786 if $(_found) { 2787 _ss = [ NormSrcTargets $(_found[1]) ] ; # Add it to our list 2788#Echo "Using new found target '" $(_ss) "'" ; 2789 _s += $(_ss) ; 2790 } 2791 # Mark off not found targets 2792 for _k in $(_schpath) { 2793 _n = [ NormPaths $(_j) : $(_k) ] ; # Normalized path for that search path 2794 _i = [ _TargetIDs $(_n) ] ; # Target ID/name if it exitsts 2795 if $(_i) = $(_ss) { 2796 break ; # The one we found 2797 } 2798#Echo "marking off '" $(_i) "' as non-existant" ; 2799 $(_i)-target = "false" ; # That combination doesn't exist 2800 } 2801 if ! $(_found) { 2802 _k = "__unknown__" ; 2803 _ss = [ NormSrcTargets $(_j) : $(_k) ] ; 2804 # ~~99 This would make good warning information ? 2805#Echo "Include unresolved: '" $(_ss) "'" ; 2806 _s += $(_ss) ; # Use plain header name as target ID 2807 } 2808 } 2809 # We're left with $(_ss_) being the target and $(_k) being the search path 2810 2811 # Add this to our list that will also be scanned for #includes 2812#Echo "Dealt with'" $(_j) "', _ss = '" $(_ss) "' and _k = '" $(_k) "'" ; 2813 if ( ! $(_k) in "__unknown__" ) 2814 && ( $(TRACESTDHDRS) = true || ! $(_k) in $(_stdhdrs) ) { 2815 _st += $(_ss) ; 2816 } 2817 } 2818 2819#Echo "Normalized includes = '" $(_s) "'" ; 2820#Echo "Includes to be traced = '" $(_st) "'" ; 2821 2822 # Propagate on $(<) to $(>) 2823 # Compute header search path for any #includes in these #includes 2824 2825 if $(_st) { 2826 HDRSEARCH2 on $(_st) = [ geton $(<) : HDRSEARCH2 ] ; 2827 HDRSEARCH3 on $(_st) = [ geton $(<) : HDRSEARCH3 ] ; 2828 for _i in $(_st) { 2829 # Replace file dot/HDRSEARCH1 with one for this file 2830 local _dot = [ geton $(_i) : NOMLOC ] ; 2831 if ! $(_dot) { _dot = $(DOT) ; } 2832 HDRSEARCH1 on $(_i) = $(_dot) ; 2833 HDRSEARCH on $(_i) = [ geton $(_i) : HDRSEARCH1 ] [ geton $(_i) : HDRSEARCH2 ] 2834 [ geton $(_i) : HDRSEARCH3 ] ; 2835 } 2836 HDRSCAN on $(_st) = [ geton $(<) : HDRSCAN ] ; 2837 HDRRULE on $(_st) = [ geton $(<) : HDRRULE ] ; 2838 HDRGRIST on $(_st) = [ geton $(<) : HDRGRIST ] ; 2839#Echo "HdrRule SEARCH on '" $(_st) "' set to '" [ geton $(_st) : SEARCH ] "'" ; 2840#Echo "HdrRule HDRSEARCH on '" $(_st) "' set to '" [ geton $(_st) : HDRSEARCH ] "'" ; 2841#Echo "HdrRule HDRSCAN on '" $(_st) "' set to '" [ geton $(_st) : HDRSCAN ] "'" ; 2842#Echo "HdrRule HDRRULE on '" $(_st) "' set to '" [ geton $(_st) : HDRRULE ] "'" ; 2843 } 2844 2845 # Tell Jam that anything depending on $(<) also depends on $(>), 2846 # set SEARCH so Jam can find the headers, but then say we don't 2847 # care if we can't actually find the headers (they may have been 2848 # within ifdefs), 2849 2850 NoCare $(_s) ; 2851 SEARCH on $(_s) = $(_schpath) ; # Use search path used to find these #includes as Jam SEARCH path. 2852 Includes $(<) : $(_s) ; 2853} 2854 2855# Public InstallInto 2856# InstallInto dir : sources ; install any files 2857rule InstallInto 2858{ 2859#Echo "InstallInto got '" $(<) "' and '" $(>) "'" ; 2860 local _d = [ NormPaths $(<) ] ; # Directory 2861 local _s = [ NormSrcTargets $(>) ] ; # Sources 2862 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2863 _InstallInto $(_t) : $(_s) ; 2864} 2865 2866# Private InstallInto 2867# Note that the install rules ignore SRDDIR and DSTDIR. 2868# InstallInto destinations : sources ; install any files 2869rule _InstallInto 2870{ 2871#Echo "_InstallInto got '" $(<) "' and '" $(>) "'" ; 2872 2873 local _t = $(<) ; # targets 2874 local _s = $(>) ; # sources 2875 local _is _it ; # individual source and target 2876 2877 # Arrange for jam install 2878 # Arrange for jam uninstall 2879 # targets are in dir 2880 2881 Depends install : $(_t) ; 2882 Clean uninstall : $(_t) ; 2883 MakeLocate $(_t) ; # create directories 2884 2885 # For each source, Install, Chmod, Chown, and Chgrp 2886 2887 for _is in $(_s) 2888 { 2889 _it = $(_t[1]) ; 2890 _t = $(_t[2-]) ; # Track _is 2891 2892#Echo "_InstallInto installing target '" $(_it) "' from src '" $(_is) "'" ; 2893 Depends $(_it) : $(_is) ; 2894 Install $(_it) : $(_is) ; 2895 Chmod_ $(_it) ; 2896 2897 if $(OWNER) && $(CHOWN) 2898 { 2899 Chown_ $(_it) ; 2900 OWNER on $(_it) = $(OWNER) ; 2901 } 2902 2903 if $(GROUP) && $(CHGRP) 2904 { 2905 Chgrp_ $(_it) ; 2906 GROUP on $(_it) = $(GROUP) ; 2907 } 2908 } 2909} 2910 2911# InstallBin dir : sources ; install binaries 2912rule InstallBin 2913{ 2914#Echo "InstallBin got '" $(<) "' and '" $(>) "'" ; 2915 local _d = [ NormPaths $(<) ] ; # Directory 2916 local _s = [ NormSrcTargets $(>:S=$(SUFEXE)) ] ; # Sources 2917 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2918#Echo "InstallBin norm '" $(_d) "' and '" $(_s) "' and '" $(_t) "'" ; 2919 MODE on $(_t) = $(EXEMODE) ; 2920 _InstallInto $(_t) : $(_s) ; 2921#Echo "InstallBin done " ; 2922} 2923 2924# InstallFile dir : sources ; install files 2925rule InstallFile 2926{ 2927#Echo "InstallFile got '" $(<) "' and '" $(>) "'" ; 2928 local _d = [ NormPaths $(<) ] ; # Directory 2929 local _s = [ NormSrcTargets $(>) ] ; # Sources 2930 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2931#Echo "InstallFile normed targ '" $(_t) "' src '" $(_s) "' and dir '" $(_d) "'" ; 2932 MODE on $(_t) = $(FILEMODE) ; 2933 _InstallInto $(_t) : $(_s) ; 2934} 2935 2936# InstallLib dir : sources ; install static library files 2937rule InstallLib 2938{ 2939#Echo "InstallLib got '" $(<) "' and '" $(>) "'" ; 2940 local _d = [ NormPaths $(<) ] ; # Directory 2941 local _s = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ; # Sources 2942 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2943 MODE on $(_t) = $(FILEMODE) ; 2944 _InstallInto $(_t) : $(_s) ; 2945} 2946 2947# InstallShLib dir : sources ; install shared library files 2948rule InstallShLib 2949{ 2950#Echo "InstallShLib got '" $(<) "' and '" $(>) "'" ; 2951 local _d = [ NormPaths $(<) ] ; # Directory 2952 local _s = [ NormSrcTargets $(>:S=$(SUFSHLIB)) ] ; # Sources 2953 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2954 MODE on $(_t) = $(FILEMODE) ; 2955 _InstallInto $(_t) : $(_s) ; 2956} 2957 2958# InstallShell dir : sources ; install files 2959rule InstallShell 2960{ 2961#Echo "InstallShell got '" $(<) "' and '" $(>) "'" ; 2962 local _d = [ NormPaths $(<) ] ; # Directory 2963 local _s = [ NormSrcTargets $(>) ] ; # Sources 2964 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2965 MODE on $(_t) = $(SHELLMODE) ; 2966 _InstallInto $(_t) : $(_s) ; 2967} 2968 2969# InstallMan dir : sources ; install files 2970rule InstallMan 2971{ 2972#Echo "InstallMan got '" $(<) "' and '" $(>) "'" ; 2973 local _d = [ NormPaths $(<) ] ; # Directory 2974 local _s = [ NormSrcTargets $(>) ] ; # Sources 2975 local _t = [ CreateIDstTargets $(_s) : $(_d) ] ; # Relocate targs to dir 2976 2977 # Really this just strips the . from the suffix 2978 2979 local _is _it _tt _s _id ; 2980 2981 _tt = $(_t) ; 2982 for _is in $(_s) 2983 { 2984 _it = $(_tt[1]) ; 2985 _tt = $(_tt[2-]) ; 2986 2987 switch $(_is:S) 2988 { 2989 case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ; 2990 case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ; 2991 case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ; 2992 case .n : s = n ; case .man : s = 1 ; 2993 } 2994 2995 _id = [ RootPaths $(_d) : man$(_s) ] ; 2996 CreateIDstTargets $(_it) : $(_id) ; 2997 MODE on $(_it) = $(FILEMODE) ; 2998 _InstallInto $(_it) : $(_is) ; 2999 } 3000} 3001 3002# Lex 3003# Lex source.c : source.l ; 3004rule Lex 3005{ 3006 # Normalize target names and set Grist LOCATE and SOURCE 3007 local _t = [ NormDstTargets $(<[1]) ] ; 3008 local _s = [ NormSrcTargets $(>[1]) ] ; 3009 3010 Depends $(_t) : $(_s) ; 3011 Clean clean : $(_t) ; 3012 MakeLocate $(_t) ; 3013 3014 Lex_ $(_t) : $(_s) ; 3015} 3016 3017# Internal Lex 3018rule Lex_ 3019{ 3020 LexMv_ $(<) : $(>) ; 3021} 3022 3023# Library - create a static library from sources. 3024# Library library : sources : flags : defines : hdrpaths : objects ; 3025rule Library 3026{ 3027 LibraryFromObjects $(<) : $(>) $(6) ; 3028 Objects $(>) : $(3) : $(4) : $(5) ; 3029} 3030 3031# LibraryFromObjects - create a static library from object files. 3032# LibraryFromObjects library : objects ; 3033rule LibraryFromObjects 3034{ 3035 local _i ; 3036 3037#Echo "LibraryFromObjects got " $(<) "and" $(>) "'" ; 3038 # Normalize target names and set Grist LOCATE and SOURCE 3039 local _l = [ NormDstTargets $(<[1]:S=$(SUFLIB)) ] ; 3040 local _s = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ; 3041#Echo "LibraryFromObjects nomed = " $(_l) "and" $(_s) ; 3042 3043 Depends lib : $(_l) ; 3044 3045 MakeLocate $(_l) ; 3046 3047 if $(NOARSCAN) 3048 { 3049 # If we can't scan the library to timestamp its contents, 3050 # we have to just make the library depend directly on the 3051 # on-disk object files. 3052 3053 Depends $(_l) : $(_s) ; 3054 } 3055 else 3056 { 3057 # If we can scan the library, we make the library depend 3058 # on its members and each member depend on the on-disk 3059 # object file. 3060 3061 for _i in $(_s) 3062 { 3063 local _m ; 3064 _m = $(_l:M=$(_i:BS)) ; 3065 CopyTarget $(_m) : $(_l) ; # Transfer LOCATE, SEARCH, NOMLOC 3066 Depends $(_l) : $(_m) ; 3067 Depends $(_m) : $(_i) ; 3068 } 3069 } 3070 3071 Clean clean : $(_l) ; 3072 3073 if $(CRELIB) { 3074 CreLib $(_l) : $(_s[1]) ; 3075 } 3076 3077 Archive $(_l) : $(_s) ; 3078 3079 if $(RANLIB) { 3080 Ranlib $(_l) ; 3081 } 3082 3083 # If we can't scan the library, we have to leave the .o's around. 3084 if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { 3085 local _ds ; 3086 for _i in $(_s) { 3087 # Don't delete any objects that we've marked with KEEPOBJS 3088 if ! [ geton $(_i) : KEEPOBJS ] { 3089 _ds += $(_i) ; 3090 } 3091 } 3092 if $(_ds) { 3093 RmTemps_ $(_l) : $(_ds) ; 3094 } 3095 } 3096} 3097 3098# LibraryFromLibraries - create a static library from object files and static libraries. 3099# LibraryFromLibraries library : libraries ; 3100rule LibraryFromLibraries 3101{ 3102 local _i ; 3103 3104#Echo "LibraryFromLibraries got " $(<) "and" $(>) ; 3105 # Normalize target names and set Grist LOCATE and SOURCE 3106 local _l = [ NormDstTargets $(<[1]:S=$(SUFLIB)) ] ; 3107 local _s = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ; 3108#Echo "LibraryFromObjects nomed = " $(_l) "and" $(_s) ; 3109 3110 Depends lib : $(_l) ; 3111 Depends $(_l) : $(_s) ; 3112 3113 MakeLocate $(_l) ; 3114 3115 Clean clean : $(_l) ; 3116 3117 if $(CRELIB) { 3118 CreLib $(_l) : $(_s[1]) ; 3119 } 3120 3121 ArchiveArchive $(_l) : $(_s) ; 3122} 3123 3124# ShLibrary - create a shared library from sources. 3125# ShLibrary library : sources : flags : defines : hdrpaths : objects : libs : shlibs ; 3126rule ShLibrary 3127{ 3128 ShLibraryFromObjects $(<) : $(>) $(6) : $(7) : $(8) ; 3129 Objects $(>) : $(CCSHOBJFLAG) $(3) : $(4) : $(5) ; 3130} 3131 3132# ShLibraryFromObjects - create a shared library from object files. 3133# Both the import (if used on the system) and shared library will be created. 3134# ShLibraryFromObjects shlib : objects : libs : shlibs ; 3135rule ShLibraryFromObjects 3136{ 3137 local _i _l ; 3138 3139#Echo "ShLibraryFromObjects got " $(<) "and" $(>) ; 3140 # Normalize target names and set Grist LOCATE and SOURCE 3141 local _sl = [ NormDstTargets $(<[1]:S=$(SUFSHLIB)) ] ; 3142 if $(NT) { 3143 _l = [ NormDstTargets $(<[1]:S=$(SUFIMPLIB)) ] ; 3144 } 3145 local _s = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ; 3146#Echo "ShLibraryFromObjects nomed =" $(_sl) "and" $(_l) "and" $(_s) ; 3147 3148 Depends lib : $(_sl) ; 3149# Depends lib : $(_l) ; 3150 MakeLocate $(_sl) ; 3151 3152 Depends $(_sl) : $(_s) ; 3153 Clean clean : $(_sl) $(_l) ; 3154 3155 if $(_l) { 3156 Depends $(_l) : $(_s) ; 3157 Clean clean : $(_l:S=.exp) ; 3158 } 3159 3160#Echo "ShLibraryFromObjects SHLINKFLAGS = '" $(SHLINKFLAGS) "' and P_SHLINKFLAGS ='" $(P_LSHINKFLAGS) "'" ; 3161 3162 if $(SHLINKFLAGS) || $(P_SHLINKFLAGS) 3163 || $(PREF_SHLINKFLAGS) || $(P_PREF_SHLINKFLAGS) { 3164 local pref_shlinkflags = $(P_PREF_SHLINKFLAGS) ; 3165 pref_shlinkflags ?= $(PREF_SHLINKFLAGS) ; 3166 SHLINKFLAGS on $(_sl) += $(P_SHLINKFLAGS) $(SHLINKFLAGS) $(pref_shlinkflags) ; 3167 } 3168 3169#Echo "ShLibraryFromObjects SHLINKOBJS = '" $(SHLINKOBJS) "' and P_SHLINKOBJS ='" $(P_SHLINKOBJS) "'" ; 3170 if $(SHLINKOBJS) || $(P_SHLINKOBJS) { 3171 local _o = [ NormSrcTargets $(SHLINKOBJS:S=$(SUFOBJ)) ] $(P_SHLINKOBJS:S=$(SUFOBJ)) ; 3172 Depends $(_sl) : $(_o) ; 3173 SHLINKOBJS on $(_sl) += $(_o) ; 3174 } 3175 3176#Echo "ShLibraryFromObjects SHLINKLIBS = '" $(SHLINKLIBS) "' and P_SHLINKLIBS ='" $(P_SHLINKLIBS) "'" ; 3177 if $(SHLINKLIBS) || $(P_SHLINKLIBS) { 3178 local _l = [ NormSrcTargets $(SHLINKLIBS:S=$(SUFLIB)) ] $(P_SHLINKLIBS:S=$(SUFLIB)) ; 3179 Depends $(_sl) : $(_l) ; 3180 SHLINKLIBS on $(_sl) += $(_l) ; 3181 } 3182 3183#Echo "ShLibraryFromObjects SHLINKSHLIBS = '" $(SHLINKSHLIBS) "' and P_SHLINKSHLIBS ='" $(P_SHLINKSHLIBS) "'" ; 3184 if $(SHLINKSHLIBS) || $(P_SHLINKSHLIBS) { 3185 local _l = [ NormSrcTargets $(SHLINKSHLIBS:S=$(SUFSHLIB)) ] $(P_SHLINKSHLIBS:S=$(SUFSHLIB)) ; 3186 Depends $(_sl) : $(_l) ; 3187 SHLINKSHLIBS on $(_sl) += $(_l) ; 3188 } 3189 3190 if $(SHLINKDEFFILE) { # Windows special option 3191 SHLINKDEFFILE on $(_sl) $(_l) = [ NormSrcTargets $(SHLINKDEFFILE) ] ; 3192 Depends $(_sl) : [ geton $(_sl) : SHLINKDEFFILE ] ; 3193 FakeFile_ $(_l) : $(_sl) ; # .lib is created with .dll 3194 ShLinkDef_ $(_sl) $(_l) : $(_s) ; 3195 } else { 3196 if (SHLINKSEARCHEXEPATH) { # UNIX special option 3197 3198 if $(OS) = MACOSX { # OS X version of ld 3199 SHLINKSEARCHEXEPATH = @executable_path/ ; 3200 } else { 3201# SHLINKSEARCHEXEPATH = \\$PATH/ ; 3202 SHLINKSEARCHEXEPATH = \\$ORIGIN/ ; 3203 } 3204 } 3205 ShLink_ $(_sl) $(_l) : $(_s) ; 3206 } 3207 3208 # Try and make sure the objects are build with the correct flag 3209 ObjectCcFlags $(>) : $(CCSHOBJFLAG) ; 3210 ObjectC++Flags $(>) : $(CCSHOBJFLAG) ; 3211 3212 if $(3) { 3213 ShLibraryLibraries $(<) : $(3) ; 3214 } 3215 if $(4) { 3216 ShLibraryShLibraries $(<) : $(4) ; 3217 } 3218} 3219 3220# Internal link 3221rule Link_ 3222{ 3223 MODE on $(<) = $(EXEMODE) ; 3224 Chmod_ $(<) ; 3225} 3226 3227# Make the shared library link with the given objects. 3228# This is just a way of adding common object files to many shlibs. 3229# ShLibraryObjects shlib : objects ; 3230rule ShLibraryObjects 3231{ 3232#Echo "ShLibraryObjects got '" $(<) "' and '" $(>) "'" ; 3233 # Normalize target names and set Grist LOCATE and SOURCE 3234 local _t = [ NormDstTargets $(<:S=$(SUFSHLIB)) ] ; 3235 local _o = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ; 3236 3237 Depends $(_t) : $(_o) ; 3238 3239 SHLINKOBJS on $(_t) += $(_o) ; 3240} 3241 3242# Make the executables link with the given static libraries. 3243# ShLibraryLibraries shlib : libraries ; 3244rule ShLibraryLibraries 3245{ 3246#Echo "ShLibraryLibraries got '" $(<) "' and '" $(>) "'" ; 3247 # Normalize target names and set Grist LOCATE and SOURCE 3248 local _t = [ NormDstTargets $(<:S=$(SUFSHLIB)) ] ; 3249 local _l = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ; 3250 3251 Depends $(_t) : $(_l) ; 3252 3253 SHLINKLIBS on $(_t) += $(_l) ; 3254} 3255 3256# Make the executables link with the given shared libraries. 3257# ShLibraryShLibraries shlib : shlibraries ; 3258rule ShLibraryShLibraries 3259{ 3260#Echo "ShLibraryShLibraries got '" $(<) "' and '" $(>) "'" ; 3261 # Normalize target names and set Grist LOCATE and SOURCE 3262 local _t = [ NormDstTargets $(<:S=$(SUFSHLIB)) ] ; 3263 local _l = [ NormSrcTargets $(>:S=$(SUFSHIMPLIB)) ] ; 3264 3265 Depends $(_t) : $(_l) ; 3266 3267 SHLINKSHLIBS on $(_t) += $(_l) ; 3268} 3269 3270# Add extra LINKFLAGS to mains 3271# MainLinkFlags mains : flags ; 3272rule MainLinkFlags 3273{ 3274#Echo "MainLinkFlags got '" $(<) "' and '" $(>) "'" ; 3275 local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ; 3276 local _i ; 3277 3278 for _i in $(_t) { 3279 LINKFLAGS on $(_i) += $(>) ; 3280#Echo "exes '" $(_i) "' got LINKFLAGS '" [ geton $(_i) : LINKFLAGS ] "'" ; 3281 } 3282} 3283 3284# Make an executable from sources 3285# Main image : sources : flags : defines : hdrpaths : objects : libs : shlibs ; 3286rule Main 3287{ 3288 MainFromObjects $(<) : $(>) $(6) : $(7) : $(8) ; 3289 Objects $(>) : $(3) : $(4) : $(5) ; 3290} 3291 3292# Make a variant executable from sources 3293# Objects are distiguished by appending "_image" 3294# MainVariant image : sources : flags : defines : hdrpaths : objects : libs : shlibs ; 3295rule MainVariant 3296{ 3297 local _i _t _o ; 3298 3299#Echo "MainVariant got '" $(<) "' and '" $(>) "'" ; 3300 for _i in $(>) { 3301 _t = $(_i:DB)_$(<[1]) ; 3302 Object $(_t) : $(_i) : $(3) : $(4) : $(5) ; 3303#Echo "MainVariant object '" $(_t) "' and src '" $(_i) "'" ; 3304 _o += $(_t) ; 3305 } 3306#Echo "MainVariant image '" $(<) "' and objs '" $(_o) "'" ; 3307 MainFromObjects $(<) : $(_o) $(6) : $(7) : $(8) ; 3308} 3309 3310# Make an executable from objects 3311# MainFromObjects image : objects : libs : shlibs ; 3312rule MainFromObjects 3313{ 3314#Echo "MainFromObjects got" $(<) "and" $(>) ; 3315 3316 # Normalize target names and set Grist LOCATE and SOURCE 3317 local _t = [ NormDstTargets $(<[1]:S=$(SUFEXE)) ] ; 3318 local _s = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ; 3319 3320#Echo "MainFromObjects _t" $(_t) "and _s" $(_s) ; 3321 3322 # so 'jam foo' works when it's really foo.exe 3323 if $(_t:S=) != $(_t) 3324 { 3325 Depends $(_t:S=) : $(_t) ; 3326 NotFile $(_t:S=) ; 3327 } 3328 3329 # make compiled sources a dependency of target 3330 3331 Depends exe : $(_t) ; 3332 Depends $(_t) : $(_s) ; 3333 Clean clean : $(_t) ; 3334 MakeLocate $(_t) ; 3335 3336 if $(3) { 3337 LinkLibraries $(<) : $(3) ; 3338 } 3339 if $(4) { 3340 LinkShLibraries $(<) : $(4) ; 3341 } 3342 3343#Echo "MainFromObjects LINKFLAGS = '" $(LINKFLAGS) "' and P_LINKFLAGS ='" $(P_LINKFLAGS) "'" ; 3344#Echo " PREF_LINKFLAGS = '" $(PREF_LINKFLAGS) "' and P_PREF_LINKFLAGS ='" $(P_PREF_LINKFLAGS) "'" ; 3345 if $(LINKFLAGS) || $(P_LINKFLAGS) 3346 || $(PREF_LINKFLAGS) || $(P_PREF_LINKFLAGS) { 3347 local pref_linkflags = $(P_PREF_LINKFLAGS) ; 3348 pref_linkflags ?= $(PREF_LINKFLAGS) ; 3349 LINKFLAGS on $(_t) += $(P_LINKFLAGS) $(LINKFLAGS) $(pref_linkflags) ; 3350#Echo "LINKFLAGS on $(_t) = '" [ geton $(_t) : LINKFLAGS ] "'" ; 3351 } 3352 3353#Echo "MainFromObjects LINKOBJS = '" $(LINKOBJS) "' and P_LINKOBJS ='" $(P_LINKOBJS) "'" ; 3354 if $(LINKOBJS) || $(P_LINKOBJS) { 3355 local _o = [ NormSrcTargets $(LINKOBJS:S=$(SUFOBJ)) ] $(P_LINKOBJS:S=$(SUFOBJ)) ; 3356 Depends $(_t) : $(_o) ; 3357 LINKOBJS on $(_t) += $(_o) ; 3358 } 3359 3360#Echo "MainFromObjects LINKLIBS = '" $(LINKLIBS) "' and P_LINKLIBS ='" $(P_LINKLIBS) "'" ; 3361 if $(LINKLIBS) || $(P_LINKLIBS) { 3362 local _l = [ NormSrcTargets $(LINKLIBS:S=$(SUFLIB)) ] $(P_LINKLIBS:S=$(SUFLIB)) ; 3363 Depends $(_t) : $(_l) ; 3364 LINKLIBS on $(_t) += $(_l) ; 3365 } 3366 3367#Echo "MainFromObjects LINKSHLIBS = '" $(LINKSHLIBS) "' and P_LINKSHLIBS ='" $(P_LINKSHLIBS) "'" ; 3368 if $(LINKSHLIBS) || $(P_LINKSHLIBS) { 3369 local _l = [ NormSrcTargets $(LINKSHLIBS:S=$(SUFIMPLIB)) ] $(P_LINKSHLIBS:S=$(SUFIMPLIB)) ; 3370 Depends $(_t) : $(_l) ; 3371 LINKSHLIBS on $(_t) += $(_l) ; 3372 } 3373 3374 Link_ $(_t) : $(_s) ; 3375 3376 # Some OS's need to post process GUI apps to work (ie. OS X bundle) 3377 if [ geton $(_t) : GUIAPP ] = "true" { 3378 GUIAPP $(_t) ; 3379 } 3380#Echo "MainFromObjects done" ; 3381} 3382 3383# A rule to make several mains from each of their single source files. 3384# MainsFromSources executables ; 3385rule MainsFromSources 3386{ 3387 local _i ; 3388 for _i in $(<) { 3389 Main $(_i) : $(_i) ; 3390 } 3391} 3392 3393# Make the executables link with the given objects. 3394# This is just a way of adding common object files to many mains. 3395# LinkObjects image : objects ; 3396rule LinkObjects 3397{ 3398#Echo "LinkObjects got '" $(<) "' and '" $(>) "'" ; 3399 # Normalize target names and set Grist LOCATE and SOURCE 3400 local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ; 3401 local _o = [ NormSrcTargets $(>:S=$(SUFOBJ)) ] ; 3402 3403 Depends $(_t) : $(_o) ; 3404 3405 LINKOBJS on $(_t) += $(_o) ; 3406} 3407 3408# Make the executables link with the given static libraries. 3409# LinkLibraries image : libraries ; 3410rule LinkLibraries 3411{ 3412#Echo "LinkLibraries got '" $(<) "' and '" $(>) "'" ; 3413 # Normalize target names and set Grist LOCATE and SOURCE 3414 local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ; 3415 local _l = [ NormSrcTargets $(>:S=$(SUFLIB)) ] ; 3416 3417 Depends $(_t) : $(_l) ; 3418 3419 LINKLIBS on $(_t) += $(_l) ; 3420} 3421 3422# Make the executables link with the given shared libraries. 3423# LinkShLibraries image : shlibraries ; 3424rule LinkShLibraries 3425{ 3426#Echo "LinkShLibraries got '" $(<) "' and '" $(>) "'" ; 3427 # Normalize target names and set Grist LOCATE and SOURCE 3428 local _t = [ NormDstTargets $(<:S=$(SUFEXE)) ] ; 3429 local _l = [ NormSrcTargets $(>:S=$(SUFSHIMPLIB)) ] ; 3430 3431 Depends $(_t) : $(_l) ; 3432 3433 LINKSHLIBS on $(_t) += $(_l) ; 3434} 3435 3436# Ensure that each targets directories are created 3437# Makelocate targets ; 3438rule MakeLocate 3439{ 3440#Echo "MakeLocate got '" $(<) "'" ; 3441 local _i ; 3442 # Uses special variable LOCATE of targets, and arranges 3443 # with MkDir to create target directory. 3444 # The directory itself becomes a target 3445 3446 for _i in $(<) { 3447 local _t = [ geton $(_i) : LOCATE ] ; 3448 if $(_t) { 3449 MkDir_ $(_t) : $(_i) ; 3450 } 3451 } 3452} 3453 3454# Make the directories and all their parent directories. 3455# MkDir directories ; 3456rule MkDir 3457{ 3458#Echo "MkDir got '" $(<) "'" ; 3459 # Ignore timestamps on directories: we only care if they exist. 3460 local _t= [ NormPaths $(<) ] ; 3461 local _i ; 3462 3463 for _i in $(_t) { 3464 MkDir_ $(_i) ; 3465 } 3466} 3467 3468# Internal MkDir 3469# MkDir dir [ : dependency ] 3470rule MkDir_ 3471{ 3472#Echo "MkDir_ got '" $(<) "' : '" $(>) "'" ; 3473 3474 if ! $(<:BS) { 3475 return ; 3476 } 3477 3478 local _t ; 3479 local _d = $(<:D) ; # Form target id from path + last directory 3480 if ! $(_d) { 3481 _d = $(DOT) ; 3482 } 3483 local _t = [ NormIDstTargets $(<:BS) : $(_d) ] ; 3484 3485#Echo "MkDir_ target = '" $(_t) "' dependant = '" $(>) "'" ; 3486 3487 if $(>) { # Thing that depends on this directory 3488 Depends $(>) : $(_t) ; 3489 } 3490 NoUpdate $(_t) ; 3491 3492 # Don't create . or any directory already created. 3493 3494 if $(_t) != $(DOT) && ! $($(_t)-mkdir) 3495 { 3496 # Cheesy gate to prevent multiple invocations on same dir 3497 # Arrange for jam dirs 3498 # MkDir1 has the actions 3499 3500#Echo "Making '" $(_t) "'" ; 3501 $(_t)-mkdir = true ; 3502 Depends dirs : $(_t) ; 3503 MkDir1 $(_t) ; 3504 3505 # Recursively make parent directories. 3506 # $(_t:P) = $(_t)'s parent, & we recurse until root 3507 3508 local _s = $(<:P) ; 3509#Echo "parent = '" $(_s) "'" ; 3510 3511 # Don't try to create A: or A:\ on windows 3512 3513 if $(NT) 3514 { 3515 switch $(_s) 3516 { 3517 case *: : _s = ; 3518 case *:\\ : _s = ; 3519 case *:/ : _s = ; 3520 } 3521 } 3522 3523#Echo "parent now = '" $(_s) "'" ; 3524 if $(_s) = $(SLASH) # Hmm. Was $(_s) = $(<). How could that work ? 3525 { 3526#Echo "At root, ignore '" $(_s) "' = '" $(<) "'" ; 3527 # The parent is the same as the dir. 3528 # We're at the root, which some OS's can't stat, so we mark 3529 # it as NotFile. 3530 3531 NotFile $(_s) ; 3532 } 3533 else if $(_s) 3534 { 3535 # There's a parent; recurse. 3536 3537#Echo "Doing Depends '" $(_t) "' with '" [ _TargetIDs $(_s) ] "'" ; 3538 Depends $(_t) : [ _TargetIDs $(_s) ] ; 3539#Echo "Recursing with parent '" $(_s) "'" ; 3540 MkDir_ $(_s) ; 3541 } 3542 } else { 3543#Echo "Not making '" $(_t) "' because it's dot, or it's been made before" ; 3544 } 3545} 3546 3547# Deal with a single source to object. 3548# Object object : sources : flags : defines : hdrpaths 3549rule Object 3550{ 3551 #Echo "Object got " $(<) "and" $(>) "' flags '" $(3) "' defs '" $(4) "' hds '" $(5) "'" ; 3552 3553 # Normalize target names and set Grist LOCATE and SOURCE 3554 local _t = [ NormDstTargets $(<[1]:S=$(SUFOBJ)) ] ; 3555 local _s = [ NormSrcTargets $(>[1]) ] ; 3556 local _dot ; 3557 3558#Echo "Object norms " $(_t) "and" $(_s) ; 3559 3560 Depends $(_t) : $(_s) ; 3561 Depends obj : $(_t) ; 3562 Clean clean : $(_t) ; 3563 MakeLocate $(_t) ; 3564 3565 # HDRS is used to provide the -I$(HDRS) options on compile. 3566 3567#Echo "Object sets HDRS on '" $(_t) "' to HDRS '" $(HDRS) "' and P_HDRS '" $(P_HDRS) "'" ; 3568 HDRS on $(_t) = [ geton $(_t) : SEARCH ] [ NormPaths $(HDRS) ] $(P_HDRS) ; 3569#Echo "HDRS on '" $(_t) "' is now '" [ geton $(_t) : HDRS ] "'" ; 3570 3571 # we need to mark what the associated source is so 3572 # that if we want to change HDRS we can propogate 3573 # it to the #include files. 3574 3575 SOURCE on $(_t) = $(_s) ; # ~~99 should check source is the same as any previous ? 3576 3577 # handle #includes for source: Jam scans for headers with 3578 # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE) 3579 # with the scanned file as the target and the found headers 3580 # as the sources. HDRSEARCH is the value of SEARCH used for 3581 # the found header files. 3582 3583 HDRRULE on $(_s) = HdrRule ; 3584 HDRSCAN on $(_s) = $(HDRPATTERN) ; 3585 3586 # Construct HDRSEARCH so that we can latter add to HDRS 3587 local _dot = [ geton $(_s) : NOMLOC ] ; 3588 if ! $(_dot) { _dot = $(DOT) ; } 3589 HDRSEARCH1 on $(_s) = $(_dot) ; 3590 HDRSEARCH2 on $(_s) = [ NormPaths $(HDRS) ] $(P_HDRS) ; 3591 HDRSEARCH3 on $(_s) = [ NormPaths $(STDHDRS) ] ; 3592 HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ] 3593 [ geton $(_s) : HDRSEARCH3 ] ; 3594#Echo "Object: HDRSEARCH on '" $(_s) "' set to '" [ geton $(_s) : HDRSEARCH ] "'" ; 3595 3596 # propagate target specific-defines 3597 3598 DEFINES on $(_t) = $(P_DEFINES) $(DEFINES) ; 3599 3600 # if source is not .c, generate .c with specific rule 3601 3602 switch $(_s:S) 3603 { 3604 case .asm : As_ $(_t) : $(_s) ; 3605 3606 case .c : Cc_ $(_t) : $(_s) ; 3607 3608 case .C : C++_ $(_t) : $(_s) ; 3609 case .cc : C++_ $(_t) : $(_s) ; 3610 case .cpp : C++_ $(_t) : $(_s) ; 3611 case .cxx : C++_ $(_t) : $(_s) ; 3612 3613 case .m : Cc_ $(_t) : $(_s) ; 3614 3615 case .f : Fortran_ $(_t) : $(_s) ; 3616 3617 case .l : { 3618 local _c = $(_t:S=.c) ; 3619 CopyTarget $(_c) : $(_t) ; # Transfer LOCATE, SEARCH, NOMLOC 3620 Lex_ $(_c) : $(_s) ; 3621 Cc_ $(_t) : $(_c) ; 3622 } 3623 3624 case .s : As_ $(_t) : $(_s) ; 3625 3626 case .y : { 3627 local _c = $(_t:S=$(YACCGEN)) ; 3628 CopyTarget $(_c) : $(_t) ; # Transfer LOCATE, SEARCH, NOMLOC 3629 Yacc_ $(_c) : $(_s) ; 3630 Cc_ $(_t) : $(_c) ; 3631 } 3632 # Note user object gets normalized target and source 3633 case * : UserObject $(_t) : $(_s) : $(3) : $(4) : $(5) ; 3634 } 3635#Echo ; 3636 3637 if $(3) { 3638 ObjectCcFlags $(<) : $(3) ; 3639 switch $(_s:S) 3640 { 3641 case .c : ObjectCcFlags $(_t) : $(3) ; 3642 3643 case .C : ObjectC++Flags $(_t) : $(3) ; 3644 case .cc : ObjectC++Flags $(_t) : $(3) ; 3645 case .cpp : ObjectC++Flags $(_t) : $(3) ; 3646 case .cxx : ObjectC++Flags $(_t) : $(3) ; 3647 3648 case .l : ObjectCcFlags $(_t) : $(3) ; 3649 case .y : ObjectCcFlags $(_t) : $(3) ; 3650 } 3651 } 3652 if $(4) { 3653 ObjectDefines $(<) : $(4) ; 3654 } 3655 if $(5) { 3656 ObjectHdrs $(<) : $(5) ; 3657 } 3658} 3659 3660# Add extra CCFLAGS to objects 3661# ObjectCcFlags objects : flags ; 3662rule ObjectCcFlags 3663{ 3664#Echo "ObjectCcFLags got '" $(<) "' and '" $(>) "'" ; 3665 local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ; 3666 local _i ; 3667 3668 for _i in $(_t) { 3669 CCFLAGS1 on $(_i) += $(>) ; 3670 CCFLAGS on $(_i) = [ geton $(_i) : CCFLAGS1 ] [ geton $(_i) : CCFLAGS2 ] ; 3671#Echo "object '" $(_i) "' got CCFLAGS1 '" [ geton $(_i) : CCFLAGS1 ] "' and CCFLAGS2 '" [ geton $(_i) : CCFLAGS2 ] "' for total CCFLAGS '" [ geton $(_i) : CCFLAGS ] "'" ; 3672 } 3673} 3674 3675# Add extra PREF_CCFLAGS to objects 3676# ObjectPrefCcFlags objects : flags ; 3677rule ObjectPrefCcFlags 3678{ 3679#Echo "ObjectPrefCcFLags got '" $(<) "' and '" $(>) "'" ; 3680 if ! $(P_PREF_CCFLAGS) { 3681 local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ; 3682 local _i ; 3683 3684 for _i in $(_t) { 3685 CCFLAGS2 on $(_i) += $(>) ; 3686 CCFLAGS on $(_i) = [ geton $(_i) : CCFLAGS1 ] [ geton $(_i) : CCFLAGS2 ] ; 3687#Echo "object '" $(_i) "' got CCFLAGS1 '" [ geton $(_i) : CCFLAGS1 ] "' and CCFLAGS2 '" [ geton $(_i) : CCFLAGS2 ] "' for total CCFLAGS '" [ geton $(_i) : CCFLAGS ] "'" ; 3688 } 3689 } 3690} 3691 3692# Add extra C++FLAGS to objects 3693# ObjectC++Flags objects : flags ; 3694rule ObjectC++Flags 3695{ 3696#Echo "ObjectC++FLags got '" $(<) "' and '" $(>) "'" ; 3697 local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ; 3698 local _i ; 3699 3700 for _i in $(_t) { 3701 C++FLAGS1 on $(_i) += $(>) ; 3702 C++FLAGS on $(_i) = [ geton $(_i) : C++FLAGS1 ] [ geton $(_i) : C++FLAGS2 ] ; 3703 } 3704} 3705 3706# Add extra PREF_C++FLAGS to objects 3707# ObjectPrefC++Flags objects : flags ; 3708rule ObjectPrefC++Flags 3709{ 3710#Echo "ObjectPrefC++FLags got '" $(<) "' and '" $(>) "'" ; 3711 if ! $(P_PREF_C++FLAGS) { 3712 local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ; 3713 local _i ; 3714 3715 for _i in $(_t) { 3716 C++FLAGS2 on $(_i) += $(>) ; 3717 C++FLAGS on $(_i) = [ geton $(_i) : C++FLAGS1 ] [ geton $(_i) : C++FLAGS2 ] ; 3718 } 3719 } 3720} 3721 3722# Add extra DEFINES to objects 3723# ObjectDefines objects : defines ; 3724rule ObjectDefines 3725{ 3726 # must reformat CCDEFS according to current defines 3727 3728 local s = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ; 3729 3730 DEFINES on $(s) += $(>) ; 3731 CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ; 3732} 3733 3734# Add extra header search paths to objects. 3735# ObjectHdrs objects : dirs ; 3736rule ObjectHdrs 3737{ 3738#Echo "ObjectHdrs HDRS got '" $(<) "' and '" $(>) "'" ; 3739 # Add to HDRS for CCHDRS benefit. 3740 local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ; 3741 local _h = [ NormSrcPaths $(>) ] ; 3742 local _i _s ; 3743 3744#Echo "ObjectHdrs changed HDRS on '" $(_t) "' from '" [ geton $(_t) : HDRS ] "'" ; 3745 HDRS on $(_t) += $(_h) ; 3746#Echo " to '" [ geton $(_t) : HDRS ] "'" ; 3747 for _i in $(_t) { 3748 _s = [ geton $(_i) : SOURCE ] ; 3749#Echo " obj '" $(_i) "' has source '" $(_s) "'" ; 3750#Echo " ObjectHdrs changed HDRSEARCH on '" $(_s) "' from '" [ geton $(_s) : HDRSEARCH ] "'" ; 3751 HDRSEARCH2 on $(_s) += $(_h) ; 3752 HDRSEARCH on $(_s) = [ geton $(_s) : HDRSEARCH1 ] [ geton $(_s) : HDRSEARCH2 ] 3753 [ geton $(_s) : HDRSEARCH3 ] ; 3754#Echo " to '" [ geton $(_s) : HDRSEARCH ] "'" ; 3755 CCHDRS on $(_i) = [ on $(_i) FIncludes $(HDRS) ] ; 3756 } 3757} 3758 3759# Set KEEPOBJS on the given headers 3760# ObjectKeep objects ; 3761rule ObjectKeep 3762{ 3763#Echo "ObjectKeep got '" $(<) "" ; 3764 local _t = [ NormDstTargets $(<:S=$(SUFOBJ)) ] ; 3765 3766 KEEPOBJS on $(_t) = "true" ; 3767#Echo "ObjectHdrs changed KEEPOBJS on '" $(_t) "' to '" [ geton $(_t[1]) : KEEPOBJS ] "'" ; 3768} 3769 3770# Create object files from sources. 3771# Objects sources : flags : defines : hdrpaths ; 3772rule Objects 3773{ 3774#Echo "Objects got src '" $(<) "' flags '" $(2) "' def '" $(3) "' hdrs '" $(4) "'" ; 3775 local _i ; 3776 3777 for _i in $(<) { 3778 Object $(_i) : $(_i) : $(2) : $(3) : $(4) ; 3779 } 3780} 3781 3782# Marks sources as temporary with the TEMPORARY rule, and deletes sources once targets are built. 3783# Must be the last rule invoked on targets. 3784# RmTemps targets : sources ; 3785rule RmTemps 3786{ 3787 local _s = [ NormPaths $(>) ] ; 3788 if $(_s) { 3789 RmTemps_ $(<) : $(_s) ; 3790 } 3791} 3792 3793# internal RmTemps 3794rule RmTemps_ 3795{ 3796 Temporary $(>) ; 3797} 3798 3799# Setuid 3800rule Setuid 3801{ 3802 local _t = [ NormPaths $(>:S=$(SUFEXE)) ] ; 3803 MODE on $(_t) = 4755 ; 3804} 3805 3806# Shell 3807rule Shell 3808{ 3809 local _t = [ NormTargs $(>:S=$(SUFSH)) ] ; 3810 local _s = [ NormSrcTargets $(>[1]) ] ; 3811 Shell_ $(_t) : $(_s) ; 3812} 3813 3814# internal Shell 3815rule Shell_ 3816{ 3817 Depends shell : $(<) ; 3818 Depends $(<) : $(>) ; 3819 MODE on $(<) = $(SHELLMODE) ; 3820 Clean clean : $(<) ; 3821 Chmod_ $(<) ; 3822} 3823 3824# SoftLink 3825rule SoftLink 3826{ 3827 local _t = [ NormDstTargets $(<) ] ; 3828 local _s = [ NormSrcTargets $(>) ] ; 3829 3830 SoftLink_ $(_t) : $(_s) ; 3831} 3832 3833# internal SoftLink 3834rule SoftLink_ 3835{ 3836 Depends files : $(<) ; 3837 Depends $(<) : $(>) ; 3838 Clean clean : $(<) ; 3839} 3840 3841#Adds flags to mark symbols as undefined on link command for images 3842rule Undefines 3843{ 3844 local _t = [ NormDstTargets $(<) ] ; 3845 UNDEFS on [ $(_t:S=$(SUFEXE)) ] += $(UNDEFFLAG)$(>) ; 3846} 3847 3848# User routine to handle objects. Note that 3849# targets and sources are in normalized form. 3850rule UserObject 3851{ 3852 Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ; 3853} 3854 3855# Yacc source.c : source.y ; 3856rule Yacc 3857{ 3858 local _t = [ NormDstTargets $(<[1]) ] ; 3859 local _s = [ NormSrcTargets $(>[1]) ] ; 3860 3861 Yacc_ $(_t) : $(_s) ; 3862} 3863 3864# internal Yacc 3865rule Yacc_ 3866{ 3867 local _h ; 3868 3869 _h = $(<:S=.h) ; 3870 CopyTarget $(_h) : $(<) ; # Transfer LOCATE, SEARCH, NOMLOC 3871 3872 # Some places don't have a yacc. 3873 3874 MakeLocate $(<) $(_h) ; 3875 3876 if $(YACC) 3877 { 3878 Depends $(<) : $(>) ; 3879 FakeFile_ $(_h) : $(<) ; # .h is created with .c 3880 Yacc1_ $(<) $(_h) : $(>) ; 3881 YaccMv_ $(<) $(_h) ; 3882 Clean clean : $(<) $(_h) ; 3883 } 3884 3885 # make sure someone includes $(_h) else it will be 3886 # a deadly independent target 3887 3888 Includes $(<) : $(_h) ; 3889} 3890 3891# Aswig : source.i ; 3892# Argyll C class generator. Creates C class declaration source.h, 3893# C class partial implementation source_i.c, C++ class wrapper 3894# declaration & implementation source.hpp. 3895rule Aswig 3896{ 3897#Echo "Aswig called with $(>) " ; 3898 local _s = [ NormSrcTargets $(>[1]) ] ; 3899 3900 Aswig_ : $(_s) ; 3901} 3902 3903# internal Aswig 3904rule Aswig_ 3905{ 3906#Echo "Aswig_ called with $(>)" ; 3907 local _i = $(>[1]) ; 3908 local _h = $(_i:S=.h) ; 3909 CopyTarget $(_h) : $(_i) ; # Transfer LOCATE, SEARCH, NOMLOC 3910 local _c = $(_i:B=$(_i:B)_i:S=.c) ; 3911 CopyTarget $(_c) : $(_i) ; # Transfer LOCATE, SEARCH, NOMLOC 3912 local _hpp = $(_i:S=.hpp) ; 3913 CopyTarget $(_hpp) : $(_i) ; # Transfer LOCATE, SEARCH, NOMLOC 3914 3915#Echo "Aswig_ creates $(_h) $(_c) $(_hpp) from $(_i) " ; 3916 3917 MakeLocate $(_h) $(_c) $(_hpp) ; 3918 3919 Depends $(_h) : $(_i) ; 3920 FakeFile_ $(_c) : $(_h) ; # _i.c is created with .h 3921 FakeFile_ $(_hpp) : $(_h) ; # _.hpp is created with .h 3922 Aswig1_ $(_h) : $(_i) ; 3923 Clean clean : $(_h) $(_c) $(_hpp) ; 3924} 3925 3926# 3927# Utility rules; no side effects on these 3928# 3929 3930# FReverse a1 a2 a3 ... ; 3931# return ... a3 a2 a1 ; 3932rule FReverse 3933{ 3934 3935 local _i _o = ; 3936 for _i in $(1) 3937 { 3938 _o = $(_i) $(_o) ; 3939 } 3940 return $(_o) ; 3941} 3942 3943# Strip common initial elements of variables v1 and v2. 3944# Modifies the variable values themselves. 3945# FStripCommon v1 : v2 ; 3946rule FStripCommon 3947{ 3948 3949 if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) 3950 { 3951 $(<) = $($(<)[2-]) ; 3952 $(>) = $($(>)[2-]) ; 3953 FStripCommon $(<) : $(>) ; 3954 } 3955} 3956 3957# Append suffix if there is not already one 3958# E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;" 3959# returns (yacc,lex,foo.bat) on Unix and 3960# (yacc.exe,lex.exe,foo.bat) on NT. 3961# FAppendSuffix files : suffix ; 3962rule FAppendSuffix 3963{ 3964 3965 if $(>) 3966 { 3967 local _i _o ; 3968 3969 for _i in $(<) 3970 { 3971 if $(_i:S) 3972 { 3973 _o += $(_i) ; 3974 } 3975 else 3976 { 3977 _o += $(_i:S=$(>)) ; 3978 } 3979 } 3980 return $(_o) ; 3981 } 3982 else 3983 { 3984 return $(<) ; 3985 } 3986} 3987 3988# return a1 a2 ... with any empty elements deleted 3989# FDelEmpty a1 a2 ... ; 3990rule FDelEmpty 3991{ 3992 3993 local _i _o = ; 3994 for _i in $(<) 3995 { 3996 if $(_i) { 3997 _o += $(_i) ; 3998 } 3999 } 4000 return $(_o) ; 4001} 4002 4003# 4004# Operating system specific utility rules 4005# First, the (generic) UNIX versions 4006# 4007 4008rule FQuote { return \\\"$(<)\\\" ; } 4009rule FDefines { local _t = [ FDelEmpty $(<) ] ; return -D$(_t) ; } 4010rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return -I$(_t) ; } 4011 4012if $(OS2) 4013{ 4014 rule FQuote { return \"$(<)\" ; } 4015 rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return /I$(_t) ; } 4016} 4017 4018else if $(NT) 4019{ 4020 if ! $(MINGW) { 4021 rule FDefines { local _t = [ FDelEmpty $(<) ] ; return /D$(_t) ; } 4022 rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return /I$(_t) ; } 4023 } 4024} 4025 4026else if $(MAC) 4027{ 4028 rule FQuote { return \"$(<)\" ; } 4029 rule FDefines { local _t = [ FDelEmpty $(<) ] ; return "-define '$(_t)'" ; } 4030 rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return \"$(_t:J=,)\" ; } 4031} 4032 4033else if $(VMS) 4034{ 4035 rule FQuote { return \"\"\"$(<)\"\"\" ; } 4036 rule FDefines { local _t = [ FDelEmpty $(<) ] ; return "/define=( $(_t:J=,) )" ; } 4037 rule FIncludes { local _t = [ FDelEmpty $(<) ] ; return "/inc=( $(_t:J=,) )" ; } 4038 4039 rule FDirName 4040 { 4041 local _s _i ; 4042 4043 # Turn individual elements in $(<) into a usable path. 4044 4045 if ! $(<) 4046 { 4047 _s = $(DOT) ; 4048 } 4049 else 4050 { 4051 # This handles the following cases: 4052 # a -> [.a] 4053 # a b c -> [.a.b.c] 4054 # x: -> x: 4055 # x: a -> x:[a] 4056 # x:[a] b -> x:[a.b] 4057 4058 switch $(<[1]) 4059 { 4060 case *:* : _s = $(<[1]) ; 4061 case \\[*\\] : _s = $(<[1]) ; 4062 case * : _s = [.$(<[1])] ; 4063 } 4064 4065 for _i in [.$(<[2-])] 4066 { 4067 _s = $(_i:R=$(_s)) ; 4068 } 4069 } 4070 4071 return $(_s) ; 4072 } 4073} 4074 4075# 4076# Actions 4077# 4078 4079# 4080# First the defaults 4081# 4082 4083actions updated together piecemeal Archive 4084{ 4085 $(AR) $(<) $(>) 4086} 4087 4088actions together ArchiveArchive 4089{ 4090 mkdir .jamArchiveArchive$PPID 4091 cp $(>) .jamArchiveArchive$PPID 4092 cd .jamArchiveArchive$PPID 4093 for i in $(>:BS) 4094 do 4095 ar -xo $i 4096 done 4097 cd .. 4098 ar -r $(<) .jamArchiveArchive$PPID/*.o 4099 rm -rf .jamArchiveArchive$PPID 4100} 4101 4102actions As 4103{ 4104 $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>) 4105} 4106 4107actions C++_ 4108{ 4109 $(C++) -c -o $(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 4110} 4111 4112actions Cc_ 4113{ 4114 $(CC) -c -o $(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 4115} 4116 4117actions Chgrp_ 4118{ 4119 $(CHGRP) $(GROUP) $(<) 4120} 4121 4122actions Chmod1 4123{ 4124 $(CHMOD) $(MODE) $(<) 4125} 4126 4127actions Chown_ 4128{ 4129 $(CHOWN) $(OWNER) $(<) 4130} 4131 4132actions piecemeal together existing Clean 4133{ 4134 $(RM) $(>) 4135} 4136 4137actions File_ 4138{ 4139 $(CP) $(>) $(<) 4140} 4141 4142#actions FakeFile_ { } 4143 4144actions GenFile1 4145{ 4146 $(>[1]) $(<) $(>[2-]) 4147} 4148 4149actions GenFileND1 4150{ 4151 $(>) 4152} 4153 4154actions GenFileNND1 4155{ 4156 $(>) 4157} 4158 4159actions CreateCatFile_ 4160{ 4161 $(CP) /Y nul $(<) > nul 4162} 4163 4164actions CatToFile_ 4165{ 4166 echo $(>) >> $(<) 4167} 4168 4169actions Fortran_ 4170{ 4171 $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>) 4172} 4173 4174actions HardLink_ 4175{ 4176 $(RM) $(<) && $(LN) $(>) $(<) 4177} 4178 4179actions Install 4180{ 4181 $(CP) $(>) $(<) 4182} 4183 4184actions Lex_ 4185{ 4186 $(LEX) $(>) 4187} 4188 4189actions LexMv_ 4190{ 4191 $(MV) lex.yy.c $(<) 4192} 4193 4194# Old: $(LINK) $(LINKFLAGS) $(LINKOUTFLAG)$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS) 4195# $(LINK) $(LINKOUTFLAG)$(<) $(UNDEFS) $(>) $(LINKFLAGS) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS) 4196actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS 4197{ 4198 $(LINK) $(LINKOUTFLAG)$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(LINKFLAGS) $(STDLIBS) 4199} 4200 4201if $(OS) = MACOSX { # OS X version of ld 4202 4203 # Link .o and .a into a .dylib 4204 # 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) 4205 # -Wl,-install_name,@executable_path ??? 4206 actions ShLink_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS 4207 { 4208 $(LINK) -dynamiclib -Wl,-undefined,dynamic_lookup,-install_name,$(SHLINKSEARCHEXEPATH)$(<[1]:BS) $(LINKOUTFLAG)$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHLINKFLAGS) $(SHSTDLIBS) 4209 } 4210 4211} else { # General gcc 4212 4213 # Link .o and .a into a .so 4214 # To set .so search path: -Wl,-rpath,$(LINKSHLIBS:D) 4215 # or set LD_LIBRARY_PATH 4216 # or set /etc/ld.so.conf.d/*.conf 4217 # To set .so search path (after flag): -Wl,-soname=$(<[1]:BS) 4218# Old: $(LINK) -shared -Wl,-soname=$(SHLINKSEARCHEXEPATH)$(<[1]:BS) $(SHLINKFLAGS) $(LINKOUTFLAG)$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS) 4219 actions ShLink_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS 4220 { 4221 $(LINK) -shared -Wl,-soname=$(SHLINKSEARCHEXEPATH)$(<[1]:BS) $(LINKOUTFLAG)$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHLINKFLAGS) $(SHSTDLIBS) 4222 } 4223} 4224 4225actions MkDir1 4226{ 4227 $(MKDIR) $(<) 4228} 4229 4230actions together Ranlib 4231{ 4232 $(RANLIB) $(<) 4233} 4234 4235actions quietly updated piecemeal together RmTemps_ 4236{ 4237 $(RM) $(>) 4238} 4239 4240actions Shell_ 4241{ 4242 $(AWK) ' 4243 NR == 1 { print "$(SHELLHEADER)" } 4244 NR == 1 && /^[#:]/ { next } 4245 /^##/ { next } 4246 { print } 4247 ' < $(>) > $(<) 4248} 4249 4250actions SoftLink_ 4251{ 4252 $(RM) $(<) && $(LN) -s $(>) $(<) 4253} 4254 4255actions Yacc1_ 4256{ 4257 $(YACC) $(YACCFLAGS) $(>) 4258} 4259 4260actions YaccMv_ 4261{ 4262 $(MV) $(YACCFILES).c $(<[1]) 4263 $(MV) $(YACCFILES).h $(<[2]) 4264} 4265 4266actions Aswig1_ 4267{ 4268 aswig $(ASWIGFLAGS) -c++ -a2c $(>) 4269} 4270 4271# 4272# RELOCATE - for compilers with broken -o flags 4273# 4274 4275if $(RELOCATE) 4276{ 4277 actions C++_ 4278 { 4279 $(C++) -c $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 4280 } 4281 4282 actions Cc_ 4283 { 4284 $(CC) -c $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 4285 } 4286 4287 actions ignore CcMv 4288 { 4289 [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<) 4290 } 4291} 4292 4293# 4294# NOARUPDATE - can't update an archive 4295# 4296 4297if $(NOARUPDATE) 4298{ 4299 actions Archive 4300 { 4301 $(AR) $(<) $(>) 4302 } 4303} 4304 4305# 4306# UNIX specific actions 4307# 4308 4309if $(UNIX) 4310{ 4311 actions GenFile1 4312 { 4313 PATH="$PATH:." 4314 $(>[1]) $(<) $(>[2-]) 4315 } 4316 4317 actions CreateCatFile_ 4318 { 4319 $(CP) /dev/null $(<) 4320 } 4321 4322 actions CatToFile_ 4323 { 4324 echo "$(>)" >> $(<) 4325 } 4326 4327 # Make OS X GUI apps work 4328 if $(OS) = MACOSX 4329 { 4330 4331 # Used to use /Developer/Tools/Rez -t APPL Carbon.r -o $(<) 4332 # but this no longer works in OS X 10.5, and we don't need this 4333 # stuff with TransformProcessType() 4334 # Another alternative is to use link option "-sectcreate __TEXT __info_plist Info.plist" ??? 4335 # to embed the plist in the executable, but not sure what should be in plist. 4336 # Pure GUI app 4337 actions GUIAPP 4338 { 4339 rm -rf $(<).app 4340 mkdir -p $(<).app 4341 mkdir $(<).app/Contents 4342 mkdir $(<).app/Contents/Resources 4343 mkdir $(<).app/Contents/MacOS 4344 echo APPLnone > $(<).app/Contents/PkgInfo 4345 mv $(<) $(<).app/Contents/MacOS 4346 chmod 755 $(<).app/Contents/MacOS/$(<:BS) 4347 cat << EOF > $(<).app/Contents/info.plist 4348<?xml version="1.0" encoding="UTF-8"?> 4349<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> 4350<plist version="0.9"> 4351<dict> 4352 <key>CFBundleName</key> 4353 <string>$(<:BS)</string> 4354 <key>CFBundlePackageType</key> 4355 <string>APPL</string> 4356 <key>CFBundleVersion</key> 4357 <string>59</string> 4358 <key>CFBundleShortVersionString</key> 4359 <string>1.1</string> 4360 <key>CFBundleSignature</key> 4361 <string>none</string> 4362</dict> 4363</plist> 4364EOF 4365 cat << EOF > $(<) 4366#!/bin/sh 4367\$0.app/Contents/MacOS/$(<:BS) 4368EOF 4369 chmod 755 $(<) 4370 } 4371 } 4372} 4373 4374# 4375# NT specific actions 4376# 4377 4378if $(NT) 4379{ 4380 # Ensure timestamp is updated 4381 4382 actions File_ 4383 { 4384 $(CP) /b $(>) + nul $(<) > nul 4385 } 4386 4387 actions Install 4388 { 4389 $(CP) /b $(>) + nul $(<) > nul 4390 } 4391} 4392 4393if $(NT) && $(MSVCNT) 4394{ 4395# actions updated together piecemeal Archive 4396# { 4397# if exist $(<) set _$(<:B)_=$(<) 4398# $(AR) /out:$(<) %_$(<:B)_% $(>) 4399# } 4400 4401 # This is slightly dodgy if you've got multiple 4402 # libraries with the same name in different directories with 4403 # jam -j n, or you have .obj's distinguished only by their directory 4404 # being combined into the same library, but it overcomes 4405 # the problem of lib not updating a library properly if 4406 # jam is involked from different directories. 4407 actions updated together piecemeal Archive 4408 { 4409 if exist $(<:BS)_ RMDIR /S/Q $(<:BS)_ 4410 MKDIR $(<:BS)_ 4411 for %%i in ( $(>) ) do COPY %%i $(<:BS)_ 1>nul 4412 if exist $(<) set _$(<:B)_=$(<) 4413 $(AR) /out:$(<) %_$(<:B)_% $(<:BS)_\* 4414 DEL /F/S/Q $(<:BS)_\* 1>nul 4415 RMDIR /Q $(<:BS)_ 4416 } 4417 4418 actions together ArchiveArchive 4419 { 4420 $(AR) /out:$(<) $(>) 4421 } 4422 4423 actions As 4424 { 4425 $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul; 4426 } 4427 4428 actions Cc_ 4429 { 4430 $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>) 4431 } 4432 4433 actions C++_ 4434 { 4435 $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp $(>) 4436 } 4437 4438 actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS 4439 { 4440 $(LINK) $(LINKFLAGS) $(P_LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS) 4441 } 4442 4443 # Create DLL using export attribute 4444 actions ShLink_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS 4445 { 4446 $(LINK) /DLL $(SHLINKFLAGS) /out:$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS) 4447 } 4448 4449 # Create DLL using .def file 4450 actions ShLinkDef_ bind SHLINKDEFFILE SHLINKOBJS SHLINKLIBS SHLINKSHLIBS 4451 { 4452 $(LINK) /DLL /DEF:$(SHLINKDEFFILE) $(SHLINKFLAGS) /out:$(<[1]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS) 4453 } 4454} 4455else if $(NT) && $(MSVC) 4456{ 4457 actions updated together piecemeal Archive 4458 { 4459 $(AR) $(<) -+$(>) 4460 } 4461 4462 actions Cc_ 4463 { 4464 $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 4465 } 4466 4467 actions C++_ 4468 { 4469 $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /Tp $(>) 4470 } 4471 4472 actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS 4473 { 4474 $(LINK) $(LINKFLAGS) $(P_LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS) 4475 } 4476} 4477else if $(NT) && $(BCCROOT) 4478{ 4479 actions updated together piecemeal Archive 4480 { 4481 $(AR) $(<) -+$(>) 4482 } 4483 4484 actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS 4485 { 4486 $(LINK) -e$(<) $(LINKFLAGS) $(P_LINKFLAGS) $(UNDEFS) -L$(STDLIBS) $(LINKLIBS) $(LINKSHLIBS) $(>) $(LINKOBJS) 4487 } 4488 4489 actions C++_ 4490 { 4491 $(C++) -c -o$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 4492 } 4493 4494 actions Cc_ 4495 { 4496 $(CC) -c -o$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 4497 } 4498} 4499 4500else if $(NT) && $(MINGW) { 4501 4502 # Create DLL using export attribute 4503 actions ShLink_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS 4504 { 4505 $(LINK) -shared $(SHLINKFLAGS) $(LINKOUTFLAG)$(<[1]) -Wl,--out-implib,$(<[2]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS) 4506 } 4507 # Create DLL using .def file 4508 actions ShLinkDef_ bind SHLINKOBJS SHLINKLIBS SHLINKSHLIBS SHLINKDEFFILE 4509 { 4510 $(LINK) -shared $(SHLINKFLAGS) $(LINKOUTFLAG)$(<[1]) -Wl,--out-implib,$(<[2]) $(>) $(SHLINKOBJS) $(SHLINKLIBS) $(SHLINKSHLIBS) $(SHSTDLIBS) $(SHLINKDEFFILE) 4511 } 4512} 4513 4514# 4515# OS2 specific actions 4516# 4517 4518else if $(OS2) && $(WATCOM) 4519{ 4520 actions together piecemeal Archive 4521 { 4522 $(AR) $(<) +-$(>) 4523 } 4524 4525 actions Cc_ 4526 { 4527 $(CC) /Fo=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 4528 } 4529 4530 actions C++_ 4531 { 4532 $(C++) /Fo=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 4533 } 4534 4535 actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS 4536 { 4537 $(LINK) $(LINKFLAGS) $(P_LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(LINKOBJS) $(LINKLIBS) $(LINKSHLIBS) $(STDLIBS) 4538 } 4539 4540 actions Shell_ 4541 { 4542 $(CP) $(>) $(<) 4543 } 4544} 4545 4546# 4547# VMS specific actions 4548# 4549 4550else if $(VMS) 4551{ 4552 actions updated together piecemeal Archive 4553 { 4554 lib/replace $(<) $(>[1]) ,$(>[2-]) 4555 } 4556 4557 actions Cc_ 4558 { 4559 $(CC)/obj=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 4560 } 4561 4562 actions C++_ 4563 { 4564 $(C++)/obj=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 4565 } 4566 4567 actions piecemeal together existing Clean 4568 { 4569 $(RM) $(>[1]);* ,$(>[2-]);* 4570 } 4571 4572 actions together quietly CreLib 4573 { 4574 if f$search("$(<)") .eqs. "" then lib/create $(<) 4575 } 4576 4577 actions GenFile1 4578 { 4579 mcr $(>[1]) $(<) $(>[2-]) 4580 } 4581 4582 actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS 4583 { 4584 $(LINK)/exe=$(<) $(LINKFLAGS) $(P_LINKFLAGS) $(>:J=,) ,$(LINKOBJS:J=,) ,$(LINKLIBS)/lib ,$(LINKSHLIBS)/lib ,$(STDLIBS) 4585 } 4586 4587 actions quietly updated piecemeal together RmTemps_ 4588 { 4589 $(RM) $(>[1]);* ,$(>[2-]);* 4590 } 4591 4592 actions Shell_ 4593 { 4594 $(CP) $(>) $(<) 4595 } 4596} 4597 4598# 4599# Mac specifc actions 4600# 4601 4602else if $(MAC) 4603{ 4604 actions together Archive 4605 { 4606 $(LINK) -library -o $(<) $(>) 4607 } 4608 4609 actions Cc_ 4610 { 4611 set -e MWCincludes $(CCHDRS) 4612 $(CC) -o $(<) $(CCFLAGS) $(CCDEFS) $(>) 4613 } 4614 4615 actions C++_ 4616 { 4617 set -e MWCincludes $(CCHDRS) 4618 $(CC) -o $(<) $(C++FLAGS) $(CCDEFS) $(>) 4619 } 4620 4621 actions Link_ bind LINKOBJS LINKLIBS LINKSHLIBS 4622 { 4623 $(LINK) -o $(<) $(LINKOBJS) $(LINKFLAGS) $(P_LINKFLAGS) $(>) $(LINKLIBS) $(LINKSHLIBS) "$(STDLIBS)" 4624 } 4625} 4626 4627if $(WIN98) 4628{ 4629 actions existing Clean 4630 { 4631 del $(>) 4632 } 4633} 4634 4635# ========================================= 4636 4637# Now do Argyll init and read default Jamtop 4638DoInit ; 4639 4640# 4641# Now include the user's Jamfile. 4642# 4643 4644#PeerInclude $(DOT) ; 4645SubInclude $(DOT) ; 4646 4647