Tricks to overcome the search-order issue

  • tta

    tta - 2010-03-29


    $ROOT = root directory of MinGW installation, say C:/MinGW or /usr/local/mingw
    $HOST = host platform, e.g i686-w64-mingw32
    $PATHSEP = path separator
    For native compiler, $PATHSEP = ; (semicolon)
    For cross compiler, $PATHSEP = : (colon)
    $GCCVER = GCC version, e.g 4.4.1-1a

    By default, the following directories are searched (in order of priority):

    - $ROOT/$HOST/include/c++/$GCCVER (C++ only)
    - $ROOT/$HOST/include/c++/$GCCVER/$HOST (C++ only)
    - $ROOT/$HOST/include/c++/$GCCVER/backward (C++ only)
    - $ROOT/lib/gcc/$HOST/$GCCVER/include
    - $ROOT/lib/gcc/$HOST/$GCCVER/include-fixed
    - $ROOT/$HOST/include

    However, this order is incorrect. The correct one must be:

    - $ROOT/$HOST/include/c++/$GCCVER (C++ only)
    - $ROOT/$HOST/include/c++/$GCCVER/$HOST (C++ only)
    - $ROOT/$HOST/include/c++/$GCCVER/backward (C++ only)
    - $ROOT/$HOST/include
    - $ROOT/lib/gcc/$HOST/$GCCVER/include
    - $ROOT/lib/gcc/$HOST/$GCCVER/include-fixed

    To fix this, as a user, you have two choice:

    1. Using "-isystem" option

    This means you need to add "-isystem $ROOT/$HOST/include" to compiler
    command line, or invoke configure script like this:

    ./configure -enable-foo -disable-bar CPPFLAGS="-isystem $ROOT/$HOST/include"

    2. Using "-nostdinc" with CPATH environment variable. This requires two steps:

    First, set CPATH to correct value:


    Second, add "-nostdinc" to compiler command line, or invoke configure script
    like this:

    ./configure -enable-foo -disable-bar CPPFLAGS="-nostdinc"

    Compare to the first approach, the second is a bit more annoying, but it has a
    benefit: it allows you to reinstall MinGW to different location without
    the need of updating all your makefiles, or project files.

    Unfortunately, it also has a drawback: you have to reset CPATH whenever you
    switch to other version of GCC, e.g back to the native compiler (Linux GCC) from
    the cross one (MinGW GCC).

    If you use a 3rd party build system, please read its documentation
    to know how to add extra compiler flags to compiler command line.

    For examples:

    1. Boost.Jam with Boost.Build

    - Invoke bjam with compileflags option: bjam compileflags=-nostdinc, or
    bjam compileflags="-isystem $ROOT/$HOST/include"


    - Add this to user-config.jam:

    # toolset name : version : invocation-command : compiler-options ;
    # 32-bit compiler
    using gcc : 4.5.0 : i686-w64-mingw32-g++ : <compileflags>-nostdinc ;
    # 64-bit compiler
    using gcc : 4.4.1-1a : x86_64-w64-mingw32-g++ : <compileflags>-nostdinc ;

    2. Qt's qmake with qmake-based build system

    Append this line to the appropriate qmake.conf:

    QMAKE_CFLAGS+=-nostdinc (or "-isystem,$ROOT/$HOST/include")

    HTH and have fun!

  • Jonathan Yong

    Jonathan Yong - 2010-03-29

    Searching $ROOT/$HOST/include before $ROOT/lib/gcc/$HOST/$GCCVER/include-fixed and $ROOT/lib/gcc/$HOST/$GCCVER/include is just plain wrong.

    How else would "fixed" headers be used? This is an issue with gcc fixinclude, it needs to be fixed.

  • Doug Semler

    Doug Semler - 2010-03-29

    I'm still not sure the problem is in fixincludes per se, since fixincludes is intended to repair broken system headers (which, as far as I can tell, w64-mingw's headers are not broken).  I believe the problem is more in gcc target Makefile fragment that doesn't override USER_H to remove the gcc provided ginclude headers that conflict with mingw-w64 (which right now, for mingw-w64, blindly assumes that all the files are needed).

    In other words, maybe gcc's config/i386/t-mingw-w64 fragment should define USER_H without the float.h, stdarg.h, varargs.h, stddef.h files?  Mingw's are sufficient, correct?

    Note I am not sure what needs to be done on the intrinsics side, isn't there an issue there as well?

  • Ozkan Sezer

    Ozkan Sezer - 2010-03-29

    A change regarding USER_H was actually suggested to gcc fairly recently:
    .. but it got forgotten, and the admins have some concerns about maintaining
    duplicated files. I still bleieve that it is a good solution, though.

  • Doug Semler

    Doug Semler - 2010-03-29

    Yeah, there is a slight maintenance issue:  changes to the default USER_H would need to be monitored, in addition to changes to any of the includes in the gcc/ginclude directory to ensure that they are compatible with the mingw headers…

    You need a way of preventing the install of these files anyway, because currently gcc installs those files blindly into the include directory, and even if you were to use fixincludes to fix the includes -- the "fixed" files ended up in the include-fixed directory, gcc would grab the wrong one because gcc searches include prior to include-fixed (note: I *THINK* that is the case)

    The only other real way of doing it would be similar to the "glue" in the Makefile and configury that does the fixups for stdint.h.  But that is really, really messy, and seems silly to me when there seems to be a perfectly workable solution with overriding USER_H…

  • tta

    tta - 2010-03-31

    As tpaxatb said, MinGW ISO C headers are not broken, i.e they fully conform with
    ANSI C / ISO C, so they should be preferred over GCC ones. We can either
    remove/rename GCC headers or put MinGW directory before GCC directory.

    Of course, it is a GCC bug and needs to be fixed on GCC side, but anyway this
    trick allows users to overcome the issue with ISO C headers regardless of
    whether it will be fixed or not. And if they want to get back to the default
    search order, all that they needs to do is removing "-nostdinc" (or "-isystem").
    They do not have to intefere with GCC source code and/or its configure
    script to rebuild GCC at all. It's very simple and easy.

    AFAIK, users do not face this problem, since GCC always
    searchs MinGW directory before GCC directory (I guess guys did realize
    the issue, too). BTW, here is the default search list of compiler:

    $ROOT/include (MinGW include path - equivalent to MinGW64's $ROOT/$HOST/include)
    $ROOT/lib/gcc/$HOST/$GCCVER/include (GCC include path)
    $ROOT/lib/gcc/$HOST/$GCCVER/include-fixed (ignore fixed headers)


    Note I am not sure what needs to be done on the intrinsics side, isn't there an issue there as well?

    Speaking of GCC *intrin.h headers, they are just OK IMO. And all bugs are
    on MINGW64 side, not GCC side I think.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks