From 6f46c98872322ccd01aff4e3a65ee099d3c32cae Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Fri, 31 Dec 2021 19:54:28 +0000 Subject: [PATCH] Publish GCC 'specs' customization HOWTO. * gccspecs.html: New file; adapted from original Drupal content, and in particular, on user comments relating to that content, this offers advice on customizing GCC's default behaviour, especially insofar as it affects include file and library search paths, and the option to deploy non-free Microsoft C runtime libraries, as alternatives to pseudo-free MSVCRT.DLL. --- gccspecs.html | 1068 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1068 insertions(+) create mode 100644 gccspecs.html diff --git a/gccspecs.html b/gccspecs.html new file mode 100644 index 0000000..be186c0 --- /dev/null +++ b/gccspecs.html @@ -0,0 +1,1068 @@ + + + + +
+

Introduction

+

The MinGW compiler comprises a comprehensive suite of separate programs, +intended for deployment as a native compiler, on the Microsoft Windows platform, +or alternatively, as a cross‑compiler for use on some other platform, +to create applications for deployment on the native Windows platform. +In either case, the compiler suite consists of, at least:– +

+

In addition to the above, +a native MinGW compiler deployment is accompanied by several other GNU DLLs, +which are required to support the operation of the compiler itself; +in the case of a cross‑compiler, +the function of these additional DLLs is served by equivalents, +which are native to the platform on which the cross‑compiler is run. +

+

Regardless of whether it is deployed as a native compiler, +or as a cross‑compiler suite, +the MinGW compiler, assembler, and linker are normally invoked +by means of a common driver  program; +in the case of a native compiler, +this driver program is normally gcc, +(or g++, when compiling C++ code); +in the case of a cross‑compiler, +the corresponding driver programs may be mingw32‑gcc, +and mingw32‑g++, +(possibly qualified by an additional prefix, +to identify the target CPU). +In either case, +the driver program determines the sequence of auxiliary programs, +which are to be executed, +and the options and file names which are to be passed to them, +on the basis of:– +

+

In this HOWTO, +we explore the capabilities afforded by ‘specs’ string +modifications, illustrating these capabilities by examples of:– +

+
+ +
+

Preparing the GCC ‘specs’ for Customization

+

By default, +the behaviour of GCC is controlled by +a collection of ‘specs’ strings, +which are defined at the time when GCC itself is built, +and are built‑in to the driver program; +such built‑in ‘specs’ strings +are internally immutable,  +but any of them may be redefined in external  +‘specs’ files, +thus allowing them to be effectively modified  +at GCC run‑time. +Thus, it should be evident +that customization of GCC behaviour will require +the use of external  +‘specs’ files. +

+

Before we embark on the customization process, +it may be helpful to clarify some aspects of how GCC interprets, +‘specs’ files ... an area in which the GCC documentation, +and its built‑in help are ambiguously vague! +In particular, +within the built‑in help: +

+
+$ gcc --help
+   :
+  -specs=<file>      Override built-in specs with the contents of <file>.
+   :
+
+

this terse description of the -specs option, +while technically accurate, +may lead to a misconception that, +when this option is specified, +GCC will ignore its built‑in ‘specs’ +in their entirety ; +however, in reality: +

+

Having established an understanding of +how GCC processes ‘specs’ files, +we may now progress to development of our customization strategy. +First we must decide, in the case of each planned customization, +whether we would like it to affect every  GCC invocation, +or if it should be subject to selection, +by specification of a -specs=<file> option. +In the former case, +the customization should be applied in a ‘specs’ file +which overrides all of the built‑in ‘specs’, +(i.e. in a file named “specs”); +in the latter, a selective customization +(in a file with any user-chosen name other than “specs”) +may be more appropriate. +

+

Regardless of how any required ‘specs’ files are to be named, +they must  be installed at an appropriate location within the +GCC installation directory hierarchy; +the appropriate directory path name may be identified, +(as in this example for a MinGW installation of GCC-3.4.5), +by running the command: +

+
+$ gcc -print-libgcc-file-name
+c:/mingw/bin/../lib/gcc/mingw32/3.4.5/libgcc.a
+
+

and discarding the final file name component of the path name, +to obtain a directory path name resembling +c:/mingw/bin/../lib/gcc/mingw32/3.4.5. +

