Revision of <em>HOWTO Use the GCC specs file</em> from <em>2008, September 4 - 12:57</em>

About Specs file

The "gcc" program invoked by users is a convenient front-end driver executable which will invoke other programs in the background such as cc1, as or ld to do its work according to the command line parameter given. A specs file is plain text used to control the default behavior for the "gcc" front-end. The specs file is usually built-in but for flexibility purposes, it can be overridden with an external version.

Basic Specs file modifications

GCC will produce a specs file via the following command.

gcc -dumpspecs > specs

You may use a text editor of your choice to inspect it. It may be confusing at first, but there are many places of interest. To use the specs file, invoke gcc with -specs=<path_to_specs_file> or place it at "/mingw/lib/gcc/mingw32/<version>/specs" to make GCC use it by default, where <version> refers to the GCC version installed.

Adding include directories to the search path

The *cpp: section should be modified. It contains the following by default:

*cpp:
%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}

If "z:\libx\include" needs to be added to the GCC includes search path, it should be changed to the following

*cpp:
%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} -I z:/libx/include

Adding lib directories to the search path

The *link_libgcc: section should be modified. It contains the following by default:

*link_libgcc:
%D

If "z:\libx\lib" needs to be added to the GCC library search path, it should be changed to the following

*link_libgcc:
%D -L z:/libx/lib

More Help

I have a number of concerns about the veracity and advisability of the recommendations posted above.

First, and perhaps most importantly, GCC is not an MSYS application, so it knows nothing about the MSYS syntax for representing path names. Thus, the MSYS style paths used in the above examples, specifically /z/libx/include, used with the -I flag in the sample *cpp: spec, and /z/libx/lib, used with the -L flag in the sample *link_libgcc: spec, simply will not work; these need to be expressed as z:/libx/include and z:/libx/lib respectively. Similarly, the path stated for the standard location for specs files is only valid from within the MSYS shell, and would be better expressed generically in native MS-Windows format as

<mingw-root>/lib/gcc/mingw32/<gcc-version>

where <mingw-root> represents the MinGW installation directory, (which is c:/mingw in a default installation), and users of cmd.exe will need to substitute backslashes for slashes, on the command line, (but are advised to use slashes, and not backslashes, within any modified specs file).

Second, the above text neatly, but ambiguously, dodges the issue of overriding the built-in specs; (an issue where GCC's own --help output causes confusion, for it says

-specs=<file> Override built-in specs with the contents of <file>

but in fact, this option augments, rather than explicitly overrides the built-in specs). Here is how specs work, in practice:

GCC provides a set of built-in specs, tailored to its specific implementation, (MinGW, in our case), which are used by default, when specs need to be evaluated.

When the specs are evaluated, GCC looks for the file

<mingw-root>/lib/gcc/mingw32/<gcc-version>/specs

If this file exists, then the built-in specs are ignored en-masse, and the contents of this file are evaluated in their stead. (Thus, this file, and this file only, has the effect of overriding the built-in specs, in their entirety). This file is always processed, if it exists; it is unnecessary to specify it in a -specs=<file> option.

After the default specs have been loaded, any additional specs files specified with -specs=<file> options are loaded. Such additional specs files may redefine every spec previously loaded; in this manner, such a file may override the built-in or external default specs, as suggested by the --help text. However, much more usefully, such files may selectively redefine just a small subset of the default specs, so augmenting rather than overriding the default behaviour. For example, here is a method for utilising a version of MSVCRT.DLL, other than the default, (say MSVCR80.DLL), on demand:

Ensure that the default specs are defined externally, (i.e. ensure that they are defined in the

Open the default external specs file in your favourite editor, and add the new specs:

*msvcrt:
msvcrt
*msvcrt_version:
*moldname:
moldname

(note that each spec definition requires at least one definition line, and must be separated from the next by exactly one blank line; thus, the tag line for '*msvcrt_version:' must be followed by exactly two blank lines, one for the empty definition, and the second to mark the end of that definition. Pay particular attention to those blank lines, especially if you copy-and-paste from these examples: they must be completely empty; no stray white space is permitted, but it is present here, to ensure that the layout is shown correctly in your browser).

Still editing the external default specs file, locate the definition for '*cpp:'; in a default specs file, it should look like:

*cpp:
%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}

(noting that it too must be followed by exactly one blank line); to that definition, add the substitution macro '%(msvcrt_version)', (note parentheses, not braces here, but do leave the braces as they are, in the original conditional macros), so that it now looks like:

*cpp:
%(msvcrt_version) %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}

Similarly, locate the spec for '*libgcc:'; it should look something like:

Within this spec string, locate the specific reference for '-lmsvcrt', and change it to use the substitution macro '-l%(msvcrt)'; do likewise for the '-lmoldname' reference, so that the entire spec now looks like:

(again noting the one blank line, at end of file, following the '*moldname:' definition). This file need contain no more than this; save it.

Repeat the preceding step, with appropriate alternative file names, and definitions, to specify any other MSVCRT.DLL versions you wish to support.

To compile applications, such that they use the default version of MSVCRT.DLL, you may continue to invoke GCC just as you usually would, e.g.

gcc -o foo foo.c

To compile applications, such that they use an alternative version of MSVCRT.DLL, simply add the appropriate -specs=<file> option, e.g. for MSVCR80.DLL

gcc -specs=msvcr80 -o foo foo.c

Third, while the modifications suggested in the original text, (with appropriate corrections to the path name syntax), will certainly achieve the desired effect, I would strongly recommend a less intrusive approach; e.g. rather than hard code the absolute paths into '*cpp:' and '*link_libgcc:' directly, I would insert:

and also, (not mentioned in the original article, but required to make g++ work correctly), '*cc1plus:' to add:

*cc1plus:
%(local_includes)

This allows the local includes and library paths to be readily modified, either directly within the default specs file, or more usefully perhaps, through the use of supplementary specs files.

And finally, I would add a word of caution: do not blindly overwrite an existing specs file at

<mingw-root>/lib/gcc/mingw32/<gcc-version>/specs

if there is one already present, (which there always should be, for versions of GCC prior to gcc-4.0), by executing

gcc -dumpspecs > <mingw-root>/lib/gcc/mingw32/<gcc-version>/specs

If you do this, you will destroy any customisations which are already in place. It is better to make a backup copy of any such existing specs file, (in case your subsequent changes mess it up), and then use the original as the basis for further customisation.