Option to jump with up on keyboard.
[supertux.git] / mk / jam / objects.jam
1 #============================================================================
2 # Rules for compiling a set of sources to object files
3 #============================================================================
4 # These are slightly modified versions of the Object and Objects rules from
5 # jam. The problem with the original rules in Jambase is the handling of
6 # custom file types. The solution with the UserObject rule is monolithic, you
7 # can only have 1 such rule. Thus we construct a more flexible toolkit here
8 # which let's you register rules for certain filetypes.
9
10 ##  RegisterFileType Rulename : extensions
11 ##    Register a rule which is used to compile a filetype into object
12 ##    files. The registered rule is called with the name of the
13 ##    sourcefile as argument (completely gristed and SEARCH is set already).
14 ##    The rule should return the object files created completely gristed and
15 ##    with LOCATE set (use the LocateTarget rule to do this).
16 rule RegisterFileType
17 {
18     local suffix ;
19     for suffix in $(>)
20     {
21         FILETYPE_$(suffix) = $(<) ;
22     }
23 }
24
25 ##  RegisterHeaderRule rulename : regexpattern : extensions
26 ##    Registers a rule and a regular expression which will be used for header
27 ##    file scanning of the specified extensions.
28 rule RegisterHeaderRule
29 {
30     local suffix ;
31     for suffix in $(3)
32     {
33         HDRRULE_$(suffix) = $(<) ;
34         HDRPATTERN_$(suffix) = $(>) ;
35     }
36 }
37
38 ##  CompileObjects sources [ : options ]
39 ##    Compile a set of sourcefiles into objectfiles (usually .o extension).
40 ##    For ungristed sourcefiles $(SEARCH) will be set to $(SEARCH_SOURCE).
41 ##    The function returns the names of the targets being built (gristed and
42 ##    with LOCATE set.
43 ##    Normally you don't have to use this rule. The Application or Library rules
44 ##    are taking care of calling it for you.
45 rule CompileObjects
46 {
47     local s ;
48     local sources = [ SearchSource $(<) ] ;
49     local targets ;
50
51     for s in $(sources)
52     {
53         # compile the sourcefile to targetfile
54         targets += [ CompileObject $(s) : $(2) ] ;
55     }
56
57     return $(targets) ;
58 }
59
60 #----------------------------------------------------------------------------
61 # private part
62
63 # CompileObject sourcefile [ : options ]
64 # helper rule: Compiles a source file to an object file. The source should be
65 # correctly gristed and SEARCH should be set. The function will return the
66 # target names gristed and with LOCATE set.
67 rule CompileObject
68 {
69     # handle #includes for source: Jam scans for headers with
70     # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
71     # with the scanned file as the target and the found headers
72     # as the sources.  HDRSEARCH is the value of SEARCH used for
73     # the found header files.
74
75     # $(SEARCH_SOURCE:E) is where cc first looks for #include 
76     # "foo.h" files.  If the source file is in a distant directory, 
77     # look there.  Else, look in "" (the current directory).
78     if $(HDRRULE_$(<:S))
79     {
80         HDRSEARCH on $(<) = $(SEARCH_SOURCE:E) $(HDRSEARCH) $(STDHDRSEARCH) ;
81         SEARCH_SOURCE on $(<) = $(SEARCH_SOURCE) ;
82         HDRRULE on $(<) = $(HDRRULE_$(<:S)) ;
83         HDRSCAN on $(<) = $(HDRPATTERN_$(<:S)) ;
84     }
85
86     local targets ;
87     # Invoke filetype specific rule
88     if $(FILETYPE_$(<:S)) {
89         targets = [ $(FILETYPE_$(<:S)) $(<) : $(2) ] ;
90     } else {
91         echo "Warning: no rules for filetype $(<:S) defined (at file $(<))." ;
92     }
93
94     if $(targets) {
95         # construct clean target
96         Clean clean : $(targets) ;
97     }
98
99     return $(targets) ;
100 }
101
102 ##  HeaderRule source : headers
103 ##    This rule is the default header rule used by the objects rules. You
104 ##    might register custom rules with the RegisterHeaderRule rule.
105 rule HeaderRule
106 {
107     # N.B.  This rule is called during binding, potentially after
108     # the fate of many targets has been determined, and must be
109     # used with caution: don't add dependencies to unrelated
110     # targets, and don't set variables on $(<).
111                                                                                 
112     # Tell Jam that anything depending on $(<) also depends on $(>),
113     # set SEARCH so Jam can find the headers, but then say we don't
114     # care if we can't actually find the headers (they may have been
115     # within ifdefs),
116     local HDRSEARCH = [ on $(<) GetVar HDRSEARCH ] ;
117     local SEARCH_SOURCE = [ on $(<) GetVar SEARCH_SOURCE ] ;
118
119     Includes $(<) : $(>) ;
120     SEARCH on $(>) = $(HDRSEARCH) $(SEARCH_SOURCE)/$(<:D) ;
121     NoCare $(>) ;
122
123     local i ;
124     for i in $(>)
125     {
126
127         SEARCH on $(>) = $(HDRSEARCH) $(SEARCH_SOURCE)/$(<:D) ;
128         if $(i:D) = "" {
129             SEARCH_SOURCE on $(i) = $(SEARCH_SOURCE)/$(<:D) ;
130         } else {
131             SEARCH_SOURCE on $(i) = $(SEARCH_SOURCE) ;
132         }
133         HDRSEARCH on $(>) = $(HDRSEARCH) ;
134         HDRRULE on $(>) = [ on $(<) GetVar HDRRULE ] ;
135         HDRSCAN on $(>) = [ on $(<) GetVar HDRPATTERN ] ;
136     }
137 }
138
139 # Dummy rule: .o files are used as is.
140 rule UseObjectFile
141 {
142     return $(<) ;
143 }
144 RegisterFileType UseObjectFile : .o ;
145
146 # Ignore header files.
147 rule UseHeaderFile
148 {
149     return ;
150 }
151 RegisterFileType UseHeaderFile : .h .hpp .inc .inl ;
152 RegisterHeaderRule HeaderRule : $(HDRPATTERN) : .h .hpp .inc .inl ;
153
154 ##  SearchSource
155 ##    Sets search path of the sourcefiles to the current SUBDIR and sets a
156 ##    suitable grist on the sources. Ignores source files that already have
157 ##    grist set.
158 rule SearchSource
159 {
160     local sources ;
161     
162     for f in $(<) {
163         if $(f:G) {
164             sources += $(f) ;
165         } else {
166             local source = $(f:G=$(SOURCE_GRIST:E)) ;
167             sources += $(source) ;
168             SEARCH on $(source) = $(SEARCH_SOURCE) ;
169         }
170     }
171     return $(sources) ;
172 }
173
174 ##  LocateTarget
175 ##    Sets LOCATE on the current output directory (depending on builddir,
176 ##    variant and current subdir), sets a suitable grist and makes sure the
177 ##    target directory is created if it doesn't exist.
178 rule LocateTarget
179 {
180     local targetdir ;
181     if $(>) {
182         targetdir = $(>) ;
183     } else {
184         targetdir = $(LOCATE_TARGET) ;
185     }
186     
187     local targets = $(<:G=T!$(SOURCE_GRIST:E)!$(SUBVARIANT)) ;
188     MakeLocate $(targets) : $(targetdir) ;
189
190     return $(targets) ;
191 }
192