+

Note: if you are running this +in an MSYS (or other POSIX‑compatible) shell, +and assuming that the sed utility program is installed, +you may wish to use it, in an adaptation of the preceding command, +to obtain the requisite directory path name directly, +expressing it in canonical form): +

+
+$ gcc -print-libgcc-file-name | sed 's!/[^/]*$!!;:1;s![^/][^/]*/\.\./!/!;t 1'
+c:/mingw/lib/gcc/mingw32/3.4.5
+
+

Alternatively, in Microsoft’s cmd.exe shell, +with a suitable POSIX‑compatible sed utility program available, +you may use the same adaptation of the command, +except  that you must substitute double quotes, +in place of the single quotes: +

+
+C:\> gcc -print-libgcc-file-name | sed "s!/[^/]*$!!;:1;s![^/][^/]*/\.\./!/!;t 1"
+c:/mingw/lib/gcc/mingw32/3.4.5
+
+

If you plan to apply any customizations +which you wish to take effect every  time you run GCC, +(i.e. without  requiring +a -specs=<file> option), +then you must  apply those customizations +within a ‘specs’ file which is +explicitly  named “specs”, +in the directory which you have just identified, +as described above. +If such a ‘specs’ file already exists, +then you are good to go; +back it up, +(in case you need to revert it ... a mistake in customization +could break GCC in some “interesting” way), +then proceed to edit it, +to apply your chosen customizations. +Conversely, if no file named “specs” yet exists, +in the appropriate directory, +you must create it. +Ideally, you should start from a baseline which exactly reproduces +GCC’s built‑in ‘specs’; +you may create, (or subsequently revert to), such a baseline, +by running the command: +

+
+$ gcc -dumpspecs > c:/path/to/libgcc/dir/specs
+
+

where /path/to/libgcc/dir represents the path +to the directory in which libgcc.a is installed, +as you have identified previously, from the output of the +gcc -print-libgcc-file-name command; +(thus, by extension of the earlier example, you would execute): +

+
+$ gcc -dumpspecs > c:/mingw/lib/gcc/mingw32/3.4.5/specs
+
+
+ +
+

Defining a Custom Include File Search Path

+

As noted in the +“Include File Search Path HOWTO”, +if a mingw32 build of GCC had been +configured to run on a typical Unix system, +it might be expected to search for include files +in /usr/local/include, +some GCC and mingw32 specific directories, +and /usr/include. +

+

On its native MS‑Windows host, +when installed at its default file system location of C:/MinGW, +it may seem reasonable to consider that C:/MinGW could be used +as a representative equivalent of the /usr directory +of the typical Unix system; thus, +C:/MinGW/local/include would be equivalent to +the Unix system’s /usr/local/include directory. +However, in a standard mingw32 build of GCC, +C:/MinGW/local/include is conspicuously omitted  +from the configured include file search path. +

+

On a Unix system, +the /usr/local/lib file system hierarchy +would typically be used to segregate third‑party, +locally installed libraries, from the core system libraries, +with the corresponding header files, +associated with such locally installed libraries, +being placed into the file system hierarchy +below /usr/local/include. +From a system management perspective, +this segregation is very convenient; +the absence of a similar file system infrastructure, +in a standard MinGW installation, +introduces an inconvenience which we would like to mitigate. +

+

Of course, +having created a supporting directory structure, +and installed our third‑party header files within it, +we can always  instruct GCC to search for them by specifying +-I..., -isystem..., +or even -iquote... options to GCC commands, +or by specifying CPATH=..., C_INCLUDE_PATH=..., +CPLUS_INCLUDE_PATH=..., or OBJC_INCLUDE_PATH=... +environment variables,  as appropriate; +of more interest here, however, +is the development of an inconvenience mitigating configuration, +by means of ‘specs’ file customization. +

+

Let us assume that we have created a suitable +file system hierarchy at C:/MinGW/local, +and we have installed our third‑party header files +into C:/MinGW/local/include; +(we could just as well have chosen a path outside +the default MinGW installation hierarchy +. . . say C:/Local/MinGW, +with header files in +C:/Local/MinGW/include . . . +but the principle remains the same; +we would simply substitute C:/Local/MinGW +for C:/MinGW/local, +in ‘specs’ file references). +Given this assumption, as stated, +our objective will be to customize the GCC ‘specs’ state, +such that C:/MinGW/local/include will be searched, +as if specified by -isystem C:/MinGW/local/include, +every  time GCC is invoked. +

