1 | .TH ACD 1
|
---|
2 | .SH NAME
|
---|
3 | acd \- a compiler driver
|
---|
4 | .SH SYNOPSIS
|
---|
5 | .B acd
|
---|
6 | \fB\-v\fR[\fIn\fR]
|
---|
7 | \fB\-vn\fR[\fIn\fR]
|
---|
8 | .BI \-name " name"
|
---|
9 | .BI \-descr " descr"
|
---|
10 | .BI \-T " dir"
|
---|
11 | .RI [ arg " ...]"
|
---|
12 | .SH DESCRIPTION
|
---|
13 | .de SP
|
---|
14 | .if t .sp 0.4
|
---|
15 | .if n .sp
|
---|
16 | ..
|
---|
17 | .B Acd
|
---|
18 | is a compiler driver, a program that calls the several passes that are needed
|
---|
19 | to compile a source file. It keeps track of all the temporary files used
|
---|
20 | between the passes. It also defines the interface of the compiler, the
|
---|
21 | options the user gets to see.
|
---|
22 | .PP
|
---|
23 | This text only describes
|
---|
24 | .B acd
|
---|
25 | itself, it says nothing about the different options the C-compiler accepts.
|
---|
26 | (It has nothing to do with any language, other than being a tool to give
|
---|
27 | a compiler a user interface.)
|
---|
28 | .SH OPTIONS
|
---|
29 | .B Acd
|
---|
30 | itself takes five options:
|
---|
31 | .TP
|
---|
32 | \fB\-v\fR[\fIn\fR]
|
---|
33 | Sets the diagnostic level to
|
---|
34 | .I n
|
---|
35 | (by default
|
---|
36 | .BR 2 ).
|
---|
37 | The higher
|
---|
38 | .I n
|
---|
39 | is, the more output
|
---|
40 | .B acd
|
---|
41 | generates:
|
---|
42 | .B \-v0
|
---|
43 | does not produce any output.
|
---|
44 | .B \-v1
|
---|
45 | prints the basenames of the programs called.
|
---|
46 | .B \-v2
|
---|
47 | prints names and arguments of the programs called.
|
---|
48 | .B \-v3
|
---|
49 | shows the commands executed from the description file too.
|
---|
50 | .B \-v4
|
---|
51 | shows the program read from the description file too. Levels 3 and 4 use
|
---|
52 | backspace overstrikes that look good when viewing the output with a smart
|
---|
53 | pager.
|
---|
54 | .TP
|
---|
55 | \fB\-vn\fR[\fIn\fR]
|
---|
56 | Like
|
---|
57 | .B \-v
|
---|
58 | except that no command is executed. The driver is just play-acting.
|
---|
59 | .TP
|
---|
60 | .BI \-name " name"
|
---|
61 | .B Acd
|
---|
62 | is normally linked to the name the compiler is to be called with by the
|
---|
63 | user. The basename of this, say
|
---|
64 | .BR cc ,
|
---|
65 | is the call name of the driver. It plays a role in selecting the proper
|
---|
66 | description file. With the
|
---|
67 | .B \-name
|
---|
68 | option one can change this.
|
---|
69 | .B Acd \-name cc
|
---|
70 | has the same effect as calling the program as
|
---|
71 | .BR cc .
|
---|
72 | .TP
|
---|
73 | .BI \-descr " descr"
|
---|
74 | Allows one to choose the pass description file of the driver. By default
|
---|
75 | .I descr
|
---|
76 | is the same as
|
---|
77 | .IR name ,
|
---|
78 | the call name of the program. If
|
---|
79 | .I descr
|
---|
80 | doesn't start with
|
---|
81 | .BR / ,
|
---|
82 | .BR ./ ,
|
---|
83 | or
|
---|
84 | .BR ../
|
---|
85 | then the file
|
---|
86 | .BI /usr/lib/ descr /descr
|
---|
87 | will be used for the description, otherwise
|
---|
88 | .I descr
|
---|
89 | itself. Thus
|
---|
90 | .B cc \-descr newcc
|
---|
91 | calls the C-compiler with a different description file without changing the
|
---|
92 | call name. Finally, if
|
---|
93 | .I descr
|
---|
94 | is \fB"\-"\fP, standard input is read. (The default lib directory
|
---|
95 | .BR /usr/lib ,
|
---|
96 | may be changed to
|
---|
97 | .I dir
|
---|
98 | at compile time by \fB\-DLIB=\e"\fP\fIdir\fP\fB\e"\fP. The default
|
---|
99 | .I descr
|
---|
100 | may be set with \fB\-DDESCR=\e"\fP\fIdescr\fP\fB\e"\fP for simple
|
---|
101 | installations on a system without symlinks.)
|
---|
102 | .TP
|
---|
103 | .BI \-T " dir"
|
---|
104 | Temporary files are made in
|
---|
105 | .B /tmp
|
---|
106 | by default, which may be overridden by the environment variable
|
---|
107 | .BR TMPDIR ,
|
---|
108 | which may be overridden by the
|
---|
109 | .B \-T
|
---|
110 | option.
|
---|
111 | .SH "THE DESCRIPTION FILE"
|
---|
112 | The description file is a program interpreted by the driver. It has variables,
|
---|
113 | lists of files, argument parsing commands, and rules for transforming input
|
---|
114 | files.
|
---|
115 | .SS Syntax
|
---|
116 | There are four simple objects:
|
---|
117 | .PP
|
---|
118 | .RS
|
---|
119 | Words, Substitutions, Letters, and Operators.
|
---|
120 | .RE
|
---|
121 | .PP
|
---|
122 | And there are two ways to group objects:
|
---|
123 | .PP
|
---|
124 | .RS
|
---|
125 | Lists, forming sequences of anything but letters,
|
---|
126 | .SP
|
---|
127 | Strings, forming sequences of anything but Words and Operators.
|
---|
128 | .RE
|
---|
129 | .PP
|
---|
130 | Each object has the following syntax:
|
---|
131 | .IP Words
|
---|
132 | They are sequences of characters, like
|
---|
133 | .BR cc ,
|
---|
134 | .BR \-I/usr/include ,
|
---|
135 | .BR /lib/cpp .
|
---|
136 | No whitespace and no special characters. The backslash character
|
---|
137 | .RB ( \e )
|
---|
138 | may be used to make special characters common, except whitespace. A backslash
|
---|
139 | followed by whitespace is completely removed from the input. The sequence
|
---|
140 | .B \en
|
---|
141 | is changed to a newline.
|
---|
142 | .IP Substitutions
|
---|
143 | A substitution (henceforth called 'subst') is formed with a
|
---|
144 | .BR $ ,
|
---|
145 | e.g.
|
---|
146 | .BR $opt ,
|
---|
147 | .BR $PATH ,
|
---|
148 | .BR ${lib} ,
|
---|
149 | .BR $\(** .
|
---|
150 | The variable name after the
|
---|
151 | .B $
|
---|
152 | is made of letters, digits and underscores, or any sequence of characters
|
---|
153 | between parentheses or braces, or a single other character. A subst indicates
|
---|
154 | that the value of the named variable must be substituted in the list or string
|
---|
155 | when fully evaluated.
|
---|
156 | .IP Letters
|
---|
157 | Letters are the single characters that would make up a word.
|
---|
158 | .IP Operators
|
---|
159 | The characters
|
---|
160 | .BR = ,
|
---|
161 | .BR + ,
|
---|
162 | .BR \- ,
|
---|
163 | .BR \(** ,
|
---|
164 | .BR < ,
|
---|
165 | and
|
---|
166 | .B >
|
---|
167 | are the operators. The first four must be surrounded by whitespace if they
|
---|
168 | are to be seen as special (they are often used in arguments). The last two
|
---|
169 | are always special.
|
---|
170 | .IP Lists
|
---|
171 | One line of objects in the description file forms a list. Put parentheses
|
---|
172 | around it and you have a sublist. The values of variables are lists.
|
---|
173 | .IP Strings
|
---|
174 | Anything that is not yet a word is a string. All it needs is that the substs
|
---|
175 | in it are evaluated, e.g.
|
---|
176 | .BR $LIBPATH/lib$key.a .
|
---|
177 | A single subst doesn't make a string, it expands to a list. You need at
|
---|
178 | least one letter or other subst next to it. Strings (and words) may also
|
---|
179 | be formed by enclosing them in double quotes. Only
|
---|
180 | .B \e
|
---|
181 | and
|
---|
182 | .B $
|
---|
183 | keep their special meaning within quotes.
|
---|
184 | .SS Evaluation
|
---|
185 | One thing has to be carefully understood: Substitutions are delayed until
|
---|
186 | the last possible moment, and description files make heavy use of this.
|
---|
187 | Only if a subst is tainted, either because its variable is declared local, or
|
---|
188 | because a subst in its variable's value is tainted, is it immediately
|
---|
189 | substituted. So if a list is assigned to a variable then this list is only
|
---|
190 | checked for tainted substs. Those substs are replaced by the value
|
---|
191 | of their variable. This is called partial evaluation.
|
---|
192 | .PP
|
---|
193 | Full evaluation expands all substs, the list is flattened, i.e. all
|
---|
194 | parentheses are removed from sublists.
|
---|
195 | .PP
|
---|
196 | Implosive evaluation is the last that has to be done to a list before it
|
---|
197 | can be used as a command to execute. The substs within a string have been
|
---|
198 | evaluated to lists after full expansion, but a string must be turned into
|
---|
199 | a single word, not a list. To make this happen, a string is first exploded
|
---|
200 | to all possible combinations of words choosing one member of the lists within
|
---|
201 | the string. These words are tried one by one to see if they exist as a
|
---|
202 | file. The first one that exists is taken, if none exists than the first
|
---|
203 | choice is used. As an example, assume
|
---|
204 | .B LIBPATH
|
---|
205 | equals
|
---|
206 | .BR "(/lib /usr/lib)" ,
|
---|
207 | .B key
|
---|
208 | is
|
---|
209 | .B (c)
|
---|
210 | and
|
---|
211 | .B key
|
---|
212 | happens to be local. Then we have:
|
---|
213 | .PP
|
---|
214 | .RS
|
---|
215 | \fB"$LIBPATH/lib$key.a"\fP
|
---|
216 | .RE
|
---|
217 | .PP
|
---|
218 | before evaluation,
|
---|
219 | .PP
|
---|
220 | .RS
|
---|
221 | \fB"$LIBPATH/lib(c).a"\fP
|
---|
222 | .RE
|
---|
223 | .PP
|
---|
224 | after partial evaluation,
|
---|
225 | .PP
|
---|
226 | .RS
|
---|
227 | \fB"(/lib/libc.a /usr/lib/libc.a)"\fP
|
---|
228 | .RE
|
---|
229 | .PP
|
---|
230 | after full evaluation, and finally
|
---|
231 | .PP
|
---|
232 | .RS
|
---|
233 | .B /usr/lib/libc.a
|
---|
234 | .RE
|
---|
235 | .PP
|
---|
236 | after implosion, if the file exists.
|
---|
237 | .SS Operators
|
---|
238 | The operators modify the way evaluation is done and perform a special
|
---|
239 | function on a list:
|
---|
240 | .TP
|
---|
241 | .B \(**
|
---|
242 | Forces full evaluation on all the list elements following it. Use it to
|
---|
243 | force substitution of the current value of a variable. This is the only
|
---|
244 | operator that forces immediate evaluation.
|
---|
245 | .TP
|
---|
246 | .B +
|
---|
247 | When a
|
---|
248 | .B +
|
---|
249 | exists in a list that is fully evaluated, then all the elements before the
|
---|
250 | .B +
|
---|
251 | are imploded and all elements after the
|
---|
252 | .B +
|
---|
253 | are imploded and added to the list if they are not already in the list. So
|
---|
254 | this operator can be used either for set addition, or to force implosive
|
---|
255 | expansion within a sublist.
|
---|
256 | .TP
|
---|
257 | .B \-
|
---|
258 | Like
|
---|
259 | .BR + ,
|
---|
260 | except that elements after the
|
---|
261 | .B \-
|
---|
262 | are removed from the list.
|
---|
263 | .PP
|
---|
264 | The set operators can be used to gather options that exclude each other
|
---|
265 | or for their side effect of implosive expansion. You may want to write:
|
---|
266 | .PP
|
---|
267 | .RS
|
---|
268 | \fBcpp \-I$LIBPATH/include\fP
|
---|
269 | .RE
|
---|
270 | .PP
|
---|
271 | to call cpp with an extra include directory, but
|
---|
272 | .B $LIBPATH
|
---|
273 | is expanded using a filename starting with
|
---|
274 | .B \-I
|
---|
275 | so this won't work. Given that any problem in Computer Science can be solved
|
---|
276 | with an extra level of indirection, use this instead:
|
---|
277 | .PP
|
---|
278 | .RS
|
---|
279 | .ft B
|
---|
280 | cpp \-I$INCLUDE
|
---|
281 | .br
|
---|
282 | INCLUDE = $LIBPATH/include +
|
---|
283 | .ft P
|
---|
284 | .RE
|
---|
285 | .SS "Special Variables"
|
---|
286 | There are three special variables used in a description file:
|
---|
287 | .BR $\(** ,
|
---|
288 | .BR $< ,
|
---|
289 | and
|
---|
290 | .BR $> .
|
---|
291 | These variables are always local and mostly read-only. They will be
|
---|
292 | explained later.
|
---|
293 | .SS "A Program"
|
---|
294 | The lists in a description file form a program that is executed from the
|
---|
295 | first to the last list. The first word in a list may be recognized as a
|
---|
296 | builtin command (only if the first list element is indeed simply a word.)
|
---|
297 | If it is not a builtin command then the list is imploded and used as a
|
---|
298 | \s-2UNIX\s+2 command with arguments.
|
---|
299 | .PP
|
---|
300 | Indentation (by tabs or spaces) is not just makeup for a program, but are
|
---|
301 | used to group lines together. Some builtin commands need a body. These
|
---|
302 | bodies are simply lines at a deeper indentation.
|
---|
303 | .PP
|
---|
304 | Empty lines are not ignored either, they have the same indentation level as
|
---|
305 | the line before it. Comments (starting with a
|
---|
306 | .B #
|
---|
307 | and ending at end of line) have an indentation of their own and can be used
|
---|
308 | as null commands.
|
---|
309 | .PP
|
---|
310 | .B Acd
|
---|
311 | will complain about unexpected indentation shifts and empty bodies. Commands
|
---|
312 | can share the same body by placing them at the same indentation level before
|
---|
313 | the indented body. They are then "guards" to the same body, and are tried
|
---|
314 | one by one until one succeeds, after which the body is executed.
|
---|
315 | .PP
|
---|
316 | Semicolons may be used to separate commands instead of newlines. The commands
|
---|
317 | are then all at the indentation level of the first.
|
---|
318 | .SS "Execution phases"
|
---|
319 | The driver runs in three phases: Initialization, Argument scanning, and
|
---|
320 | Compilation. Not all commands work in all phases. This is further explained
|
---|
321 | below.
|
---|
322 | .SS "The Commands"
|
---|
323 | The commands accept arguments that are usually generic expressions that
|
---|
324 | implode to a word or a list of words. When
|
---|
325 | .I var
|
---|
326 | is specified, then a single word or subst needs to be given, so
|
---|
327 | an assignment can be either
|
---|
328 | .I name
|
---|
329 | .B =
|
---|
330 | .IR value ,
|
---|
331 | or
|
---|
332 | .BI $ name
|
---|
333 | .B =
|
---|
334 | .IR value .
|
---|
335 | .TP
|
---|
336 | .IB "var " = " expr ..."
|
---|
337 | The partially evaluated list of expressions is assigned to
|
---|
338 | .IR var .
|
---|
339 | During the evaluation is
|
---|
340 | .I var
|
---|
341 | marked as local, and after the assignment set from undefined to defined.
|
---|
342 | .TP
|
---|
343 | .BI unset " var"
|
---|
344 | .I Var
|
---|
345 | is set to null and is marked as undefined.
|
---|
346 | .TP
|
---|
347 | .BI import " var"
|
---|
348 | If
|
---|
349 | .I var
|
---|
350 | is defined in the environment of
|
---|
351 | .B acd
|
---|
352 | then it is assigned to
|
---|
353 | .IR var .
|
---|
354 | The environment variable is split into words at whitespace and colons. Empty
|
---|
355 | space between two colons
|
---|
356 | .RB ( :: )
|
---|
357 | is changed to a dot.
|
---|
358 | .TP
|
---|
359 | .BI mktemp " var " [ suffix ]
|
---|
360 | Assigns to
|
---|
361 | .I var
|
---|
362 | the name of a new temporary file, usually something like /tmp/acd12345x. If
|
---|
363 | .I suffix
|
---|
364 | is present then it will be added to the temporary file's name. (Use it
|
---|
365 | because some programs require it, or just because it looks good.)
|
---|
366 | .B Acd
|
---|
367 | remembers this file, and will delete it as soon as you stop referencing it.
|
---|
368 | .TP
|
---|
369 | .BI temporary " word"
|
---|
370 | Mark the file named by
|
---|
371 | .I word
|
---|
372 | as a temporary file. You have to make sure that the name is stored in some
|
---|
373 | list in imploded form, and not just temporarily created when
|
---|
374 | .I word
|
---|
375 | is evaluated, because then it will be immediately removed and forgotten.
|
---|
376 | .TP
|
---|
377 | .BI stop " suffix"
|
---|
378 | Sets the target suffix for the compilation phase. Something like
|
---|
379 | .B stop .o
|
---|
380 | means that the source files must be compiled to object files. At least one
|
---|
381 | .B stop
|
---|
382 | command must be executed before the compilation phase begins. It may not be
|
---|
383 | changed during the compilation phase. (Note: There is no restriction on
|
---|
384 | .IR suffix ,
|
---|
385 | it need not start with a dot.)
|
---|
386 | .TP
|
---|
387 | .BI treat " file suffix"
|
---|
388 | Marks the file as having the given suffix for the compile phase. Useful
|
---|
389 | for sending a
|
---|
390 | .B \-l
|
---|
391 | option directly to the loader by treating it as having the
|
---|
392 | .B .a
|
---|
393 | suffix.
|
---|
394 | .TP
|
---|
395 | .BI numeric " arg"
|
---|
396 | Checks if
|
---|
397 | .I arg
|
---|
398 | is a number. If not then
|
---|
399 | .B acd
|
---|
400 | will exit with a nice error message.
|
---|
401 | .TP
|
---|
402 | .BI error " expr ..."
|
---|
403 | Makes the driver print the error message
|
---|
404 | .I "expr ..."
|
---|
405 | and exit.
|
---|
406 | .TP
|
---|
407 | .BI if " expr " = " expr"
|
---|
408 | .B If
|
---|
409 | tests if the two expressions are equal using set comparison, i.e. each
|
---|
410 | expression should contain all the words in the other expression. If the
|
---|
411 | test succeeds then the if-body is executed.
|
---|
412 | .TP
|
---|
413 | .BI ifdef " var"
|
---|
414 | Executes the ifdef-body if
|
---|
415 | .I var
|
---|
416 | is defined.
|
---|
417 | .TP
|
---|
418 | .BI ifndef " var"
|
---|
419 | Executes the ifndef-body if
|
---|
420 | .I var
|
---|
421 | is undefined.
|
---|
422 | .TP
|
---|
423 | .BI iftemp " arg"
|
---|
424 | Executes the iftemp-body if
|
---|
425 | .I arg
|
---|
426 | is a temporary file. Use it when a command has the same file as input and
|
---|
427 | output and you don't want to clobber the source file:
|
---|
428 | .SP
|
---|
429 | .RS
|
---|
430 | .nf
|
---|
431 | .ft B
|
---|
432 | transform .o .o
|
---|
433 | iftemp $\(**
|
---|
434 | $> = $\(**
|
---|
435 | else
|
---|
436 | cp $\(** $>
|
---|
437 | optimize $>
|
---|
438 | .ft P
|
---|
439 | .fi
|
---|
440 | .RE
|
---|
441 | .TP
|
---|
442 | .BI ifhash " arg"
|
---|
443 | Executes the ifhash-body if
|
---|
444 | .I arg
|
---|
445 | is an existing file with a '\fB#\fP' as the very first character. This
|
---|
446 | usually indicates that the file must be pre-processed:
|
---|
447 | .SP
|
---|
448 | .RS
|
---|
449 | .nf
|
---|
450 | .ft B
|
---|
451 | transform .s .o
|
---|
452 | ifhash $\(**
|
---|
453 | mktemp ASM .s
|
---|
454 | $CPP $\(** > $ASM
|
---|
455 | else
|
---|
456 | ASM = $\(**
|
---|
457 | $AS \-o $> $ASM
|
---|
458 | unset ASM
|
---|
459 | .ft P
|
---|
460 | .fi
|
---|
461 | .RE
|
---|
462 | .TP
|
---|
463 | .B else
|
---|
464 | Executes the else-body if the last executed
|
---|
465 | .BR if ,
|
---|
466 | .BR ifdef ,
|
---|
467 | .BR ifndef ,
|
---|
468 | .BR iftemp ,
|
---|
469 | or
|
---|
470 | .B ifhash
|
---|
471 | was unsuccessful. Note that
|
---|
472 | .B else
|
---|
473 | need not immediately follow an if, but you are advised not to make use of
|
---|
474 | this. It is a "feature" that may not last.
|
---|
475 | .TP
|
---|
476 | .BI apply " suffix1 suffix2"
|
---|
477 | Executed inside a transform rule body to transform the input file according
|
---|
478 | to another transform rule that has the given input and output suffixes. The
|
---|
479 | file under
|
---|
480 | .B $\(**
|
---|
481 | will be replaced by the new file. So if there is a
|
---|
482 | .B .c .i
|
---|
483 | preprocessor rule then the example of
|
---|
484 | .B ifhash
|
---|
485 | can be replaced by:
|
---|
486 | .SP
|
---|
487 | .RS
|
---|
488 | .nf
|
---|
489 | .ft B
|
---|
490 | transform .s .o
|
---|
491 | ifhash $\(**
|
---|
492 | apply .c .i
|
---|
493 | $AS \-o $> $*
|
---|
494 | .ft P
|
---|
495 | .fi
|
---|
496 | .RE
|
---|
497 | .TP
|
---|
498 | .BI include " descr"
|
---|
499 | Reads another description file and replaces the
|
---|
500 | .B include
|
---|
501 | with it. Execution continues with the first list in the new program. The
|
---|
502 | search for
|
---|
503 | .I descr
|
---|
504 | is the same as used for the
|
---|
505 | .B \-descr
|
---|
506 | option. Use
|
---|
507 | .B include
|
---|
508 | to switch in different front ends or back ends, or to call a shared
|
---|
509 | description file with a different initialization. Note that
|
---|
510 | .I descr
|
---|
511 | is only evaluated the first time the
|
---|
512 | .B include
|
---|
513 | is called. After that the
|
---|
514 | .B include
|
---|
515 | has been replaced with the included program, so changing its argument won't
|
---|
516 | get you a different file.
|
---|
517 | .TP
|
---|
518 | .BI arg " string ..."
|
---|
519 | .B Arg
|
---|
520 | may be executed in the initialization and scanning phase to post an argument
|
---|
521 | scanning rule, that's all the command itself does. Like an
|
---|
522 | .B if
|
---|
523 | that fails it allows more guards to share the same body.
|
---|
524 | .TP
|
---|
525 | .BI transform " suffix1 suffix2"
|
---|
526 | .BR Transform ,
|
---|
527 | like
|
---|
528 | .BR arg ,
|
---|
529 | only posts a rule to transform a file with the suffix
|
---|
530 | .I suffix1
|
---|
531 | into a file with the suffix
|
---|
532 | .IR suffix2 .
|
---|
533 | .TP
|
---|
534 | .BI prefer " suffix1 suffix2"
|
---|
535 | Tells that the transformation rule from
|
---|
536 | .I suffix1
|
---|
537 | to
|
---|
538 | .I suffix2
|
---|
539 | is to be preferred when looking for a transformation path to the stop suffix.
|
---|
540 | Normally the shortest route to the stop suffix is used.
|
---|
541 | .B Prefer
|
---|
542 | is ignored on a
|
---|
543 | .BR combine ,
|
---|
544 | because the special nature of combines does not allow ambiguity.
|
---|
545 | .SP
|
---|
546 | The two suffixes on a
|
---|
547 | .B transform
|
---|
548 | or
|
---|
549 | .B prefer
|
---|
550 | may be the same, giving a rule that is only executed when preferred.
|
---|
551 | .TP
|
---|
552 | .BI combine " suffix-list suffix"
|
---|
553 | .B Combine
|
---|
554 | is like
|
---|
555 | .B transform
|
---|
556 | except that it allows a list of input suffixes to match several types of
|
---|
557 | input files that must be combined into one.
|
---|
558 | .TP
|
---|
559 | .B scan
|
---|
560 | The scanning phase may be run early from the initialization phase with the
|
---|
561 | .B scan
|
---|
562 | command. Use it if you need to make choices based on the arguments before
|
---|
563 | posting the transformation rules. After running this,
|
---|
564 | .B scan
|
---|
565 | and
|
---|
566 | .B arg
|
---|
567 | become no-ops.
|
---|
568 | .TP
|
---|
569 | .B compile
|
---|
570 | Move on to the compilation phase early, so that you have a chance to run
|
---|
571 | a few extra commands before exiting. This command implies a
|
---|
572 | .BR scan .
|
---|
573 | .PP
|
---|
574 | Any other command is seen as a \s-2UNIX\s+2 command. This is where the
|
---|
575 | .B <
|
---|
576 | and
|
---|
577 | .B >
|
---|
578 | operators come into play. They redirect standard input and standard output
|
---|
579 | to the file mentioned after them, just like the shell.
|
---|
580 | .B Acd
|
---|
581 | will stop with an error if the command is not successful.
|
---|
582 | .SS The Initialization Phase
|
---|
583 | The driver starts by executing the program once from top to bottom to
|
---|
584 | initialize variables and post argument scanning and transformation rules.
|
---|
585 | .SS The Scanning Phase
|
---|
586 | In this phase the driver makes a pass over the command line arguments to
|
---|
587 | process options. Each
|
---|
588 | .B arg
|
---|
589 | rule is tried one by one in the order they were posted against the front of
|
---|
590 | the argument list. If a match is made then the matched arguments are removed
|
---|
591 | from the argument list and the arg-body is executed. If no match can be made
|
---|
592 | then the first argument is moved to the list of files waiting to be
|
---|
593 | transformed and the scan is restarted.
|
---|
594 | .PP
|
---|
595 | The match is done as follows: Each of the strings after
|
---|
596 | .B arg
|
---|
597 | must match one argument at the front of the argument list. A character
|
---|
598 | in a string must match a character in an argument word, a subst in a string
|
---|
599 | may match 1 to all remaining characters in the argument, preferring the
|
---|
600 | shortest possible match. The hyphen in a argument starting with a hyphen
|
---|
601 | cannot be matched by a subst. Therefore:
|
---|
602 | .PP
|
---|
603 | .RS
|
---|
604 | .B arg \-i
|
---|
605 | .RE
|
---|
606 | .PP
|
---|
607 | matches only the argument
|
---|
608 | .BR \-i .
|
---|
609 | .PP
|
---|
610 | .RS
|
---|
611 | .B arg \-O$n
|
---|
612 | .RE
|
---|
613 | .PP
|
---|
614 | matches any argument that starts with
|
---|
615 | .B \-O
|
---|
616 | and is at least three characters long. Lastly,
|
---|
617 | .PP
|
---|
618 | .RS
|
---|
619 | .B arg \-o $out
|
---|
620 | .RE
|
---|
621 | .PP
|
---|
622 | matches
|
---|
623 | .B \-o
|
---|
624 | and the argument following it, unless that argument starts with a hyphen.
|
---|
625 | .PP
|
---|
626 | The variable
|
---|
627 | .B $\(**
|
---|
628 | is set to all the matched arguments before the arg-body is executed. All
|
---|
629 | the substs in the arg strings are set to the characters they match. The
|
---|
630 | variable
|
---|
631 | .B $>
|
---|
632 | is set to null. All the values of the variables are saved and the variables
|
---|
633 | marked local. All variables except
|
---|
634 | .B $>
|
---|
635 | are marked read-only. After the arg-body is executed is the value of
|
---|
636 | .B $>
|
---|
637 | concatenated to the file list. This allows one to stuff new files into the
|
---|
638 | transformation phase. These added names are not evaluated until the start
|
---|
639 | of the next phase.
|
---|
640 | .SS The Compilation Phase
|
---|
641 | The files gathered in the file list in the scanning phase are now transformed
|
---|
642 | one by one using the transformation rules. The shortest, or preferred route
|
---|
643 | is computed for each file all the way to the stop suffix. Each file is
|
---|
644 | transformed until it lands at the stop suffix, or at a combine rule. After
|
---|
645 | a while all files are either fully transformed or at a combine rule.
|
---|
646 | .PP
|
---|
647 | The driver chooses a combine rule that is not on a path from another combine
|
---|
648 | rule and executes it. The file that results is then transformed until it
|
---|
649 | again lands at a combine rule or the stop suffix. This continues until all
|
---|
650 | files are at the stop suffix and the program exits.
|
---|
651 | .PP
|
---|
652 | The paths through transform rules may be ambiguous and have cycles, they will
|
---|
653 | be resolved. But paths through combines must be unambiguous, because of
|
---|
654 | the many paths from the different files that meet there. A description file
|
---|
655 | will usually have only one combine rule for the loader. However if you do
|
---|
656 | have a combine conflict then put a no-op transform rule in front of one to
|
---|
657 | resolve the problem.
|
---|
658 | .PP
|
---|
659 | If a file matches a long and a short suffix then the long suffix is preferred.
|
---|
660 | By putting a null input suffix (\fB""\fP) in a rule one can match any file
|
---|
661 | that no other rule matches. You can send unknown files to the loader this
|
---|
662 | way.
|
---|
663 | .PP
|
---|
664 | The variable
|
---|
665 | .B $\(**
|
---|
666 | is set to the file to be transformed or the files to be combined before the
|
---|
667 | transform or combine-body is executed.
|
---|
668 | .B $>
|
---|
669 | is set to the output file name, it may again be modified.
|
---|
670 | .B $<
|
---|
671 | is set to the original name of the first file of
|
---|
672 | .B $\(**
|
---|
673 | with the leading directories and the suffix removed.
|
---|
674 | .B $\(**
|
---|
675 | will be made up of temporary files after the first rule.
|
---|
676 | .B $>
|
---|
677 | will be another temporary file or the name of the target file
|
---|
678 | .RB ( $<
|
---|
679 | plus the stop suffix), if the stop suffix is reached.
|
---|
680 | .PP
|
---|
681 | .B $>
|
---|
682 | is passed to the next rule; it is imploded and checked to be a single word.
|
---|
683 | This driver does not store intermediate object files in the current directory
|
---|
684 | like most other compilers, but keeps them in
|
---|
685 | .B /tmp
|
---|
686 | too. (Who knows if the current directory can have files created in?) As an
|
---|
687 | example, here is how you can express the "normal" method:
|
---|
688 | .PP
|
---|
689 | .RS
|
---|
690 | .nf
|
---|
691 | .ft B
|
---|
692 | transform .s .o
|
---|
693 | if $> = $<.o
|
---|
694 | # Stop suffix is .o
|
---|
695 | else
|
---|
696 | $> = $<.o
|
---|
697 | temporary $>
|
---|
698 | $AS \-o $> $\(**
|
---|
699 | .ft P
|
---|
700 | .fi
|
---|
701 | .RE
|
---|
702 | .PP
|
---|
703 | Note that
|
---|
704 | .B temporary
|
---|
705 | is not called if the target is already the object file, or you would lose
|
---|
706 | the intended result!
|
---|
707 | .B $>
|
---|
708 | is known to be a word, because
|
---|
709 | .B $<
|
---|
710 | is local. (Any string whose substs are all expanded changes to a word.)
|
---|
711 | .SS "Predefined Variables"
|
---|
712 | The driver has three variables predefined:
|
---|
713 | .BR PROGRAM ,
|
---|
714 | set to the call name of the driver,
|
---|
715 | .BR VERSION ,
|
---|
716 | the driver's version number, and
|
---|
717 | .BR ARCH ,
|
---|
718 | set to the name of the default output architecture. The latter is optional,
|
---|
719 | and only defined if
|
---|
720 | .B acd
|
---|
721 | was compiled with \fB\-DARCH=\e"\fP\fIarch-name\fP\fB\e"\fP.
|
---|
722 | .SH EXAMPLE
|
---|
723 | As an example a description file for a C compiler is given. It has a
|
---|
724 | front end (ccom), an intermediate code optimizer (opt), a code generator (cg),
|
---|
725 | an assembler (as), and a loader (ld). The compiler can pre-process, but
|
---|
726 | there is also a separate cpp. If the
|
---|
727 | .B \-D
|
---|
728 | and options like it are changed to look like
|
---|
729 | .B \-o
|
---|
730 | then this example is even as required by \s-2POSIX\s+2.
|
---|
731 | .RS
|
---|
732 | .nf
|
---|
733 |
|
---|
734 | # The compiler support search path.
|
---|
735 | C = /lib /usr/lib /usr/local/lib
|
---|
736 |
|
---|
737 | # Compiler passes.
|
---|
738 | CPP = $C/cpp $CPP_F
|
---|
739 | CCOM = $C/ccom $CPP_F
|
---|
740 | OPT = $C/opt
|
---|
741 | CG = $C/cg
|
---|
742 | AS = $C/as
|
---|
743 | LD = $C/ld
|
---|
744 |
|
---|
745 | # Predefined symbols.
|
---|
746 | CPP_F = \-D__EXAMPLE_CC__
|
---|
747 |
|
---|
748 | # Library path.
|
---|
749 | LIBPATH = $USERLIBPATH $C
|
---|
750 |
|
---|
751 | # Default transformation target.
|
---|
752 | stop .out
|
---|
753 |
|
---|
754 | # Preprocessor directives.
|
---|
755 | arg \-D$name
|
---|
756 | arg \-U$name
|
---|
757 | arg \-I$dir
|
---|
758 | CPP_F = $CPP_F $\(**
|
---|
759 |
|
---|
760 | # Stop suffix.
|
---|
761 | arg \-c
|
---|
762 | stop .o
|
---|
763 |
|
---|
764 | arg \-E
|
---|
765 | stop .E
|
---|
766 |
|
---|
767 | # Optimization.
|
---|
768 | arg \-O
|
---|
769 | prefer .m .m
|
---|
770 | OPT = $OPT -O1
|
---|
771 |
|
---|
772 | arg \-O$n
|
---|
773 | numeric $n
|
---|
774 | prefer .m .m
|
---|
775 | OPT = $OPT $\(**
|
---|
776 |
|
---|
777 | # Add debug info to the executable.
|
---|
778 | arg \-g
|
---|
779 | CCOM = $CCOM -g
|
---|
780 |
|
---|
781 | # Add directories to the library path.
|
---|
782 | arg \-L$dir
|
---|
783 | USERLIBPATH = $USERLIBPATH $dir
|
---|
784 |
|
---|
785 | # \-llib must be searched in $LIBPATH later.
|
---|
786 | arg \-l$lib
|
---|
787 | $> = $LIBPATH/lib$lib.a
|
---|
788 |
|
---|
789 | # Change output file.
|
---|
790 | arg \-o$out
|
---|
791 | arg \-o $out
|
---|
792 | OUT = $out
|
---|
793 |
|
---|
794 | # Complain about a missing argument.
|
---|
795 | arg \-o
|
---|
796 | error "argument expected after '$\(**'"
|
---|
797 |
|
---|
798 | # Any other option (like \-s) are for the loader.
|
---|
799 | arg \-$any
|
---|
800 | LD = $LD $\(**
|
---|
801 |
|
---|
802 | # Preprocess C-source.
|
---|
803 | transform .c .i
|
---|
804 | $CPP $\(** > $>
|
---|
805 |
|
---|
806 | # Preprocess C-source and send it to standard output or $OUT.
|
---|
807 | transform .c .E
|
---|
808 | ifndef OUT
|
---|
809 | $CPP $\(**
|
---|
810 | else
|
---|
811 | $CPP $\(** > $OUT
|
---|
812 |
|
---|
813 | # Compile C-source to intermediate code.
|
---|
814 | transform .c .m
|
---|
815 | transform .i .m
|
---|
816 | $CCOM $\(** $>
|
---|
817 |
|
---|
818 | # Intermediate code optimizer.
|
---|
819 | transform .m .m
|
---|
820 | $OPT $\(** > $>
|
---|
821 |
|
---|
822 | # Intermediate to assembly.
|
---|
823 | transform .m .s
|
---|
824 | $CG $\(** > $>
|
---|
825 |
|
---|
826 | # Assembler to object code.
|
---|
827 | transform .s .o
|
---|
828 | if $> = $<.o
|
---|
829 | ifdef OUT
|
---|
830 | $> = $OUT
|
---|
831 | $AS \-o $> $\(**
|
---|
832 |
|
---|
833 | # Combine object files and libraries to an executable.
|
---|
834 | combine (.o .a) .out
|
---|
835 | ifndef OUT
|
---|
836 | OUT = a.out
|
---|
837 | $LD \-o $OUT $C/crtso.o $\(** $C/libc.a
|
---|
838 | .fi
|
---|
839 | .RE
|
---|
840 | .SH FILES
|
---|
841 | .TP 25n
|
---|
842 | .RI /usr/lib/ descr /descr
|
---|
843 | \- compiler driver description file.
|
---|
844 | .SH "SEE ALSO"
|
---|
845 | .BR cc (1).
|
---|
846 | .SH ACKNOWLEDGEMENTS
|
---|
847 | Even though the end result doesn't look much like it, many ideas were
|
---|
848 | nevertheless derived from the ACK compiler driver by Ed Keizer.
|
---|
849 | .SH BUGS
|
---|
850 | \s-2POSIX\s+2 requires that if compiling one source file to an object file
|
---|
851 | fails then the compiler should continue with the next source file. There is
|
---|
852 | no way
|
---|
853 | .B acd
|
---|
854 | can do this, it always stops after error. It doesn't even know what an
|
---|
855 | object file is! (The requirement is stupid anyhow.)
|
---|
856 | .PP
|
---|
857 | If you don't think that tabs are 8 spaces wide, then don't mix them with
|
---|
858 | spaces for indentation.
|
---|
859 | .SH AUTHOR
|
---|
860 | Kees J. Bot (kjb@cs.vu.nl)
|
---|