Bud Utility © 2006, Derek Parnell, Melbourne
(table of contents)
The
build utility supports the use of various pragma statements.
A pragma is a special statement embedded in the source code that
provides information to tools reading the source code.
They take the forms ...
pragma( <name> );
pragma( <name> , <option> [, <option>] );
If the D compiler doesn't recognise the pragma, it will fail. So to
'hide' them from the compiler, you need to wrap them in a
version
block. All the pragmas used by this utility need to be enclosed in
a
build version.
Example:
version(build) { pragma(nolink); }
This nominates one or more libraries that are required to be linked in.
If your applications needs code from a library to be linked in, rather than
supplying source code, you can tell
build which libraries are needed.
This can happen when using a library provided by a third-party.
Example: 1
// This app needs the MyGUI.lib library to be used.
version(build) { pragma(link, MyGUI); }
Example: 2
// This app needs the a DB library and TCP library to be used.
version(build) { pragma(link, EuDB, TCP4Win); }
This identifies that the current module is not to be be linked in.
Normally, each object file created by the compiler is linked in, but
if the supplied source file is just a stub for code which is externally
defined in a library, then you do not need the 'stub' object file.
Example:
version(build) { pragma(nolink); }
This identifies that the current module is not to be passed to
the compiler or linker. It is however scanned by
Bud and can thus
contain
Bud pragma directives and import statements. This would be
used to create a special
all.d file to pull in all the modules
for a library or program.
Example:
version(build) pragma(ignore);
// A list of files to include into a library.
import util.files;
import util.gfx;
import util.physics;
import util.render;
This identifies a required file which is not otherwise imported.
In some applications, especially ones converted over from C, it is
possible that the file on the
Bud command line does not directly
or indirectly import a required file. In those situations, you can
use this pragma to tell build to include it in the compilation checking
process.
The name provided in the
include pragma is assumed to be a module name
and is thus converted to a D source file name with path. The one exception
to this is if the name provided ends in ".ddoc" it is assumed to be a
Ddoc macro definition file and is taken as given rather than being transformed
from a module specification to a path and file name.
Example:
// Tell 'build' that prime.d must be included (it contains the main function.)
version(build) { pragma(include, prime); }
// Tell 'build' that user\base.d must be included
version(build) { pragma(include, user.base); }
// Tell 'build' that docdef\qwerty.ddoc must be included
version(build) { pragma(include, docdef\qwerty.ddoc); }
This identifies the basename of the target file.
By default, the target name is based on the first file on the command line.
But if you include this pragma, the name identified in the pragma becomes
the default name. In either case, the
-T switch overrides the default name.
If two or more
target pragmas are found, the first one is the one
that is used and the others are ignored (though mentioned if in
verbose mode).
Example:
// Tell 'build' to create WhizzBang.exe
version(build) { pragma(target, "WhizzBang"); }
This identifies a file that needs an external program to build it.
Some applications need to link in object files created by C source, or
by a
resource compiler, or whatever. This pragma identifies a file
that needs to be created by something other than the D compiler. The
format is ...
pragma(build, "FILENAME" [, "OPTIONS"] ...);
where
FILENAME is either the file to create, or the file to use when
creating the required file to use in the build process. Note that if you
just supply an empty string
"" the file that contains the pragma is
used.
For example, if you had a Windows resource file
that needed to be compiled, you could code the pragma as either ...
// Compile the images into a resource obj and add images.res to linker.
pragma(build, "images.rc");
or
// Compile the images into a resource obj and add images.res to linker.
pragma(build, "images.res");
The first example specifies the source file to be passed to the resource
compiler and the second example specifies the output of the resource compiler.
In either case, this utility uses the rules in a
Rule Definition File to
decide what to do.
The utility searches for the
FILENAME in the currently defined 'import'
paths and if doesn't exist,
Bud will abort.
The
OPTIONS can be included if you need to pass any special values
to the external tool. There can be any number of these, but each one must
take the form
"<KEYWORD>=<VALUE>". For example
pragma(build, "dbapi.c", "COPT=-wc -x", "HDR=abc.hp");
The OPTIONS values are used as replacement text for token in the
Rule Definition File's 'tool' specification. In the example above,
the tokens {COPT} and {HDR}, if found in the 'tool' line, would be
replaced with
-wc -x and
abc.hp respectively.
There are some OPTIONS that have a special meaning to
Bud.
- rule=<name>
- This identifies the name of the rule to use.
If this isn't supplied, the rule is found by matching the file extension
on the FILENAME against the in= and out= file types in
each rule definition.
- @pre=<text>
- This text is prepended to the FILENAME to form
the output file's name. Thus is the FILENAME was "foo.d" and <text>
was "dd" the output file name would formed as "ddfoo.d". This
can be used in conjunction with the @pos= OPTION.
- @pos=<text>
- This text is appended to the FILENAME to form
the output file's name. Thus is the FILENAME was "foo.d" and <text>
was "_ri" the output file name would formed as "foo_ri.d". This
can be used in conjunction with the @pre= OPTION.
The output file to the external tool is checked to see if it is still
up to date and the tool is only called if the output file's date is earlier
than the input file's date (or a forced compile is requested).
By default, the output file from the external tool is added to the linkage
set of files, and the input file is ignored. These behaviours can be changed
by options in the
Rule definition. It is possible to tell
Bud to
compile, link or ignore the input file and/or the output file.
All these external programs are run before the D compiler is invoked.
Example:
// Tell 'build' that it needs to use a rule called 'Resource'
// to call an external program to build an up-to-date version
// of 'images.rc'
version(build) { pragma(build, "images.rc", "rule=Resource"); }
This allows you to set a global version identifier.
DMD allows you to set a version identifier in your code, but the scope
of that is only for the module it is set in. This pragma gives you the
ability to declare a version identifier which is applied to all modules
being compiled, and not just the 'current' module.
Example:
version(build) pragma(export_version, Unix);
version(build) pragma(export_version, Limited);
These lines will cause the compiler to have these version identifiers
added to the command line switches, thus making them effectively global.
You can list more than one identifier on the pragma statement ...
version(build) pragma(export_version, Unix, Limited);
This supplies an option to be placed in an OptLink definition file.
You can have
build create a customised OptLink definition file
by coding as many
build_def pragmas as required. However,
build will
only allow the first of each type of Definition File command to be used. This
means that if you code ...
pragma (build_def, "EXETYPE DOS");
pragma (build_def, "EXETYPE NT");
Then the EXETYPE DOS will be used and the 'NT' line ignored. You can use
explicit build_def pragmas to override the default ones generated by
build for Windows programs or DLL libraries.
The syntax for these pragma is
pragma(build_def, <QUOTED_STRING> );
Example:
version(build) {
pragma (build_def, "VERSION 1.1");
version(DOS) {
pragma (build_def, "EXETYPE DOS");
}
version(WIN) {
pragma (build_def, "EXETYPE NT");
pragma (build_def, "SUBSYSTEM WINDOWS,4.0");
}
}
NOTE: You can supply anything in the text string and it is used verbatim.
There is no restrictions on what you can include in this pragma.