+

Since we would like this customization to apply for every GCC invocation, +the most appropriate place to make the necessary changes is in the external +‘specs’ file which is explicitly named “specs”, +rather than in any which needs to be nominated by specification of +a -specs=<file> option. +If this file already exists, make a backup copy of it, +(in case you mess it up, and need to revert it); +if it does not yet exist, create it. +(Please refer to the preceding section, within this document, +for advice on how to locate, or how to create, this “specs” file, +if you do not already know). +

+

Next, open this “specs” file +in your favourite text‑file editor, and add: +

+
+*local_prefix:
+c:/mingw/local/
+
+*local_includes:
+-I %(local_prefix)include
+
+
+

at (or near) the top of the file, +taking care to ensure that each of +these new custom ‘specs’ string definitions, +(while also taking care to preserve the same structure +for all existing,  adjacent definitions), +comprises exactly : +

+

Finally, +to make GCC actually use  +our local_includes definition, +we must append it to each of GCC's own (existing) ccp, +and cc1plus definitions. +While the “specs” file is still open, +in your text‑file editor, +move to the end of the file, +and add: +

+
+*cpp:
++ %(local_includes)
+
+*cc1plus:
++ %(local_includes)
+
+
+

(again, +taking care to leave the two empty lines,  +as shown), +before saving the file, +and quitting from the text‑editor, +to complete the modification. +

+

Astute readers may have noticed that, +to the extent to which this ‘specs’ file modification uses it, +our definition of local_prefix is effectively redundant; +we could just as well have specified the value of +local_includes directly,  +to be -isystem c:/mingw/local/include, +and the effect would be the same. +We have chosen to define local_prefix separately, +because, as we will see in the next section, +we will want to define a local_libpath specification, +relative to the same file system prefix. +Of course, we could also specify local_libpath +entirely  within a single ‘specs’ string, +(including a duplicate of the prefix from local_includes); +the advantage of defining local_prefix separately, +and then relating both local_includes +and local_libpath to it, +is that it offers us an option, +at some unspecified future time, +to relocate the entire  local file system hierarchy, +(from C:/MinGW/local to C:/Local/MinGW, +for example), by redefining, or by overriding,  +just the one local_prefix ‘specs’ string. +

+
+ +
+

Defining a Custom Library Search Path

+

Further building on the underlying principles of, +and complementing the customized include file search path configuration, +as described in the preceding section, +GCC also needs to be instructed where to search for the associated +third‑party library files. +

+

By analogy with the customized local include file search path, +which we have configured as c:/mingw/local/include, +the logically corresponding local library search path would be +c:/mingw/local/lib. +While the “Library Search Path HOWTO” indicates how +this search path may be specified, +without recourse to ‘specs’ file customization, +for the additional convenience which it will ultimately afford, +we are more interested, here, in how to specify this custom search path +using  ‘specs’ file customization. +

+

Like the local include file search path configuration, +this ‘specs’ file customization will be most convenient +if its deployment does not  require the use of +a -specs=<file> command line option. +So, assuming that you have already followed the preceding procedures, +to provision a primary ‘specs’ file, +(explicitly named “specs”), +and to configure the custom include file search path, +open this ‘specs’ file once again, +in your favourite text‑file editor; +locate the definition for local_includes, +which you added previously, and below it, +add the definition: +

+
+*local_libpath:
+-L %(local_prefix)lib
+
+
+

once again, taking care to maintain correct structure, +both within this new definition, and those adjacent to it. +

+

Finally, +to complete the configuration, +and instruct GCC to use  this new custom search path, +go to the end of the file, and add: +

+
+*link_libgcc:
++ %(local_libpath)
+
+
+

before saving the ‘specs’ file, +and quitting the editor. +

+
+ +
+

Supporting Microsoft’s Non‑Free ‘C’ Runtime Libraries

+

By default, the MinGW compiler/linker combination will link applications, +such that they depend on Microsoft’s MSVCRT.DLL +‘C’ runtime library; +while not strictly “free”, +in the sense defined by the GNU General Public Licence, +this does,  qualify for the GPL linking exemption +for integration with non‑free software components, +on the basis that it is distributed, by Microsoft, +as a standard Windows operating system component. +

