#============================================================================ # Rules for compiling a set of sources to object files # Copyright (C)2003 by Matze Braun # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Library General Public License as published by # the Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public # License for more details. # # You should have received a copy of the GNU Library General Public License # along with this library; if not, write to the Free Software Foundation, # Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # #============================================================================ # 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 [: objectfileprefix] ## Compile a set of sourcefiles into objectfiles (extension: SUFOBJ, ## usually .o). This rule takes care of setting the SEARCH and LOCATE ## variables to the values of $(SEARCH_SOURCE) and $(LOCATE_TARGET). ## 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) : $(>) ] ; } # locate the targets MakeLocate $(targets) : $(LOCATE_TARGET) ; return $(targets) ; } ## PrefixSuffix [prefix] : filename : suffix ## Replaces the suffix of 'filename' with 'suffix' and prepends 'prefix' to ## it. rule PrefixSuffix { local prefix = $(1) ; local name = $(2) ; local suffix = $(3) ; if ! $(prefix) { prefix = "" ; } return $(name:B=$(prefix)$(name:B):S=$(suffix)) ; } #---------------------------------------------------------------------------- # private part # 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. Finally, if jam must deal with # header files of the same name in different directories, # they can be distinguished with HDRGRIST. # $(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) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ; HDRGRIST on $(<) = $(HDRGRIST) ; HDRRULE on $(<) = $(HDRRULE_$(<:S)) ; HDRSCAN on $(<) = $(HDRPATTERN_$(<:S)) ; } local targets ; # Invoke filetype specific rule if $(FILETYPE_$(<:S)) { targets = [ $(FILETYPE_$(<:S)) $(<) : $(>) ] ; } else { echo Warning: no rules for file type $(<:S) defined (at file $(<)). ; } if $(targets) { # construct clean target Clean clean : $(targets) ; # 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) $(SUBDIRHDRS) $(HDRS) ; # propagate target specific-defines DEFINES on $(<) += $(DEFINES) ; } 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 s = $(>:G=$(HDRGRIST:E)) ; Includes $(<) : $(s) ; SEARCH on $(s) = $(HDRSEARCH) ; NoCare $(s) ; local i ; for i in $(s) { HDRGRIST on $(i) = $(HDRGRIST) ; HDRSEARCH on $(i) = $(HDRSEARCH) ; HDRRULE on $(i) = [ on $(<) GetVar HDRRULE ] ; HDRSCAN on $(i) = [ 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:E)) ; Includes $(<) : $(s) ; SEARCH on $(s) = $(HDRSEARCH) ; NoCare $(s) ; local i ; for i in $(s) { if $(HDRRULE_$(i:S)) { HDRGRIST on $(i) = $(HDRGRIST) ; HDRSEARCH on $(i) = $(HDRSEARCH) ; HDRRULE on $(i) = $(HDRRULE_$(i:S)) ; HDRSCAN on $(i) = $(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:J=!)) ; } # Generates a grist suitable for source files based on SUBDIR variable. # Doesn't change an existing grist. rule DoSourceGrist { local gristed ; for g in $(<) { local grist ; if $(g:G) { grist = $(g:G) ; } gristed += $(g:G=$(grist:E=$(SOURCE_GRIST:E))) ; } return $(gristed) ; }