2
* This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3
* http://www.gnu.org/licenses/gpl-3.0.html
6
* $Id: compilerMINGW.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
7
* $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/plugins/compilergcc/compilerMINGW.cpp $
12
#include "compilerMINGW.h"
15
#include <wx/config.h>
16
#include <wx/fileconf.h>
17
#include <wx/msgdlg.h>
18
#include <wx/filename.h>
19
#include <wx/filefn.h>
21
#include "logmanager.h"
22
#include "compilerMINGWgenerator.h"
24
#include <configmanager.h>
27
#include <wx/msw/registry.h>
30
CompilerMINGW::CompilerMINGW(const wxString& name, const wxString& ID)
36
CompilerMINGW::~CompilerMINGW()
41
Compiler * CompilerMINGW::CreateCopy()
43
Compiler* c = new CompilerMINGW(*this);
44
c->SetExtraPaths(m_ExtraPaths); // wxArrayString doesn't seem to be copied with the default copy ctor...
48
CompilerCommandGenerator* CompilerMINGW::GetCommandGenerator()
50
return new CompilerMINGWGenerator;
53
void CompilerMINGW::Reset()
55
if (platform::windows)
57
m_Programs.C = _T("mingw32-gcc.exe");
58
m_Programs.CPP = _T("mingw32-g++.exe");
59
m_Programs.LD = _T("mingw32-g++.exe");
60
m_Programs.DBG = _T("gdb.exe");
61
m_Programs.LIB = _T("ar.exe");
62
m_Programs.WINDRES = _T("windres.exe");
63
m_Programs.MAKE = _T("mingw32-make.exe");
67
m_Programs.C = _T("gcc");
68
m_Programs.CPP = _T("g++");
69
m_Programs.LD = _T("g++");
70
m_Programs.DBG = _T("gdb");
71
m_Programs.LIB = _T("ar");
72
m_Programs.WINDRES = _T("");
73
m_Programs.MAKE = _T("make");
75
m_Switches.includeDirs = _T("-I");
76
m_Switches.libDirs = _T("-L");
77
m_Switches.linkLibs = _T("-l");
78
m_Switches.defines = _T("-D");
79
m_Switches.genericSwitch = _T("-");
80
m_Switches.objectExtension = _T("o");
81
m_Switches.needDependencies = true;
82
m_Switches.forceCompilerUseQuotes = false;
83
m_Switches.forceLinkerUseQuotes = false;
84
m_Switches.logging = clogSimple;
85
m_Switches.libPrefix = _T("lib");
86
m_Switches.libExtension = _T("a");
87
m_Switches.linkerNeedsLibPrefix = false;
88
m_Switches.linkerNeedsLibExtension = false;
89
m_Switches.supportsPCH = true;
90
m_Switches.PCHExtension = _T("h.gch");
91
m_Switches.UseFullSourcePaths = true; // use the GDB workaround !!!!!!!!
93
// Summary of GCC options: http://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html
95
m_Options.ClearOptions();
96
m_Options.AddOption(_("Produce debugging symbols"),
101
_T("-O -O1 -O2 -O3 -Os"),
102
_("You have optimizations enabled. This is Not A Good Thing(tm) when producing debugging symbols..."));
103
wxString gprof_link = _T("-pg");
104
if (platform::windows)
105
gprof_link = _T("-pg -lgmon");
106
m_Options.AddOption(_("Profile code when executed"), _T("-pg"), _("Profiling"), gprof_link);
108
wxString category = _("Warnings");
111
m_Options.AddOption(_("In C mode, support all ISO C90 programs. In C++ mode, remove GNU extensions that conflict with ISO C++"), _T("-ansi"), category);
112
m_Options.AddOption(_("Enable all compiler warnings (overrides every other setting)"), _T("-Wall"), category);
113
m_Options.AddOption(_("Enable standard compiler warnings"), _T("-W"), category);
114
m_Options.AddOption(_("Stop compiling after first error"), _T("-Wfatal-errors"), category);
115
m_Options.AddOption(_("Inhibit all warning messages"), _T("-w"), category);
116
m_Options.AddOption(_("Enable warnings demanded by strict ISO C and ISO C++"), _T("-pedantic"), category);
117
m_Options.AddOption(_("Treat as errors the warnings demanded by strict ISO C and ISO C++"), _T("-pedantic-errors"), category);
118
m_Options.AddOption(_("Warn if main() is not conformant"), _T("-Wmain"), category);
120
category = _("Optimization");
121
m_Options.AddOption(_("Strip all symbols from binary (minimizes size)"), _T(""), category, _T("-s"), true, _T("-g -ggdb"), _("Stripping the binary will strip debugging symbols as well!"));
122
m_Options.AddOption(_("Optimize generated code (for speed)"), _T("-O"), category);
123
m_Options.AddOption(_("Optimize more (for speed)"), _T("-O1"), category);
124
m_Options.AddOption(_("Optimize even more (for speed)"), _T("-O2"), category);
125
m_Options.AddOption(_("Optimize fully (for speed)"), _T("-O3"), category);
126
m_Options.AddOption(_("Optimize generated code (for size)"), _T("-Os"), category);
127
m_Options.AddOption(_("Expensive optimizations"), _T("-fexpensive-optimizations"), category);
128
// machine dependent options - cpu arch
129
category = _("CPU architecture tuning (choose none, or only one of these)");
130
m_Options.AddOption(_("i386"), _T("-march=i386"), category);
131
m_Options.AddOption(_("i486"), _T("-march=i486"), category);
132
m_Options.AddOption(_("Intel Pentium"), _T("-march=i586"), category);
133
m_Options.AddOption(_("Intel Pentium (MMX)"), _T("-march=pentium-mmx"), category);
134
m_Options.AddOption(_("Intel Pentium PRO"), _T("-march=i686"), category);
135
m_Options.AddOption(_("Intel Pentium 2 (MMX)"), _T("-march=pentium2"), category);
136
m_Options.AddOption(_("Intel Pentium 3 (MMX, SSE)"), _T("-march=pentium3"), category);
137
m_Options.AddOption(_("Intel Pentium 4 (MMX, SSE, SSE2)"), _T("-march=pentium4"), category);
138
m_Options.AddOption(_("Intel Pentium 4 Prescott (MMX, SSE, SSE2, SSE3)"), _T("-march=prescott"), category);
139
m_Options.AddOption(_("Intel Pentium 4 Nocona (MMX, SSE, SSE2, SSE3, 64bit extensions)"), _T("-march=nocona"), category);
140
m_Options.AddOption(_("Intel Pentium M (MMX, SSE, SSE2)"), _T("-march=pentium-m"), category);
141
m_Options.AddOption(_("AMD K6 (MMX)"), _T("-march=k6"), category);
142
m_Options.AddOption(_("AMD K6-2 (MMX, 3DNow!)"), _T("-march=k6-2"), category);
143
m_Options.AddOption(_("AMD K6-3 (MMX, 3DNow!)"), _T("-march=k6-3"), category);
144
m_Options.AddOption(_("AMD Athlon (MMX, 3DNow!, enhanced 3DNow!, SSE prefetch)"), _T("-march=athlon"), category);
145
m_Options.AddOption(_("AMD Athlon Thunderbird (MMX, 3DNow!, enhanced 3DNow!, SSE prefetch)"), _T("-march=athlon-tbird"), category);
146
m_Options.AddOption(_("AMD Athlon 4 (MMX, 3DNow!, enhanced 3DNow!, full SSE)"), _T("-march=athlon-4"), category);
147
m_Options.AddOption(_("AMD Athlon XP (MMX, 3DNow!, enhanced 3DNow!, full SSE)"), _T("-march=athlon-xp"), category);
148
m_Options.AddOption(_("AMD Athlon MP (MMX, 3DNow!, enhanced 3DNow!, full SSE)"), _T("-march=athlon-mp"), category);
149
m_Options.AddOption(_("AMD K8 core (x86-64 instruction set)"), _T("-march=k8"), category);
150
m_Options.AddOption(_("AMD Opteron (x86-64 instruction set)"), _T("-march=opteron"), category);
151
m_Options.AddOption(_("AMD Athlon64 (x86-64 instruction set)"), _T("-march=athlon64"), category);
152
m_Options.AddOption(_("AMD Athlon-FX (x86-64 instruction set)"), _T("-march=athlon-fx"), category);
154
m_Commands[(int)ctCompileObjectCmd].push_back(CompilerTool(_T("$compiler $options $includes -c $file -o $object")));
155
m_Commands[(int)ctGenDependenciesCmd].push_back(CompilerTool(_T("$compiler -MM $options -MF $dep_object -MT $object $includes $file")));
156
m_Commands[(int)ctCompileResourceCmd].push_back(CompilerTool(_T("$rescomp -i $file -J rc -o $resource_output -O coff $res_includes")));
157
m_Commands[(int)ctLinkConsoleExeCmd].push_back(CompilerTool(_T("$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs")));
158
if (platform::windows)
160
m_Commands[(int)ctLinkNativeCmd].push_back(CompilerTool(_T("$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs --subsystem,native")));
161
m_Commands[(int)ctLinkExeCmd].push_back(CompilerTool(_T("$linker $libdirs -o $exe_output $link_objects $link_resobjects $link_options $libs -mwindows")));
162
m_Commands[(int)ctLinkDynamicCmd].push_back(CompilerTool(_T("$linker -shared -Wl,--output-def=$def_output -Wl,--out-implib=$static_output -Wl,--dll $libdirs $link_objects $link_resobjects -o $exe_output $link_options $libs")));
166
m_Commands[(int)ctLinkExeCmd] = m_Commands[(int)ctLinkConsoleExeCmd]; // no -mwindows
167
m_Commands[(int)ctLinkNativeCmd] = m_Commands[(int)ctLinkConsoleExeCmd]; // no -mwindows
168
m_Commands[(int)ctLinkDynamicCmd].push_back(CompilerTool(_T("$linker -shared $libdirs $link_objects $link_resobjects -o $exe_output $link_options $libs")));
170
m_Commands[(int)ctLinkStaticCmd].push_back(CompilerTool(_T("$lib_linker -r -s $static_output $link_objects")));
172
LoadDefaultRegExArray();
174
m_CompilerOptions.Clear();
175
m_LinkerOptions.Clear();
177
m_CmdsBefore.Clear();
182
void CompilerMINGW::LoadDefaultRegExArray()
185
m_RegExes.Add(RegExStruct(_("Fatal error"), cltError, _T("FATAL:[ \t]*(.*)"), 1));
186
m_RegExes.Add(RegExStruct(_("'In function...' info"), cltInfo, _T("(") + FilePathWithSpaces + _T("):[ \t]+") + _T("([iI]n ([cC]lass|[cC]onstructor|[dD]estructor|[fF]unction|[mM]ember [fF]unction).*)"), 2, 1));
187
m_RegExes.Add(RegExStruct(_("'Instantiated from' info"), cltInfo, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t]+([iI]nstantiated from .*)"), 3, 1, 2));
188
m_RegExes.Add(RegExStruct(_("Resource compiler error"), cltError, _T("windres.exe:[ \t](") + FilePathWithSpaces + _T("):([0-9]+):[ \t](.*)"), 3, 1, 2));
189
m_RegExes.Add(RegExStruct(_("Resource compiler error (2)"), cltError, _T("windres.exe:[ \t](.*)"), 1));
190
m_RegExes.Add(RegExStruct(_("Preprocessor warning"), cltWarning, _T("(") + FilePathWithSpaces + _T("):([0-9]+):([0-9]+):[ \t]([Ww]arning:[ \t].*)"), 4, 1, 2));
191
m_RegExes.Add(RegExStruct(_("Preprocessor error"), cltError, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[0-9]+:[ \t](.*)"), 3, 1, 2));
192
m_RegExes.Add(RegExStruct(_("Compiler note"), cltInfo, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t]([Nn]ote:[ \t].*)"), 3, 1, 2));
193
m_RegExes.Add(RegExStruct(_("General note"), cltInfo, _T("([Nn]ote:[ \t].*)"), 1));
194
m_RegExes.Add(RegExStruct(_("Compiler warning"), cltWarning, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t]([Ww]arning:[ \t].*)"), 3, 1, 2));
195
m_RegExes.Add(RegExStruct(_("Compiler error"), cltError, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[ \t](.*)"), 3, 1, 2));
196
m_RegExes.Add(RegExStruct(_("Linker error"), cltError, _T("(") + FilePathWithSpaces + _T("):([0-9]+):[0-9]+:[ \t](.*)"), 3, 1, 2));
197
m_RegExes.Add(RegExStruct(_("Linker error (2)"), cltError, FilePathWithSpaces + _T("\\(.text\\+[0-9A-Za-z]+\\):([ \tA-Za-z0-9_:+/\\.-]+):[ \t](.*)"), 2, 1));
198
m_RegExes.Add(RegExStruct(_("Linker error (lib not found)"), cltError, _T(".*(ld.*):[ \t](cannot find.*)"), 2, 1));
199
m_RegExes.Add(RegExStruct(_("Undefined reference"), cltError, _T("(") + FilePathWithSpaces + _T("):[ \t](undefined reference.*)"), 2, 1));
200
m_RegExes.Add(RegExStruct(_("General warning"), cltWarning, _T("([Ww]arning:[ \t].*)"), 1));
201
m_RegExes.Add(RegExStruct(_("Auto-import info"), cltInfo, _T("([Ii]nfo:[ \t].*)\\(auto-import\\)"), 1));
204
AutoDetectResult CompilerMINGW::AutoDetectInstallationDir()
206
// try to find MinGW in environment variable PATH first
208
list.AddEnvList(_T("PATH"));
209
wxString path = list.FindAbsoluteValidPath(m_Programs.C);
212
wxFileName fname(path);
213
fname.RemoveLastDir();
214
m_MasterPath = fname.GetPath(wxPATH_GET_VOLUME);
218
wxString sep = wxFileName::GetPathSeparator();
219
if (platform::windows)
221
// look first if MinGW was installed with Code::Blocks (new in beta6)
222
m_MasterPath = ConfigManager::GetExecutableFolder();
223
if (!wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C))
224
// if that didn't do it, look under C::B\MinGW, too (new in 08.02)
225
m_MasterPath += sep + _T("MinGW");
226
if (!wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C))
228
// no... search for MinGW installation dir
229
wxString windir = wxGetOSDirectory();
230
wxFileConfig ini(_T(""), _T(""), windir + _T("/MinGW.ini"), _T(""), wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_NO_ESCAPE_CHARACTERS);
231
m_MasterPath = ini.Read(_T("/InstallSettings/InstallPath"), _T("C:\\MinGW"));
232
if (!wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C))
234
#ifdef __WXMSW__ // for wxRegKey
236
// look for dev-cpp installation
237
wxRegKey key; // defaults to HKCR
238
key.SetName(_T("HKEY_LOCAL_MACHINE\\Software\\Dev-C++"));
239
if (key.Exists() && key.Open(wxRegKey::Read))
242
key.QueryValue(_T("Install_Dir"), m_MasterPath);
246
// installed by inno-setup
247
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Minimalist GNU for Windows 4.1_is1
250
key.SetName(_T("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
251
//key.SetName("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion");
252
bool ok = key.GetFirstKey(name, index);
253
while (ok && !name.StartsWith(_T("Minimalist GNU for Windows")))
255
ok = key.GetNextKey(name, index);
259
name = key.GetName() + _T("\\") + name;
261
if (key.Exists() && key.Open(wxRegKey::Read))
262
key.QueryValue(_T("InstallLocation"), m_MasterPath);
269
m_Programs.MAKE = _T("make.exe"); // we distribute "make" not "mingw32-make"
272
m_MasterPath = _T("/usr");
274
AutoDetectResult ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C) ? adrDetected : adrGuessed;
275
// don't add lib/include dirs. GCC knows where its files are located
281
void CompilerMINGW::SetVersionString()
283
wxArrayString output, errors;
284
wxString sep = wxFileName::GetPathSeparator();
285
wxString masterpath = m_MasterPath;
287
/* We should read the master path from the configuration manager as
288
* the m_MasterPath is empty if AutoDetectInstallationDir() is not
291
ConfigManager* cmgr = Manager::Get()->GetConfigManager(_T("compiler"));
293
cmgr->Read(_T("/sets/gcc/master_path"), &masterpath);
295
if (masterpath.IsEmpty())
297
if (platform::windows)
298
masterpath = _T("C:\\MinGW");
300
masterpath = _T("/usr");
302
wxString gcc_command = masterpath + sep + _T("bin") + sep + m_Programs.C;
303
if (!wxFileExists(gcc_command))
305
long result = wxExecute(gcc_command + _T(" --version"), output, errors, wxEXEC_NODISABLE);
308
Manager::Get()->GetLogManager()->DebugLog(_T("Error in executing ") + gcc_command);
312
if (output.GetCount() > 0)
315
if (reg_exp.Compile(_T("[0-9][.][0-9][.][0-9]")) && reg_exp.Matches(output[0]))
316
m_VersionString = reg_exp.GetMatch(output[0]);
319
m_VersionString = output[0].Mid(10);
320
m_VersionString = m_VersionString.Left(5);
321
m_VersionString.Trim(false);