From: Keith Marshall Date: Fri, 31 Dec 2021 19:39:45 +0000 (+0000) Subject: Publish GCC include file search path HOWTO. X-Git-Url: http://git.osdn.net/view?p=mingw%2Fwebsite.git;a=commitdiff_plain;h=515a8fd24c1a098a8aaa9386e81d11bf1013f238 Publish GCC include file search path HOWTO. * isystem.html: New file; adapted from original Drupal content, this describes the GCC include file search mechanism, and offers advice on installation of third party header files, to take best advantage of this search mechanism. --- diff --git a/isystem.html b/isystem.html new file mode 100644 index 0000000..771d563 --- /dev/null +++ b/isystem.html @@ -0,0 +1,542 @@ + + + +
+

Introduction

+

This Mini‑HOWTO answers the question: +“Why can’t the MinGW compilers find +my project’s header files?” +

+

Prior to the publication of the GCC‑7 documentation, +(when the wording changed, to provide only a brief outline of +the identification method described below), +the CPP Section +of the GCC Manual +indicated that header files may be located in +the following directories:– +

+
+

On a normal Unix system, if you do not instruct it otherwise, +[GCC] will look for headers requested with +#include <file> in: +

+     /usr/local/include
+     libdir/gcc/target/version/include
+     /usr/target/include
+     /usr/include
+
+

For C++ programs, +it will also look in /usr/include/g++-v3, first. +

+

Of course, the +MinGW ports of GCC +target Microsoft’s Windows system, +which is not +a “normal UNIX system”. +Nevertheless, many users, +particularly those coming from a UNIX or GNU/Linux background, +and especially when they use MSYS to emulate a UNIX file system model +on their MS‑Windows hosts, +are surprised to find that MinGW, +using its default configuration, +does not automatically +search for header files in these directories. +

+
+ +
+

Other Directories Searched by Default

+

The minimal list of directories, +identified as described above, +specifies the only locations +which will be searched by default, +for system header files, +or for headers associated with user installed libraries; +however, there is one exception. +Astute readers may have noticed that +the include file search path is itemised in a pair of sequential lists, +with the second being concatenated to the first; however, the first, +identified as the +#include "..." search +list appears to be empty. +In reality, this apparent emptiness may be misleading; +unless the user specifies the ‘-I-’ option +when invoking GCC, this list contains exactly one directory: +the directory in which the source file containing the +#include "file" directive resides. +

+

Notice that this one additional directory +is not searched for headers specified +with the #include <file> form of +the #include directive; +it applies only for those headers specified using +the #include "file" form of the directive. +Also note that the location of this additional directory is not fixed; +it is dependent on the location of the source file being compiled, +and, while unique for each individual source file, +it may vary even within the compilation scope for any project, +and even within the scope of a single translation unit, +if multiple source files are distributed among different directories +in the project’s source hierarchy. +

+

To clarify this point, +let us consider a trivial example. +Suppose that we have a small project, +which provides all of it’s sources in a single directory; +among them we might have:– +

+
+~/src
+   :
+   :--- bar.h
+   :
+   :--- foo.c
+   :--- foo.h
+   :
+
+

Further suppose that the file, foo.c, +includes the project‑local header, foo.h:– +

+
+/* foo.c
+ */
+ :
+#include "foo.h"
+ :
+
+

and that foo.h, in turn, +includes bar.h:– +

+
+/* foo.h
+ */
+ :
+#include "bar.h"
+ :
+
+

With this arrangement, +we may create a build directory which is a sibling of src, +and with that as current directory, +we may compile foo.c:– +

+
+$ mkdir ~/build
+$ cd ~/build
+$ gcc -c ../src/foo.c
+$
+
+

and we might have every expectation that it will compile correctly; +it certainly should have no problem finding the pair of header files, +foo.h and bar.h. +

+

Now, suppose that the project grows +to such a size that we decide to separate our headers +into a subdirectory of src:– +

+
+~/src
+   :
+   :--- foo.c
+   :
+   :--- hdr
+   :     :
+   :     :--- bar.h
+   :     :--- foo.h
+   :     :
+
+

After making this rearrangement, +if we again try to compile foo.c, +we will likely see errors resulting from the failure +to locate the header file foo.h:– +

+
+$ gcc -c ../src/foo.c
+../src/foo.c:3:17: foo.h: No such file or directory
+ :
+$
+
+

To correct this, we must also modify foo.c, +to reflect the relocation of the header files:– +

+
+/* foo.c
+ */
+ :
+#include "hdr/foo.h"
+ :
+
+

and this should be sufficient to again let us compile +foo.c successfully:– +

+
+$ gcc -c ../src/foo.c
+$
+
+

Note here, +that we did not make any corresponding change +in bar.h; that would have been wrong! +The rule is that, in any #include directive of the form:– +

+
#include "path/file"
+

path must be a relative path, +and it must be relative to the directory in which the file containing +the pertinent #include directive is itself located. +In our example, +since foo.h and bar.h are still +in the same directory, +searches for files included by either will commence in that same directory. +If we had changed foo.h, +in a manner similar to the change we made in foo.c, +then foo.h would have attempted +to #include the file ~/src/hdr/hdr/bar.h, +instead of the intended ~/src/hdr/bar.h. +

