3. Component of the TDF System

  1. 3.1. The C to TDF Producer
    1. 3.1.1. Include File Directories
    2. 3.1.2. Start-up Files and End-up Files
    3. 3.1.3. Compilation Modes and Portability Tables
    4. 3.1.4. Description of Compilation Modes
  2. 3.2. The TDF Linker
    1. 3.2.1. The Linker and TDF Libraries
    2. 3.2.2. Combining TDF Capsules
    3. 3.2.3. Constructing TDF Libraries
    4. 3.2.4. Useful TLD Options
  3. 3.3. The TDF to Target Translator
    1. 3.3.1. TCC Options Affecting the Translator
    2. 3.3.2. Useful trans Options
    3. 3.3.3. Optimisation in TDF Translators
    4. 3.3.4. The Mips Translator and Assembler
  4. 3.4. The System Assembler
  5. 3.5. The System Linker
    1. 3.5.1. The System Linker and TCC Environments
    2. 3.5.2. The Effect of Command-Line Options on the System Linker
  6. 3.6. The C Preprocessor
  7. 3.7. The TDF Pretty Printer
  8. 3.8. The TDF Archiver

3.1. The C to TDF Producer

We now turn to the individual components of the TDF system. Most of the command-line options to TCC so far discussed have been concerned with controlling the behaviour of TCC itself. Another, even more important, class of options concern the ways in which the behaviour of the components can be specified. The -Wtoolopt, ... command-line option for communicating directly with the components has already been mentioned. This however is not recommended for normal purposes; the other TCC command-line options give a more controlled access to the components.

The first component to be considered is the C → TDF producer, TDFC. This translates an input C source file (a .c file or a .i file) into a output target independent TDF capsule (a .j file).

3.1.1. Include File Directories

The most important producer options are those which tell it where to search for files included using a #include preprocessing directive. As with CC, the user can specify a directory, dir, to search for these files using the -Idir command-line option. However, unlike CC, the producer does not search /usr/include as default. Instead, the default search directories are those containing the target independent headers for the API selected, as given by the INCL identifier in the environment describing the API. In addition, the directories to search for the default start-up files (see below), as given by the STARTUP_DIR environmental identifier, are also passed to the producer.

If the -H option is passed to TCC then it will cause the producer to print the name of each file it opens. This is often helpful if a multiplicity of -I options leads to confusion.

3.1.2. Start-up Files and End-up Files

The producer has a useful feature of start-up and end-up files. The TCC command-line option -ffile is equivalent to inserting the line:

#include "file"

at the start of each input C source file. Similarly -efile is equivalent to inserting this line at the end of each such file. These included files are searched for along the directories specified by the -I options in the normal manner.

TCC generates a producer start-up file, called tcc_startup.h, in order to implement certain command-line options. The CC-compatible options:

-Dname -Dname=value -Uname -Astr

are translated into the lines:

#define name 1 #define name value #undef name #assert str

respectively. TCC does not check that these lines are valid C preprocessing directives since this will be done by the producer. So any producer error message referring to tcc_startup.h is likely actually to refer to the -D, -U and -A command-line options. In case of difficulties, tcc_startup.h can be preserved for closer examination using the -Ph option to TCC.