+

In addition to MSVCRT.DLL, +Microsoft also distribute various alternative ‘C’ runtime libraries, +as components of their “Visual Studio”, or “Visual C” +software development suites. +Bearing names such as +MSVCR70.DLL..MSVCR120.DLL, +these are not  distributed as standard components +of the Windows operating system; +thus, they do not  qualify for the GPL linking exemption, +and MinGW.OSDN is not  licensed to distribute them. +

+

Notwithstanding the foregoing licensing restrictions on their use, +the non‑free Microsoft ‘C’ runtime libraries +do  introduce a small number of functions, +which Microsoft have never incorporated into +MSVCRT.DLL; +consequently, there may be occasions when users will +wish to link their MinGW applications with one of these +non‑free ‘C’ runtime libraries. +While MinGW.OSDN is not licensed to distribute these +‘C’ runtime libraries, +in DLL form, +we can,  and do,  +distribute import libraries  which map their entry points, +(at least for MSVCR70.DLL..MSVCR100.DLL), +so that any users who are prepared to handle the licensing implications, +and the provisioning of the DLLs for themselves, +may link their MinGW applications with these libraries, +if they so wish. +

+

Some users may assume, naïvely, +that linking with, for example MSVCR80.DLL, would be +as simple as adding the -lmsvcr80 library specification +to the gcc command line; +unfortunately, it is not  as simple as this! +The problem with this naïve approach is twofold:– +

    +
  1. When linking with -lmsvcr80, +it is also necessary  to link with -lmoldname80; +while it may appear that this would be as simple as +also adding -lmoldname80, +this is also the wrong way to accomplish the objective! +
  2. +
  3. The fundamental reason why it is wrong  to simply add +-lmoldname80 -lmsvcr80 +to the gcc command line +is that the default GCC ‘specs’ strings already add  +-lmoldname -lmsvcrt +to the effectivegcc command. +Thus, by also  adding +-lmoldname80 -lmsvcr80, +we are asking the linker to search both  +libmoldname80.a andlibmoldname.a, +to resolve OLDNAME symbols, +and ultimately bothlibmsvcr80.a +andlibmsvcrt.a, +to resolve ‘C’ runtime DLL references. +This introduces potential for the linked application to depend on +bothMSVCR80.DLL +andMSVCRT.DLL, +which is definitively unsupported ; +at best, you may  be lucky, and get away with it; +more likely, your application will be unstable, +and may crash and burn at run time, +with unpredictable side effects. +
+

Thus, we should not simply specify -lmsvcr80, +(either free‑standing, or accompanied by -lmoldname80), +to the gcc command line, when our intent is to link with +MSVCR80.DLL, in preference to MSVCRT.DLL. +(Nor, following similar reasoning, should we attempt to substitute +any of Microsoft’s other non‑free ‘C’ +runtime DLLs, in this manner). +Rather, we must  modify the GCC ‘specs’ strings, +such that all  existing references to -lmsvcrt, +and to -lmoldname, are replaced  by +-lmsvcr80 and -lmoldname80, respectively, +(or whatever alternative references are appropriate, +for the intended substitute ‘C’ runtime DLL). +Below, we will explore some methods for achieving this objective. +

+

Identifying the Required ‘specs’ String Modifications

+

As we’ve seen above, +when we wish to link with any of Microsoft’s non‑free +‘C’ runtime libraries, +we really  ought to modify the GCC ‘specs’ strings, +to avoid any conflicting application dependencies on both  +MSVCRT.DLL, +and the chosen non‑free DLL. +The default libraries specification, +for linking with MSVCRT.DLL, +is -lmoldname -lmsvcrt; +for linking with any of the non‑free ‘C’ runtime DLLs, +this couplet must  be replaced, +in any ‘specs’ string which includes it, +by an alternative couplet selected from the following table:– +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
To UsePreprocessor IdentificationLink With LibrariesRemarks
MSVCRT.DLL-lmoldname -lmsvcrtMinGW default; + no preprocessor identification or ‘specs’ changes required +
MSVCR70.DLL-D__MSVCRT_VERSION__=0x0700-lmoldname70 -lmsvcr70
MSVCR71.DLL-D__MSVCRT_VERSION__=0x0710-lmoldname71 -lmsvcr71
MSVCR80.DLL-D__MSVCRT_VERSION__=0x0800-lmoldname80 -lmsvcr80
MSVCR90.DLL-D__MSVCRT_VERSION__=0x0900-lmoldname90 -lmsvcr90
MSVCR100.DLL-D__MSVCRT_VERSION__=0x1000-lmoldname100 -lmsvcr100
MSVCR110.DLL-D__MSVCRT_VERSION__=0x1100-lmoldname110 -lmsvcr110
MSVCR120.DLL-D__MSVCRT_VERSION__=0x1200-lmoldname120 -lmsvcr120
+

