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# 10# JAMBASE - jam 2.5 ruleset providing make(1)-like functionality 11# 12# Supports UNIX, NT, and VMS. 13# 14# 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST 15# 04/18/94 (seiwald) - use '?=' when setting OS specific vars 16# 04/21/94 (seiwald) - do RmTemps together 17# 05/05/94 (seiwald) - all supported C compilers support -o: relegate 18# RELOCATE as an option; set Ranlib to "" to disable it 19# 06/01/94 (seiwald) - new 'actions existing' to do existing sources 20# 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS 21# 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS 22# 09/19/94 (seiwald) - LinkLibraries and Undefs now append 23# - Rule names downshifted. 24# 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile. 25# 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files. 26# 01/08/95 (seiwald) - Shell now handled with awk, not sed 27# 01/09/95 (seiwald) - Install* now take dest directory as target 28# 01/10/95 (seiwald) - All entries sorted. 29# 01/10/95 (seiwald) - NT support moved in, with LauraW's help. 30# 01/10/95 (seiwald) - VMS support moved in. 31# 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added. 32# 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE. 33# 02/08/95 (seiwald) - SubDir works on VMS. 34# 02/14/95 (seiwald) - MkDir and entourage. 35# 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves. 36# 07/10/95 (taylor) - Support for Microsoft C++. 37# 11/21/96 (peterk) - Support for BeOS 38# 07/19/99 (sickel) - Support for Mac OS X Server (and maybe client) 39# 02/18/00 (belmonte)- Support for Cygwin. 40 41# Special targets defined in this file: 42# 43# all - parent of first, shell, files, lib, exe 44# first - first dependent of 'all', for potential initialization 45# shell - parent of all Shell targets 46# files - parent of all File targets 47# lib - parent of all Library targets 48# exe - parent of all Main targets 49# dirs - parent of all MkDir targets 50# clean - removes all Shell, File, Library, and Main targets 51# uninstall - removes all Install targets 52# 53 54# Rules defined by this file: 55# 56# as obj.o : source.s ; .s -> .o 57# Bulk dir : files ; populate directory with many files 58# Cc obj.o : source.c ; .c -> .o 59# C++ obj.o : source.cc ; .cc -> .o 60# Clean clean : sources ; remove sources with 'jam clean' 61# File dest : source ; copy file 62# Fortran obj.o : source.f ; .f -> .o 63# GenFile source.c : program args ; make custom file 64# HardLink target : source ; make link from source to target 65# HdrRule source : headers ; handle #includes 66# InstallInto dir : sources ; install any files 67# InstallBin dir : sources ; install binaries 68# InstallLib dir : sources ; install files 69# InstallFile dir : sources ; install files 70# InstallMan dir : sources ; install man pages 71# InstallShell dir : sources ; install shell scripts 72# Lex source.c : source.l ; .l -> .c 73# Library lib : source ; archive library from compiled sources 74# LibraryFromObjects lib : objects ; archive library from objects 75# LinkLibraries images : libraries ; bag libraries onto Mains 76# LocalClean target : deps ; a conditional Clean 77# LocalDepends target : deps ; a conditional Depends 78# Main image : source ; link executable from compiled sources 79# MainFromObjects image : objects ; link executable from objects 80# MkDir dir ; make a directory, if not there 81# Object object : source ; compile object from source 82# ObjectCcFlags source : flags ; add compiler flags for object 83# ObjectC++Flags source : flags ; add compiler flags for object 84# ObjectHdrs source : dirs ; add include directories for object 85# Objects sources ; compile sources 86# RmTemps target : sources ; remove temp sources after target made 87# Setuid images ; mark executables Setuid 88# SoftLink target : source ; make symlink from source to target 89# SubDir TOP d1 d2 ... ; start a subdirectory Jamfile 90# SubDirCcFlags flags ; add compiler flags until next SubDir 91# SubDirC++Flags flags ; add compiler flags until next SubDir 92# SubDirHdrs d1 d2 ... ; add include dir until next SubDir 93# SubInclude TOP d1 d2 ... ; include a subdirectory Jamfile 94# Shell exe : source ; make a shell executable 95# Undefines images : symbols ; save undef's for linking 96# UserObject object : source ; handle unknown suffixes for Object 97# Yacc source.c : source.y ; .y -> .c 98# 99# Utility rules that have no side effects (not supported): 100# 101# FAppendSuffix f1 f2 ... : $(SUF) ; return $(<) with suffixes 102# FDirName d1 d2 ... ; return path from root to dir 103# FGrist d1 d2 ... ; return d1!d2!... 104# FGristFiles value ; return $(value:G=$(SOURCE_GRIST)) 105# FGristSourceFiles value ; return $(value:G=$(SOURCE_GRIST)) 106# FIsPrefix a : b ; return whether or not a is a prefix of b 107# FStripCommon v1 : v2 ; strip common initial parts of v1 v2 108# FReverse a1 a2 ... ; return ... a2 a1 109# FRelPath d1 : d2 ; return rel path from d1 to d2 110# FSubDir d1 d2 ... ; return path to root 111# 112 113 114# Brief review of the jam language: 115# 116# Statements: 117# rule RULE - statements to process a rule 118# actions RULE - system commands to carry out target update 119# 120# Modifiers on actions: 121# together - multiple instances of same rule on target get executed 122# once with their sources ($(>)) concatenated 123# updated - refers to updated sources ($(>)) only 124# ignore - ignore return status of command 125# quietly - don't trace its execution unless verbose 126# piecemeal - iterate command each time with a small subset of $(>) 127# existing - refers to currently existing sources ($(>)) only 128# bind vars - subject to binding before expanding in actions 129# 130# Special rules: 131# Always - always build a target 132# Depends - builds the dependency graph 133# Echo - blurt out targets on stdout 134# Exit - blurt out targets and exit 135# Includes - marks sources as headers for target (a codependency) 136# NoCare - don't panic if the target can't be built 137# NoUpdate - create the target if needed but never update it 138# NotFile - ignore the timestamp of the target (it's not a file) 139# Temporary - target need not be present if sources haven't changed 140# 141# Special variables set by jam: 142# $(<) - targets of a rule (to the left of the :) 143# $(>) - sources of a rule (to the right of the :) 144# $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC) 145# $(OS) - name of OS - varies wildly 146# $(JAMVERSION) - version number (2.5) 147# 148# Special variables used by jam: 149# SEARCH - where to find something (used during binding and actions) 150# LOCATE - where to plop something not found with SEARCH 151# HDRRULE - rule to call to handle include files 152# HDRSCAN - egrep regex to extract include files 153# 154# Special targets: 155# all - default if none given on command line 156# 157 158# for perforce use -- jambase version 159 160JAMBASEDATE = 2002.05.09 ; 161 162# Initialize variables 163# 164 165# 166# OS specific variable settings 167# 168 169if $(NT) 170{ 171 MV ?= move /y ; 172 CP ?= copy ; 173 RM ?= del /f/q ; 174 RMDIR ?= rmdir /s/q ; 175 SLASH ?= \\ ; 176 SUFLIB ?= .lib ; 177 SUFOBJ ?= .obj ; 178 SUFEXE ?= .exe ; 179 180 if $(BCCROOT) 181 { 182 AR ?= tlib /C /P64 ; 183 CC ?= bcc32 ; 184 CCFLAGS ?= -v -w- -q -DWIN -tWR -tWM -tWC ; 185 C++ ?= $(CC) ; 186 C++FLAGS ?= $(CCFLAGS) -P ; 187 LINK ?= $(CC) ; 188 LINKFLAGS ?= $(CCFLAGS) ; 189 STDLIBPATH ?= $(BCCROOT)\\lib ; 190 STDHDRS ?= $(BCCROOT)\\include ; 191 NOARSCAN ?= true ; 192 } 193 else if $(MSVC) 194 { 195 AR ?= lib /nologo ; 196 CC ?= cl /nologo ; 197 CCFLAGS ?= /D \"WIN\" ; 198 C++ ?= $(CC) ; 199 C++FLAGS ?= $(CCFLAGS) ; 200 LINK ?= $(CC) ; 201 LINKFLAGS ?= $(CCFLAGS) ; 202 LINKLIBS ?= 203 $(MSVC)\\lib\\mlibce.lib 204 $(MSVC)\\lib\\oldnames.lib 205 ; 206 LINKLIBS ?= ; 207 NOARSCAN ?= true ; 208 OPTIM ?= ; 209 STDHDRS ?= $(MSVC)\\include ; 210 UNDEFFLAG ?= "/u _" ; 211 } 212 else if $(MSVCNT) || $(MSVCDIR) 213 { 214 # Visual C++ 6.0 uses MSVCDIR 215 216 MSVCNT ?= $(MSVCDIR) ; 217 218 # bury IA64 in the path for the SDK 219 220 local I ; if $(OSPLAT) = IA64 { I = ia64\\ ; } else { I = "" ; } 221 222 AR ?= lib ; 223 AS ?= masm386 ; 224 CC ?= cl /nologo ; 225 CCFLAGS ?= "" ; 226 C++ ?= $(CC) ; 227 C++FLAGS ?= $(CCFLAGS) ; 228 LINK ?= link /nologo ; 229 LINKFLAGS ?= "" ; 230 LINKLIBS ?= 231 $(MSVCNT)\\lib\\$(I)libc.lib 232 $(MSVCNT)\\lib\\$(I)oldnames.lib 233 $(MSVCNT)\\lib\\$(I)kernel32.lib ; 234 OPTIM ?= "" ; 235 STDHDRS ?= $(MSVCNT)\\include ; 236 UNDEFFLAG ?= "/u _" ; 237 } 238 else 239 { 240 EXIT On NT, set BCCROOT, MSVCDIR, MSVCNT, or MSVC to the root 241 of the Borland or Microsoft directories. ; 242 } 243 244} 245else if $(MINGW) 246{ 247 Echo "MingW32" ; 248 249 CC ?= gcc ; 250 C++ ?= g++ ; 251 CCFLAGS += -DMINGW ; 252 RANLIB ?= "ranlib" ; 253 SUFEXE ?= .exe ; 254} 255else if $(OS2) 256{ 257 WATCOM ?= $(watcom) ; 258 259 if ! $(WATCOM) 260 { 261 Exit On OS2, set WATCOM to the root of the Watcom directory. ; 262 } 263 264 AR ?= wlib ; 265 BINDIR ?= \\os2\\apps ; 266 CC ?= wcc386 ; 267 CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet 268 C++ ?= wpp386 ; 269 C++FLAGS ?= $(CCFLAGS) ; 270 CP ?= copy ; 271 DOT ?= . ; 272 DOTDOT ?= .. ; 273 LINK ?= wcl386 ; 274 LINKFLAGS ?= /zq ; # zq=quiet 275 LINKLIBS ?= ; 276 MV ?= move ; 277 NOARSCAN ?= true ; 278 OPTIM ?= ; 279 RM ?= del /f ; 280 SLASH ?= \\ ; 281 STDHDRS ?= $(WATCOM)\\h ; 282 SUFEXE ?= .exe ; 283 SUFLIB ?= .lib ; 284 SUFOBJ ?= .obj ; 285 UNDEFFLAG ?= "/u _" ; 286 287} 288else if $(VMS) 289{ 290 C++ ?= cxx ; 291 C++FLAGS ?= ; 292 CC ?= cc ; 293 CCFLAGS ?= ; 294 CHMOD ?= set file/prot= ; 295 CP ?= copy/replace ; 296 CRELIB ?= true ; 297 DOT ?= [] ; 298 DOTDOT ?= [-] ; 299 EXEMODE ?= (w:e) ; 300 FILEMODE ?= (w:r) ; 301 HDRS ?= ; 302 LINK ?= link ; 303 LINKFLAGS ?= "" ; 304 LINKLIBS ?= ; 305 MKDIR ?= create/dir ; 306 MV ?= rename ; 307 OPTIM ?= "" ; 308 RM ?= delete ; 309 RUNVMS ?= mcr ; 310 SHELLMODE ?= (w:er) ; 311 SLASH ?= . ; 312 STDHDRS ?= decc$library_include ; 313 SUFEXE ?= .exe ; 314 SUFLIB ?= .olb ; 315 SUFOBJ ?= .obj ; 316 317 switch $(OS) 318 { 319 case OPENVMS : CCFLAGS ?= /stand=vaxc ; 320 case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ; 321 } 322} 323else if $(MAC) 324{ 325 local OPT ; 326 327 CW ?= "{CW}" ; 328 329 MACHDRS ?= 330 "$(UMACHDRS):Universal:Interfaces:CIncludes" 331 "$(CW):MSL:MSL_C:MSL_Common:Include" 332 "$(CW):MSL:MSL_C:MSL_MacOS:Include" ; 333 334 MACLIBS ?= 335 "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" 336 "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ; 337 338 MPWLIBS ?= 339 "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" 340 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ; 341 342 MPWNLLIBS ?= 343 "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" 344 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ; 345 346 SIOUXHDRS ?= ; 347 348 SIOUXLIBS ?= 349 "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib" 350 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib" 351 "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ; 352 353 C++ ?= mwcppc ; 354 C++FLAGS ?= -w off ; 355 CC ?= mwcppc ; 356 CCFLAGS ?= -w off ; 357 CP ?= duplicate -y ; 358 DOT ?= ":" ; 359 DOTDOT ?= "::" ; 360 HDRS ?= $(MACHDRS) $(MPWHDRS) ; 361 LINK ?= mwlinkppc ; 362 LINKFLAGS ?= -mpwtool -warn ; 363 LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ; 364 MKDIR ?= newfolder ; 365 MV ?= rename -y ; 366 NOARSCAN ?= true ; 367 OPTIM ?= ; 368 RM ?= delete -y ; 369 SLASH ?= ":" ; 370 STDHDRS ?= ; 371 SUFLIB ?= .lib ; 372 SUFOBJ ?= .o ; 373} 374else if $(OS) = BEOS && $(OSPLAT) = PPC 375{ 376 AR ?= mwld -xml -o ; 377 BINDIR ?= /boot/home/config/bin ; 378 CC ?= mwcc ; 379 CCFLAGS ?= -nosyspath ; 380 C++ ?= $(CC) ; 381 C++FLAGS ?= -nosyspath ; 382 CHMOD ?= chmod ; 383 CHGRP ?= chgrp ; 384 CHOWN ?= chown ; 385 FORTRAN ?= "" ; 386 LEX ?= flex ; 387 LIBDIR ?= /boot/home/config/lib ; 388 LINK ?= mwld ; 389 LINKFLAGS ?= "" ; 390 MANDIR ?= /boot/home/config/man ; 391 NOARSCAN ?= true ; 392 RANLIB ?= ranlib ; 393 STDHDRS ?= /boot/develop/headers/posix ; 394 YACC ?= bison -y ; 395 YACCGEN ?= .c ; 396 YACCFILES ?= y.tab ; 397 YACCFLAGS ?= -d ; 398} 399else if $(OS) = BEOS 400{ 401 BINDIR ?= /boot/home/config/bin ; 402 CC ?= gcc ; 403 C++ ?= $(CC) ; 404 CHMOD ?= chmod ; 405 CHGRP ?= chgrp ; 406 CHOWN ?= chown ; 407 FORTRAN ?= "" ; 408 LEX ?= flex ; 409 LIBDIR ?= /boot/home/config/lib ; 410 LINK ?= gcc ; 411 MANDIR ?= /boot/home/config/man ; 412 NOARSCAN ?= true ; 413 RANLIB ?= ranlib ; 414 STDHDRS ?= /boot/develop/headers/posix ; 415 YACC ?= bison -y ; 416 YACCGEN ?= .c ; 417 YACCFILES ?= y.tab ; 418 YACCFLAGS ?= -d ; 419} 420else if $(OS) = HAIKU 421{ 422 BINDIR ?= /boot/common/bin ; 423 CC ?= gcc ; 424 C++ ?= $(CC) ; 425 CHMOD ?= chmod ; 426 CHGRP ?= chgrp ; 427 CHOWN ?= chown ; 428 FORTRAN ?= "" ; 429 LEX ?= flex ; 430 LIBDIR ?= /boot/common/lib ; 431 LINK ?= gcc ; 432 MANDIR ?= /boot/common/man ; 433 NOARSCAN ?= true ; 434 RANLIB ?= ranlib ; 435 STDHDRS ?= /boot/develop/headers/posix ; 436 YACC ?= bison -y ; 437 YACCGEN ?= .c ; 438 YACCFILES ?= y.tab ; 439 YACCFLAGS ?= -d ; 440} 441else if $(UNIX) 442{ 443 switch $(OS) 444 { 445 case AIX : 446 LINKLIBS ?= -lbsd ; 447 448 case AMIGA : 449 CC ?= gcc ; 450 YACC ?= bison -y ; 451 452 case CYGWIN : 453 CC ?= gcc ; 454 CCFLAGS += -D__cygwin__ ; 455 LEX ?= flex ; 456 JAMSHELL ?= sh -c ; 457 RANLIB ?= "" ; 458 SUFEXE ?= .exe ; 459 YACC ?= bison -y ; 460 461 case DGUX : 462 RANLIB ?= "" ; 463 RELOCATE ?= true ; 464 465 case HPUX : 466 RANLIB ?= "" ; 467 468 case INTERIX : 469 CC ?= gcc ; 470 JAMSHELL ?= sh -c ; 471 RANLIB ?= "" ; 472 473 case IRIX : 474 RANLIB ?= "" ; 475 476 case MPEIX : 477 CC ?= gcc ; 478 C++ ?= gcc ; 479 CCFLAGS += -D_POSIX_SOURCE ; 480 HDRS += /usr/include ; 481 RANLIB ?= "" ; 482 NOARSCAN ?= true ; 483 NOARUPDATE ?= true ; 484 485 case MVS : 486 RANLIB ?= "" ; 487 488 case NEXT : 489 AR ?= libtool -o ; 490 RANLIB ?= "" ; 491 492 case MACOSX : 493 C++ ?= c++ ; 494 MANDIR ?= /usr/local/share/man ; 495 496 case NCR : 497 RANLIB ?= "" ; 498 499 case PTX : 500 RANLIB ?= "" ; 501 502 case QNX : 503 AR ?= wlib ; 504 CC ?= cc ; 505 CCFLAGS ?= -Q ; # quiet 506 C++ ?= $(CC) ; 507 C++FLAGS ?= -Q ; # quiet 508 LINK ?= $(CC) ; 509 LINKFLAGS ?= -Q ; # quiet 510 NOARSCAN ?= true ; 511 RANLIB ?= "" ; 512 513 case SCO : 514 RANLIB ?= "" ; 515 RELOCATE ?= true ; 516 517 case SINIX : 518 RANLIB ?= "" ; 519 520 case SOLARIS : 521 RANLIB ?= "" ; 522 AR ?= "/usr/ccs/bin/ar ru" ; 523 524 case UNICOS : 525 NOARSCAN ?= true ; 526 OPTIM ?= -O0 ; 527 528 case UNIXWARE : 529 RANLIB ?= "" ; 530 RELOCATE ?= true ; 531 } 532 533 # UNIX defaults 534 535 CCFLAGS ?= ; 536 C++FLAGS ?= $(CCFLAGS) ; 537 CHMOD ?= chmod ; 538 CHGRP ?= chgrp ; 539 CHOWN ?= chown ; 540 LEX ?= lex ; 541 LINKFLAGS ?= $(CCFLAGS) ; 542 LINKLIBS ?= ; 543 OPTIM ?= ; 544 RANLIB ?= ranlib ; 545 YACC ?= yacc ; 546 YACCGEN ?= .c ; 547 YACCFILES ?= y.tab ; 548 YACCFLAGS ?= -d ; 549} 550 551# 552# General defaults; a lot like UNIX 553# 554 555 AR ?= ar ru ; 556 AS ?= as ; 557 ASFLAGS ?= ; 558 AWK ?= awk ; 559 BINDIR ?= /usr/local/bin ; 560 C++ ?= cc ; 561 C++FLAGS ?= ; 562 CC ?= cc ; 563 CCFLAGS ?= ; 564 CP ?= cp -f ; 565 CRELIB ?= ; 566 DOT ?= . ; 567 DOTDOT ?= .. ; 568 EXEMODE ?= 711 ; 569 FILEMODE ?= 644 ; 570 FORTRAN ?= f77 ; 571 FORTRANFLAGS ?= ; 572 HDRS ?= ; 573 INSTALLGRIST ?= installed ; 574 JAMFILE ?= Jamfile ; 575 JAMRULES ?= Jamrules ; 576 LEX ?= ; 577 LIBDIR ?= /usr/local/lib ; 578 LINK ?= $(CC) ; 579 LINKFLAGS ?= ; 580 LINKLIBS ?= ; 581 LN ?= ln ; 582 MANDIR ?= /usr/local/man ; 583 MKDIR ?= mkdir ; 584 MV ?= mv -f ; 585 OPTIM ?= ; 586 RCP ?= rcp ; 587 RM ?= rm -f ; 588 RMDIR ?= $(RM) ; 589 RSH ?= rsh ; 590 SED ?= sed ; 591 SHELLHEADER ?= "#!/bin/sh" ; 592 SHELLMODE ?= 755 ; 593 SLASH ?= / ; 594 STDHDRS ?= /usr/include ; 595 SUBDIRRULES ?= ; 596 SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ; 597 SUFEXE ?= "" ; 598 SUFLIB ?= .a ; 599 SUFOBJ ?= .o ; 600 UNDEFFLAG ?= "-u _" ; 601 YACC ?= ; 602 YACCGEN ?= ; 603 YACCFILES ?= ; 604 YACCFLAGS ?= ; 605 606 HDRPATTERN = 607 "^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ; 608 609 OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; 610 611 612# 613# Base dependencies - first for "bootstrap" kinds of rules 614# 615 616Depends all : shell files lib exe obj ; 617Depends all shell files lib exe obj : first ; 618NotFile all first shell files lib exe obj dirs clean uninstall ; 619Always clean uninstall ; 620 621# 622# Rules 623# 624 625rule As 626{ 627 Depends $(<) : $(>) ; 628 ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ; 629 ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ; 630} 631 632rule Bulk 633{ 634 local i ; 635 636 for i in $(>) 637 { 638 File $(i:D=$(<)) : $(i) ; 639 } 640} 641 642rule Cc 643{ 644 Depends $(<) : $(>) ; 645 646 # If the compiler's -o flag doesn't work, relocate the .o 647 648 if $(RELOCATE) 649 { 650 CcMv $(<) : $(>) ; 651 } 652 653 # Just to clarify here: this sets the per-target CCFLAGS to 654 # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS. 655 # CCHDRS and CCDEFS must be reformatted each time for some 656 # compiles (VMS, NT) that malign multiple -D or -I flags. 657 658 CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ; 659 660 CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; 661 CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; 662} 663 664rule C++ 665{ 666 Depends $(<) : $(>) ; 667 668 if $(RELOCATE) 669 { 670 CcMv $(<) : $(>) ; 671 } 672 673 C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) $(OPTIM) ; 674 675 CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; 676 CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; 677} 678 679rule Chmod 680{ 681 if $(CHMOD) { Chmod1 $(<) ; } 682} 683 684rule File 685{ 686 LocalDepends files : $(<) ; 687 Depends $(<) : $(>) ; 688 SEARCH on $(>) = $(SEARCH_SOURCE) ; 689 MODE on $(<) = $(FILEMODE) ; 690 Chmod $(<) ; 691} 692 693rule Fortran 694{ 695 Depends $(<) : $(>) ; 696} 697 698rule GenFile 699{ 700 local _t = [ FGristSourceFiles $(<) ] ; 701 local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ; 702 Depends $(_t) : $(_s) $(>[2-]) ; 703 GenFile1 $(_t) : $(_s) $(>[2-]) ; 704 LocalClean clean : $(_t) ; 705} 706 707rule GenFile1 708{ 709 MakeLocate $(<) : $(LOCATE_SOURCE) ; 710 SEARCH on $(>) = $(SEARCH_SOURCE) ; 711} 712 713rule HardLink 714{ 715 LocalDepends files : $(<) ; 716 Depends $(<) : $(>) ; 717 SEARCH on $(>) = $(SEARCH_SOURCE) ; 718} 719 720rule HdrRule 721{ 722 # HdrRule source : headers ; 723 724 # N.B. This rule is called during binding, potentially after 725 # the fate of many targets has been determined, and must be 726 # used with caution: don't add dependencies to unrelated 727 # targets, and don't set variables on $(<). 728 729 # Tell Jam that anything depending on $(<) also depends on $(>), 730 # set SEARCH so Jam can find the headers, but then say we don't 731 # care if we can't actually find the headers (they may have been 732 # within ifdefs), 733 734 local s = $(>:G=$(HDRGRIST:E)) ; 735 736 Includes $(<) : $(s) ; 737 SEARCH on $(s) = $(HDRSEARCH) ; 738 NoCare $(s) ; 739 740 # Propagate on $(<) to $(>) 741 742 HDRSEARCH on $(s) = $(HDRSEARCH) ; 743 HDRSCAN on $(s) = $(HDRSCAN) ; 744 HDRRULE on $(s) = $(HDRRULE) ; 745 HDRGRIST on $(s) = $(HDRGRIST) ; 746} 747 748rule InstallInto 749{ 750 # InstallInto dir : sources ; 751 752 local i t ; 753 754 t = $(>:G=$(INSTALLGRIST)) ; 755 756 # Arrange for jam install 757 # Arrange for jam uninstall 758 # sources are in SEARCH_SOURCE 759 # targets are in dir 760 761 LocalDepends install : $(t) ; 762 LocalClean uninstall : $(t) ; 763 SEARCH on $(>) = $(SEARCH_SOURCE) ; 764 MakeLocate $(t) : $(<) ; 765 766 # For each source, make gristed target name 767 # and Install, Chmod, Chown, and Chgrp 768 769 for i in $(>) 770 { 771 local tt = $(i:G=$(INSTALLGRIST)) ; 772 773 Depends $(tt) : $(i) ; 774 Install $(tt) : $(i) ; 775 Chmod $(tt) ; 776 777 if $(OWNER) && $(CHOWN) 778 { 779 Chown $(tt) ; 780 OWNER on $(tt) = $(OWNER) ; 781 } 782 783 if $(GROUP) && $(CHGRP) 784 { 785 Chgrp $(tt) ; 786 GROUP on $(tt) = $(GROUP) ; 787 } 788 } 789} 790 791rule InstallBin 792{ 793 local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ; 794 795 InstallInto $(<) : $(_t) ; 796 MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ; 797} 798 799rule InstallFile 800{ 801 InstallInto $(<) : $(>) ; 802 MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; 803} 804 805rule InstallLib 806{ 807 InstallInto $(<) : $(>) ; 808 MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; 809} 810 811rule InstallMan 812{ 813 # Really this just strips the . from the suffix 814 815 local i s d ; 816 817 for i in $(>) 818 { 819 switch $(i:S) 820 { 821 case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ; 822 case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ; 823 case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ; 824 case .n : s = n ; case .man : s = 1 ; 825 } 826 827 d = man$(s) ; 828 829 InstallInto $(d:R=$(<)) : $(i) ; 830 } 831 832 MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; 833} 834 835rule InstallShell 836{ 837 InstallInto $(<) : $(>) ; 838 MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ; 839} 840 841rule Lex 842{ 843 LexMv $(<) : $(>) ; 844 Depends $(<) : $(>) ; 845 MakeLocate $(<) : $(LOCATE_SOURCE) ; 846 LocalClean clean : $(<) ; 847} 848 849rule Library 850{ 851 LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ; 852 Objects $(>) ; 853} 854 855rule LibraryFromObjects 856{ 857 local _i _l _s ; 858 859 # Add grist to file names 860 861 _s = [ FGristFiles $(>) ] ; 862 _l = $(<:S=$(SUFLIB)) ; 863 864 # library depends on its member objects 865 866 if $(KEEPOBJS) 867 { 868 LocalDepends obj : $(_s) ; 869 } 870 else 871 { 872 LocalDepends lib : $(_l) ; 873 } 874 875 # Set LOCATE for the library and its contents. The bound 876 # value shows up as $(NEEDLIBS) on the Link actions. 877 # For compatibility, we only do this if the library doesn't 878 # already have a path. 879 880 if ! $(_l:D) 881 { 882 MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ; 883 } 884 885 if $(NOARSCAN) 886 { 887 # If we can't scan the library to timestamp its contents, 888 # we have to just make the library depend directly on the 889 # on-disk object files. 890 891 Depends $(_l) : $(_s) ; 892 } 893 else 894 { 895 # If we can scan the library, we make the library depend 896 # on its members and each member depend on the on-disk 897 # object file. 898 899 Depends $(_l) : $(_l)($(_s:BS)) ; 900 901 for _i in $(_s) 902 { 903 Depends $(_l)($(_i:BS)) : $(_i) ; 904 } 905 } 906 907 LocalClean clean : $(_l) ; 908 909 if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; } 910 911 Archive $(_l) : $(_s) ; 912 913 if $(RANLIB) { Ranlib $(_l) ; } 914 915 # If we can't scan the library, we have to leave the .o's around. 916 917 if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; } 918} 919 920rule Link 921{ 922 MODE on $(<) = $(EXEMODE) ; 923 Chmod $(<) ; 924} 925 926rule LinkLibraries 927{ 928 # make library dependencies of target 929 # set NEEDLIBS variable used by 'actions Main' 930 931 local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; 932 933 Depends $(_t) : $(>:S=$(SUFLIB)) ; 934 NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ; 935} 936 937rule LocalClean 938{ 939 # LocalClean <targets> : <deps> ; 940 # Like Clean, but has only effect in a Jamfile in the 941 # directory or any of its subdirectories where jam has been invoked. 942 943 if [ FIsPrefix $(SUBDIR_UP) : $(SUBDIR_DOWN) ] { 944 Clean $(1) : $(2) ; 945 } 946} 947 948rule LocalDepends 949{ 950 # LocalDepends <targets> : <deps> ; 951 # Like Depends, but has only effect in a Jamfile in the 952 # directory or any of its subdirectories where jam has been invoked. 953 954 if [ FIsPrefix $(SUBDIR_UP) : $(SUBDIR_DOWN) ] { 955 Depends $(1) : $(2) ; 956 } 957} 958 959rule Main 960{ 961 MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ; 962 Objects $(>) ; 963} 964 965rule MainFromObjects 966{ 967 local _s _t ; 968 969 # Add grist to file names 970 # Add suffix to exe 971 972 _s = [ FGristFiles $(>) ] ; 973 _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; 974 975 # so 'jam foo' works when it's really foo.exe 976 977 if $(_t) != $(<) 978 { 979 Depends $(<) : $(_t) ; 980 NotFile $(<) ; 981 } 982 983 # make compiled sources a dependency of target 984 985 LocalDepends exe : $(_t) ; 986 Depends $(_t) : $(_s) ; 987 MakeLocate $(_t) : $(LOCATE_TARGET) ; 988 989 LocalClean clean : $(_t) ; 990 991 Link $(_t) : $(_s) ; 992} 993 994rule MakeLocate 995{ 996 # MakeLocate targets : directory ; 997 998 # Sets special variable LOCATE on targets, and arranges 999 # with MkDir to create target directory. 1000 1001 # Note we grist the directory name with 'dir', 1002 # so that directory path components and other 1003 # targets don't conflict. 1004 1005 if $(>) 1006 { 1007 LOCATE on $(<) = $(>) ; 1008 Depends $(<) : $(>[1]:G=dir) ; 1009 MkDir $(>[1]:G=dir) ; 1010 } 1011} 1012 1013rule MkDir 1014{ 1015 # MkDir directory ; 1016 1017 # Make a directory and all its parent directories. 1018 1019 # Ignore timestamps on directories: we only care if they 1020 # exist. 1021 1022 NoUpdate $(<) ; 1023 1024 # Don't create . or any directory already created. 1025 1026 if $(<:G=) != $(DOT) && ! $($(<)-mkdir) 1027 { 1028 # Cheesy gate to prevent multiple invocations on same dir 1029 # Arrange for jam dirs 1030 # MkDir1 has the actions 1031 1032 $(<)-mkdir = true ; 1033 LocalDepends dirs : $(<) ; 1034 MkDir1 $(<) ; 1035 1036 # Recursively make parent directories. 1037 # $(<:P) = $(<)'s parent, & we recurse until root 1038 1039 local s = $(<:P) ; 1040 1041 # Don't try to create A: or A:\ on windows 1042 1043 if $(NT) 1044 { 1045 switch $(s) 1046 { 1047 case *: : s = ; 1048 case *:\\ : s = ; 1049 } 1050 } 1051 1052 if $(s) = $(<) 1053 { 1054 # The parent is the same as the dir. 1055 # We're at the root, which some OS's can't stat, so we mark 1056 # it as NotFile. 1057 1058 NotFile $(s) ; 1059 } 1060 else if $(s:G=) 1061 { 1062 # There's a parent; recurse. 1063 1064 Depends $(<) : $(s) ; 1065 MkDir $(s) ; 1066 } 1067 } 1068} 1069 1070rule Object 1071{ 1072 # locate object and search for source, if wanted 1073 1074 LocalClean clean : $(<) ; 1075 1076 MakeLocate $(<) : $(LOCATE_TARGET) ; 1077 SEARCH on $(>) = $(SEARCH_SOURCE) ; 1078 1079 # Save HDRS for -I$(HDRS) on compile. 1080 # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers 1081 # in the .c file's directory, but generated .c files (from 1082 # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly 1083 # different from $(SEARCH_SOURCE). 1084 1085 HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ; 1086 1087 # handle #includes for source: Jam scans for headers with 1088 # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE) 1089 # with the scanned file as the target and the found headers 1090 # as the sources. HDRSEARCH is the value of SEARCH used for 1091 # the found header files. Finally, if jam must deal with 1092 # header files of the same name in different directories, 1093 # they can be distinguished with HDRGRIST. 1094 1095 # $(SEARCH_SOURCE:E) is where cc first looks for #include 1096 # "foo.h" files. If the source file is in a distant directory, 1097 # look there. Else, look in "" (the current directory). 1098 1099 HDRRULE on $(>) = HdrRule ; 1100 HDRSCAN on $(>) = $(HDRPATTERN) ; 1101 HDRSEARCH on $(>) = 1102 $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ; 1103 1104 HDRGRIST on $(>) = $(HDRGRIST) ; 1105 1106 # propagate target specific-defines 1107 1108 DEFINES on $(<) += $(DEFINES) ; 1109 1110 # if source is not .c, generate .c with specific rule 1111 1112 switch $(>:S) 1113 { 1114 case .asm : As $(<) : $(>) ; 1115 case .c : Cc $(<) : $(>) ; 1116 case .C : C++ $(<) : $(>) ; 1117 case .cc : C++ $(<) : $(>) ; 1118 case .cpp : C++ $(<) : $(>) ; 1119 case .f : Fortran $(<) : $(>) ; 1120 case .l : Cc $(<) : $(<:S=.c) ; 1121 Lex $(<:S=.c) : $(>) ; 1122 case .s : As $(<) : $(>) ; 1123 case .y : Cc $(<) : $(<:S=$(YACCGEN)) ; 1124 Yacc $(<:S=$(YACCGEN)) : $(>) ; 1125 case * : UserObject $(<) : $(>) ; 1126 } 1127} 1128 1129rule ObjectCcFlags 1130{ 1131 CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; 1132} 1133 1134rule ObjectC++Flags 1135{ 1136 C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; 1137} 1138 1139rule ObjectDefines 1140{ 1141 # must reformat CCDEFS according to current defines 1142 1143 local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ; 1144 1145 DEFINES on $(s) += $(>) ; 1146 CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ; 1147} 1148 1149rule ObjectHdrs 1150{ 1151 # Add to HDRS for HdrScan's benefit. 1152 # must reformat CCHDRS according to headers 1153 1154 local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ; 1155 1156 HDRS on $(s) += $(>) ; 1157 CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ; 1158} 1159 1160rule Objects 1161{ 1162 local _i ; 1163 1164 for _i in [ FGristFiles $(<) ] 1165 { 1166 Object $(_i:S=$(SUFOBJ)) : $(_i) ; 1167 LocalDepends obj : $(_i:S=$(SUFOBJ)) ; 1168 } 1169} 1170 1171rule RmTemps 1172{ 1173 Temporary $(>) ; 1174} 1175 1176rule Setuid 1177{ 1178 MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ; 1179} 1180 1181rule Shell 1182{ 1183 LocalDepends shell : $(<) ; 1184 Depends $(<) : $(>) ; 1185 SEARCH on $(>) = $(SEARCH_SOURCE) ; 1186 MODE on $(<) = $(SHELLMODE) ; 1187 LocalClean clean : $(<) ; 1188 Chmod $(<) ; 1189} 1190 1191rule SoftLink 1192{ 1193 LocalDepends files : $(<) ; 1194 Depends $(<) : $(>) ; 1195 SEARCH on $(>) = $(SEARCH_SOURCE) ; 1196 LocalClean clean : $(<) ; 1197} 1198 1199rule SubDir 1200{ 1201 # 1202 # SubDir TOP d1 d2 ... ; 1203 # 1204 # Support for a project tree spanning multiple directories. 1205 # 1206 # SubDir declares a Jamfile's location in a project tree, setting 1207 # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source 1208 # files can be found. 1209 # 1210 # TOP is a user-select variable name for root of the tree, and 1211 # d1 d2 ... are the directory elements that lead from the root 1212 # of the tree to the directory of the Jamfile. 1213 # 1214 # TOP can be set externally, but normally the first SubDir call 1215 # computes TOP as the path up from the current directory; the 1216 # path contains one ../ for each of d1 d2 ... 1217 # 1218 # SubDir reads once the project-specific rules file Jamrules 1219 # in the TOP directory, if present. This can be overridden 1220 # with the variable TOPRULES. 1221 # 1222 # SubDir supports multiple, overlaid project trees: SubDir 1223 # invocations with different TOPs can appear in the same Jamfile. 1224 # The location established by the first SubDir call is used set 1225 # the TOPs for the subsequent SubDir calls. 1226 # 1227 # SubDir's public variables: 1228 # 1229 # $(TOP) = path from CWD to root. 1230 # $(SUBDIR) = path from CWD to the directory SubDir names. 1231 # $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names 1232 # $(SEARCH_SOURCE) = $(SUBDIR) 1233 # $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR) 1234 # $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR) 1235 # $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s 1236 # 1237 1238 local _top = $(<[1]) ; 1239 local _tokens = $(<[2-]) ; 1240 1241 # 1242 # First time through sets up relative root and includes Jamrules. 1243 # 1244 1245 if ! $(_top) 1246 { 1247 Exit SubDir syntax error ; 1248 } 1249 1250 if ! $($(_top)-SET) 1251 { 1252 $(_top)-SET = true ; 1253 1254 ## LOCAL CHANGE 1255 # 1256 # Needed below to reset $(_top), so that to the SubDir invoked by the 1257 # top jamfile we will include, it will appear, as if the code has 1258 # never been executed. 1259 # 1260 local _originalTop = $($(_top)) ; 1261 # 1262 ## LOCAL CHANGE 1263 1264 1265 # First time we've seen this TOP. 1266 # We'll initialize a number of internal variables: 1267 # 1268 # $(TOP-UP) = directories from ROOT to a common point 1269 # $(TOP-DOWN) = directories from common point to TOP 1270 # $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD 1271 # $(SUBDIR_UP) = current value of $(TOP-UP) 1272 # $(SUBDIR_DOWN) = current value of $(TOP-DOWN) 1273 # $(SUBDIR_ROOT) = current value of $(TOP-ROOT) 1274 # 1275 1276 if $($(_top)) 1277 { 1278 # TOP externally set. 1279 # We'll ignore the relative (UP/DOWN) path that 1280 # got us here, and instead remember the hard ROOT. 1281 1282 $(_top)-UP = ; 1283 $(_top)-DOWN = ; 1284 $(_top)-ROOT = $($(_top)) ; 1285 } 1286 else 1287 { 1288 # TOP not preset. 1289 1290 # Establishing a new TOP. In the simplest case, 1291 # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's 1292 # merely a certain number of directories down from 1293 # the current directory, and FSubDirPath will set 1294 # TOP to a path consisting of ../ for each of the 1295 # elements of _tokens, because that represents how 1296 # far below TOP the current directory sits. 1297 # 1298 # In the more complicated case, the starting directory 1299 # isn't the directory of jam's invocation but an 1300 # location established by previous SubDir call. The 1301 # starting directory is SUBDIR_UP directories up from 1302 # SUBDIR_ROOT, and then SUBDIR_DOWN directories down 1303 # from that. If SUBDIR_ROOT is not set, that means 1304 # SUBDIR_DOWN and SUBDIR_UP represent the path from 1305 # the directory of jam's invocation. 1306 # 1307 # In the most complicated case, the _tokens also 1308 # represents directories down, because TOP is being 1309 # estalished in a directory other than TOP's root. 1310 # Hopefully, _tokens and SUBDIR_DOWN represent the 1311 # same final directory, relative to the new TOP and 1312 # the previous SubDIr's TOP. To find the new TOP, 1313 # we have to chop off any common directories from 1314 # then ends of _tokens and SUBDIR_DOWN. To do so, 1315 # we reverse each of them, call FStripCommon to 1316 # remove the initial common elements, and then 1317 # reverse them again. After this process, if 1318 # both _tokens and SUBDIR_DOWN have elements, it 1319 # means the directory names estalished by the two 1320 # SubDir calls don't match, and a warning is issued. 1321 # All hell will likely break loose at this point, 1322 # since the whole SubDir scheme relies on the SubDir 1323 # calls accurately naming the current directory. 1324 1325 # Strip common trailing elements of _tokens and SUBDIR_DOWN. 1326 1327 _tokens = [ FReverse $(_tokens) ] ; 1328 SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; 1329 FStripCommon _tokens : SUBDIR_DOWN ; 1330 SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; 1331 _tokens = [ FReverse $(_tokens) ] ; 1332 1333 if $(SUBDIR_DOWN) && $(_tokens) 1334 { 1335 Echo Warning: SubDir $(<) misplaced! ; 1336 } 1337 1338 # We'll remember the relative (UP/DOWN) path that 1339 # got us here, plus any hard ROOT starting point 1340 # for the UP/DOWN. If TOP is never set externally, 1341 # ROOT will always be "" (directory of jam's invocation). 1342 1343 $(_top)-UP = $(SUBDIR_UP) $(_tokens) ; 1344 $(_top)-DOWN = $(SUBDIR_DOWN) ; 1345 $(_top)-ROOT = $(SUBDIR_ROOT:E="") ; 1346 $(_top) = [ FSubDirPath $(_top) ] ; 1347 } 1348 1349 # Set subdir vars for the inclusion of the Jamrules, 1350 # just in case they have SubDir rules of their own. 1351 # Note that SUBDIR_DOWN is empty: it's all the way 1352 # up where the Jamrules live. These gets overrided 1353 # just after the inclusion. 1354 1355 SUBDIR_UP = $($(_top)-UP) ; 1356 SUBDIR_DOWN = ; 1357 SUBDIR_ROOT = $($(_top)-ROOT) ; 1358 1359 ## LOCAL CHANGE 1360 # 1361 # If we are the first Jamfile, we include the top Jamfile of this 1362 # tree and stop processing. 1363 # 1364 if ! $(INVOCATION_SUBDIR_SET) 1365 { 1366 INVOCATION_SUBDIR_SET = true ; 1367 INVOCATION_SUBDIR_TOP = $($(_top)) ; 1368 INVOCATION_SUBDIR = $(_tokens) ; 1369 if $(INVOCATION_SUBDIR) 1370 { 1371 # Reset $(_top)-SET and $(_top) so that it appears as if the 1372 # code till this point has never been executed (let alone the 1373 # setting of the INVOCATION_SUBDIR_SET and INVOCATION_SUBDIR 1374 # variables). 1375 # 1376 $(_top)-SET = ; 1377 $(_top) = $(_originalTop) ; 1378 1379 include $(JAMFILE:D=$(INVOCATION_SUBDIR_TOP)) ; 1380 jumptoeof ; 1381 } 1382 } 1383 # 1384 ## LOCAL CHANGE 1385 1386 # Include $(TOPRULES) or $(TOP)/Jamrules. 1387 # Include $(TOPRULES) if set. 1388 # Otherwise include $(TOP)/Jamrules if present. 1389 1390 if $($(_top)RULES) { 1391 include $($(_top)RULES) ; 1392 } else { 1393 NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ; 1394 include $(JAMRULES:R=$($(_top)):G=$(_top)) ; 1395 } 1396 } 1397 1398 # Get path from $(TOP) to named directory. 1399 # Save dir tokens for other potential uses. 1400 1401 SUBDIR_UP = $($(_top)-UP) ; 1402 SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ; 1403 SUBDIR_ROOT = $($(_top)-ROOT) ; 1404 SUBDIR_TOKENS = $(SUBDIR_DOWN) ; 1405 1406 SUBDIR = [ FSubDirPath $(<) ] ; 1407 1408 # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST 1409 # These can be reset if needed. For example, if the source 1410 # directory should not hold object files, LOCATE_TARGET can 1411 # subsequently be redefined. 1412 1413 SEARCH_SOURCE = $(SUBDIR) ; 1414 LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ; 1415 LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ; 1416 SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ; 1417 1418 ## LOCAL CHANGE -- OPT_HEADER_CACHE_EXT. With the header 1419 # cache, we can grist all files found during a header scan 1420 # without incurring a performance penalty. 1421 # 1422 HDRGRIST = $(SOURCE_GRIST) ; 1423 # 1424 ## LOCAL CHANGE 1425 1426 # Reset per-directory ccflags, hdrs, etc, 1427 # listed in SUBDIRRESET. 1428 # Note use of variable expanded assignment var 1429 1430 SUBDIR$(SUBDIRRESET) = ; 1431 1432 # Invoke user-specific SubDir extensions, 1433 # rule names listed in SUBDIRRULES. 1434 # Note use of variable expanded rule invocation 1435 1436 $(SUBDIRRULES) $(<) ; 1437} 1438 1439rule FSubDirPath 1440{ 1441 # FSubDirPath TOP d1 ... ; 1442 1443 # Returns path to named directory. 1444 1445 # If jam is invoked in a subdirectory of the TOP, then we 1446 # need to prepend a ../ for every level we must climb up 1447 # (TOP-UP), and then append the directory names we must 1448 # climb down (TOP-DOWN), plus the named directories d1 ... 1449 # If TOP was set externally, or computed from another TOP 1450 # that was, we'll have to reroot the whole thing at TOP-ROOT. 1451 1452 local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ; 1453 1454 return $(_r:R=$($(<[1])-ROOT)) ; 1455} 1456 1457rule SubDirCcFlags 1458{ 1459 SUBDIRCCFLAGS += $(<) ; 1460} 1461 1462rule SubDirC++Flags 1463{ 1464 SUBDIRC++FLAGS += $(<) ; 1465} 1466 1467rule SubDirHdrs 1468{ 1469 SUBDIRHDRS += [ FDirName $(<) ] ; 1470} 1471 1472rule SubInclude 1473{ 1474 # SubInclude TOP d1 ... ; 1475 # 1476 # Include a subdirectory's Jamfile. 1477 1478 # We use SubDir to get there, in case the included Jamfile 1479 # either doesn't have its own SubDir (naughty) or is a subtree 1480 # with its own TOP. 1481 1482 if ! $($(<[1])) 1483 { 1484 Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ; 1485 } 1486 1487 SubDir $(<) ; 1488 1489 include $(JAMFILE:D=$(SUBDIR)) ; 1490} 1491 1492rule SubRules 1493{ 1494 # SubRules TOP d1 ... : Other-TOP ; 1495 # 1496 # Read another tree's Jamrules, by giving it's path according 1497 # to this tree and it's own name. 1498 1499 if ! $($(<[1])) 1500 { 1501 Exit SubRules $(<[1]) without prior SubDir $(<[1]) ; 1502 } 1503 1504 SubDir $(<) ; 1505 SubDir $(>) ; 1506} 1507 1508rule Undefines 1509{ 1510 UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ; 1511} 1512 1513rule UserObject 1514{ 1515 Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ; 1516} 1517 1518rule Yacc 1519{ 1520 local _h ; 1521 1522 _h = $(<:S=.h) ; 1523 1524 # Some places don't have a yacc. 1525 1526 MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ; 1527 1528 if $(YACC) 1529 { 1530 Depends $(<) $(_h) : $(>) ; 1531 Yacc1 $(<) $(_h) : $(>) ; 1532 YaccMv $(<) $(_h) : $(>) ; 1533 LocalClean clean : $(<) $(_h) ; 1534 } 1535 1536 # make sure someone includes $(_h) else it will be 1537 # a deadly independent target 1538 1539 Includes $(<) : $(_h) ; 1540} 1541 1542# 1543# Utility rules; no side effects on these 1544# 1545 1546rule FGrist 1547{ 1548 return $(<:J=!) ; 1549 1550} 1551 1552rule FGristFiles 1553{ 1554 return $(<:G=$(SOURCE_GRIST:E)) ; 1555} 1556 1557rule FGristSourceFiles 1558{ 1559 ## LOCAL CHANGE: OPT_HEADER_CACHE_EXT 1560 # With header caching, there is no performance penalty to gristing 1561 # header files. It is also not correct to assume that header 1562 # files have global visibility. 1563 # 1564 # Here we comment out the old version and replace it with the new. 1565# # Produce source file name name with grist in it, 1566# # if SOURCE_GRIST is set. 1567# 1568# # Leave header files alone, because they have a global 1569# # visibility. 1570# 1571# if ! $(SOURCE_GRIST) 1572# { 1573# return $(<) ; 1574# } 1575# else 1576# { 1577# local _i _o ; 1578# 1579# for _i in $(<) 1580# { 1581# switch $(_i) 1582# { 1583# case *.h : _o += $(_i) ; 1584# case * : _o += $(_i:G=$(SOURCE_GRIST)) ; 1585# } 1586# } 1587# 1588# return $(_o) ; 1589# } 1590 return [ FGristFiles $(<) ] ; 1591 # 1592 ## LOCAL CHANGE: end 1593} 1594 1595rule FIsPrefix 1596{ 1597 # FIsPrefix <a> : <b> ; 1598 # Returns true, if list <a> is a prefix (a proper one or equal) of 1599 # list <b>, an empty list otherwise. 1600 local a = $(1) ; 1601 local b = $(2) ; 1602 while $(a) && $(a[1]) = $(b[1]) { 1603 a = $(a[2-]) ; 1604 b = $(b[2-]) ; 1605 } 1606 1607 if $(a) { 1608 return ; 1609 } else { 1610 return true ; 1611 } 1612} 1613 1614rule FReverse 1615{ 1616 # FReverse a1 a2 a3 ... ; 1617 # return ... a3 a2 a1 ; 1618 1619 if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; } 1620} 1621 1622rule FSubDir 1623{ 1624 # If $(>) is the path to the current directory, compute the 1625 # path (using ../../ etc) back to that root directory. 1626 # Sets result in $(<) 1627 1628 if ! $(<[1]) 1629 { 1630 return $(DOT) ; 1631 } 1632 else 1633 { 1634 local _i _d ; 1635 1636 _d = $(DOTDOT) ; 1637 1638 for _i in $(<[2-]) 1639 { 1640 _d = $(_d:R=$(DOTDOT)) ; 1641 } 1642 1643 return $(_d) ; 1644 } 1645} 1646 1647rule FStripCommon 1648{ 1649 # FStripCommon v1 : v2 ; 1650 1651 # Strip common initial elements of variables v1 and v2. 1652 # Modifies the variable values themselves. 1653 1654 if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) 1655 { 1656 $(<) = $($(<)[2-]) ; 1657 $(>) = $($(>)[2-]) ; 1658 FStripCommon $(<) : $(>) ; 1659 } 1660} 1661 1662rule FRelPath 1663{ 1664 local _l _r ; 1665 1666 # first strip off common parts 1667 1668 _l = $(<) ; 1669 _r = $(>) ; 1670 1671 FStripCommon _l : _r ; 1672 1673 # now make path to root and path down 1674 1675 _l = [ FSubDir $(_l) ] ; 1676 _r = [ FDirName $(_r) ] ; 1677 1678 # Concatenate and save 1679 1680 # XXX This should be better 1681 1682 if $(_r) = $(DOT) { 1683 return $(_l) ; 1684 } else { 1685 return $(_r:R=$(_l)) ; 1686 } 1687} 1688 1689rule FAppendSuffix 1690{ 1691 # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;" 1692 # returns (yacc,lex,foo.bat) on Unix and 1693 # (yacc.exe,lex.exe,foo.bat) on NT. 1694 1695 if $(>) 1696 { 1697 local _i _o ; 1698 1699 for _i in $(<) 1700 { 1701 if $(_i:S) 1702 { 1703 _o += $(_i) ; 1704 } 1705 else 1706 { 1707 _o += $(_i:S=$(>)) ; 1708 } 1709 } 1710 return $(_o) ; 1711 } 1712 else 1713 { 1714 return $(<) ; 1715 } 1716} 1717 1718# 1719# Operating system specific utility rules 1720# First, the (generic) UNIX versions 1721# 1722 1723rule FQuote { return \\\"$(<)\\\" ; } 1724rule FDefines { return -D$(<) ; } 1725rule FIncludes { return -I$(<) ; } 1726 1727rule FDirName 1728{ 1729 # Turn individual elements in $(<) into a usable path. 1730 1731 local _i ; 1732 local _s = $(DOT) ; 1733 1734 for _i in $(<) 1735 { 1736 _s = $(_i:R=$(_s)) ; 1737 } 1738 1739 return $(_s) ; 1740} 1741 1742if $(OS2) 1743{ 1744 rule FQuote { return \"$(<)\" ; } 1745 rule FIncludes { return /I$(<) ; } 1746} 1747 1748else if $(NT) 1749{ 1750 rule FDefines { return /D$(<) ; } 1751 rule FIncludes { return /I$(<) ; } 1752} 1753 1754else if $(MAC) 1755{ 1756 rule FQuote { return \"$(<)\" ; } 1757 rule FDefines { return "-define '$(<)'" ; } 1758 rule FIncludes { return \"$(<:J=,)\" ; } 1759} 1760 1761else if $(VMS) 1762{ 1763 rule FQuote { return \"\"\"$(<)\"\"\" ; } 1764 rule FDefines { return "/define=( $(<:J=,) )" ; } 1765 rule FIncludes { return "/inc=( $(<:J=,) )" ; } 1766 1767 rule FDirName 1768 { 1769 local _s _i ; 1770 1771 # Turn individual elements in $(<) into a usable path. 1772 1773 if ! $(<) 1774 { 1775 _s = $(DOT) ; 1776 } 1777 else 1778 { 1779 # This handles the following cases: 1780 # a -> [.a] 1781 # a b c -> [.a.b.c] 1782 # x: -> x: 1783 # x: a -> x:[a] 1784 # x:[a] b -> x:[a.b] 1785 1786 switch $(<[1]) 1787 { 1788 case *:* : _s = $(<[1]) ; 1789 case \\[*\\] : _s = $(<[1]) ; 1790 case * : _s = [.$(<[1])] ; 1791 } 1792 1793 for _i in [.$(<[2-])] 1794 { 1795 _s = $(_i:R=$(_s)) ; 1796 } 1797 } 1798 1799 return $(_s) ; 1800 } 1801} 1802 1803# 1804# Actions 1805# 1806 1807# 1808# First the defaults 1809# 1810 1811actions updated together piecemeal Archive 1812{ 1813 $(AR) $(<) $(>) 1814} 1815 1816actions As 1817{ 1818 $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>) 1819} 1820 1821actions C++ 1822{ 1823 $(C++) -c -o $(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 1824} 1825 1826actions Cc 1827{ 1828 $(CC) -c -o $(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 1829} 1830 1831actions Chgrp 1832{ 1833 $(CHGRP) $(GROUP) $(<) 1834} 1835 1836actions Chmod1 1837{ 1838 $(CHMOD) $(MODE) $(<) 1839} 1840 1841actions Chown 1842{ 1843 $(CHOWN) $(OWNER) $(<) 1844} 1845 1846actions piecemeal together existing Clean 1847{ 1848 $(RM) $(>) 1849} 1850 1851actions File 1852{ 1853 $(CP) $(>) $(<) 1854} 1855 1856actions GenFile1 1857{ 1858 $(>[1]) $(<) $(>[2-]) 1859} 1860 1861actions Fortran 1862{ 1863 $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>) 1864} 1865 1866actions HardLink 1867{ 1868 $(RM) $(<) && $(LN) $(>) $(<) 1869} 1870 1871actions Install 1872{ 1873 $(CP) $(>) $(<) 1874} 1875 1876actions Lex 1877{ 1878 $(LEX) $(>) 1879} 1880 1881actions LexMv 1882{ 1883 $(MV) lex.yy.c $(<) 1884} 1885 1886actions Link bind NEEDLIBS 1887{ 1888 $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 1889} 1890 1891actions MkDir1 1892{ 1893 $(MKDIR) "$(<)" 1894} 1895 1896actions together Ranlib 1897{ 1898 $(RANLIB) $(<) 1899} 1900 1901actions quietly updated piecemeal together RmTemps 1902{ 1903 $(RM) $(>) 1904} 1905 1906actions Shell 1907{ 1908 $(AWK) ' 1909 NR == 1 { print "$(SHELLHEADER)" } 1910 NR == 1 && /^[#:]/ { next } 1911 /^##/ { next } 1912 { print } 1913 ' < $(>) > $(<) 1914} 1915 1916actions SoftLink 1917{ 1918 $(RM) $(<) && $(LN) -s $(>) $(<) 1919} 1920 1921actions Yacc1 1922{ 1923 $(YACC) $(YACCFLAGS) $(>) 1924} 1925 1926actions YaccMv 1927{ 1928 $(MV) $(YACCFILES).c $(<[1]) 1929 $(MV) $(YACCFILES).h $(<[2]) 1930} 1931 1932# 1933# RELOCATE - for compilers with broken -o flags 1934# 1935 1936if $(RELOCATE) 1937{ 1938 actions C++ 1939 { 1940 $(C++) -c $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 1941 } 1942 1943 actions Cc 1944 { 1945 $(CC) -c $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 1946 } 1947 1948 actions ignore CcMv 1949 { 1950 [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<) 1951 } 1952} 1953 1954# 1955# NOARUPDATE - can't update an archive 1956# 1957 1958if $(NOARUPDATE) 1959{ 1960 actions Archive 1961 { 1962 $(AR) $(<) $(>) 1963 } 1964} 1965 1966# 1967# UNIX specific actions 1968# 1969 1970if $(UNIX) 1971{ 1972 actions GenFile1 1973 { 1974 PATH="$PATH:." 1975 $(>[1]) $(<) $(>[2-]) 1976 } 1977} 1978 1979# 1980# NT specific actions 1981# 1982 1983if $(NT) && $(MSVCNT) 1984{ 1985 actions updated together piecemeal Archive 1986 { 1987 if exist $(<) set _$(<:B)_=$(<) 1988 $(AR) /out:$(<) %_$(<:B)_% $(>) 1989 } 1990 1991 actions As 1992 { 1993 $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul; 1994 } 1995 1996 actions Cc 1997 { 1998 $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>) 1999 } 2000 2001 actions C++ 2002 { 2003 $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>) 2004 } 2005 2006 actions Link bind NEEDLIBS 2007 { 2008 $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 2009 } 2010} 2011else if $(NT) && $(MSVC) 2012{ 2013 actions updated together piecemeal Archive 2014 { 2015 $(AR) $(<) -+$(>) 2016 } 2017 2018 actions Cc 2019 { 2020 $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 2021 } 2022 2023 actions C++ 2024 { 2025 $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /Tp$(>) 2026 } 2027 2028 actions Link bind NEEDLIBS 2029 { 2030 $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 2031 } 2032} 2033else if $(NT) && $(BCCROOT) 2034{ 2035 actions updated together piecemeal Archive 2036 { 2037 $(AR) $(<) -+$(>) 2038 } 2039 2040 actions Link bind NEEDLIBS 2041 { 2042 $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>) 2043 } 2044 2045 actions C++ 2046 { 2047 $(C++) -c -o$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 2048 } 2049 2050 actions Cc 2051 { 2052 $(CC) -c -o$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 2053 } 2054} 2055 2056# 2057# OS2 specific actions 2058# 2059 2060else if $(OS2) && $(WATCOM) 2061{ 2062 actions together piecemeal Archive 2063 { 2064 $(AR) $(<) +-$(>) 2065 } 2066 2067 actions Cc 2068 { 2069 $(CC) /Fo=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 2070 } 2071 2072 actions C++ 2073 { 2074 $(C++) /Fo=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 2075 } 2076 2077 actions Link bind NEEDLIBS 2078 { 2079 $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 2080 } 2081 2082 actions Shell 2083 { 2084 $(CP) $(>) $(<) 2085 } 2086} 2087 2088# 2089# VMS specific actions 2090# 2091 2092else if $(VMS) 2093{ 2094 actions updated together piecemeal Archive 2095 { 2096 lib/replace $(<) $(>[1]) ,$(>[2-]) 2097 } 2098 2099 actions Cc 2100 { 2101 $(CC)/obj=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 2102 } 2103 2104 actions C++ 2105 { 2106 $(C++)/obj=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 2107 } 2108 2109 actions piecemeal together existing Clean 2110 { 2111 $(RM) $(>[1]);* ,$(>[2-]);* 2112 } 2113 2114 actions together quietly CreLib 2115 { 2116 if f$search("$(<)") .eqs. "" then lib/create $(<) 2117 } 2118 2119 actions GenFile1 2120 { 2121 mcr $(>[1]) $(<) $(>[2-]) 2122 } 2123 2124 actions Link bind NEEDLIBS 2125 { 2126 $(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS) 2127 } 2128 2129 actions quietly updated piecemeal together RmTemps 2130 { 2131 $(RM) $(>[1]);* ,$(>[2-]);* 2132 } 2133 2134 actions Shell 2135 { 2136 $(CP) $(>) $(<) 2137 } 2138} 2139 2140# 2141# Mac specifc actions 2142# 2143 2144else if $(MAC) 2145{ 2146 actions together Archive 2147 { 2148 $(LINK) -library -o $(<) $(>) 2149 } 2150 2151 actions Cc 2152 { 2153 set -e MWCincludes $(CCHDRS) 2154 $(CC) -o $(<) $(CCFLAGS) $(CCDEFS) $(>) 2155 } 2156 2157 actions C++ 2158 { 2159 set -e MWCincludes $(CCHDRS) 2160 $(CC) -o $(<) $(C++FLAGS) $(CCDEFS) $(>) 2161 } 2162 2163 actions Link bind NEEDLIBS 2164 { 2165 $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)" 2166 } 2167} 2168 2169if $(WIN98) 2170{ 2171 actions existing Clean 2172 { 2173 del $(>) 2174 } 2175} 2176 2177# 2178# Backwards compatibility with jam 1, where rules were uppercased. 2179# 2180 2181rule BULK { Bulk $(<) : $(>) ; } 2182rule FILE { File $(<) : $(>) ; } 2183rule HDRRULE { HdrRule $(<) : $(>) ; } 2184rule INSTALL { Install $(<) : $(>) ; } 2185rule LIBRARY { Library $(<) : $(>) ; } 2186rule LIBS { LinkLibraries $(<) : $(>) ; } 2187rule LINK { Link $(<) : $(>) ; } 2188rule MAIN { Main $(<) : $(>) ; } 2189rule SETUID { Setuid $(<) ; } 2190rule SHELL { Shell $(<) : $(>) ; } 2191rule UNDEFINES { Undefines $(<) : $(>) ; } 2192 2193# Old INSTALL* didn't take dest directory. 2194 2195rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; } 2196rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; } 2197rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; } 2198 2199# Compatibility with jam 2.2. 2200 2201rule addDirName { $(<) += [ FDirName $(>) ] ; } 2202rule makeCommon { FStripCommon $(<) : $(>) ; } 2203rule _makeCommon { FStripCommon $(<) : $(>) ; } 2204rule makeDirName { $(<) = [ FDirName $(>) ] ; } 2205rule makeGrist { $(<) = [ FGrist $(>) ] ; } 2206rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; } 2207rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; } 2208rule makeString { $(<) = $(>:J) ; } 2209rule makeSubDir { $(<) = [ FSubDir $(>) ] ; } 2210rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; } 2211 2212# 2213# Now include the user's Jamfile. 2214# 2215 2216include $(JAMFILE) ; 2217