There may be default start-up options specified by the STARTUP environmental identifier. The purpose of these is discussed below. The order the start-up options are passed to the producer is: firstly, the default start-up options; secondly, the start-up option for the TCC built-in start-up file, tcc_startup.h; thirdly, any command-line start-up options. (For technical reasons, a -no_startup_options command-line option is provided which causes no start-up or end-up options to be passed to TDFC. This is not likely to prove useful in normal use.

3.1.3. Compilation Modes and Portability Tables

We have already described how one aspect of the compilation environment, the API, is specified to the producer by means of the default -I options. But another aspect, the control of the syntax and portability checks applied by the producer, can also be specified in a fairly precise manner.

The producer accepts a number of #pragma statements which tell it which portability checks to apply and which syntactic extensions to ISO/ANSI C to allow (see [3] and [2]). These can be inserted into the main C source, but the ideal place for them is in a start-up file. This is the purpose of the STARTUP environmental identifier, to give a list of default start-up files containing #pragma statements which specify the default behaviour of the producer.

In fact not all the information the producer requires is obtained through start-up files. The basic information on the minimum sizes which can be assumed for the basic integer types is passed to the producer by means of another type of file, the portability table. This is specified by means of the PORTABILITY environmental identifier. There are in fact only two portability tables provided, bounds/c89.pf, which specifies the minimum sizes permitted by the ANSI C89 standard, and bounds/32bit.pf, which specifies the minimum sizes found on most 32-bits machines. The main difference between the two is that in ISO/ANSI it is stated that int is only guaranteed to have 16 bits, whereas on 32-bits machines it has at least 32 bits.

A number of TCC command-line options are concerned with specifying the compilation environment to the producer. The main option for setting the compilation mode is -Xmode. A number of different modes are available:

ModeEnvironment
-XsStrict ISO/ANSI C with extra portability checks
-XpStrict ISO/ANSI C with minimal portability checks
-XcStrict ISO/ANSI C with no extra portability checks
-XaISO/ANSI C with various syntactic extensions
-XtTraditional C

The default is -Xc. For a precise description of each of these modes, see [3]. In addition the command-line options -not_ansi and -nepc can be used to modify the basic compilation modes. -not_ansi specifies that certain non-ANSI syntactic constructions should be allowed. -nepc switches off the producer's extra portability checks (it also suppresses certain constant overflow checks in the TDF translators). All these options are implemented by start-up files.

Two built-in portability tables are provided by TCC. The default reflects the minimal requirements laid down in the ISO C89 standard. The 32-bit portability table (specified by the passing the -Y32bit option to tcc -ch) reflects the implementation on most modern 32 bit machines. These tables are shown below.

ISO/ANSI (default)-Y32bit
char_bits8char_bits8
short_bits16short_bits16
int_bits16int_bits32
long_bits32long_bits32
longlong_bits64longlong_bits64
signed_rangesymmetricsigned_rangemaximum
char_typeeitherchar_typeeither
ptr_intnoneptr_intint
ptr_fnnoptr_fnyes
non_prototype_checksyesnon_prototype_checksyes
multitbyte1multitbyte1
Table 1. ISO/ANSI Minimum Requirements Portability Table

The portability table to be used is specified separately by means of an environment. The default is the ISO/ANSI portability table, but -Y32bit or -Ycommon can be used to specify 32-bit checking. -Y16bit will restore the portability table to the default. Note that all checks involving the portability table are switched off by the -nepc command-line option, so in this case no portability table is specified to the producer.

3.1.4. Description of Compilation Modes

Let us briefly describe the compilation modes introduced in the previous section. The following tables describe some of the main features of each mode. The list of pre-defined macros is complete (other than the built-in macros, __FILE__, __LINE__, __DATE__ and __TIME__; because the producer is designed to be target independent it does not define any of the machine name macros which are built into CC. The CC-compatible option, -A-, which is meant to cause all pre-defined macros (other than those beginning with __) to be undefined, and all pre-assertions to be unasserted, is ignored by TCC. In the standard compilation modes there are no such macros and no such assertions. The integer promotion rules are either the arithmetic rules specified by ISO/ANSI or the "traditional" signed promotion rules. The precise set of syntactic relaxations to the ISO/ANSI standard allowed by each mode varies. For a complete list see [3]. The -not_ansi command-line option can be used to allow further relaxations. The extra prototype checks cause the producer to construct a prototype for procedures which are actually traditionally defined. This is very useful for getting prototype-like checking without having to use prototypes in function definitions. This, and other portability checks, are switched off by the -nepc option. Finally, the additional checks are lint-like checks which are useful in detecting possible portability problems.

ModePre-defined MacrosInteger PromotionsRelaxationsExtra Checks
-Xs__STDC__ = 1ISO/ANSInoneyes *
-Xp__STDC__ = 1ISO/ANSInonesome *
-Xc__STDC__ = 1ISO/ANSInonenone
-Xa__STDC__ = 1ISO/ANSIsyntacticnone
-Xt__STDC__ = 0signedsyntacticnone

* Includes extra prototype checks.

All the above -X* modes provide the pre-defined macros __ANDF__ = 1 and __TenDRA__ = 1.

The choice of compilation mode very much depends on the level of checking required. -Xa is suitable for general compilation, and -Xc. -Xp and -Xs for serious program checking (although some may find the latter excessive). -Xt is provided for CC compatibility only; its use is discouraged.

The recommended method of proceeding is to define your own compilation mode. In this way any choices about syntax and portability checking are made into conscious decisions. One still needs to select a basic mode to form the basis for this user-defined mode. -Xc is probably best; it is a well-defined mode (the definition being the ISO/ANSI standard) and so forms a suitable baseline. Suppose that, on examining the program to be compiled, we decide that we need to do the following:

  • allow the #ident directive,

  • allow through unknown escape sequences with a warning,

  • warn of uses of undeclared procedures,

  • warn of incorrect uses of simple return statements.

The first two of these are syntactic in nature. The third is more interesting. ISO/ANSI says that any undeclared procedures are assumed to return int. However for strict API checking we really need to know about these undeclared procedures, because they may be library routines which are not part of the declared API. The fourth condition is a simple lint-like check that no procedure which is declared to return a value contains a simple return statement (without a return value).

To tell the producer about these options, it is necessary to have them included in every source file. The easiest way of doing this is by using a start-up file, check.h say, containing the lines:

#pragma TenDRA begin
#pragma TenDRA directive ident allow
#pragma TenDRA unknown escape warning
#pragma TenDRA implicit function declaration warning
#pragma TenDRA incompatible void return warning

The second, third, fourth and fifth lines correspond to the statements above (see [3]). The first line indicates that this file is defining a new checking scope.

Once the compilation mode has been described in this way, it needs to be specified to TCC in the form of the command-line options -Xc -fcheck.h.

3.2. The TDF Linker

The next component of the system to be considered is the TDF linker, TLD. This is used to combine several TDF capsules or TDF libraries into a single TDF capsule. It is put to two distinct purposes in the TCC compilation scheme. Firstly, in the main compilation path, it is used in the installer half to combine a target independent TDF capsule (a .j file) with the TDF libraries representing the API implementation on the target machine, to form a target dependent TDF capsule (a .t file). Secondly, if the -M option is given to TCC, it is used in the producer half to combine all the target independent TDF capsules (.j files) into a single target independent capsule. Let us consider these two cases separately.

3.2.1. The Linker and TDF Libraries

In the main TDF linking phase, combining target independent capsules with TDF libraries to form target dependent capsules, two pieces of information need to be specified to TLD. Firstly, the TDF libraries to be linked with, and, secondly, the directories to search for these libraries. For standard APIs, the location of the TDF libraries describing the API implementation is given in the environment corresponding to the API. The LIB identifier gives the names of the TDF libraries, and the LINK identifier the directories to be searched for these libraries. The user can also specify libraries and library directories by means of command-line options to TCC. The option -jstr indicates that the TDF library str.tl should be used for linking (.tl is the standard suffix for TDF libraries). The option -Jdir indicates that the directory dir should be added to the TDF library search path. Libraries and directories specified by command-line options are searched before those given in the API environment.

There is a potential source of confusion in that the TLD options specifying the TDF library str.tl and the library directory dir are respectively -lstr and -Ldir. TCC automatically translates command-line -j options into TLD -l options, and command-line -J options into TLD -L options. However the LIB and LINK identifiers are actually lists of TLD options, so they should use the -l and -L forms.

3.2.2. Combining TDF Capsules

The second use of TLD is to combine all the .j files in the producer half of the compilation into a single capsule. This is specified by means of the -M ("merge") command-line option to TCC described in section 3.5.4. By default, the resultant capsule is called a.j. If the -M option is used to merge all the .j files from a very large program, the resultant TDF capsule can in turn be very large. It may in fact become too large for the installer to handle. Interestingly it is often the system assembler rather than TDF translator which has problems.

The -MA ("merge all") option is similar to -M, but will in addition "hide" all the external tag and token names in the resultant capsule, except for the token names required for linking with the TDF libraries and the tag names required for linking with the system libraries (plus main). In effect, all the names which are internal to the program are removed. This means that the -MA option should only be used to merge complete programs. For details on how to use TLD for more selective name hiding, see below.

3.2.3. Constructing TDF Libraries

There is a final use of the TDF linker supported by TCC which has not so far been mentioned, namely the construction of TDF libraries. As has been mentioned, TDF libraries are an indexed set of TDF capsules. TLD, in addition to its linking mode, also has routines for constructing and manipulating TDF libraries. The library construction mode is supported by TCC by means of the makelib environment. This tells TCC to merge all the .j files and then to stop. But it also passes an option to TLD which causes the merged file to be, not a TDF capsule, but a TDF library. Thus the command-line options:

% tcc -Ymakelib -o a.tl a.j b.j c.j

cause the TDF capsules a.j, b.j and c.j to be combined into a TDF library, a.tl.

3.2.4. Useful TLD Options

TLD has a number of options which may be useful to the general user. The -w option, which causes warnings to be printed about undefined tags and tokens, can often provide interesting information; other options are concerned with the hiding of tag and token names. These options can be passed directly to TLD by means of the -WL, opt, ... command-line option to TCC. The TLD options are fully documented on the appropriate manual page.

3.3. The TDF to Target Translator

The next compilation tool to be considered is the TDF translator. This translates an input target dependent TDF capsule (.t file) into an assembly source file (.s) file for the appropriate target machine. This is the main code generation phase of the compilation process; most of the optimisation of code which occurs happens in the translator (some machines also have optimising assemblers).

Although referred to by the generic name of trans, the TDF translators for different target machines in fact have different names. The main division between translators is in the supported processor. However, operating system dependent features such as the precise form of the assembler input, and the symbolic debugger to be supported, may also cause different versions of the basic translator to be required for different machines of the same processor group. The current generation of translators includes the following:

  • The TDF → i386/i486 translator is called trans386. This exists in two versions, one running on SVR4.2 and one on SCO. The two versions differ primarily in the symbolic debugger they support. trans386 has also been ported to several other i386-based machines, including MS-DOS.

  • The TDF → Sparc (Version 7) translator is called sparctrans. This again exists in two versions, one running on SVR4.2 and one on SunOS and Solaris 1. These versions again differ primarily in the symbolic debugger supported.

  • The TDF → Mips (R2000/R3000, little-endian) translator is called mipstrans. This differs from the other translators in that instead of outputting a single .s file, it outputs two files, a binasm file (with a .G suffix) and a symbol table file (with a .T suffix). This is discussed in more detail below. mipstrans runs on Ultrix, but again has two versions. One runs on Ultrix 4.1 and earlier, the other on 4.2 and later. This necessary because of a change in the format of the binasm file between these two releases.

  • The TDF → 68030/68040 translator also exists in two versions. One runs on HP-UX and is called hptrans; the other runs on NeXTStep and is called nexttrans (however the NeXT is not a supported platform because of its lack of standard API coverage). These differ, not only in the symbolic debugger supported, but also in the format of the assembly source output.

This list is not intended to be definitive. Development work is proceeding on new translators all the time. Existing translators are also updated to support new operating systems releases when this is necessary.

3.3.1. TCC Options Affecting the Translator

A number of TCC command-line options are aimed at controlling the behaviour of the TDF translator. The CC-compatible option -Kitem, ... specifies the behaviour indicated by the argument item. Possible values for item, together with the behaviour they specify, include:

ValueBehaviour
PICCauses position independent code to be produced
ieeeCauses strict conformance to the IEEE floating point standard
noieeeAllows non-strict conformance to the IEEE standard
frameSpecifies that a frame pointer should always be used
no_frameSpecifies that frame pointers need not always be used
i386Causes code generation to be tuned for the i386 processor
i486Causes code generation to be tuned for the i486 processor
P5Causes code generation to be tuned for the P5 processor

Obviously not all of these options are appropriate for all versions of trans. Therefore all -K options are implemented by means of environments which translate item into the appropriate trans options. If a certain item is not applicable on a particular target machine then the corresponding environment will not exist, and TCC will print a warning to this effect.

The CC-compatible -Zstr option is similarly implemented by means of environments. On those machines which support this option it can be used to specify the packing of structures. If str is p1 then they are tightly packed, with no padding. Values of p2 and p4 specify padding to 2 or 4 byte boundaries when appropriate.

Finally, the TCC command-line option -wsl causes the translator to make all string literals writable. Again, this is implemented by an environment. For many machines this behaviour is default; for others it requires an option to be passed to the translator.

3.3.2. Useful trans Options

For further specifying the behaviour of trans it may be necessary to pass options to it directly. The command-line options implemented by trans vary from machine to machine. The following options are however common to all translators and may prove useful:

OptionEffect
-ESwitches off certain constant overflow checks
-XSwitches off most optimisations
-ZPrints the version number(s) of the input capsule

These options may be passed directly to trans by means of the -Wt, opt, ... command-line option to TCC. The -E option is also automatically invoked when the -nepc command-line option to TCC is used. The manual page for the appropriate version of trans should be consulted for more details on these and other, machine dependent, options.

3.3.3. Optimisation in TDF Translators

As has been mentioned, the TDF translator is the main optimising phase of the TDF compilation scheme. All optimisations are believed to be correct and are switched on by default. Thus the standard CC -O option, which is intended to switch optimisations on, has no effect in TCC except to cancel any previous -g option. If, due to a translator bug, a certain piece of code is being optimised incorrectly, then the optimisations can be switched off by means of the -Wt, -X option mentioned above. However this should not normally be necessary.

3.3.4. The Mips Translator and Assembler

As has been mentioned, the TDF → Mips translator, mipstrans is genuinely exceptional in that it outputs a pair of files for each input TDF capsule, rather than a single assembly source file. The general scheme is shown in Fig. 5.

Target-dependent TDF .t mipstrans Binary symbol table .T as1 Binasm source .G Assembly source .s as Binary object .o
Figure 2. Mips Compilation Path

mipstrans translates each input target dependent TDF capsule, a.t, into a binasm source file, a.G, and an assembler symbol table file, a.T. It may optionally output an assembly source file, a.s, which combines all the information from a.G with part of the information from a.T (it is the remainder of the information in a.T which is the reason why this scheme has to be adopted). The .s file is only produced if TCC is explicit told to preserve .s files by means of one of the command-line options, -Ps, -Pa, -Fs or -S. The two main mipstrans output files, a.G and a.T, are then transformed by the auxiliary Mips assembler, as1, into a binary object file, a.o.

Although they can be preserved for examination, the .G and .T files output by mipstrans cannot subsequently be processed using TCC. If a break in compilation is required at this stage, a .s file should be produced, and then entered as a TCC input file in the normal way. The information lost from the symbol table in this process is only important when symbolic debugging information is required. Input .s files are translated into binary object files by the main Mips assembler, .s, in the normal way.

So, in addition to the main assembler, which is given by the AS environmental identifier, the location of the auxiliary assembler also needs to be specified to TCC. This is done using the AS1 environmental identifier, which is normally defined in the default environment.

3.4. The System Assembler

The system assembler is the stage in the TCC compilation path which is likely to be of least interest to normal users. The assembler translates an assembly source (or .s) file into a binary object (or .o) file. (The exception to this is the Mips auxiliary assembler discussed above.) Most assemblers are straight translation phases, although some also offer peephole optimisation and scheduling facilities. No TCC command-line options are directly concerned with the assembler, however options can be passed to it directly by means of the -Wa, opt, ... command-line option.

3.5. The System Linker

The final stage in the main TCC compilation path is the system linking. The system linker, ld, combines all the binary object files with the system libraries to form a final executable image. By default this executable is called a.out, although this can be changed using the -o command-line option to TCC. In terms of the differences between target machines, the system linker is the most complex of the tools which are controlled by TCC. Our discussion can be divided between those aspects of the linker's behaviour which are controlled by TCC environments, and those which are controlled by command-line options.

3.5.1. The System Linker and TCC Environments

The general form of TCC's calls to ld are as follows:

ld (linker options) -o (output file)     (initial .o files) (binary object files) (final .o files)     (default system library directories) (default system libraries) (default standard libraries)

The linker may require certain default binary object files to be linked into every executable created. These are divided between the initial .o files, which come before the main list of binary object files, and the final .o files, which come after. For technical reasons, the list of initial .o files is split into two; the first list is given by the CRT0 environmental identifier, and the second by CRT1. The list of final .o files is given by the CRTN environmental identifier.

The information on the default system libraries the linker requires is given by three environmental identifiers. SYS_LINK gives a list of directories to be searched for system libraries. This will exclude /lib and /usr/lib which are usually built into ld. These directories will be given as a list of options of the form -Ldir. The default system libraries are divided into two lists. The environmental identifier SYS_LIBC gives the "standard" library options (usually just -lc), and SYS_LIB gives any other default library options. Both of these are given by lists of options of the form -lstr. This option specifies that the linker should search for the library libstr.a if linking statically, or libstr.so if linking dynamically.

So the main target dependencies affecting the system linker are described in these six environmental variables: CRT0, CRT1, CRTN, SYS_LINK, SYS_LIB and SYS_LIBC. For a given machine these will be given once and for all in the default environment. Standard API environments may modify SYS_LINK and SYS_LIB to specify the location of the system libraries containing the API implementation, although at present this has not been done.

3.5.2. The Effect of Command-Line Options on the System Linker

The most important TCC command-line options affecting the system linker are those which specify the use of certain system libraries. The option -lstr indicates that the system libraries libstr.a (or libstr .so) should be searched for. The option -Ldir indicates that the directory dir should be added to the list of directories searched for system libraries. Both these options are position dependent. They are passed to the system linker in exactly the same position relative to the input files as they were given on the command-line. Thus normally -l (and to a lesser extent -L) options should be the final command-line options given.

The following TCC command-line options are passed directly to ld. A brief description is given of the purpose of each option, however whether or not ld supports this option depends on the target machine. The local ld manual page should be consulted for details.

OptionEffect
-Bstrsets library type: str can be dynamic or static
-Gcauses a shared object rather than an executable to be produced
-dncauses dynamic linking to be switched off
-dycauses dynamic linking to be switched on
-hstrcauses str to be marked as dynamic in a shared object
-scauses the resultant executable to be stripped
-ustrcauses str to be marked as undefined
-zstrspecifies error behaviour, depending on str

The position of any -Bstr options on the command-line is significant. These positions are therefore preserved. The position of the other options is not significant. In addition to these options, the -b command-line option causes the default standard system libraries (i.e. those given by the SYS_LIBC environmental identifier) not to be passed to ld.

Other command-line options may affect the system linker indirectly. For example, the -g option may require different default .o files and system libraries, the precise details of which are target dependent. Such options will be implemented by means of environments which will change the values of the environmental identifiers controlling the linker.

3.6. The C Preprocessor

The TDF C preprocessor, TDFCPP, is invoked only when TCC is passed the -E or -P command-line option, as described in section 3.5.1. These both cause all input .c files to be preprocessed, but in the former case the output is send to the standard output, whereas in the latter it is send to the corresponding .i files.

The TDF system differs from most C compilation systems in that preprocessing is an integral part of the producer, TDFC, rather than a preliminary textual substitution phase. This is because of difficulties involved with trying to perform the preprocessing in a target independent manner. Therefore TDFCPP is merely a modified version of TDFC which halts after the preprocessing phase and prints what it has read. This means that the TDFCPP output, while being equivalent to its input, will not correspond at the textual level to the degree which is normal in C preprocessors.

3.7. The TDF Pretty Printer

The TDF pretty printer, disp, and the TDF notation compiler, TNC, have already been discussed in some detail in section 3.5.3. The TDF decoding command-line options, -disp and -disp_t, cause respectively all .j files and all .t files to be decoded into .p files. This decoding is done using disp by default, and with TNC -p if the -Ytnc command-line option is specified. The -Ytnc option also causes any input .p files to be encoded into .j files by TNC.

The pretty printer, disp, can be used as a useful check that a given .j or .t file is a legal TDF capsule. The TDF decoding routines in the TDF linker and the TDF translator assume that their input is a legal capsule. The pretty printer performs more checks and has better diagnostics for illegal capsules. By default disp only decodes capsule units which belong to "core" TDF. Options to decode other unit types can be passed directly to disp by means of the -Wd, opt, ... command-line option to TCC. The potentially useful disp options include:

OptionEffect
-ACauses all known unit types to be decoded
-gCauses diagnostic information units to be decoded
-DCauses a binary dump of the capsule to be printed
-UCauses link information units to be decoded
-VCauses the input not to be rationalised
-WCauses a warning to be printed if a token is used before it is declared

The manual page for disp should be consulted for more details.

The TDF notation compiler, TNC, is fully documented in [4].

3.8. The TDF Archiver

A TDF archive is a TCC-specific form intended for software distribution. It consists of a set of target independent TDF capsules (.j files) and a set of TCC command-line options. It is intended that a TDF archive can be produced on one machine, and distributed to, and installed on, a number of target machines.

If a TDF archive is given as an input file to TCC (it will be recognised by its .ta suffix), then it is split into its constituent capsules and options. The options are interpreted as if they had been given on the command-line (unless the -WJ, -no_options flag is specified), and the capsules are treated as input files in the normal way. The archive splitting and archive building routines are both built into TCC; there is no separate TDF archiver tool. Options passed to the archiver using -WJ, opt are interpreted by TCC.

In order to specify that a TDF archive should be created, the -prod flag should be used. This specifies that all target independent capsules (.j files) and all options opt given by a TCC option of the form -WI, opt, ... should be combined into a TDF archive. The compilation process halts after producing this archive. By default the TDF archive created is called a.ta, but this can be changed using the -o option. Normally the names of the capsules comprising the archive are inserted into the archive, but this may be suppressed by the use of the -WJ, -no_names option.

As an example of the kind of option that might be included in an archive, suppose that the production has been done using the POSIX API. Then the installation should also be done using this same API. Alternatively expressed, if a TDF archive has been constructed using the posix environment, then the -Yposix flag should be included in the archive to ensure that the installation also takes place in this same environment. In fact the environments describing the standard APIs have been set up so that this happens automatically. For example, the posix environment contains the line:

+FLAG "-WI,-Yposix"

Another kind of option that it might be useful to include in an archive is a -lstr option. In this way all the information on the install-time options can be specified at produce-time.

A final example of an option which might be included in an archive is the -message option. The command-line option -message str causes TCC to print the message str with any @ characters in str replaced by spaces (there are problems with escaping spaces). So, by using the command-line option:

-WI,-message"Installing@TDF@archive@..."

one can produce an archive which prints a message as it is installed. This option is also useful in environments. By inserting the line:

+FLAG "-message Reading@tcc@environment@..."

one can produce an environment which prints a message whenever it is read.