# # /+\ # +\ Copyright 1993, 1995 Christopher Seiwald. # \+/ # # This file is part of Jam - see jam.c for Copyright information. # # # JAMBASE - jam 2.1 ruleset providing make(1)-like functionality # # Supports UNIX, NT, and VMS. # # 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST # 04/18/94 (seiwald) - use 'default =' when setting OS specific vars # 04/21/94 (seiwald) - do RmTemps together # 05/05/94 (seiwald) - all supported C compilers support -o: relegate # RELOCATE as an option; set Ranlib to "" to disable it # 06/01/94 (seiwald) - new 'actions existing' to do existing sources # 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS # 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS # 09/19/94 (seiwald) - LinkLibraries and Undefs now append # - Rule names downshifted. # 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile. # 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files. # 01/08/95 (seiwald) - Shell now handled with awk, not sed # 01/09/95 (seiwald) - Install* now take dest directory as target # 01/10/95 (seiwald) - All entries sorted. # 01/10/95 (seiwald) - NT support moved in, with LauraW's help. # 01/10/95 (seiwald) - VMS support moved in. # 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added. # 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE. # 02/08/95 (seiwald) - SubDir works on VMS. # 02/14/95 (seiwald) - MkDir and entourage. # 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves. # 07/10/95 (taylor) - Support for Microsoft C++. # 11/21/96 (peterk) - Support for BeOS # Special targets defined in this file: # # all - parent of first, shell, files, lib, exe # first - first dependent of 'all', for potential initialization # shell - parent of all Shell targets # files - parent of all File targets # lib - parent of all Library targets # exe - parent of all Main targets # dirs - parent of all MkDir targets # clean - removes all Shell, File, Library, and Main targets # uninstall - removes all Install targets # # Rules defined by this file: # # as obj.o : source.s ; .s -> .o # Bulk dir : files ; populate directory with many files # Cc obj.o : source.c ; .c -> .o # C++ obj.o : source.cc ; .cc -> .o # Clean clean : sources ; remove sources with 'jam clean' # File dest : source ; copy file # Fortran obj.o : source.f ; .f -> .o # GenFile source.c : program args ; make custom file # Hardlink target : source ; make link from source to target # HdrRule source : headers ; handle #includes # InstallInto dir : sources ; install any files # InstallBin dir : sources ; install binaries # InstallLib dir : sources ; install files # InstallFile dir : sources ; install files # InstallMan dir : sources ; install man pages # InstallShell dir : sources ; install shell scripts # Lex source.c : source.l ; .l -> .c # Library lib : source ; archive library from compiled sources # LibraryFromObjects lib : objects ; archive library from objects # LinkLibraries images : libraries ; bag libraries onto Mains # Main image : source ; link executable from compiled sources # MainFromObjects image : objects ; link executable from objects # MkDir dir ; make a directory, if not there # Object object : source ; compile object from source # ObjectCcFlags source : flags ; add compiler flags for object # ObjectC++Flags source : flags ; add compiler flags for object # ObjectHdrs source : dirs ; add include directories for object # Objects sources ; compile sources # RmTemps target : sources ; remove temp sources after target made # Setuid images ; mark executables Setuid # SubDir TOP d1 d2 ... ; start a subdirectory Jamfile # SubDirCcFlags flags ; add compiler flags until next SubDir # SubDirC++Flags flags ; add compiler flags until next SubDir # SubDirHdrs dirs ; add include dirs until next SubDir # SubInclude TOP d1 d2 ... ; include a subdirectory Jamfile # Shell exe : source ; make a shell executable # Undefines images : symbols ; save undef's for linking # UserObject object : source ; handle unknown suffixes for Object # Yacc source.c : source.y ; .y -> .c # # Utility rules that have no side effects: # # makeSubDir var : d1 d2 ... ; $(var) = path to root # addDirName var : d1 d2 ... ; $(var) += path from root to dir # makeDirName var : d1 d2 ... ; $(var) = path from root to dir # makeGrist var : d1 d2 ... ; $(var) = grist form of dir # makeGristedName var : value ; $(var) = $(value:G=$(SOURCE_GRIST)) # makeCommon var1 : var2 ; strip common initial elements # makeRelPath var d1 : d2 ; $(var) = rel path from d1 to d2 # makeSuffixed var $(SUF) : f1 f2 ... ; $(var) = $(>) with suffixes # makeString var : value ... ; $(var) = contatenated values # # Brief review of the jam language: # # Statements: # rule RULE - statements to process a rule # actions RULE - system commands to carry out target update # # Modifiers on actions: # together - multiple instances of same rule on target get executed # once with their sources ($(>)) concatenated # updated - refers to updated sources ($(>)) only # ignore - ignore return status of command # quietly - don't trace its execution unless verbose # piecemeal - iterate command each time with a small subset of $(>) # existing - refers to currently existing sources ($(>)) only # # Special rules: # ALWAYS - always build a target # DEPENDS - builds the dependency graph # ECHO - blurt out targets on stdout # EXIT - blurt out targets and exit # INCLUDES - marks sources as headers for target (a codependency) # NOCARE - don't panic if the target can't be built # NOUPDATE - create the target if needed but never update it # NOTFILE - ignore the timestamp of the target (it's not a file) # TEMPORARY - target need not be present if sources haven't changed # # Special variables set by jam: # $(<) - targets of a rule (to the left of the :) # $(>) - sources of a rule (to the right of the :) # $(UNIX) - true on UNIX # $(VMS) - true on VMS # $(NT) - true on NT # $(OS) - name of OS - varies wildly # $(JAMVERSION) - version number (2.1) # # Special variables used by jam: # SEARCH - where to find something (used during binding and actions) # LOCATE - where to plop something not found with SEARCH # HDRRULE - rule to call to handle include files # HDRSCAN - egrep regex to extract include files # # Special targets: # all - default if none given on command line # # Initialize variables # # "default =" - set only if unset OSFULL = $(OS)$(OSPLAT)$(OSVER) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; # # OS specific variable settings # switch $(OS) { case AIX : LINKLIBS default = -lbsd ; case DGUX : RANLIB default = "" ; RELOCATE = true ; case HPUX : RANLIB default = "" ; INSTALL default = "" ; case IRIX : RANLIB default = "" ; INSTALL default = "" ; case MVS : RANLIB default = "" ; RELOCATE = true ; case NEXT : AR default = libtool -o ; RANLIB default = "" ; case NCR : RANLIB default = "" ; INSTALL default = "" ; case PTX : RANLIB default = "" ; case QNX : INSTALL default = "" ; case SCO : RANLIB default = "" ; INSTALL default = "" ; RELOCATE = true ; case SINIX : RANLIB default = "" ; RELOCATE = true ; case SOLARIS : RANLIB default = "" ; INSTALL default = "install" ; AR default = "/usr/ccs/bin/ar ru" ; case UNIXWARE : RANLIB default = "" ; RELOCATE = true ; } #if $(OS) = SUNOS && $(TZ) #{ # Echo Warning: you are running the SunOS jam on Solaris. ; #} if $(UNIX) { if $(OS) = QNX { AR default = wlib ; CC default = cc ; CCFLAGS default = -Q ; # quiet C++ default = $(CC) ; C++FLAGS default = -Q ; # quiet LINK default = $(CC) ; LINKFLAGS default = -Q ; # quiet NOARSCAN default = true ; RANLIB default = "" ; } else if $(OS) = BEOS { AR default = mwld -xml -o ; BINDIR default = /boot/bin ; CC default = mwcc ; CCFLAGS default = -nosyspath ; C++ default = $(CC) ; C++FLAGS default = -nosyspath ; FORTRAN default = "" ; LIBDIR default = /boot/develop/libraries ; LINK default = $(CC) ; LEX default = "" ; MANDIR default = /boot/documentation/"Shell Tools"/HTML ; NOARSCAN default = true ; RANLIB default = "" ; STDHDRS default = /boot/develop/headers/posix ; YACC default = "" ; YACCFLAGS default = "" ; YACCFILES default = "" ; } AR default = ar ru ; AS default = as ; AWK default = awk ; ASFLAGS default = ; BINDIR default = /usr/local/bin ; C++ default = gcc ; C++FLAGS default = ; CC default = cc ; CCFLAGS default = ; CP default = cp ; CHMOD default = chmod ; DOT default = . ; DOTDOT default = .. ; EXEMODE default = 711 ; FILEMODE default = 644 ; FORTRAN default = f77 ; FORTRANFLAGS default = ; HDRS default = ; INSTALL default = install -c ; LEX default = lex ; LIBDIR default = /usr/local/lib ; LINK default = $(CC) ; LINKFLAGS default = $(CCFLAGS) ; LINKLIBS default = ; LN default = ln ; MANDIR default = /usr/local/man ; MKDIR default = mkdir ; MV default = mv -f ; OPTIM default = -O ; RANLIB default = ranlib ; RCP default = rcp ; RSH default = rsh ; RM default = rm -f ; SED default = sed ; SHELLHEADER default = "#!/bin/sh" ; SHELLMODE default = 755 ; SLASH default = / ; STDHDRS default = /usr/include ; SUFLIB default = .a ; SUFOBJ default = .o ; SUFEXE default = "" ; UNDEFFLAG default = "-u _" ; YACC default = yacc ; YACCFLAGS default = -d ; YACCFILES default = y.tab ; } else if $(NT) { AWK default = awk ; CHMOD default = chmod ; CP default = copy ; DOT default = . ; DOTDOT default = .. ; EXEMODE default = 711 ; FILEMODE default = 644 ; MKDIR default = mkdir ; MV default = mv -f ; OS = NT ; # replace Windows_NT RCP default = rcp ; RSH default = rsh ; RM default = del /f/q ; SED default = sed ; SLASH default = \\ ; SUFLIB default = .lib ; SUFOBJ default = .obj ; SUFEXE default = .exe ; if $(BCCROOT) { ECHO "Compiler is Borland C++" ; AR default = tlib ; ARFLAGS default = /C /P64 ; CC default = bcc32 ; CCFLAGS default = -v -w- -DNT ; C++ default = bcc32 ; C++FLAGS default = -v -w- ; LINK default = $(CC) ; LINKFLAGS default = $(CCFLAGS) ; STDLIBPATH default = $(BCCROOT)\\lib ; STDHDRS default = $(BCCROOT)\\include ; NOARSCAN default = true ; } else if $(MSVC) { ECHO "Compiler is Microsoft Visual C++ 16 bit" ; AR default = lib /nologo ; CC default = cl /nologo ; CCFLAGS default = /D \"WIN\" ; C++ default = $(CC) ; C++FLAGS default = $(CCFLAGS) ; LINK default = $(CC) ; LINKFLAGS default = $(CCFLAGS) ; LINKLIBS default = #$(MSVC)\\lib\\advapi32.lib #$(MSVC)\\lib\\libcmt.lib $(MSVC)\\lib\\mlibce.lib #$(MSVC)\\lib\\slibce.lib $(MSVC)\\lib\\oldnames.lib #$(MSVC)\\lib\\kernel32.lib ; LINKLIBS default = ; NOARSCAN default = true ; OPTIM default = ; STDHDRS default = $(MSVC)\\include ; UNDEFFLAG default = "/u _" ; } else if $(MSVCNT) { ECHO "Compiler is Microsoft Visual C++" ; AR default = lib ; AS default = masm386 ; CC default = cl /nologo ; CCFLAGS default = ; C++ default = $(CC) ; C++FLAGS default = $(CCFLAGS) ; LINK default = link ; LINKFLAGS default = ; LINKLIBS default = $(MSVCNT)\\lib\\advapi32.lib $(MSVCNT)\\lib\\libc.lib $(MSVCNT)\\lib\\oldnames.lib $(MSVCNT)\\lib\\kernel32.lib ; OPTIM default = ; STDHDRS default = $(MSVCNT)\\include ; UNDEFFLAG default = "/u _" ; } else { EXIT On NT, set BCCROOT, MSVCNT, or MSVC to the root of the Borland or Microsoft directories. ; } } else if $(OS2) { WATCOM default = $(watcom) ; CP default = copy ; DOT default = . ; DOTDOT default = .. ; MKDIR default = mkdir ; MV default = move ; RM default = del /f ; SED default = sed ; SLASH default = \\ ; SUFLIB default = .lib ; SUFOBJ default = .obj ; SUFEXE default = .exe ; if ! $(WATCOM) { EXIT On OS2, set WATCOM to the root of the Watcom directory. ; } ECHO "OS2 compiler is Watcom." ; AR default = wlib ; CC default = wcc386 ; CCFLAGS default = /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet C++ default = wpp386 ; C++FLAGS default = $(CCFLAGS) ; LINK default = wcl386 ; LINKFLAGS default = /zq ; # zq=quiet LINKLIBS default = ; NOARSCAN default = true ; OPTIM default = ; STDHDRS default = $(WATCOM)\\h ; UNDEFFLAG default = "/u _" ; } else if $(VMS) { AS default = as ; CC default = cc ; CCFLAGS default = ; CP default = copy/replace ; CRELIB default = true ; DOT default = [] ; DOTDOT default = [-] ; EXEMODE default = (w:e) ; FILEMODE default = (w:r) ; HDRS default = ; LEX default = lex ; LINK default = link ; LINKFLAGS default = ; LINKLIBS default = ; MV default = rename ; OPTIM default = ; RM default = delete ; RUNVMS default = mcr ; SED default = sed ; SHELLMODE default = (w:er) ; SLASH default = . ; STDHDRS default = decc$library_include ; SUFLIB default = .olb ; SUFOBJ default = .obj ; SUFEXE default = .exe ; switch $(OS) { case OPENVMS : CCFLAGS default = /stand=vaxc ; case VMS : LINKLIBS default = sys$library:vaxcrtl.olb/lib ; } } else if $(MAC) { CWGUSI default = "{CWGUSI}" ; CWMAC default = "{CWMAC}" ; CWGUSIHDR default = $(CWGUSI):include ; CWGUSILIB default = $(CWGUSI):Lib ; CWMACLIB default = $(CWMAC):Libraries ; CWMACHDR default = $(CWMAC):Headers ; CC default = mwcppc ; CCFLAGS default = -w off ; CP default = copy ; DOT default = ":" ; DOTDOT default = "::" ; HDRS default = $(CWGUSIHDR) $(CWMACHDR):"ANSI Headers" $(CWMACHDR):"Universal Headers" ; LINK default = mwlinkppc ; LINKFLAGS default = -mpwtool -warn ; LINKLIBS default = "$(CWGUSILIB):GUSIMPW.Lib.PPC" "$(CWGUSILIB):GUSI.Lib.PPC" "$(CWMACLIB):MacOS Common:Interfacelib" "$(CWMACLIB):MacOS Common:PLStringFuncs Glue:PLStringFuncsPPC.lib" "$(CWMACLIB):Runtime:Runtime PPC:MWMPWCRuntime.lib" "$(CWMACLIB):ANSI PPC:MPW ANSI.C.PPC.Lib" "$(CWMACLIB):MacOS PPC:PPCToolLibs.o" "$(CWMACLIB):MacOS PPC:Mathlib" ; MKDIR default = newfolder ; MV default = rename ; NOARSCAN default = true ; OPTIM default = ; RM default = delete ; SLASH default = ":" ; STDHDRS default = ; #$(MWCIncludes) ; SUFLIB default = .lib ; SUFOBJ default = .o ; SUFEXE default = "" ; NOARSCAN default = true ; } # # Define some MS-specific commands for MS-specific actions (which # are not yet added to Jambase) # if $(NT) || $(OS2) { MSLIB default = lib ; MSLINK default = link ; MSIMPLIB default = implib ; MSRC default = rc ; } JAMFILE default = Jamfile ; JAMRULES default = Jamrules ; HDRPATTERN = "^#[ ]*include[ ]*[<\"](.*)[\">].*$" ; # # Base dependencies - first for "bootstrap" kinds of rules # DEPENDS all : shell files lib exe obj ; DEPENDS all shell files lib exe obj : first ; NOTFILE all first shell files lib exe obj dirs clean uninstall ; ALWAYS clean uninstall ; # # Rules # rule As { DEPENDS $(<) : $(>) ; ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ; } rule Bulk { local i ; for i in $(>) { File $(i:D=$(<)) : $(i) ; } } rule Cc { local _h ; DEPENDS $(<) : $(>) ; # Just to clarify here: this sets the per-target CCFLAGS to # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS. CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ; # If the compiler's -o flag doesn't work, relocate the .o if $(RELOCATE) { CcMv $(<) : $(>) ; } _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; if $(VMS) && $(_h) { SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ; } else if $(MAC) && $(_h) { local _i _j ; _j = $(_h[1]) ; for _i in $(_h[2-]) { _j = $(_j),$(_i) ; } MACINC on $(<) = \"$(_j)\" ; } } rule C++ { local _h ; DEPENDS $(<) : $(>) ; C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ; if $(RELOCATE) { CcMv $(<) : $(>) ; } _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; if $(VMS) && $(_h) { SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ; } else if $(MAC) && $(_h) { local _i _j ; _j = $(_h[1]) ; for _i in $(_h[2-]) { _j = $(_j),$(_i) ; } MACINC on $(<) = \"$(_j)\" ; } } rule File { DEPENDS files : $(<) ; DEPENDS $(<) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MODE on $(<) = $(FILEMODE) ; Chmod $(<) ; } rule Fortran { DEPENDS $(<) : $(>) ; } rule GenFile { local s ; makeGristedName s : $(<) ; Depends $(s) : $(>[1]:S=$(SUFEXE)) $(>[2-]) ; GenFile1 $(s) : $(>[1]:S=$(SUFEXE)) $(>[2-]) ; Clean clean : $(s) ; } rule GenFile1 { MakeLocate $(<) : $(LOCATE_SOURCE) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; } rule HardLink { DEPENDS files : $(<) ; DEPENDS $(<) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; } rule HdrRule { # HdrRule source : headers ; # N.B. This rule is called during binding, potentially after # the fate of many targets has been determined, and must be # used with caution: don't add dependencies to unrelated # targets, and don't set variables on $(<). # Tell Jam that anything depending on $(<) also depends on $(>), # set SEARCH so Jam can find the headers, but then say we don't # care if we can't actually find the headers (they may have been # within ifdefs), local s ; if $(HDRGRIST) { s = $(>:G=$(HDRGRIST)) ; } else { s = $(>) ; } INCLUDES $(<) : $(s) ; SEARCH on $(s) = $(HDRSEARCH) ; NOCARE $(s) ; # Propagate on $(<) to $(>) HDRSEARCH on $(s) = $(HDRSEARCH) ; HDRSCAN on $(s) = $(HDRSCAN) ; HDRRULE on $(s) = $(HDRRULE) ; HDRGRIST on $(s) = $(HDRGRIST) ; } rule InstallInto { local i t ; t = $(>:G=installed) ; DEPENDS install : $(t) ; DEPENDS $(t) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MakeLocate $(t) : $(<) ; # Arrange for jam uninstall Clean uninstall : $(t) ; for i in $(>) { Install $(i:G=installed) : $(i) ; } if ! $(INSTALL) { Chmod $(t) ; if $(OWNER) { Chown $(t) ; OWNER on $(t) = $(OWNER) ; } if $(GROUP) { Chgrp $(t) ; GROUP on $(t) = $(GROUP) ; } } } rule InstallBin { InstallInto $(<) : $(>) ; MODE on $(>:G=installed) = $(EXEMODE) ; } rule InstallFile { InstallInto $(<) : $(>) ; MODE on $(>:G=installed) = $(FILEMODE) ; } rule InstallLib { InstallInto $(<) : $(>) ; MODE on $(>:G=installed) = $(FILEMODE) ; } rule InstallMan { # Really this just strips the . from the suffix local i s d ; for i in $(>) { switch $(i:S) { case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ; case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ; case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ; case .n : s = n ; case .man : s = 1 ; } d = man$(s) ; InstallInto $(d:R=$(<)) : $(i) ; } MODE on $(>:G=installed) = $(FILEMODE) ; } rule InstallShell { InstallInto $(<) : $(>) ; MODE on $(>:G=installed) = $(SHELLMODE) ; } rule Lex { DEPENDS $(<) : $(>) ; MakeLocate $(<) : $(LOCATE_SOURCE) ; Clean clean : $(<) ; } rule Library { LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ; Objects $(>) ; } rule LibraryFromObjects { local i l s ; # Add grist to file names makeGristedName s : $(>) ; # library depends on its member objects l = $(<:S=$(SUFLIB)) ; if $(KEEPOBJS) { DEPENDS obj : $(s) ; } else { DEPENDS lib : $(l) ; } # Set LOCATE for the library and its contents. The bound # value shows up as $(NEEDLIBS) on the Link actions. # For compatibility, we only do this if the library doesn't # already have a path. if ! $(l:D) { MakeLocate $(l) $(l)($(s:BS)) : $(LOCATE_TARGET) ; } if $(NOARSCAN) { # If we can't scan the library to timestamp its contents, # we have to just make the library depend directly on the # on-disk object files. DEPENDS $(l) : $(s) ; } else { # If we can scan the library, we make the library depend # on its members and each member depend on the on-disk # object file. DEPENDS $(l) : $(l)($(s:BS)) ; for i in $(s) { DEPENDS $(l)($(i:BS)) : $(i) ; } } Clean clean : $(l) ; if $(CRELIB) { CreLib $(l) : $(s[1]) ; } Archive $(l) : $(s) ; if $(RANLIB) { Ranlib $(l) ; } # If we can't scan the library, we have to leave the .o's around. if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(l) : $(s) ; } } rule Link { MODE on $(<) = $(EXEMODE) ; Chmod $(<) ; } rule LinkLibraries { local t ; # make library dependencies of target # set NEEDLIBS variable used by 'actions Main' if $(<:S) { t = $(<) ; } else { t = $(<:S=$(SUFEXE)) ; } DEPENDS $(t) : $(>:S=$(SUFLIB)) ; NEEDLIBS on $(t) += $(>:S=$(SUFLIB)) ; } rule Main { MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ; Objects $(>) ; } rule MainFromObjects { local s t ; # Add grist to file names makeGristedName s : $(>) ; makeSuffixed t $(SUFEXE) : $(<) ; if $(t) != $(<) { DEPENDS $(<) : $(t) ; NOTFILE $(<) ; } # make compiled sources a dependency of target DEPENDS exe : $(t) ; DEPENDS $(t) : $(s) ; MakeLocate $(t) : $(LOCATE_TARGET) ; Clean clean : $(t) ; Link $(t) : $(s) ; } rule MakeLocate { if $(>) { LOCATE on $(<) = $(>) ; Depends $(<) : $(>[1]) ; MkDir $(>[1]) ; } } rule MkDir { if $(<) != $(DOT) && ! $($(<)-mkdir) { local s ; # Cheesy gate to prevent multiple invocations on same dir # MkDir1 has the actions # If dir exists, don't update it # Arrange for jam dirs $(<)-mkdir = true ; MkDir1 $(<) ; NOUPDATE $(<) ; Depends dirs : $(<) ; # Recursively make parent directories. # $(<:P) = $(<)'s parent, & we recurse until root s = $(<:P) ; if $(NT) { switch $(s) { case *: : s = ; case *:\\ : s = ; } } if $(s) && $(s) != $(<) { Depends $(<) : $(s) ; MkDir $(s) ; } else if $(s) { NOTFILE $(s) ; } } } rule Object { local h ; # locate object and search for source, if wanted Clean clean : $(<) ; MakeLocate $(<) : $(LOCATE_TARGET) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; # Save HDRS for -I$(HDRS) on compile. # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers # in the .c file's directory, but generated .c files (from # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly # different from $(SEARCH_SOURCE). HDRS on $(<) = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; # handle #includes for source: Jam scans for headers with # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE) # with the scanned file as the target and the found headers # as the sources. HDRSEARCH is the value of SEARCH used for # the found header files. Finally, if jam must deal with # header files of the same name in different directories, # they can be distinguished with HDRGRIST. # $(h) is where cc first looks for #include "foo.h" files. # If the source file is in a distant directory, look there. # Else, look in "" (the current directory). if $(SEARCH_SOURCE) { h = $(SEARCH_SOURCE) ; } else { h = "" ; } HDRRULE on $(>) = HdrRule ; HDRSCAN on $(>) = $(HDRPATTERN) ; HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ; HDRGRIST on $(>) = $(HDRGRIST) ; # if source is not .c, generate .c with specific rule switch $(>:S) { case .asm : As $(<) : $(>) ; case .c : Cc $(<) : $(>) ; case .C : C++ $(<) : $(>) ; case .cc : C++ $(<) : $(>) ; case .cpp : C++ $(<) : $(>) ; case .f : Fortran $(<) : $(>) ; case .l : Cc $(<) : $(<:S=.c) ; Lex $(<:S=.c) : $(>) ; case .s : As $(<) : $(>) ; case .y : Cc $(<) : $(<:S=.c) ; Yacc $(<:S=.c) : $(>) ; case * : UserObject $(<) : $(>) ; } } rule ObjectCcFlags { local s ; # Add grist to file names makeGristedName s : $(<:S=$(SUFOBJ)) ; CCFLAGS on $(s) += $(>) ; } rule ObjectC++Flags { local s ; # Add grist to file names makeGristedName s : $(<:S=$(SUFOBJ)) ; C++FLAGS on $(s) += $(>) ; } rule ObjectHdrs { local s ; # Add grist to file names makeGristedName s : $(<:S=$(SUFOBJ)) ; HDRS on $(s) += $(>) ; } rule Objects { local i s ; # Add grist to file names makeGristedName s : $(<) ; for i in $(s) { Object $(i:S=$(SUFOBJ)) : $(i) ; DEPENDS obj : $(i:S=$(SUFOBJ)) ; } } rule RmTemps { TEMPORARY $(>) ; } rule Setuid { local t ; if $(<:S) { t = $(<) ; } else { t = $(<:S=$(SUFEXE)) ; } MODE on $(t) = 4711 ; } rule Shell { DEPENDS shell : $(<) ; DEPENDS $(<) : $(>) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; MODE on $(<) = $(SHELLMODE) ; Clean clean : $(<) ; Chmod $(<) ; } rule SubDir { local r s ; # # SubDir TOP d1 [ ... ] # # This introduces a Jamfile that is part of a project tree # rooted at $(TOP). It (only once) includes the project-specific # rules file $(TOP)/Jamrules and then sets search & locate stuff. # # If the variable $(TOPRULES) is set (where TOP is the first arg # to SubDir), that file is included instead of $(TOP)/Jamrules. # # d1 ... are the directory elements that lead to this directory # from $(TOP). We construct the system dependent path from these # directory elements in order to set search&locate stuff. # if ! $($(<[1])) { if ! $(<[1]) { EXIT SubDir syntax error ; } makeSubDir $(<[1]) : $(<[2-]) ; } # # If $(TOP)/Jamrules hasn't been included, do so. # if ! $($(<[1])-included) { # Gated entry. $(<[1])-included = TRUE ; # File is $(TOPRULES) or $(TOP)/Jamrules. r = $($(<[1])RULES) ; if ! $(r) { r = $(JAMRULES:R=$($(<[1]))) ; } # Include it. include $(r) ; } # Get path to current directory from root using makeSubDir. # Save dir tokens for other potential uses. makeDirName s : $(<[2-]) ; SUBDIR = $(s:R=$($(<[1]))) ; SUBDIR_TOKENS = $(<[2-]) ; # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST # These can be reset if needed. For example, if the source # directory should not hold object files, LOCATE_TARGET can # subsequently be redefined. SEARCH_SOURCE = $(SUBDIR) ; LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ; LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ; makeGrist SOURCE_GRIST : $(<[2-]) ; # Reset per-directory ccflags, hdrs SUBDIRCCFLAGS = ; SUBDIRC++FLAGS = ; SUBDIRHDRS = ; } rule SubDirCcFlags { SUBDIRCCFLAGS += $(<) ; } rule SubDirC++Flags { SUBDIRC++FLAGS += $(<) ; } rule SubDirHdrs { SUBDIRHDRS += $(<) ; } rule SubInclude { local s ; # That's # SubInclude TOP d1 [ d2 [ d3 [ d4 ] ] ] # # to include a subdirectory's Jamfile. if ! $($(<[1])) { EXIT Top level of source tree has not been set with $(<[1]) ; } makeDirName s : $(<[2-]) ; include $(JAMFILE:D=$(s):R=$($(<[1]))) ; } rule Undefines { local t ; if $(<:S) { t = $(<) ; } else { t = $(<:S=$(SUFEXE)) ; } UNDEFS on $(t) += $(UNDEFFLAG)$(>) ; } rule UserObject { EXIT "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ; } rule Yacc { local h ; h = $(<:BS=.h) ; # Some places don't have a yacc. MakeLocate $(<) $(h) : $(LOCATE_SOURCE) ; if $(YACC) { DEPENDS $(<) $(h) : $(>) ; Yacc1 $(<) $(h) : $(>) ; Clean clean : $(<) $(h) ; } # make sure someone includes $(h) else it will be # a deadly independent target INCLUDES $(<) : $(h) ; } # # Utility rules; no side effects on these # rule makeString { local _t ; $(<) = $(>[1]) ; for _t in $(>[2-]) { $(<) = $($(<))$(_t) ; } } rule makeSubDir { local _i _d ; # If $(>) is the path to the current directory, compute the # path (using ../../ etc) back to that root directory. # Sets result in $(<) if ! $(>[1]) { _d = $(DOT) ; } else { _d = $(DOTDOT) ; for _i in $(>[2-]) { _d = $(_d:R=$(DOTDOT)) ; } } $(<) = $(_d) ; } rule addDirName { local _s _i ; # Turn individual elements in $(>) into a usable path. # Add result to $(<). if ! $(>) { _s = $(DOT) ; } else if $(VMS) { # This handles the following cases: # a -> [.a] # a b c -> [.a.b.c] # x: -> x: # x: a -> x:[a] # x:[a] b -> x:[a.b] switch $(>[1]) { case *:* : _s = $(>[1]) ; case \\[*\\] : _s = $(>[1]) ; case * : _s = [.$(>[1])] ; } for _i in [.$(>[2-])] { _s = $(_i:R=$(_s)) ; } } else if $(MAC) { _s = $(DOT) ; for _i in $(>) { _s = $(_i:R=$(_s)) ; } } else { _s = $(>[1]) ; for _i in $(>[2-]) { _s = $(_i:R=$(_s)) ; } } $(<) += $(_s) ; } rule makeDirName { $(<) = ; addDirName $(<) : $(>) ; } rule makeGrist { local _g _i ; # Turn individual elements in $(>) into grist. # Return result in $(<) _g = $(>[1]) ; for _i in $(>[2-]) { _g = $(_g)!$(_i) ; } $(<) = $(_g) ; } rule makeGristedName { local _i _o ; # Produce name with grist in it, if SOURCE_GRIST is set. if ! $(SOURCE_GRIST) { $(<) = $(>) ; } else { _o = ; for _i in $(>) { switch $(_i) { case *.h : _o += $(_i) ; case * : _o += $(_i:G=$(SOURCE_GRIST)) ; } } $(<) = $(_o) ; } } rule makeCommon { if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) { $(<) = $($(<)[2-]) ; $(>) = $($(>)[2-]) ; makeCommon $(<) : $(>) ; } } rule makeRelPath { local _l _r ; # first strip off common parts _l = $(<[2-]) ; _r = $(>) ; makeCommon _l : _r ; # now make path to root and path down makeSubDir _l : $(_l) ; makeDirName _r : $(_r) ; # Concatenate and save # XXX This should be better if $(_r) = $(DOT) { $(<[1]) = $(_l) ; } else { $(<[1]) = $(_r:R=$(_l)) ; } } rule makeSuffixed { # E.g., "makeSuffixed s_exe $(SUFEXE) : yacc lex foo.bat ;" # sets $(s_exe) to (yacc,lex,foo.bat) on Unix and # (yacc.exe,lex.exe,foo.bat) on NT. if $(<[2]) { local _i ; $(<[1]) = ; for _i in $(>) { if $(_i:S) { $(<[1]) += $(_i) ; } else { $(<[1]) += $(_i:S=$(<[2])) ; } } } else { $(<[1]) = $(>) ; } } rule unmakeDir { if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\ { unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ; } else { $(<) = $(>) ; } } # # Actions # if $(UNIX) { if $(OS) = QNX { actions together piecemeal Archive { $(AR) $(<) +-$(>) } } else if $(OS) = BEOS { actions together Archive { $(AR) $(<) $(>) } } else { actions updated together piecemeal Archive { $(AR) $(<) $(>) } } actions As { $(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>) } if $(OS) = SINIX { actions C++ { [ $(>:S) != .C ] && $(CP) $(>) $(>:S=.C) && trap "rm -f $(>:S=.C)" 0 $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>:S=.C) } } else if $(RELOCATE) { actions C++ { $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>) } } else { actions C++ { $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>) } } actions Cc { $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>) } if $(RELOCATE) { actions Cc { $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>) } } actions ignore CcMv { [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<) } actions Chgrp { chgrp $(GROUP) $(<) } actions Chmod { chmod $(MODE) $(<) } actions Chown { chown $(OWNER) $(<) } actions piecemeal together existing Clean { $(RM) $(>) } actions File { $(RM) $(<) $(CP) $(>) $(<) } actions GenFile1 { $(>[1]) $(<) $(>[2-]) } actions Fortran { $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>) } actions HardLink { $(RM) $(<) && $(LN) $(>) $(<) } if $(INSTALL) { actions Install { $(INSTALL) -m$(MODE) -o$(OWNER) -g$(GROUP) $(>) $(<) } } else { actions Install { $(CP) $(>) $(<) } } actions Lex { $(LEX) $(>) && $(MV) lex.yy.c $(<) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } actions MkDir1 { $(MKDIR) $(<) } actions together Ranlib { $(RANLIB) $(<) } actions quietly updated piecemeal together RmTemps { $(RM) $(>) } actions Shell { $(AWK) ' NR == 1 { print "$(SHELLHEADER)" } NR == 1 && /^[#:]/ { next } /^##/ { next } { print } ' < $(>) > $(<) } actions Yacc1 { $(YACC) $(YACCFLAGS) $(>) && { $(MV) $(YACCFILES).c $(<[1]) $(MV) $(YACCFILES).h $(<[2]) } } } else if $(NT) || $(OS2) { if $(BCCROOT) { actions C++ { $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) } actions Link bind NEEDLIBS { $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>) } actions updated together piecemeal Archive { $(AR) $(ARFLAGS) $(<) -+$(>) } actions Cc { $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) } } else if $(MSVC) { actions updated together piecemeal Archive { $(AR) $(<) -+$(>) ; } actions Cc { $(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>) } actions C++ { $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } } else if $(MSVCNT) { actions updated together piecemeal Archive { if exist $(<) set _$(<:B)_=$(<) $(AR) /out:$(<) %_$(<:B)_% $(>) } actions As { $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul; } actions Cc { $(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>) } actions C++ { $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } } else if $(WATCOM) { actions together piecemeal Archive { $(AR) $(<) +-$(>) } actions Cc { $(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) } actions C++ { $(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) } actions Link bind NEEDLIBS { $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) } } actions Chmod { } actions piecemeal together existing Clean { $(RM) $(>) } actions File { copy $(>) $(<) } actions GenFile1 { $(>[1]) $(<) $(>[2-]) } actions Install { copy $(>) $(<) } actions MkDir1 { $(MKDIR) $(<) } actions quietly updated piecemeal together RmTemps { $(RM) $(>) } actions Shell { copy $(>) $(<) } } else if $(VMS) { actions updated together piecemeal Archive { lib/replace $(<) $(>[1]) ,$(>[2-]) } actions Cc { cc/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>) } actions C++ { cxx/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>) } actions Chmod { set file/prot=$(MODE) $(<) } actions piecemeal together existing Clean { $(RM) $(>[1]);* ,$(>[2-]);* } actions together quietly CreLib { if f$search("$(<)") .eqs. "" then lib/create $(<) } actions File { copy $(>) $(<) } actions GenFile1 { mcr $(>[1]) $(<) $(>[2-]) } actions Install { copy $(>) $(<) } actions Lex { $(LEX) $(>) $(MV) lex.yy.c $(<) } actions Link bind NEEDLIBS { $(LINK)/exe=$(<) $(LINKFLAGS) $(>[1]) ,$(>[2-]) ,$(NEEDLIBS)/lib ,$(LINKLIBS) } actions MkDir1 { create/dir $(<) } actions quietly updated piecemeal together RmTemps { $(RM) $(>[1]);* ,$(>[2-]);* } actions Shell { copy $(>) $(<) } actions Yacc1 { $(YACC) $(YACCFLAGS) $(>) $(MV) $(YACCFILES).c $(<[1]) $(MV) $(YACCFILES).h $(<[2]) } } else if $(MAC) { SP = " " ; actions together piecemeal Archive { $(LINK) -library -o $(<) $(>) } actions Cc { set MWCincludes $(MACINC) $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>) } actions C++ { set MWCincludes $(MACINC) $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) } rule Chmod { # no chmod on mac - could setfile -l/-L to make rw/ro } actions piecemeal together existing Clean { $(RM) $(>) } actions File { copy $(>) $(<) } actions GenFile1 { $(>[1]) $(<) $(>[2-]) } actions Install { copy $(>) $(<) } actions Link bind NEEDLIBS { $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)" } actions MkDir1 { $(MKDIR) $(<) } actions quietly updated piecemeal together RmTemps { $(RM) $(>) } actions Shell { copy $(>) $(<) } } # # Backwards compatibility with jam 1, where rules were uppercased. # rule BULK { Bulk $(<) : $(>) ; } rule FILE { File $(<) : $(>) ; } rule HDRRULE { HdrRule $(<) : $(>) ; } rule INSTALL { Install $(<) : $(>) ; } rule LIBRARY { Library $(<) : $(>) ; } rule LIBS { LinkLibraries $(<) : $(>) ; } rule LINK { Link $(<) : $(>) ; } rule MAIN { Main $(<) : $(>) ; } rule SETUID { Setuid $(<) ; } rule SHELL { Shell $(<) : $(>) ; } rule UNDEFINES { Undefines $(<) : $(>) ; } # Old INSTALL* didn't take dest directory. rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; } rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; } rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; } # # Now include the user's Jamfile. # { if $(JAMFILE) { include $(JAMFILE) ; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#13 | 3184 | Craig Mcpheeters | Integration of my recent work jam changes into my public mainline branch | ||
#12 | 3181 | Craig Mcpheeters | Integration of the Jam mainline into my branch | ||
#11 | 1604 | Craig Mcpheeters | Integration of rc1 from the mainline | ||
#10 | 1568 | Craig Mcpheeters | An integration from the mainline, from a little while ago. | ||
#9 | 1469 | Craig Mcpheeters | A tiny change to doc only. | ||
#8 | 1468 | Craig Mcpheeters |
Fixed makeString in the Jambase. It was calling FConcat which is no more Fixed the "expr 'in' expr" problem in the mainline, after a suggestion from the jam mailing list. It used to be "expr 'in' list" - it looks like a simple type as that section was redone in the mainline. I've put it back |
||
#7 | 1371 | Craig Mcpheeters |
Integration from the jam mainline. Note, many of these are empty integrations, but I wanted to not leave any pending integrations into my branch. |
||
#6 | 1354 | Craig Mcpheeters | A minor fix for a problem in the jam mainline. | ||
#5 | 1353 | Craig Mcpheeters | Integration from the mainline. | ||
#4 | 1023 | Craig Mcpheeters |
Integration from //guest/craig_mcpheeters/work/jam/src/... This return incorporates all of the Alias|Wavefront extensions to Jam, into an area which is a proper branch of the Jam mainline. An integration of these files into the Jam mainline will show all of the differences. There are several extensions to Jam in this return. Look at the new file Jamfile.config for an explanation of the extensions, and how to compile them into your own copy of Jam. If you want to build a copy of Jam with all of the extensions, do this: jam -sAllOptions=1 Read the config file for more info. The extensions range from minor output tweaks and simple fixes to more major things like a header cache, serialization of output from multiple jobs, dynamic command block sizing These are all offered without warranty, etc. |
||
#3 | 784 | Craig Mcpheeters | Integration from Jam mainline | ||
#2 | 617 | Craig Mcpheeters | Integration from mainline as of @3 | ||
#1 | 616 | Craig Mcpheeters | Integration from Jam mainline, as of @2 |