Note that, +in addition to the alternative libraries couplet, +the foregoing table also specifies a “preprocessor +identification ”, +for all but the default MSVCRT.DLL case. +This should be added to the +cpp ‘specs’ string, +as applicable, +to ensure that definitions associated with the selected non‑free +runtime library are made visible, +when the compiler parses the appropriate ‘C’ header files. +

+

A Simplistic Approach to Implementing the ‘specs’ Strings Modifications

+

A simple, +although rather naïve, +method of implementing the necessary ‘specs’ string modifications, +might be to create a separate copy of the ‘specs’ file, +specific to each non‑free runtime DLL +which we wish to support. +For example, +to support linking with MSVCR80.DLL, +we might create a copy of an existing external ‘specs’ file, +(in the appropriate ‘specs’ file directory), +naming the copy as msvcr80, +(or, if we don’t have an external ‘specs’ file, +use the gcc -dumpspecs command to create msvcr80, +as described under the heading “Preparing the GCC +‘specs’ for Customization”, above). +

+

Once we have created a copy of the ‘specs’ file, +(which we’ve called msvcr80, in our example case), +we may edit it, to implement the required customizations. +First, we should locate the cpp string definition ... +it should look something like this: +

+
+*cpp:
+%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{pthread:-D_REENTRANT} %{!no-pthread: }
+
+
+

or, if we’ve already added an additional include file search path: +

+
+*cpp:
+%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{pthread:-D_REENTRANT} %{!no-pthread: }
+%(local_includes)
+
+
+

to which we must add +the appropriate preprocessor identification,  string, +selected from the table above, +(which, in the MSVCR80.DLL case, +is -D__MSVCRT_VERSION__=0x0800). +Thus, the modified definition becomes: +

+
+*cpp:
+%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{pthread:-D_REENTRANT} %{!no-pthread: }
+-D__MSVCRT_VERSION__=0x0800
+
+
+

or:

+
+*cpp:
+%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{pthread:-D_REENTRANT} %{!no-pthread: }
+%(local_includes) -D__MSVCRT_VERSION__=0x0800
+
+
+

Second, +we must locate all occurrences of -lmsvcrt, +and of -lmoldname, +and replace each with the corresponding equivalents from the table above, +(i.e. -lmsvcr80 +and -lmoldname80, respectively, +in the case of the MSVCR80.DLL example). +Typically, each will appear just once, +with both in the libgcc string definition, +which initially, should look something like: +

+
+*libgcc:
+%{mthreads:-lmingwthrd} -lmingw32 -lmingwex -lmingw32 -lmingwex
+%{static|static-libgcc:-lgcc -lgcc_eh} %{!static:%{!static-libgcc:%{!shared:%{!shared-libgcc:-lgcc -lgcc_eh}
+%{shared-libgcc:-lgcc_s -lgcc}} %{shared:-lgcc_s -lgcc}}} -lmoldname -lmsvcrt
+
+
+

and, after modification, should look like this: +

+
+*libgcc:
+%{mthreads:-lmingwthrd} -lmingw32 -lmingwex -lmingw32 -lmingwex
+%{static|static-libgcc:-lgcc -lgcc_eh} %{!static:%{!static-libgcc:%{!shared:%{!shared-libgcc:-lgcc -lgcc_eh}
+%{shared-libgcc:-lgcc_s -lgcc}} %{shared:-lgcc_s -lgcc}}} -lmoldname80 -lmsvcr80
+
+
+