+
+
+

Including Headers from Directories which are Not Searched by Default

+

While the default header search paths may suffice +for many simple projects, +as project complexity grows, +it will often become more convenient to collect header files into +a central directory which is not in +the default search path; +this is particularly true of projects which provide, +and possibly install, +one or more function libraries, +either exclusively for their own use, +or maybe even for general use by other projects. +In such cases, +GCC must be explicitly notified, +by specifying appropriate command line options, +to identify the additional directories in which to search. +

+

The relevant sections of +the GCC Manual, +and its associated C preprocessor manual, +document several options, +which may be used to specify directories to search for header files; +of these, +the most widely used is the +-I dir option. +As an example of its use, let us reconsider the previous example, +with the project source files organised within the hierarchy:– +

+
+~/src
+   :
+   :--- foo.c
+   :
+   :--- hdr
+   :     :
+   :     :--- bar.h
+   :     :--- foo.h
+   :     :
+
+

but this time, +we will not adapt foo.c +to locate foo.h using the default include file search path:– +

+
+/* foo.c
+ */
+ :
+#include "foo.h"
+ :
+
+

As we saw previously, +if we try to compile this unmodified foo.c, +without explicitly specifying any header search path, +the compilation will fail:– +

+
+$ gcc -c ../src/foo.c
+../src/foo.c:3:17: foo.h: No such file or directory
+ :
+$
+
+

Previously, +we corrected this failure by modifying foo.c, +to bring foo.h into the +default #include "..." search path. +This time, we will correct it, not by modifying foo.c, +but by explicitly adding our project’s +local hdr directory to the search path, +when we invoke GCC to compile foo.c:– +

+
+$ gcc -I ../src/hdr -c ../src/foo.c
+$
+
+

which, we may observe, again results in successful compilation. +

+
+
+

Using Headers Provided with Locally Installed External Libraries

+

Many projects have dependencies on external libraries, +which are not provided by a standard MinGW installation. +Users who wish to build the applications provided by such projects +must first install the appropriate prerequisite libraries. +Such libraries are referred to as +“locally installed libraries”, +and they must be installed such that MinGW’s GCC can readily +locate both the libraries themselves, +and any header files installed as prerequisites +for specifying the interface to the library functions. +

+

The installation of +such external libraries may be viewed as a challenge, +for some users. +Typically, +and particularly in the case of library packages +originally developed for Unix‑like platforms, +such libraries would be installed into +the /usr/local/... directory hierarchy. +However, as we have seen above, +MinGW’s GCC +does not consider any such hierarchy in its default search paths, +either for header files, or for libraries. +Thus, the challenge is to choose an installation strategy +which achieves a satisfactory compromise between:– +

+
    +
  1. Installing directly into MinGW’s own standard + <mingw-root>/include + and <mingw-root>/lib directory hierarchies; + this offers the advantage that the libraries, + and their associated header files, + are placed directly into MinGW‑GCC’s default search paths, + so there is no additional burden placed on the user, + to add additional -I dir options, + throughout the build systems of any project using an external library. + However, while perhaps being the simplest option, + this strategy is not without its disadvantages:– +
      +
    • The external library components are intermingled, + within the file system hierarchy, + with MinGW’s own standard components; + it may not be straightforward to segregate them later, + should this ever be necessary. +
    • +
    • Should the user wish to maintain side‑by‑side + MinGW installations, at differing release point versions, say, + then the external library installations will need to be duplicated, + within each of the separate MinGW installation hierarchies. +
    • +
    • If the MinGW installation hierarchy is purged, + in preparation for a clean re‑installation, + then any locally installed external libraries will also be purged, + and if subsequently needed, will have to be reinstalled. +
    • +
    +
  2. Creating a separate directory hierarchy, + into which all external library packages are installed; + this mitigates the disadvantages of option (1), + but introduces its own drawbacks:– +
      +
    • The header files and libraries are no longer in + MinGW GCC’s default search paths; + thus the user must make provision + to pass the appropriate -I dir, + (and associated -L dir), + options to GCC, through his own projects’ build systems. + (This may be mitigated, in turn, by customising the + GCC Specs File, + to supply the necessary options automatically, + for all invocations of GCC, + or by appropriately defining GCC’s + CPATH and related environment variables). +
    • +
    • Although now segregated from the MinGW standard library + and header components, all external library packages are still intermixed, + one with another, in a common installation hierarchy; nonetheless, + this is often considered to be an acceptable compromise. +
    • +
  3. +
  4. As a variation on option (2), + create a separate directory hierarchy, + for each and every individual external library package + to be locally installed; + this mitigates all of the disadvantages of option (1), + and the package intermixing of option (2), + but it incurs an alternative penalty:– +
      +
    • As with option (2), + appropriate -I dir + and -L dir options + must be added to each GCC invocation; however, + whereas option (2) requires only one additional path of each type, + this option requires an additional one of each type, + for each and every external library to be deployed. + (While this may still be achieved by appropriate customisation of the + GCC Specs File, + or by appropriately specifying the + CPATH and related environment variables, + the additional complexity, and maintenance overhead, + may be considered unacceptable to many users). +
    • +
    +
+
+ +