15.3 Defining Target Properties

The standard body explicitly keeps each target in the makefile completely distinct so that the properties of one target apply only to that target alone. It even goes so far as to isolate each target from the built-in rules defined by make: if something is to be done for a target, the target must say what by defining the property variables. However, within one target the properties are ``inherited.'' This means that when specify compiler options not only for a target but also for some source file, the effective options will be the combination of all the options: first the target's options, then the options from other the target's uses, the options from the option-sets defined by the target and its uses, and finally the options for the source file. Thus, if a source file requires special preprocessor definitions or compiler options--such as downgrading optimisation level--it is reasonably easy to achieve.

The target properties are defined by setting a value to a variable target_property. Here target is the target (or file) name and property is one of the properties mentioned below or in Appendix F, ``Details on Makefile Uses''. The target name should be as it was named in the target variable definitions. For example, to define C++ preprocessor options for library libclass.a you would set the property variable libclass.a_CXXCPPFLAGS.

The program and library targets can define the following properties. In addition to these the makefile uses may allow others to be defined; see Appendix F, ``Details on Makefile Uses'' for details.

USES

The special needs of this target. This is further explained in the next section.

OPTION_SETS

The option sets that apply to this target. If none are specified, $(USE_OPTION_SETS) will be used.

LINKSET

The name of the linkset defined in the PACKAGE file that ought to be used for this target. If omitted, the last linkset in PACKAGE will be used. If defined, you no longer need to define libraries that are needed (apart from the ones built in this package)--they will be determined automatically from the linksets. More details in Section 15.6, ``Linksets''.

ARFLAGS

Additional options to $(AR).

SRC

The source files for the target. All source files should be mentioned in this property regardless of their type and whether they directly generate object files or not; the standard makefile body takes care of interpreting the names correctly. However, the body will only know how to compile the files whose rules are defined by uses listed in the USES property. It will not know how to compile any other files, not even if another target includes the use.

OBJS

Object files needed to build the target but that should not be built by the release tools. The package author takes the responsibility of producing these files. The files should usually have the target system's object file extension.

LIBS

Libraries the target should be linked against. This property should only contain entries of the form -lname; other linker options should go into the LDFLAGS property. If linksets are used, this property would contain only the libraries created in this package that must precede the libraries resolved from linksets. Otherwise it must be the full set of libraries in the correct order.

This property does make sense for both programs and libraries. For programs its meaning ought to be obvious. For shared libraries the property should list of libraries from which symbols are imported to the target library. Note that while on some systems it is possible to create a shared library that has unresolved externals (you will succeed to link the library and it seems to work), on many systems you will get either warnings or errors if you miss the imports. Portability requires that you mention here the libraries that the target shared library depends on.

For archive libraries this property is used only if the object files going to the library are prelinked to close them with respect to (C++) templates. In that case the dummy prelinking executable will be built against the libraries mentioned in this property. This variable should define at the very least the libraries that contain templates the target library should not include.[1]

LDFLAGS

Linker options such as additional -L options. See also LIBS.

NOTE

On Windows NT, programs linked with one of the compilers (C, C++ or FORTRAN) can define options to be passed to the linker with the unix-style -L and -Wl,options switches. Both of these will be passed at the end of the compiler command line after the /link option. -L options will be converted to /libpath: options and -Wl options will be passed to the compiler just as on unixen (that is, the -Wl part is stripped off and remaining commas are converted to spaces).

PRELINK_MAIN

The source file for the main program to be used in prelinking. Prelinking will only occur if this property is defined, which ought to be done for all archive library targets that contain C++ code using or defining templates. Often the following simple file will do as the prelink main program:
int main (int, char **) { return 0; }

XTRADEPS

Additional dependencies for the target. These will simply go to the dependencies part of the rule that the standard makefile body generates. Only effective for programs and shared libraries. On AIX 4.1 the release tools will add the import and export files to this property.

In addition to the above the makefile can define source-file specific properities. Most compilation rules allow for instance file-specific preprocessor options or to redefine the option sets. Every source file can define at least the OPTION_SETS property. Other possible properties are described in the table in Appendix F, ``Details on Makefile Uses''; look for the entries that contain F in the scope field.

Nested targets--subdirectories and subpackages--allow you to define the following property.

FLAGS

Options to make to be used when it descends into that directory. Note that options specified for a package only apply if the build process happens to descend into that package through the makefile defining the property. Since any makefile in the release can transfer control to any other package, it is useless to define flags for a package in just one makefile.

Notes

[1]

Here is the long story. When the object files are closed with respect to templates, many C++ compilers instantiate templates not to separate object files, but to the object files going into the library. Thus, the templates used by the library will be defined in that library and clients can successfully link. However, the problem arises when the templates are really external to your library--for example if you are using the standard library class vector--as some other library may instantiate the template as well. The loop is completed by the behaviour of many linkers: when they resolve a symbol, they take the entire object file that defines the symbol, not just the symbol itself. Now, if the linker chooses two object files from two different libraries such that both of them instantiate the same templates, a linker error will occur due to duplicate symbols. You can avoid this to a certain extent by carefully constructing the lists of libraries used in prelinking. This will not, however, be a complete solution: it will only push the problematic cases further into the future. The issue only goes away when the compiler properly implements templates and external compilation (the export keyword). Neither will this practise remove the problem that you can get massive amounts of libraries brought in just because a linker picked up template symbols from them. For example, you can have a completely unrelated library brought in in its entirety just because the linker resolved vector<int> from it.