#============================================================================ # Rules for compiling a set of sources to object files #============================================================================ # These are slightly modified versions of the Object and Objects rules from # jam. The problem with the original rules in Jambase is the handling of # custom file types. The solution with the UserObject rule is monolithic, you # can only have 1 such rule. Thus we construct a more flexible toolkit here # which let's you register rules for certain filetypes. ## RegisterFileType Rulename : extensions ## Register a rule which is used to compile a filetype into object ## files. The registered rule is called with the name of the ## sourcefile as argument and should return a list of objectfiles which are ## created. You should set the grist of the object files by using the ## DoObjectGrist function. rule RegisterFileType { local suffix ; for suffix in $(>) { FILETYPE_$(suffix) = $(<) ; } } ## RegisterHeaderRule rulename : regexpattern : extensions ## Registers a rule and a regular expression which will be used for header ## file scanning of the specified extensions. rule RegisterHeaderRule { local suffix ; for suffix in $(3) { HDRRULE_$(suffix) = $(<) ; HDRPATTERN_$(suffix) = $(>) ; } } ## CompileObjects sources [ : options ] ## Compile a set of sourcefiles into objectfiles (extension: SUFOBJ, ## usually .o). This rule takes care of setting LOCATE and SEARCH ## variables to the $(SEARCH_SOURCE) and $(LOCATE_SOURCE) variables. ## The Application, Plugin and Library rules already use this rule ## internally. You should only use this rule if you have to avoid the ## Application, Plugin or Library rules. rule CompileObjects { local source ; local targets ; # Search the source SEARCH on $(<) = $(SEARCH_SOURCE) ; for source in $(<) { # compile the sourcefile to targetfile targets += [ CompileObject $(source) : $(2) ] ; } # locate the targets MakeLocate $(targets) : $(LOCATE_TARGET) ; return $(targets) ; } #---------------------------------------------------------------------------- # private part # CompileObject sourcefile [ : options ] # helper rule: Compiles a source file to an object file. Does header file # scanning, sets LOCATE and SEARCH for source and target, grists the files # with the current subdir and searches for the correct registered rule. rule CompileObject { # 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. # $(SEARCH_SOURCE:E) 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 $(HDRRULE_$(<:S)) { HDRSEARCH on $(<) = $(SEARCH_SOURCE:E) $(HDRSEARCH) $(STDHDRSEARCH) ; SEARCH_SOURCE on $(<) = $(SEARCH_SOURCE) ; HDRRULE on $(<) = $(HDRRULE_$(<:S)) ; HDRSCAN on $(<) = $(HDRPATTERN_$(<:S)) ; } local targets ; # Invoke filetype specific rule if $(FILETYPE_$(<:S)) { targets = [ $(FILETYPE_$(<:S)) $(<) : $(2) ] ; } else { echo "Warning: no rules for filetype $(>:S) defined (at file $(>))." ; } if $(targets) { # construct clean target Clean clean : $(targets) ; } return $(targets) ; } ## HeaderRule source : headers ## This rule is the default header rule used by the objects rules. You ## might register custom rules with the RegisterHeaderRule rule. rule HeaderRule { # 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 HDRSEARCH = [ on $(<) GetVar HDRSEARCH ] ; local SEARCH_SOURCE = [ on $(<) GetVar SEARCH_SOURCE ] ; Includes $(<) : $(>) ; SEARCH on $(>) = $(HDRSEARCH) $(SEARCH_SOURCE)/$(<:D) ; NoCare $(>) ; local i ; for i in $(>) { SEARCH on $(>) = $(HDRSEARCH) $(SEARCH_SOURCE)/$(<:D) ; if $(i:D) = "" { SEARCH_SOURCE on $(i) = $(SEARCH_SOURCE)/$(<:D) ; } else { SEARCH_SOURCE on $(i) = $(SEARCH_SOURCE) ; } HDRSEARCH on $(>) = $(HDRSEARCH) ; HDRRULE on $(>) = [ on $(<) GetVar HDRRULE ] ; HDRSCAN on $(>) = [ on $(<) GetVar HDRPATTERN ] ; } } if $(JAMVERSION) < 2.5 { ## XXX XXX XXX a bug in jam 2.4 let's the version above fail. I'll let this ## non-optimal version in here until jam 2.5 is out. rule HeaderRule { local s = $(>:G=$(HDRGRIST)) ; Includes $(<) : $(s) ; SEARCH on $(s) = $(HDRSEARCH) ; NoCare $(s) ; local i ; for i in $(s) { if $(HDRRULE_$(i:S)) { HDRGRIST on $(s) = $(HDRGRIST) ; HDRSEARCH on $(s) = $(HDRSEARCH) ; HDRRULE on $(s) = $(HDRRULE_$(i:S)) ; HDRSCAN on $(s) = $(HDRPATTERN_$(i:S)) ; } else if $(JAM_DEBUG) { #echo "No Header rule for $(i:S) file $(i) " ; } } } } # end of if $(JAMVERSION) < 1.5 # Dummy rule: .o files are used as is. rule UseObjectFile { return $(<) ; } RegisterFileType UseObjectFile : .o ; # Ignore header files. rule UseHeaderFile { return ; } RegisterFileType UseHeaderFile : .h .hpp ; RegisterHeaderRule HeaderRule : $(HDRPATTERN) : .h .hpp .inc ; # Generates a grist suitable for output objects based on # SUBVARIANT and SUBDIR variable. rule DoObjectGrist { return $(<:G=$(SOURCE_GRIST:E)!$(SUBVARIANT)) ; } # Generates a grist suitable for source files based on SUBDIR variable. rule DoSourceGrist { return $(<:G=$(SOURCE_GRIST:E)) ; }