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