home *** CD-ROM | disk | FTP | other *** search
-
- CONFIG USERS MANUAL
-
-
-
- 0. TABLE OF CONTENTS
-
- 0. TABLE OF CONTENTS
- 1. INTRODUCTION
- 1.1 Description
- 1.2 Overview
- 1.3 Conventions
- 2. PREPARING A CONFIGURATION
- 2.1 Syntax
- 2.2 Options Files
- 2.3 Configuration Files
- 3. PREPARING OPTIONS FILES
- 3.1 Value Options
- 3.2 Option Options
- 3.3 Required Options
- 3.4 Action Options
- 3.5 Names To Avoid
- 4. PROGRAMMING FOR CONFIG
- 4.1 Starting Out
- 4.2 Required Options
- 4.3 Option Options
- 4.4 Value Options
- 4.5 The "Appropriate" Options File
- 4.6 Converting a Program for Config
-
- 1. INTRODUCTION
-
- This section describes config, gives an overview of this manual, and
- introduces the user to the conventions and terminology of config.
-
- 1.1 Description
-
- Config is a tool that makes configuring a certain type of large
- program much easier for anyone not intimately familiar with the
- details of the program. It also makes keeping multiple different
- configurations of such programs easier - even though they may run on
- different machines, or under different operating systems.
-
- The programs in question all use numerous symbols to control the
- conditional compilation of features in the program, or to control
- which code is compiled for what system. These programs need to run on
- multiple different machines or operating systems, or run in an
- environment where having all the features of a program enabled entails
- an unacceptable performance cost, or makes running the program
- impossible.
-
- The two normal approaches to this type of program both have problems.
- One approach is to change the compile commands to enable and disable
- features. The other approach is to keep a large file which defines all
- the features, and have all other files depend on that. The first can
- quickly generate unwieldy command lines. Both require recompiling the
- entire program after a change of one option, unless that option only
- effects one file, and the automatic building facility used for that
- program is defeated. Config provides an alternative that avoids both
- of these problems.
-
- 1.2 Overview
-
- This config users manual has the following four sections:
-
- Section 1 states what config is used for, describes this manual, and
- explains some conventions and terminology used throughout the manual.
- It should be read by anyone not already partly familiar with config.
-
- Section 2 explains how, if you have a program already prepared for use
- with config and all the appropriate files set up, you would go about
- preparing a new configuration of that program. It should be read by
- everyone who wishes to rebuild a config-supported program.
-
- Section 3 explains the meaning of the options files in terms of the
- program. It should be read by all those who are adding features to a
- config-supported program.
-
- Section 4 describes what form a program must be in before it can be
- supported by config, and how to set up the initial configuration files
- for a program. It should be read by anyone who has a program they
- would like config to support.
-
- 1.3 Conventions
-
- There are several conventions associated with the use of config that
- are assumed to be true throughout this manual. The first is that
- config is being used to configure a program, referred to as "the
- program." The second is that all the files needed by config are in one
- directory, near the top of the source tree for the program. The third
- is that that directory is called "conf". It will hereinafter be
- referred to as "the conf directory", or just "conf". Config assumes
- that at the same level as the conf directory there will be one
- directory for every configuration that can currently be built. These
- will be called "configuration directories", or "the configuration
- directory". The names of these directories are usually in upper case.
- In the conf directory, there are two types of files which config cares
- about. The first are those with the extension ".options". These are
- "options files". The second are conventionally in upper case, and
- represent different configurations of the program. For each of these,
- there should be a configuration directory with the same name. These
- are "configuration files" or "config files". Configuration files and
- options files contain lines, each of which is either a comment, or
- describes some symbol the programmer uses to control compilation of
- the program. These symbols are called options. Currently, config only
- supports the configuration of C programs. It could easily support
- others, but this document assumes the program is written in C.
-
-
- 2. PREPARING A CONFIGURATION
-
- This section describes the steps necessary to prepare a configuration
- file for use in building a configuration of a config-supported
- program.
-
- 2.1 Syntax
-
- In the conf directory, you should find a collection of options files.
- These list all the options that can be used in all configurations of
- the program. Some options are required; some can be toggled on or off;
- others allow you to change values used by the compiler. The form of
- each line in an option file indicates which it is.
-
- The most important rule about options files is that it's line based.
- The end of a line is the end of an option. The second thing to know is
- that a "#" character followed by a space starts a comment. Everything
- after that will be ignored by config, and is for the benefit of the
- reader. The meaning of the option is given in the comment. The third
- rule is that the first word on the line is the "name" for the option
- this line describes, and that everything from the end of the name to
- the start of any comment or the end of the line, ignoring any leading
- or trailing whitespace, is the "value" for the option this line
- describes.
-
- There are two special values for options in the options files. The
- first is "required". This means any config file that uses options in
- that options file must specify a value for that option (explained
- in a later section). The second special value is "option". This
- means that the named option is a toggle, and is normally off. It also
- changes the format used in the configuration file for that option.
- Finally, there is one special name for options: "action". You should
- ignore any option lines with that name. All other options allow you to
- specify a value for the named option, and list the default value if
- you don't specify one.
-
- A required option could look like this, with comments:
-
- system required # which system we're compiling it for
- # currently supported: amiga, vms, bsd
-
- A toggle option might look like this, with comments.
-
- no_metakey option # disables the use of "meta" keys as modifiers
- # instead of prefacing commands sequences with
- # an ESC character
-
-
- This option, according to the comments, says that "meta" keys are supported
- for all configurations unless their config file specifies
- "no_metakey".
-
- A non-required value option could look like this:
-
- metabit 0x80 # what bit in a char is the metabit
-
- which says that metabit is normally "0x80", unless the config file
- changes it.
-
- 2.2 Options Files
-
- Now that you know the syntax for an options file, you can start
- reading them. The first one to read is always "config.options". It
- describes the options that exist in every configuration of the
- program. You should read through config.options, reading the comments
- that describe each option (if there are no such comments, you should
- find the author of the program or options file and insist that they be
- added), and considering what values you would like those options to
- have.
-
- First, decide what values the required options should have. These
- values will be limited to a small set, and should be listed in the
- comments. For example, according to the comments:
-
- system required # which system we're compiling it for
- # currently supported: amiga, vms, bsd
-
- the required option "system" can be set to amiga, vms or bsd.
-
- After you've decided what values you want the required options to
- have, you should look for options files with the first part of the
- names being the values you've chosen. For example, if you wanted
- system to be "amiga", you would look for "amiga.options". This file
- will list more options that are available for the program if it's
- configured with "system" as "amiga". You should read through that file
- in the same way you went through config.options. If it has more
- required options, you should go through the files associated with
- those, and so on. Should you wish to set a required option to a value
- for which there is no options file, you should contact the author of
- the options file that has that required option in it, or the author of
- the program.
-
- 2.3 Configuration Files
-
- Having read through all the options files associated with the
- configuration you are working on, you can start on your configuration
- file. Most people build it as they go. Decide on a name for your file,
- and create it in the conf directory - if it isn't already in use.
- At the same time, create an empty configuration directory with the
- same name. By convention, both these names should be in upper case.
-
- The form of a configuration file is the same as the form of an options
- file: name as the first token on the line, value as everything from
- the name to any comment or the end of the line, followed by comments,
- which start with a "# " and go to the end of the line. For a
- configuration file, the name of an option must be an option that
- appeared in one of the options file, or the word "option".
-
- The required options must all be listed before any other options. In
- addition, the required option whose value names an options file must
- be listed before any required options from the options file it names.
-
- So if config.options contained:
-
- system required # which system we're compiling it for
- # currently supported: amiga, vms, bsd
-
- and amiga.options contained:
-
- compiler required # which C compiler is being used.
- # currently supports only lattice or manx
-
- then your config file might start like:
-
- system amiga
- compiler lattice
-
- The remaining options can be listed in any order. Normal value options
- are listed the same way that required options are listed. Options
- whose value was "option" can be listed in one of two ways. The first
- and preferred way is with a line which specifies the name "option",
- and then the name of the option you wish to turn on. You can also list
- the name of the option as the name on the line, and give it a value of
- either "on" or "off", but this form may not be supported in future
- versions of config. Config will not complain if you vary from these
- forms, but the compiler might when you attempt to compile the program.
- The option options default to off, and "name on" is identical to
- "option name". So, if you encounter the following two options in
- various options files:
-
- no_metakey option # disables the use of "meta" keys as modifiers
- # instead of prefacing commands sequences with
- # an ESC character
-
- metabit 0x80 # what bit in a char is the metabit
-
- then part of your config file might look like:
-
- option no_metakey # My terminal doesn't support it anyway
- metabit 0x100 # For the international character set
-
- which is identical to
-
- no_metakey on
- metabit 0x100
-
- Both of these turn on the no_metakey option (thus, according to the
- comments, disabling support for the meta key), and change metabit from
- its normal value of 0x80 to 0x100.
-
- The final step is to run config on your config file. To do that, make
- sure you're in the config directory, and issue the command
-
- config CONFIGFILE
-
- Config will then scan all the appropriate options files and your
- config file and prepare your configuration directory for building the
- configuration you've specified.
-
-
- 3. PREPARING OPTIONS FILES
-
- This section discusses what config does with the values given to
- options, and how that can change the program produced.
-
- 3.1 Value Options
-
- Value options are listed in the options or config files with their
- name, and the value that will be #defined to their name at compile
- time. For section 3.1, assume that the following is in an options file
- for the config file and program being configured:
-
- promptwait 20 # number of 10ths of a second to wait before timing
- # out while waiting for the user.
-
- For each value option, config creates a file in the configuration
- directory whose name is the name of the option, with a ".h" appended.
- For the above example, there would be a file "promptwait.h" in the
- configuration directory.
-
- That file contains a single define (or in a special case, is empty)
- that defines the option name in upper case, and gives it the value
- specified (or in a special case, just defines it). So, for the above,
- if the config file doesn't change promptwait, the file promptwait.h in
- the configuration directory would contain
-
- #define PROMPTWAIT 20
-
- If the config file did change promptwait, for example, reducing it to 10:
-
- promptwait 10
-
- then config would build promptwait.h to indicate that change:
-
- #define PROMPTWAIT 10
-
- 3.2 Option Options
-
- Option options are listed in the options files with their name, and
- the value "option". They have no value #defined to their names at
- compile time - they are either defined or not. For section 3.2, assume
- that the following is in an options file for the configuration being
- configured:
-
- v11 option # must be defined for the editor to either run on
- # or compile on a version 1.1 AmigaDOS system.
- # It mainly wards against bugs in the 1.1 ROM Kernel.
-
- Config will create a file whose name is the name of the option, with
- ".h" appended. So the above option will cause "v11.h" to be created in
- the configuration directory. If the option is left off, the file is
- left empty. If the option is turned on, the file will define the
- option name - once again, in upper case - as a symbol.
-
- So if the v11 option is left off, then the file v11.h will contain
- nothing. If some config file turns v11 on, then v11.h will contain
-
- #define V11
-
- As an implementation detail, if any value option has the value
- of "on" or "off", it will be treated as if it were an option option,
- and either not defined, or just defined with no value attached to the
- symbol. This is useful in that it allows for #define symbols whose
- existence causes code to appear, and whose value is needed by the code
- if it appears.
-
- 3.3 Required Options
-
- Required options are listed in the options file with the special value
- of "required". They will be given a value in every config file that
- uses that options file, and will cause config to check the options
- file named by the value given them in the config file.
-
- Like the other kinds of options, required options cause a file whose
- name is their name with a ".h" appended to be created in the
- configuration directory. Unlike the others, the name of the option is
- not what is defined. Instead, the value of the option is defined as a
- symbol, once again in upper case. The symbol is not defined to be any
- specific value.
-
- For instance, if the options file contained
-
- compiler required # which C compiler is being used.
- # currently supports only lattice or manx
-
- Then config will create "compiler.h" in the configuration directory.
- If the config file contained this as:
-
- compiler lattice
-
- then the contents of compiler.h would be
-
- #define LATTICE
-
- In addition, the file "lattice.options" will be scanned for further
- options when the compiler option is specified in the config file.
- If the config file had instead specified "compiler manx", then MANX
- would be #defined in compiler.h, and "manx.options" would be scanned.
-
- 3.4 Action Options
-
- Action options are specified in options files with a name of "action".
- They are never mentioned in config files, and have no direct effect on
- the compilation of the program.
-
- What action options do is list commands to be issued to the command
- processor after the include files specified by the other options have
- been created. The commands are issued in the order they were found in
- the options file, and have the configuration directory as their
- current working directory when they are issued.
-
- Normally, action commands are used to take care of any preparations
- needed before the program can be compiled in the configuration
- directory. Examples are copying makefiles into the directory, building
- dependency files, or just issuing comments to the user. A typical
- short example is:
-
- action lc:lmk -f /amiga/lmkfile depend
- action echo "Ready to lmk this configuration of mg."
-
- This issues the command "lc:lmk" with the three arguments "-f",
- "/amiga/lmkfile" and "depend" (which, in this cases, creates a new
- makefile in the current directory with a dependency list appended to
- it), and the command "echo" with the argument '"Ready to lmk this
- configuration of mg."' (which, in this case, tells the user that the
- configuration directory is ready for the lmk command which will make
- the program in it).
-
- 3.5 Names To Avoid
-
- There are some names that you can not use when creating options,
- mostly became they clash with words that config uses to change the
- treatment of that option. Most of these words are external: option,
- required, off, on. The following table lists all such words, and
- describes where they cannot be used or where they should be used with
- care.
-
- word not valid
-
- action as an option name
- option as an option name, or the default value for an option
- required as the default value for an option
- on as an option value
- off as an option value
-
- 'On' and 'off' are special cases, and can be useful as option values if
- used with care. Their use is described above.
-
- In addition, any option name must be valid as the name (without
- extension) for a header file on your system. Likewise, any required
- option value must be valid as the name for an options file. Finally,
- option names and required option values must be valid preprocessor
- symbols.
-
-
- 4. PROGRAMMING FOR CONFIG
-
- This section discusses what form a program must be in so that it can
- be configured with config.
-
- 4.1 Starting Out
-
- Once you've decided that a program will be configured by config, it is
- straightforward - but some work - to insure that config can be used to
- best advantage. This is best done while the program is still in the
- design phase. Converting existing programs for configuration via
- config is possible, but painful. See section 4.6 for information on
- converting existing programs.
-
- Every time you use a new #defined symbol, you must decide which of
- four classes it belongs to:
-
- 1) The symbol in some way distinguishes one version from another.
-
- 2) The symbol causes features to appear or disappear from some or all
- versions.
-
- 3) The symbol is a compile-time value that affects some or all
- versions.
-
- 4) The symbol depends on the values of other symbols in a
- predetermined way.
-
- The four cases all require slightly different treatment, and all but
- the fourth will be discussed in separate sections. in the fourth
- case, the symbol should be dealt with in source code, and no option of
- any kind need appear for it in the options files.
-
- 4.2 Required Options
-
- Symbols that distinguish versions from one another are almost
- certainly "required" options. They usually come in sets of #defined
- symbols that are mutually contradictory - if one is on, all the others
- must be off. Each such set is represented by one required option,
- where the possible values of that required option are the different
- symbols that can be defined.
-
- When such a symbol is first referenced, you should determine if it
- belongs to such a set that already exists. If so, then change the
- comment for the required option for that set to reflect the new
- possible value, and then create an empty options file with that value as
- the first part of its name, containing a comment describing what it
- is.
-
- For example, suppose you add a new symbols "sysv" that is appropriate for
- the following option:
-
- system required # which system we're compiling it for
- # currently supported: amiga, vms, bsd
-
- Then add ", sysv" to the end of the second comment, and create an
- options file "sysv.options", with comment:
-
- #
- # support for System V. No options to choose from (yet).
- #
-
- Any code that needed to be compiled in - or needed to not be compiled
- in - for the System V version of the program would then have it's
- conditional compilation depend on the symbol SYSV.
-
- Normally, required options are added to a program after it has been
- working in some incarnation for a while - for instance, when it is
- being ported to a new machine or operating system. In those cases, if
- we are adding a value to a required type, you must find all files that
- include the .H file which config creates for that option and check to
- see what should be added.
-
- In cases where the required option did not exist before, you need to
- choose a name for the option, and add that as a required option in the
- appropriate options file with a comment indicating what values it can
- take on. You should also create the options files for each of those
- values, as above. Finally, every source file that checks for one of
- the possible values of the option being defined must be changed to
- include the .h file with the name you chose for the required option.
- Any automated compilation facilities should be informed of the change
- in whatever way is needed.
-
- For example, suppose you are adding support for a second terminal type
- to a program - for example, adding termio to a program that already
- has termcap support. The option name "tty" or "term" suggests itself,
- with the possible values of "termcap" and "termio". So you would add
- the following to the appropriate options file:
-
- term required # type of terminal support used. One of:
- # termcap, termio
-
- You should also create the files "termcap.options" and
- "termio.options", with comments describing what they are. Code should
- then appear in the source files conditionally compiled on the symbols
- "TERMCAP" and "TERMIO". Any source file that depends on those symbols
- should be changed to include the file "term.h".
-
- 4.3 Option Options
-
- Any symbols that cause code to be conditionally compiled in, but can
- be left on or off without requiring that any other symbols be on or
- off (unless they require code that those other symbols control the
- compilation of, or something similar) should become "option" options.
-
- When such a symbol is first referenced, all you need to do is add the
- name of the symbol and a comment describing it to the appropriate
- options file. For example, if you were adding mouse support to a
- program, but wanted to allow people to build the program on systems
- that didn't have mice attached, you would probably conditionally
- compile in that extra code if the symbol "MOUSE" were defined. So you
- would add:
-
- mouse option # provide mouse support
-
- Every source file that had code that depended on MOUSE should also
- include "mouse.h", as that is where config will put the #define for
- MOUSE.
-
- 4.4 Value Options
-
- If a defined symbol has a value that is used in the code, then you are
- dealing with a "value" option. It is treated the same as an "option"
- option, except that the preprocessor symbol will have a value, instead
- of merely being defined or not defined.
-
- When such a symbol is first referenced, follow the same actions as the
- "option" options, except you must choose a default value for the
- option and use that for the value in the options file instead of the
- word "option".
-
- For example, if the program had a limit for number of screen lines
- built into it, and you wished to make that limit available to the
- person compiling the program so they could raise or lower it as
- appropriate for their environment. Decide on a reasonable default -
- say 70 - and add the following line to the appropriate options file:
-
- maxlines 70 # maximum number of display lines we can work with
-
- You should then change all source files that depend on this maximum to
- use the symbol MAXLINES, and have them include "maxlines.h" to get the
- value.
-
- You can have a value option do double duty, if you so desire. If one
- of the values the option can take on is "off", then the symbol will
- not be defined. This allows you to have code that doesn't appear
- if the user doesn't want it, and a symbol that holds a needed value in
- that code. For example, if word-wrap code were part of a program, and
- you wanted it to be either on by default, off by default, or disabled
- completely, you might have entries in an option file like so:
-
- wrap 1 # word wrap code. Three values are supported:
- # off -> code isn't there at all
- # 0 -> code is there, but turned off at startup
- # 1 -> code is there, and on at startup.
-
- and C code that looks like:
-
- #ifdef WRAP
- int wrap_mode = WRAP ;
- #endif
-
- with appropriate code to handle the word wrap.
-
- 4.5 The "Appropriate" Options File
-
- The previous three sections each mentioned "the appropriate options
- file." This sections discusses how you would find that file.
-
- The matter is actually very simple. The options files for a program
- can be viewed as a tree, with "config.options" at the root, and
- branches from each options file for the required options in that file.
- The various different versions of the program then correspond to the
- leaves of this tree. The "appropriate" options file for an option to
- be added to would be the options file farthest from the root which
- contained all the versions for which that option could apply.
-
- Required options separate versions from one another, and would seem to
- require more work. This is seldom the case. Usually, when required
- options are first added, there are no options in their options file,
- so using the same method as described above will work.
-
- In practice, there usually isn't any problem. When an option is added,
- there is a clear idea of what versions it will and won't be
- appropriate to add to, and the "appropriate" options file will be
- obvious.
-
- 4.6 Converting a Program for Config
-
- Converting an existing program for use with config is easy to
- describe, and for simple programs, is easy to do. However, if you're
- considering converting a program for use with config, it's probably
- because the compile-time options have gotten out of hand, so you face
- a rather large job.
-
- There are only four steps to convert a program to config: 1) find all
- the defined symbols; 2) classify them as described in section 4.1; 3)
- create the config.options and all options files needed for required
- options; 4) modify the source as appropriate. We will look at each
- step in some depth.
-
- Finding all the defined symbols is easy if you have a tool for
- selecting lines by pattern from a file. Find all lines that start
- with #define or #if in all source files. Delete the preprocessor
- directives and any extraneous information, and then sort the results.
- At this point, you should have all symbols which are candidates for
- options in hand.
-
- Classifying symbols is slightly harder. The previous sections
- discusses the various types of symbols and their characteristics.
- Start by finding all the symbols which are values for required
- options. At this point, you can create a first version of
- config.options with the required options and their possible values
- listed. You can also create the other options files, with comments
- describing what version(s) of the program they provide options for.
-
- The second step should be to identify those symbols which aren't going
- to be visible as options to the users. These will have values that can
- be determined from the other symbols. You should start adding code (if
- it doesn't exist) to define these symbols, based on the values of the
- other symbols.
-
- Next, go through the remaining symbols and decide if they are "option"
- options or "value" options, and treat them as described in the
- preceding sections. By the time you have completed this step, you
- should have all the options files finished.
-
- Then go through the source files and add the appropriate #include's
- for all defined symbols used in each file, if those symbols are now in
- files created by config. Finally, delete the definition of those same
- symbols from wherever they were defined previously - either in build
- scripts, make files, or .h files.
-
- If you are using automated compilation tools, you should also modify
- the data files for those so that the new dependencies are reflected in
- them.
-