Finally, +while these two modifications are sufficient for gcc, +they will not  pass the correct __MSVCRT_VERSION__ +definition for compilation with g++; +to correct this deficiency, +we must also modify the cc1plus ‘specs’ string, +(which, unless we've already added anything to it, +appears to be initially empty, by default), so we define it as: +

+*cc1plus:
+-D__MSVCRT_VERSION__=0x0800
+
+
+

or, if we had already added, e.g. an additional include files search path: +

+
+*cc1plus:
+%(local_includes) -D__MSVCRT_VERSION__=0x0800
+
+
+

+With all three of the above modifications in place, +in the msvcr80 ‘specs’ file, +we may invoke gcc, (or g++), like this: +

+
+$ gcc -specs=msvcr80 foo.c -o foo.exe
+
+

to compile, and link foo.exe with MSVCR80.DLL, +without  incurring any dependency on MSVCRT.DLL. +However, the naïve simplicity of this ‘specs’ strings +modification technique does  make it sub‑optimal, +and may create potential problems; +in the following section, +we will discuss possible improvements to this simple modification technique. +

+

Improving on the Simplistic ‘specs’ Strings Modification Technique

+

The simplistic ‘specs’ strings modification technique, +as described in the preceding section, +for supporting the use of Microsoft’s non‑free +‘C’ runtime DLLs, +exhibits the following potential disadvantages:– +

+

To some extent, +these disadvantages may be mitigated by elimination of +all  unmodified ‘specs’ strings from +each of the auxiliary ‘specs’ files, +leaving the entire  content of, +for example, the msvcr80 ‘specs’ file, +(incorporating the additional include file search path modification), +as exactly : +

+
+*cpp:
+%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{pthread:-D_REENTRANT} %{!no-pthread: }
+%(local_includes) -D__MSVCRT_VERSION__=0x0800
+
+*cc1plus:
+%(local_includes) -D__MSVCRT_VERSION__=0x0800
+
+*libgcc:
+%{mthreads:-lmingwthrd} -lmingw32 -lmingwex -lmingw32 -lmingwex
+%{static|static-libgcc:-lgcc -lgcc_eh} %{!static:%{!static-libgcc:%{!shared:%{!shared-libgcc:-lgcc -lgcc_eh}
+%{shared-libgcc:-lgcc_s -lgcc}} %{shared:-lgcc_s -lgcc}}} -lmoldname80 -lmsvcr80
+
+
+

(and similarly, for other auxiliary ‘specs’ files +relating to other non‑free ‘C’ runtime DLLs). +

+

This is better, +but it still leaves a significant degree of redundancy, +in the three definitions which do  need to be modified. +A simple way to remove some of this redundancy, +without  requiring any pyhsical change to +the originating definition, +as it appears in the built‑in ‘specs‘, +is by reformulating the amended cpp +and cc1plus definitions as: +

+
+*cpp:
++ -D__MSVCRT_VERSION__=0x0800
+
+*cc1plus:
++ -D__MSVCRT_VERSION__=0x0800
+
+
+

but, unfortunately, +we cannot adopt a similar adjustment to remove the redundancy +in the modified libgcc definition. +

+

If we do wish to eliminate the redundancies entirely,  +then we must  modify the libgcc ‘specs’ +string at its point of origin; +this implies that we must  use an external  +specs file, +in which we can make the necessary modification. +Thus, if we don't already have an external ‘specs’ file, +we should follow the procedure described above, +under the heading “Preparing the GCC +‘specs’ for Customization”, +to create one now. +

+

Once we have set up an external ‘specs’ file, +such that gcc, and g++, will read it +instead of using their built‑in ‘specs’, +we may edit it, +splitting the original libgcc definition +into a modified libgcc, +and a supplementary libmsvcrt definition, thus: +

+
+*libgcc:
+%{mthreads:-lmingwthrd} -lmingw32 -lmingwex -lmingw32 -lmingwex
+%{static|static-libgcc:-lgcc -lgcc_eh} %{!static:%{!static-libgcc:%{!shared:%{!shared-libgcc:-lgcc -lgcc_eh}
+%{shared-libgcc:-lgcc_s -lgcc}} %{shared:-lgcc_s -lgcc}}} %(libmsvcrt)
+
+*libmsvcrt:
+-lmoldname -lmsvcrt
+
+
+

(noting the use of parentheses  in the +%(libmsvcrt) substitution field, +whereas braces are used elsewhere, +throughout the libgcc definition). +

+

Now, +with that single modification in place, +within the external specs file, +the supplementary msvcr80 ‘specs’ file +may be condensed, to nothing more than: +

+
+*cpp:
++ -D__MSVCRT_VERSION__=0x0800
+
+*cc1plus:
++ -D__MSVCRT_VERSION__=0x0800
+
+*libmsvcrt:
+-lmoldname80 -lmsvcr80
+
+
+

and Microsoft’s other non‑free ‘C’ runtime DLLs +may be similarly supported, +with suitably named copies of this supplementary ‘specs’ file, +each with appropriate changes to the __MSVCRT_VERSION__ assignment, +and the import libraries named in the libmsvcrt definition. +

+
+ +

Consolidating Support for Non‑Free Runtime Libraries

+

In the preceding section, +we began with a naïve collection of supplementary ‘specs’ files, +each of which was a mostly redundant copy of GCC’s built‑in +‘specs’, and each incorporating a minimal set of modifications, +specific to supporting one  particular version of +Microsoft’s non‑free ‘C’ runtime DLLs. +We observed that the redundancy in this naïvely constructed collection +of ‘specs’ files created an undesirable maintenance burden, +and we further developed the concept to eliminate the redundancy. +In the process, +we significantly reduced the size of each ‘specs’ file, +while introducing a trivial dependency on a minimally‑modified +(non‑redundant) external specs file. +

+

In this section, +we will develop this concept further, +with a view to consolidating the entire collection of separate +‘specs’ files into the fewest practicable number, +while retaining the capability to arbitrarily select any one +of Microsoft’s non‑free ‘C’ runtime DLLs, +with which to link any application. +

+

Ideally, +we would like to consolidate all of the necessary ‘specs’ +string modifications into a single, +implicitly  loaded external specs file, +and to use a command line option to specify the particular +version of the ‘C’ runtime library, +with which the application should be linked. +Unfortunately, +of all the predefined option keywords which gcc will accept, +only the -lfoo class, +(which, strictly speaking, aren’t really options anyway), +seem suitable for alternative runtime library selection, +and these do not appear to participate in conditional +‘specs’ string processing. +Thus, +we will require custom option keywords, +which gcc will accept only  if invoked +with an explicitly  loaded external ‘specs’ file, +so we will be unable to realize our ideal objective; +the best we are likely to achieve will be one  small, +explicitly  loaded external ‘specs’ file, +to enable the use of custom options, +(and to handle at least some of their interpretation), +in conjunction with an implicitly loaded external specs file, +modified as in the preceding section, to avoid redundancy. +

+

As it happens, +the latter best practicable objective is entirely achievable. +If we keep the external specs file exactly  +in the state as we developed it in the preceding section, but, +instead of the collection of supplementary ‘specs’ files, +(one for each non‑free runtime DLL), +we create just one,  +(let’s call it opt), +with content: +

+
+*cpp:
++ %{msvcr*:-D__MSVCRT_VERSION__=0x0%*0}%<msvcr*
+
+*cc1plus:
++ %{msvcr*:-D__MSVCRT_VERSION__=0x0%*0}%<msvcr*
+
+*libmsvcrt:
+-lmoldname%{msvcr*:%* -lmsvcr%*}%{!msvcr*: -lmsvcrt}
+
+
+

then we may link our applications with any  +of Microsoft’s non‑free ‘C’ runtime DLLs, +simply by invoking gcc, (or g++), like this: +

+
+$ gcc -specs=opt -msvcr<N> foo.c -o foo.exe
+
+

(where “<N> represents the numeric identifier, +within the runtime DLL name); +thus, for example: +

+
+$ gcc -specs=opt -msvcr80 foo.c -o foo.exe
+
+

would result in foo.exe being +linked with MSVCR80.DLL, while: +

+
+$ gcc -specs=opt -msvcr120 foo.c -o foo.exe
+
+

would result in linking with MSVCR120.DLL, +and the system will automatically adapt, +to accommodate linking with any other numerically identified runtime DLL, +which may be available, (or may become available in the future), +without  requiring a separate ‘specs’ file +for each distinct DLL. +

+
+
+ + -- 2.11.0