Hi, all.
In the function below
wxArrayString NativeParser::GetGCCCompilerDirs(const wxString &cpp_compiler, const wxString &base)
{
wxArrayString gcc_compiler_dirs;
// for starters , only do this for gnu compiler
// Manager::Get()->GetLogManager()->DebugLog(_T("CompilerID ") + CompilerID);
// wxString Command("mingw32-g++ -v -E -x c++ - < nul");
// specifying "< nul", does not seem to work
// workaround : create a dummy file (let's hope it does not exist)
// do the trick only for c++, not needed then for C (since this is a subset of C++)
wxString DummyFileName = wxFileName::CreateTempFileName(_T("Dummy_z4hsdkl9nf7ba3L9nv41"));
if(!DummyFileName.IsEmpty())
{
// let's construct the command
wxString Command = cpp_compiler + _T(" -v -E -x c++ ") + DummyFileName;
// action time (everything shows up on the error stream
wxArrayString Output, Errors;
wxExecute(Command, Output, Errors, wxEXEC_NODISABLE);
int nCount = Errors.GetCount();
// the include dir (1 per line) show up between the lines
// #include <...> search starts here:
// End of search list
// let's hope this does not change too quickly, otherwise we need
// to adjust our search code (for several versions ...)
bool bStart = false;
for(int idxCount = 0; idxCount < nCount; ++idxCount)
{
if (!bStart && Errors[idxCount] == _("#include <...> search starts here:"))
{
bStart = true;
}
else if (bStart && Errors[idxCount] == _("End of search list."))
{
bStart = false; // could jump out of for loop if we want
}
else if (bStart)
{
// Manager::Get()->GetLogManager()->DebugLog("include dir " + Errors[idxCount]);
// get rid of the leading space (more general : any whitespace)in front
wxRegEx reg(_T("^[ \t]*(.*)"));
if(reg.Matches(Errors[idxCount]))
{
wxString out = reg.GetMatch(Errors[idxCount], 1);
if(!out.IsEmpty())
{
wxFileName dir(out);
if (NormalizePath(dir,base))
{
Manager::Get()->GetLogManager()->DebugLog(_T("Caching GCC dir: ") + dir.GetFullPath());
gcc_compiler_dirs.Add(dir.GetFullPath());
}
else
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Error normalizing path: '%s' from '%s'"),out.wx_str(),base.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Error normalizing path: '%s' from '%s'"),out.c_str(),base.c_str()));
#endif
}
}
}
} // end for : idx : idxCount
// clean up our temp file
::wxRemoveFile(DummyFileName);
} // Dummy is open
return gcc_compiler_dirs;
}
A dummy file will be created to input to the command line like:
mingw32-g++ -v -E -x c++ dummyfilename
So, we need to create a dummyfile and after getting all the include paths, we need to delete this file.
After search on Google for an hour, I found there is a way to avoid this:
See this page:
http://gcc.gnu.org/ml/gcc-help/2004-02/msg00142.html
it use these command, it use a minus sign to replace a dummy file name.
mingw32-g++ -v -E -x c++ -
Sees work fine in MinGW, here is the report:
D:\test>mingw32-g++ -v -E -x c++ -
Using built-in specs.
Target: mingw32
Configured with: ../gcc-4.4.0/configure --prefix=/mingw --build=mingw32 --enable
-languages=c,ada,c++,fortran,objc,obj-c++ --disable-nls --disable-win32-registry
--disable-werror --enable-threads --disable-symvers --enable-cxx-flags='-fno-fu
nction-sections -fno-data-sections' --enable-fully-dynamic-string --enable-libgo
mp --enable-version-specific-runtime-libs --enable-sjlj-exceptions --with-pkgver
sion='TDM-1 mingw32' --with-bugurl=http://www.tdragon.net/recentgcc/bugs.php
Thread model: win32
gcc version 4.4.0 (TDM-1 mingw32)
COLLECT_GCC_OPTIONS='-v' '-E' '-mtune=i386'
d:/mingw/bin/../libexec/gcc/mingw32/4.4.0/cc1plus.exe -E -quiet -v -iprefix d:\
mingw\bin\../lib/gcc/mingw32/4.4.0/ - -mtune=i386
ignoring nonexistent directory "d:\mingw\bin\../lib/gcc/mingw32/4.4.0/../../../.
./mingw32/include"
ignoring duplicate directory "d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.4.0/inclu
de/c++"
ignoring duplicate directory "d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.4.0/inclu
de/c++/mingw32"
ignoring duplicate directory "d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.4.0/inclu
de/c++/backward"
ignoring duplicate directory "/mingw/lib/gcc/mingw32/4.4.0/../../../../include"
ignoring duplicate directory "d:/mingw/lib/gcc/../../include"
ignoring duplicate directory "d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.4.0/inclu
de"
ignoring duplicate directory "d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.4.0/inclu
de-fixed"
ignoring nonexistent directory "d:/mingw/lib/gcc/../../lib/gcc/mingw32/4.4.0/../
../../../mingw32/include"
ignoring duplicate directory "/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
d:\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++
d:\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/mingw32
d:\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/backward
d:\mingw\bin\../lib/gcc/mingw32/4.4.0/../../../../include
d:\mingw\bin\../lib/gcc/mingw32/4.4.0/include
d:\mingw\bin\../lib/gcc/mingw32/4.4.0/include-fixed
End of search list.
Thanks. :D
Very nice finding, ollydbg. 8)
Instead of "-", I would use /dev/null or nul depending on operating system, since otherwise gcc will hang (at least does here). Also, if you already call g++, the -x c++ is not needed.
Now, the question is whether to call gcc or g++, actually it would be nice to always call the "correct" compiler depending on whether you compile C or C++ so include paths would be different for C (which they are in real, too) ... but projects may be mixed, and you don't want to call an external program for every single source file parsed...
Oh, Yes, you are right.
In MinGW, I found that if only use "-", then gcc will hang up. So, can this method be used in Windows?
Edit:
I'm sorry, I mis understand your previous message. Now I catch the point fully :D,
In Windows, this command works ( no hang up):
mingw32-g++ -v -E -x c++ nul
In Linux, this command works:
mingw32-g++ -v -E -x c++ /dev/null
In Linux, using "/dev/null" is better. I also found in the web page below:
http://www.linuxquestions.org/questions/showthread.php?p=2344101#post2344101
For the C or C++ issue, I think g++ is better, because it include all the C headers. :D
I add a patch in BerliOS
https://developer.berlios.de/patch/index.php?func=detailpatch&patch_id=2783&group_id=5358
I would be happier any dev can test that under Linux. :D