FIXME: Page under construction; mostly complete now, but may need some clarifications.
I will add to this as time permits; please bear with me. My intent is to provide answers to some remarkably similar, but independently asked, questions which have appeared recently, on the MinGW-Users and MinGW-MSYS lists.
This Mini-HOWTO attempts to answer the FAQ: "Why can't the MinGW compilers find my project's header files?"
The CPP Section of the GCC Manual indicates 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/includeFor 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.
So, if MinGW doesn't search in these "normal" directories, where does it search?
Before answering this, it may be useful to understand why MinGW doesn't search in these directories. Firstly, on a native MS-Windows host, these directories do not typically exist; the multiply rooted nature of the file system means that such path names would be ambiguous. Secondly, since MinGW itself is not a suite of MSYS applications, even if such directories are created in the MSYS environment, MinGW would have no means to locate them.
Thus, to avoid imposing draconian restrictions on how users install MinGW, the maintainers have chosen to adopt a restricted search paradigm, which is determined on the basis of where MinGW is itself installed. The actual search path, for any specific installation of MinGW may be determined, by running the compiler itself, with the "-v" option; typically, for a GCC-3.4.5 installation in c:/mingw:--
$ touch foo.c bar.cpp$ gcc -v -c foo.c:#include "..." search starts here:#include <...> search starts here: c:/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include c:/mingw/bin/../lib/gcc/mingw32/3.4.5/includeEnd of search list.:$ g++ -v -c bar.cpp:#include "..." search starts here:#include <...> search starts here: c:/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5 c:/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/mingw32 c:/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/backward c:/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include c:/mingw/bin/../lib/gcc/mingw32/3.4.5/includeEnd of search list.:
This raw format output, as displayed by the compilers, may be difficult for human readers to interpret. Thus, it may be helpful to reduce it to canonical path forms:--
$ gcc -v -c foo.c 2>&1 | sed ':1;s,/[^/.][^/]*/\.\./,/,;t 1':#include "..." search starts here:#include <...> search starts here: c:/mingw/include c:/mingw/lib/gcc/mingw32/3.4.5/includeEnd of search list.:$ g++ -v -c bar.cpp 2>&1 | sed ':1;s,/[^/.][^/]*/\.\./,/,;t 1':#include "..." search starts here:#include <...> search starts here: c:/mingw/include/c++/3.4.5 c:/mingw/include/c++/3.4.5/mingw32 c:/mingw/include/c++/3.4.5/backward c:/mingw/include c:/mingw/lib/gcc/mingw32/3.4.5/includeEnd of search list.:
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 is possibly 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 "foo.c" #includes "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".
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 GCC Manual documents 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.
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:--
联系客服