Header Search Paths with MinGW

Hi,

I found a problem and I am writing to propose a solution, I would like to know what you think.
I am working on Win32 with MinGW (GCC 4.4)

I quote an extract of the InitHeaderSearch class ( /tools/clang/lib/Frontend/InitHeaderSearch.cpp )

//----------------------------------------------------------------------------------------------------

void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(llvm::StringRef Base,
llvm::StringRef Arch,
llvm::StringRef Version) {

AddPath(Base + “/” + Arch + “/” + Version + “/include”,
System, true, false, false);
AddPath(Base + “/” + Arch + “/” + Version + “/include/c++”,
System, true, false, false);
AddPath(Base + “/” + Arch + “/” + Version + “/include/c++/backward”,
System, true, false, false);
}

void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple) {
//…
case llvm::Triple::MinGW64:
// Try gcc 4.4.0
AddMinGWCPlusPlusIncludePaths(“c:/MinGW/lib/gcc”, “mingw64”, “4.4.0”);
// Try gcc 4.3.0
AddMinGWCPlusPlusIncludePaths(“c:/MinGW/lib/gcc”, “mingw64”, “4.3.0”);
// Fall through.
case llvm::Triple::MinGW32:
// Try gcc 4.4.0
AddMinGWCPlusPlusIncludePaths(“c:/MinGW/lib/gcc”, “mingw32”, “4.4.0”);
// Try gcc 4.3.0
AddMinGWCPlusPlusIncludePaths(“c:/MinGW/lib/gcc”, “mingw32”, “4.3.0”);
break;
//…
}

//----------------------------------------------------------------------------------------------------

For example, in this line …

AddMinGWCPlusPlusIncludePaths(“c:/MinGW/lib/gcc”, “mingw32”, “4.4.0”);

… “mingw32” corresponds to the parameter “Arch” of function “AddMinGWCPlusPlusIncludePaths”. It is harcoded!

In GCC, if I want to know what is the Header Seach Path, I can run …

g++ -v -c xxx.cpp


#include “…” search starts here:
#include <…> search starts here:
c:\mingw\bin…/lib/gcc/mingw32/4.4.0/include/c++
c:\mingw\bin…/lib/gcc/mingw32/4.4.0/include/c++/mingw32
c:\mingw\bin…/lib/gcc/mingw32/4.4.0/include/c++/backward
c:\mingw\bin…/lib/gcc/mingw32/4.4.0/…/…/…/…/include
c:\mingw\bin…/lib/gcc/mingw32/4.4.0/include
c:\mingw\bin…/lib/gcc/mingw32/4.4.0/include-fixed
c:\mingw\bin…/lib/gcc/mingw32/4.4.0/…/…/…/…/mingw32/include
End of search list.

I tried another implementation of MinGW (GCC 4.6) in which I got X.

c:\mingw\bin…/lib/gcc/i686-pc-mingw32/4.6.0/include/c++
c:\mingw\bin…/lib/gcc/i686-pc-mingw32/4.6.0/include/c++/i686-pc-mingw32
c:\mingw\bin…/lib/gcc/i686-pc-mingw32/4.6.0/include/c++/backward
c:\mingw\bin…/lib/gcc/i686-pc-mingw32/4.6.0/…/…/…/…/include
c:\mingw\bin…/lib/gcc/i686-pc-mingw32/4.6.0/include
c:\mingw\bin…/lib/gcc/i686-pc-mingw32/4.6.0/include-fixed
c:\mingw\bin…/lib/gcc/i686-pc-mingw32/4.6.0/…/…/…/…/i686-pc-mingw32/include

The problem is in the “Arch” parameter, in one implementation I have “mingw32” and in the other “i686-pc-mingw32”

How I can know which parameter to use?

The answer is…

g++ -dumpmachine
mingw32

or in the second MinGW implementation…

g++ -dumpmachine
i686-pc-mingw32

To fix this, I propose to add a new preprocessor #define on “config.h” and “llvm-config.h”, like the following…

#define LLVM_MINGW_DUMPMACHINE “mingw32”

LLVM_MINGW_DUMPMACHINE is fed in the CMake configuration phase, and can be used in the InitHeaderSearch class as follows…

AddMinGWCPlusPlusIncludePaths(“c:/MinGW/lib/gcc”, llvm::StringRef(LLVM_MINGW_DUMPMACHINE), “4.4.0”);

The files involved are:

/cmake/config-ix.cmake
/cmake/modules/GetTargetTriple.cmake
/include/llvm/Config/config.h.cmake
/include/llvm/Config/llvm-config.h.cmake
/include/llvm/Config/config.h.in
/include/llvm/Config/llvm-config.h.in

/tools/clang/lib/Frontend/InitHeaderSearch.cpp

I want to know what do you think about this solution. If you approve, I will send the patches.

The next step is to avoid the hardcoding of “c:/MinGW/lib/gcc”…

Thanks and Regards.
Fernando Pelliccioni.

This only works if the build == host.

I routinely build with build = darwin, host = mingw. I don't use CMake either.

If you can improve the search paths, that would be great, but please
bear in mind that your build approach isn't the only one.

deep

Sorry Sandeep,

I dont understand. What is your platform? Is it Darwin OS? Why you are using MinGW?
The patch only applies to Windows with MinGW.
Currently, the parameter “Arch” is hardcoded. I just want to obtain it at the ./configure process.

An alternative solution would be in compilation process, clang executes “g++ -dumpmachine” and get it in run-time.

Regards,
Fernando.

I deliver compilers for our target that run on MinGW, Darwin, and
Linux. I prefer to bootstrap those compilers from Darwin.

That means I'm not running MinGW and don't have a g++ to use -dumpmachine with.

deep

Please, Could you specify exactly how you compile clang?
I would like to reproduce it in order to find a solution for all possible cases.

Thanks.
Fernando.

In the case we're talking about my build starts with building a Darwin
-> ARM cross toolchain:

* build binutils for arm-eabi --build=i686-apple-darwin10
--host=i686-apple-darwin10
* build LLVM (with clang in llvm/tools/clang) with
--build=i686-apple-darwin10 --host=i686-apple-darwin10
* build llvm-gcc and newlib with --target=arm-eabi
--with-cpu=cortex-a9 --with-fpu=neon --with-abi=aapcs
--with-float=hard

The next step is to build a Darwin -> MinGW cross toolchain:

* build binutils for i686-pc-mingw32 --build=i686-apple-darwin10
--host=i686-apple-darwin10
* build LLVM (with clang in llvm/tools/clang) with
--build=i686-apple-darwin10 --host=i686-apple-darwin10
* build llvm-gcc and newlib with --target=i686-pc-mingw32
--enable-sjlj-exceptions --enable-threads=win32
--disable-win32-registry --disable-__cxa_atexit

Then I build a MinGW -> ARM cross toolchain, using the just built tools:

* build binutils for arm-eabi --build=i686-apple-darwin10 --host=i686-pc-mingw32
* build LLVM (with clang in llvm/tools/clang) with
--build=i686-apple-darwin10 --host=i686-pc-mingw32
* build llvm-gcc and newlib with --target=arm-eabi
--with-cpu=cortex-a9 --with-fpu=neon --with-abi=aapcs
--with-float=hard

The essential issue is that I never build directly on a MinGW machine.

deep

Yep. This is a not-uncommon scenario for embedded targets. At a previous job, we built our Windows hosted cross compilers on Linux in exactly this manner (i.e., a Canadian Cross configuration).

-Jim